rust/hwphysics/src/lib.rs
changeset 14144 165e43c3ed59
parent 14059 c6745a1c827a
child 14178 a4c17cfaa4c9
equal deleted inserted replaced
14143:745c73e0e644 14144:165e43c3ed59
       
     1 use std::{
       
     2     ops::RangeInclusive
       
     3 };
       
     4 
     1 use fpnum::*;
     5 use fpnum::*;
     2 use integral_geometry::{
     6 use integral_geometry::{
     3     Point, Size, GridIndex
     7     Point, Size, GridIndex
     4 };
     8 };
       
     9 use land2d::Land2D;
     5 
    10 
     6 type Index = u16;
    11 type Index = u16;
     7 
    12 
     8 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    13 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
     9 struct PhysicsData {
    14 struct PhysicsData {
    10     position: FPPoint,
    15     position: FPPoint,
    11     velocity: FPPoint,
    16     velocity: FPPoint,
    12 }
    17 }
    13 
    18 
    14 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    19 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    15 struct CollisionData {
    20 struct  CollisionData {
    16     bounds: CircleBounds
    21     bounds: CircleBounds
    17 }
    22 }
    18 
    23 
    19 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    24 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    20 struct ContactData {
    25 struct ContactData {
    46 
    51 
    47 pub struct World {
    52 pub struct World {
    48     enabled_physics: PhysicsCollection,
    53     enabled_physics: PhysicsCollection,
    49     disabled_physics: Vec<PhysicsData>,
    54     disabled_physics: Vec<PhysicsData>,
    50 
    55 
    51     collision: Vec<CollisionData>,
    56     enabled_collision: Vec<CollisionData>,
       
    57     disabled_collision: Vec<CollisionData>,
    52     grid: Grid,
    58     grid: Grid,
    53 
    59 
    54     physics_cleanup: Vec<PhysicsData>,
    60     physics_cleanup: Vec<PhysicsData>,
    55     collision_output: Vec<(Index, Index)>
    61     collision_output: Vec<(Index, Index)>,
       
    62     land_collision_output: Vec<Index>
    56 }
    63 }
    57 
    64 
    58 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    65 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    59 struct CircleBounds {
    66 struct CircleBounds {
    60     center: FPPoint,
    67     center: FPPoint,
    61     radius: FPNum
    68     radius: FPNum
    62 }
    69 }
    63 
    70 
    64 impl CircleBounds {
    71 impl CircleBounds {
    65     fn intersects(&self, other: &CircleBounds) -> bool {
    72     pub fn intersects(&self, other: &CircleBounds) -> bool {
    66         (other.center - self.center).is_in_range(self.radius + other.radius)
    73         (other.center - self.center).is_in_range(self.radius + other.radius)
       
    74     }
       
    75 
       
    76     pub fn rows(&self) -> impl Iterator<Item = (usize, RangeInclusive<usize>)> {
       
    77         let radius = self.radius.abs_round() as usize;
       
    78         let center = Point::from_fppoint(&self.center);
       
    79         (center.y as usize - radius..=center.y as usize + radius)
       
    80             .map(move |row| (row, center.x as usize - radius..=center.x as usize + radius))
    67     }
    81     }
    68 }
    82 }
    69 
    83 
    70 fn fppoint_round(point: &FPPoint) -> Point {
    84 fn fppoint_round(point: &FPPoint) -> Point {
    71     Point::new(point.x().round() as i32, point.y().round() as i32)
    85     Point::new(point.x().round() as i32, point.y().round() as i32)
   146         }
   160         }
   147     }
   161     }
   148 }
   162 }
   149 
   163 
   150 impl World {
   164 impl World {
   151     pub fn step(&mut self, time_step: FPNum) {
   165     pub fn step(&mut self, time_step: FPNum, land: &Land2D<u32>) {
   152         for (pos, vel) in self.enabled_physics.iter_mut_pos() {
   166         for (pos, vel) in self.enabled_physics.iter_mut_pos() {
   153             *pos += *vel
   167             *pos += *vel
   154         }
   168         }
   155 
   169 
   156         self.grid.check_collisions(&mut self.collision_output);
   170         self.grid.check_collisions(&mut self.collision_output);
       
   171     }
       
   172 
       
   173     fn check_land_collisions(&mut self, land: &Land2D<u32>) {
       
   174         for collision in &self.enabled_collision {
       
   175             if collision.bounds.rows().any(|(y, r)| (&land[y][r]).iter().any(|v| *v != 0)) {
       
   176                 self.land_collision_output.push(0)
       
   177             }
       
   178         }
   157     }
   179     }
   158 
   180 
   159     pub fn add_gear(&mut self, data: JoinedData) {
   181     pub fn add_gear(&mut self, data: JoinedData) {
   160         if data.physics.velocity == FPPoint::zero() {
   182         if data.physics.velocity == FPPoint::zero() {
   161             self.disabled_physics.push(data.physics);
   183             self.disabled_physics.push(data.physics);