rust/hwphysics/src/lib.rs
changeset 14165 165e43c3ed59
parent 14080 c6745a1c827a
child 14199 a4c17cfaa4c9
--- a/rust/hwphysics/src/lib.rs	Tue Nov 06 17:00:35 2018 +0100
+++ b/rust/hwphysics/src/lib.rs	Tue Nov 06 19:44:20 2018 +0300
@@ -1,7 +1,12 @@
+use std::{
+    ops::RangeInclusive
+};
+
 use fpnum::*;
 use integral_geometry::{
     Point, Size, GridIndex
 };
+use land2d::Land2D;
 
 type Index = u16;
 
@@ -12,7 +17,7 @@
 }
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
-struct CollisionData {
+struct  CollisionData {
     bounds: CircleBounds
 }
 
@@ -48,11 +53,13 @@
     enabled_physics: PhysicsCollection,
     disabled_physics: Vec<PhysicsData>,
 
-    collision: Vec<CollisionData>,
+    enabled_collision: Vec<CollisionData>,
+    disabled_collision: Vec<CollisionData>,
     grid: Grid,
 
     physics_cleanup: Vec<PhysicsData>,
-    collision_output: Vec<(Index, Index)>
+    collision_output: Vec<(Index, Index)>,
+    land_collision_output: Vec<Index>
 }
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
@@ -62,9 +69,16 @@
 }
 
 impl CircleBounds {
-    fn intersects(&self, other: &CircleBounds) -> bool {
+    pub fn intersects(&self, other: &CircleBounds) -> bool {
         (other.center - self.center).is_in_range(self.radius + other.radius)
     }
+
+    pub fn rows(&self) -> impl Iterator<Item = (usize, RangeInclusive<usize>)> {
+        let radius = self.radius.abs_round() as usize;
+        let center = Point::from_fppoint(&self.center);
+        (center.y as usize - radius..=center.y as usize + radius)
+            .map(move |row| (row, center.x as usize - radius..=center.x as usize + radius))
+    }
 }
 
 fn fppoint_round(point: &FPPoint) -> Point {
@@ -148,7 +162,7 @@
 }
 
 impl World {
-    pub fn step(&mut self, time_step: FPNum) {
+    pub fn step(&mut self, time_step: FPNum, land: &Land2D<u32>) {
         for (pos, vel) in self.enabled_physics.iter_mut_pos() {
             *pos += *vel
         }
@@ -156,6 +170,14 @@
         self.grid.check_collisions(&mut self.collision_output);
     }
 
+    fn check_land_collisions(&mut self, land: &Land2D<u32>) {
+        for collision in &self.enabled_collision {
+            if collision.bounds.rows().any(|(y, r)| (&land[y][r]).iter().any(|v| *v != 0)) {
+                self.land_collision_output.push(0)
+            }
+        }
+    }
+
     pub fn add_gear(&mut self, data: JoinedData) {
         if data.physics.velocity == FPPoint::zero() {
             self.disabled_physics.push(data.physics);