# HG changeset patch # User alfadur # Date 1564000386 -10800 # Node ID 501dfa1c8deb67f39d29dbcc1856a93f4d2c980f # Parent 775d7efa4e5c94d5623f8c66d54c49e8989d9605 update collision grid with position changes diff -r 775d7efa4e5c -r 501dfa1c8deb rust/hwphysics/src/collision.rs --- a/rust/hwphysics/src/collision.rs Wed Jul 24 22:49:59 2019 +0300 +++ b/rust/hwphysics/src/collision.rs Wed Jul 24 23:33:06 2019 +0300 @@ -107,6 +107,9 @@ } pub fn process(&mut self, land: &Land2D, updates: &crate::physics::PositionUpdates) { + for (id, old_position, new_position) in updates.iter() { + self.grid.update_position(id, old_position, new_position) + } self.grid.check_collisions(&mut self.detected_collisions); for (gear_id, collision) in self.enabled_collisions.iter() { diff -r 775d7efa4e5c -r 501dfa1c8deb rust/hwphysics/src/grid.rs --- a/rust/hwphysics/src/grid.rs Wed Jul 24 22:49:59 2019 +0300 +++ b/rust/hwphysics/src/grid.rs Wed Jul 24 23:33:06 2019 +0300 @@ -7,16 +7,19 @@ use integral_geometry::{GridIndex, Point, Size}; struct GridBin { - refs: Vec, + static_refs: Vec, static_entries: Vec, + + dynamic_refs: Vec, dynamic_entries: Vec, } impl GridBin { fn new() -> Self { Self { - refs: vec![], + static_refs: vec![], static_entries: vec![], + dynamic_refs: vec![], dynamic_entries: vec![], } } @@ -48,19 +51,65 @@ self.index.map(fppoint_round(position)) } + fn get_bin(&mut self, index: Point) -> &mut GridBin { + &mut self.bins[index.x as usize * self.bins_count.width + index.y as usize] + } + fn lookup_bin(&mut self, position: &FPPoint) -> &mut GridBin { - let index = self.bin_index(position); - &mut self.bins[index.x as usize * self.bins_count.width + index.y as usize] + self.get_bin(self.bin_index(position)) } pub fn insert_static(&mut self, gear_id: GearId, bounds: &CircleBounds) { - self.lookup_bin(&bounds.center).static_entries.push(*bounds) + let bin = self.lookup_bin(&bounds.center); + bin.static_refs.push(gear_id); + bin.static_entries.push(*bounds) } pub fn insert_dynamic(&mut self, gear_id: GearId, bounds: &CircleBounds) { - self.lookup_bin(&bounds.center) - .dynamic_entries - .push(*bounds) + let bin = self.lookup_bin(&bounds.center); + bin.dynamic_refs.push(gear_id); + bin.dynamic_entries.push(*bounds); + } + + pub fn update_position( + &mut self, + gear_id: GearId, + old_position: &FPPoint, + new_position: &FPPoint, + ) { + let old_bin_index = self.bin_index(old_position); + let new_bin_index = self.bin_index(new_position); + + let old_bin = self.lookup_bin(old_position); + if let Some(index) = old_bin.static_refs.iter().position(|id| *id == gear_id) { + let bounds = old_bin.static_entries.swap_remove(index); + old_bin.static_refs.swap_remove(index); + + let new_bin = if old_bin_index == new_bin_index { + old_bin + } else { + self.get_bin(new_bin_index) + }; + + new_bin.dynamic_refs.push(gear_id); + new_bin.dynamic_entries.push(CircleBounds { + center: *new_position, + ..bounds + }); + } else if let Some(index) = old_bin.dynamic_refs.iter().position(|id| *id == gear_id) { + if old_bin_index == new_bin_index { + old_bin.dynamic_entries[index].center = *new_position + } else { + let bounds = old_bin.dynamic_entries.swap_remove(index); + let new_bin = self.get_bin(new_bin_index); + + new_bin.dynamic_refs.push(gear_id); + new_bin.dynamic_entries.push(CircleBounds { + center: *new_position, + ..bounds + }); + } + } } pub fn check_collisions(&self, collisions: &mut DetectedCollisions) { diff -r 775d7efa4e5c -r 501dfa1c8deb rust/hwphysics/src/physics.rs --- a/rust/hwphysics/src/physics.rs Wed Jul 24 22:49:59 2019 +0300 +++ b/rust/hwphysics/src/physics.rs Wed Jul 24 23:33:06 2019 +0300 @@ -93,6 +93,14 @@ self.gear_ids.push(gear_id); self.shifts.push((*old_position, *new_position)); } + + pub fn iter(&self) -> impl Iterator { + self.gear_ids + .iter() + .cloned() + .zip(self.shifts.iter()) + .map(|(id, (from, to))| (id, from, to)) + } } impl PhysicsProcessor {