use grid only for static gears
authoralfadur
Tue, 25 Jan 2022 23:46:11 +0300
changeset 15827 64b0a5cead86
parent 15826 325c03494444
child 15828 44b49f255e31
use grid only for static gears
rust/hwphysics/src/collision.rs
rust/hwphysics/src/grid.rs
--- a/rust/hwphysics/src/collision.rs	Thu Dec 02 19:33:22 2021 +0100
+++ b/rust/hwphysics/src/collision.rs	Tue Jan 25 23:46:11 2022 +0300
@@ -114,11 +114,11 @@
     }
 
     pub fn add(&mut self, gear_id: GearId, gear_data: CollisionData) {
-        self.grid.insert_static(gear_id, &gear_data.bounds);
+        self.grid.insert(gear_id, &gear_data.bounds);
     }
 
     pub fn remove(&mut self, gear_id: GearId) {
-        self.grid.remove(gear_id);
+        self.grid.remove(gear_id, None);
     }
 
     pub fn get(&mut self, gear_id: GearId) -> Option<CollisionData> {
@@ -131,10 +131,6 @@
         updates: &crate::physics::PositionUpdates,
     ) -> &DetectedCollisions {
         self.detected_collisions.clear();
-        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() {
--- a/rust/hwphysics/src/grid.rs	Thu Dec 02 19:33:22 2021 +0100
+++ b/rust/hwphysics/src/grid.rs	Tue Jan 25 23:46:11 2022 +0300
@@ -7,20 +7,30 @@
 use integral_geometry::{GridIndex, Point, Size};
 
 struct GridBin {
-    static_refs: Vec<GearId>,
-    static_entries: Vec<CircleBounds>,
-
-    dynamic_refs: Vec<GearId>,
-    dynamic_entries: Vec<CircleBounds>,
+    refs: Vec<GearId>,
+    entries: Vec<CircleBounds>,
 }
 
 impl GridBin {
     fn new() -> Self {
         Self {
-            static_refs: vec![],
-            static_entries: vec![],
-            dynamic_refs: vec![],
-            dynamic_entries: vec![],
+            refs: vec![],
+            entries: vec![],
+        }
+    }
+
+    fn add(&mut self, gear_id: GearId, bounds: &CircleBounds) {
+        self.refs.push(gear_id);
+        self.entries.push(*bounds);
+    }
+
+    fn remove(&mut self, gear_id: GearId) -> bool {
+        if let Some(pos) = self.refs.iter().position(|id| *id == gear_id) {
+            self.refs.swap_remove(pos);
+            self.entries.swap_remove(pos);
+            true
+        } else {
+            false
         }
     }
 }
@@ -64,86 +74,33 @@
         self.get_bin(self.bin_index(position))
     }
 
-    pub fn insert_static(&mut self, gear_id: GearId, bounds: &CircleBounds) {
-        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) {
-        let bin = self.lookup_bin(&bounds.center);
-        bin.dynamic_refs.push(gear_id);
-        bin.dynamic_entries.push(*bounds);
+    pub fn insert(&mut self, gear_id: GearId, bounds: &CircleBounds) {
+        self.lookup_bin(&bounds.center).add(gear_id, bounds);
     }
 
-    pub fn remove(&mut self, gear_id: GearId) {}
-
-    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);
-
-        if let Some(old_bin) = self.try_get_bin(old_bin_index) {
-            let bounds = 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;
-                    None
-                } else {
-                    Some(old_bin.dynamic_entries.swap_remove(index))
-                }
-            } else if let Some(index) = old_bin.static_refs.iter().position(|id| *id == gear_id) {
-                old_bin.static_refs.swap_remove(index);
-                Some(old_bin.static_entries.swap_remove(index))
-            } else {
-                None
-            };
-
-            if let Some(bounds) = bounds {
-                let new_bin = if old_bin_index == new_bin_index {
-                    Some(old_bin)
-                } else {
-                    self.try_get_bin(new_bin_index)
-                };
-
-                if let Some(new_bin) = new_bin {
-                    new_bin.dynamic_refs.push(gear_id);
-                    new_bin.dynamic_entries.push(CircleBounds {
-                        center: *new_position,
-                        ..bounds
-                    });
-                }
+    fn remove_all(&mut self, gear_id: GearId) {
+        for bin in &mut self.bins {
+            if bin.remove(gear_id) {
+                break;
             }
         }
     }
 
+    pub fn remove(&mut self, gear_id: GearId, bounds: Option<&CircleBounds>) {
+        if let Some(bounds) = bounds {
+            if !self.lookup_bin(&bounds.center).remove(gear_id) {
+                self.remove_all(gear_id);
+            }
+        } else {
+            self.remove_all(gear_id);
+        }
+
+    }
+
     pub fn check_collisions(&self, collisions: &mut DetectedCollisions) {
         for bin in &self.bins {
-            for (index, bounds) in bin.dynamic_entries.iter().enumerate() {
-                for (other_index, other) in bin.dynamic_entries.iter().enumerate().skip(index + 1) {
-                    if bounds.intersects(other) && bounds != other {
-                        collisions.push(
-                            bin.dynamic_refs[index],
-                            Some(bin.dynamic_refs[other_index]),
-                            &((bounds.center + other.center) / 2),
-                        )
-                    }
-                }
+            for (index, bounds) in bin.entries.iter().enumerate() {
 
-                for (other_index, other) in bin.static_entries.iter().enumerate() {
-                    if bounds.intersects(other) {
-                        collisions.push(
-                            bin.dynamic_refs[index],
-                            Some(bin.static_refs[other_index]),
-                            &((bounds.center + other.center) / 2),
-                        )
-                    }
-                }
             }
         }
     }