pull land into collision detector
authoralfadur
Tue, 06 Nov 2018 19:44:20 +0300
changeset 14144 165e43c3ed59
parent 14143 745c73e0e644
child 14145 7c1e0a854dd8
pull land into collision detector
rust/hwphysics/Cargo.toml
rust/hwphysics/src/lib.rs
rust/integral-geometry/src/lib.rs
rust/land2d/src/lib.rs
--- a/rust/hwphysics/Cargo.toml	Tue Nov 06 17:00:35 2018 +0100
+++ b/rust/hwphysics/Cargo.toml	Tue Nov 06 19:44:20 2018 +0300
@@ -7,3 +7,4 @@
 [dependencies]
 fpnum = { path = "../fpnum" }
 integral-geometry = { path = "../integral-geometry" }
+land2d = { path = "../land2d" }
--- 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);
--- a/rust/integral-geometry/src/lib.rs	Tue Nov 06 17:00:35 2018 +0100
+++ b/rust/integral-geometry/src/lib.rs	Tue Nov 06 19:44:20 2018 +0300
@@ -98,9 +98,14 @@
     }
 
     #[inline]
-    pub fn to_fppoint(&self) -> FPPoint {
+    pub fn to_fppoint(self) -> FPPoint {
         FPPoint::new(self.x.into(), self.y.into())
     }
+
+    #[inline]
+    pub fn from_fppoint(p: &FPPoint) -> Self {
+        Self::new(p.x().round(), p.y().round())
+    }
 }
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
--- a/rust/land2d/src/lib.rs	Tue Nov 06 17:00:35 2018 +0100
+++ b/rust/land2d/src/lib.rs	Tue Nov 06 19:44:20 2018 +0300
@@ -1,7 +1,10 @@
 extern crate integral_geometry;
 extern crate vec2d;
 
-use std::cmp;
+use std::{
+    cmp,
+    ops::Index
+};
 
 use integral_geometry::{ArcPoints, EquidistantPoints, Line, Point, Rect, Size, SizeMask};
 
@@ -295,6 +298,14 @@
     }
 }
 
+impl<T> Index<usize> for Land2D<T> {
+    type Output = [T];
+    #[inline]
+    fn index(&self, row: usize) -> &[T] {
+        &self.pixels[row]
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;