diff --git a/common/src/comp/phys.rs b/common/src/comp/phys.rs index 29dfbcc565..88e4a64032 100644 --- a/common/src/comp/phys.rs +++ b/common/src/comp/phys.rs @@ -100,7 +100,7 @@ pub struct PhysicsState { } impl PhysicsState { - pub fn clear(&mut self) { + pub fn reset(&mut self) { // Avoid allocation overhead! let mut touch_entities = std::mem::take(&mut self.touch_entities); touch_entities.clear(); diff --git a/common/src/path.rs b/common/src/path.rs index de70785a48..cf02e684ae 100644 --- a/common/src/path.rs +++ b/common/src/path.rs @@ -418,7 +418,7 @@ impl Chaser { }); if !walking_towards_edge { - Some(((tgt - pos) * Vec3::new(1.0, 1.0, 0.0), 0.75)) + Some(((tgt - pos) * Vec3::new(1.0, 1.0, 0.0), 1.0)) } else { None } @@ -458,7 +458,7 @@ where let is_walkable = |pos: &Vec3| walkable(vol, *pos); let get_walkable_z = |pos| { let mut z_incr = 0; - for _ in 0..128 { + for _ in 0..32 { let test_pos = pos + Vec3::unit_z() * z_incr; if is_walkable(&test_pos) { return Some(test_pos); diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 4be1d1eee0..9491296d7c 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -11,8 +11,8 @@ use crate::{ }; use rayon::iter::ParallelIterator; use specs::{ - saveload::MarkerAllocator, storage, Entities, Join, ParJoin, Read, ReadExpect, ReadStorage, - System, WriteStorage, + saveload::MarkerAllocator, Entities, Join, ParJoin, Read, ReadExpect, ReadStorage, System, + WriteStorage, }; use std::ops::Range; use vek::*; @@ -96,25 +96,18 @@ impl<'a> System<'a> for Sys { let mut event_emitter = event_bus.emitter(); // Add/reset physics state components - for entity in ( + for (entity, _, _, _, _) in ( &entities, - !&physics_states, &colliders, &positions, &velocities, &orientations, ) .join() - .map(|(e, _, _, _, _, _)| e) - .collect::>() { - match physics_states.entry(entity) { - Ok(storage::StorageEntry::Occupied(mut o)) => o.get_mut().clear(), - Ok(storage::StorageEntry::Vacant(v)) => { - v.insert(Default::default()); - }, - Err(_) => {}, - } + let _ = physics_states + .entry(entity) + .map(|e| e.or_insert_with(Default::default)); } // Apply pushback @@ -159,6 +152,8 @@ impl<'a> System<'a> for Sys { .and_then(|uid| uid_allocator.retrieve_entity_internal(uid.into())) .and_then(|e| groups.get(e)); + let mut vel_delta = Vec3::zero(); + for ( entity_other, other, @@ -200,23 +195,17 @@ impl<'a> System<'a> for Sys { let vel_other = velocities.get(entity_other).copied().unwrap_or_default().0; // Sanity check: don't try colliding entities that are too far from each other - // Note: I think this catches all cases. If you get entitiy collision problems, + // Note: I think this catches all cases. If you get entity collision problems, // try removing this! if (pos.0 - pos_other.0).magnitude() - > ((vel + vel_other) * dt.0).magnitude() + collision_dist + > ((vel - vel_other) * dt.0).magnitude() + collision_dist { continue; } let min_collision_dist = 0.3; - // Ideally we'd deal with collision speed to minimise work here, but for not - // taking the maximum velocity of the two is fine. - let increments = (vel - .magnitude_squared() - .max(vel_other.magnitude_squared()) - .sqrt() - * dt.0 - / min_collision_dist) + let increments = ((vel - vel_other).magnitude() * dt.0 / min_collision_dist) + .max(1.0) .ceil() as usize; let step_delta = 1.0 / increments as f32; let mut collided = false; @@ -241,16 +230,18 @@ impl<'a> System<'a> for Sys { let force = 40.0 * (collision_dist - diff.magnitude()) * mass_other / (mass + mass_other); - // Change velocity - velocities.get_mut(entity).map(|vel| { - vel.0 += Vec3::from(diff.normalized()) * force * dt.0 * step_delta - }); + vel_delta += Vec3::from(diff.normalized()) * force * step_delta; } collided = true; } } } + + // Change velocity + velocities + .get_mut(entity) + .map(|vel| vel.0 += vel_delta * dt.0); } // Apply movement inputs @@ -258,7 +249,7 @@ impl<'a> System<'a> for Sys { &entities, scales.maybe(), stickies.maybe(), - colliders.maybe(), + &colliders, &mut positions, &mut velocities, &mut orientations, @@ -318,7 +309,7 @@ impl<'a> System<'a> for Sys { Vec3::zero() }; - match collider.copied().unwrap_or(Collider::Point) { + match *collider { Collider::Box { radius, z_min,