--- 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::*;