diff --git a/common/src/comp/phys.rs b/common/src/comp/phys.rs index bfe73179f7..de3ec7cfa3 100644 --- a/common/src/comp/phys.rs +++ b/common/src/comp/phys.rs @@ -26,8 +26,8 @@ impl Component for Vel { /// Used to defer writes to Pos/Vel in nested join loops #[derive(Copy, Clone, Debug)] pub struct PosVelDefer { - pub pos: Pos, - pub vel: Vel, + pub pos: Option, + pub vel: Option, } impl Component for PosVelDefer { diff --git a/common/sys/src/phys.rs b/common/sys/src/phys.rs index 3dd4560d69..832daef8ec 100644 --- a/common/sys/src/phys.rs +++ b/common/sys/src/phys.rs @@ -471,9 +471,10 @@ impl<'a> PhysicsData<'a> { .collect::>() .into_iter() .for_each(|(entity, pos, vel)| { - let _ = write - .pos_vel_defers - .insert(entity, PosVelDefer { pos, vel }); + let _ = write.pos_vel_defers.insert(entity, PosVelDefer { + pos: Some(pos), + vel: Some(vel), + }); }); drop(guard); @@ -580,6 +581,7 @@ impl<'a> PhysicsData<'a> { let mut land_on_ground = None; // Defer the writes of positions and velocities to allow an inner loop over // terrain-like entities + let old_vel = *vel; let mut vel = *vel; if sticky.is_some() && physics_state.on_surface().is_some() { @@ -877,10 +879,17 @@ impl<'a> PhysicsData<'a> { } } - *pos_vel_defer = PosVelDefer { - pos: Pos(tgt_pos), - vel, - }; + if tgt_pos != pos.0 { + pos_vel_defer.pos = Some(Pos(tgt_pos)); + } else { + pos_vel_defer.pos = None; + } + + if vel != old_vel { + pos_vel_defer.vel = Some(vel); + } else { + pos_vel_defer.vel = None; + } land_on_ground }, @@ -901,12 +910,16 @@ impl<'a> PhysicsData<'a> { &read.entities, &mut write.positions, &mut write.velocities, - &write.pos_vel_defers, + &mut write.pos_vel_defers, ) .join() { - *pos = pos_vel_defer.pos; - *vel = pos_vel_defer.vel; + if let Some(new_pos) = pos_vel_defer.pos.take() { + *pos = new_pos; + } + if let Some(new_vel) = pos_vel_defer.vel.take() { + *vel = new_vel; + } } drop(guard);