rust/hwphysics/src/collision.rs
changeset 14737 8e74d4eb89f5
parent 14723 29dbe9ce8b7d
child 15141 febccab419b1
equal deleted inserted replaced
14736:e519802076e9 14737:8e74d4eb89f5
     1 use std::{
     1 use std::ops::RangeInclusive;
     2     ops::RangeInclusive
       
     3 };
       
     4 
     2 
     5 use crate::{
     3 use crate::{
     6     common::{GearId, GearData, GearDataProcessor},
     4     common::{GearData, GearDataProcessor, GearId},
       
     5     grid::Grid,
     7     physics::PhysicsData,
     6     physics::PhysicsData,
     8     grid::Grid
       
     9 };
     7 };
    10 
     8 
    11 use fpnum::*;
     9 use fpnum::*;
    12 use integral_geometry::{
    10 use integral_geometry::{GridIndex, Point, Size};
    13     Point, Size, GridIndex
       
    14 };
       
    15 use land2d::Land2D;
    11 use land2d::Land2D;
    16 
    12 
    17 pub fn fppoint_round(point: &FPPoint) -> Point {
    13 pub fn fppoint_round(point: &FPPoint) -> Point {
    18     Point::new(point.x().round() as i32, point.y().round() as i32)
    14     Point::new(point.x().round() as i32, point.y().round() as i32)
    19 }
    15 }
    20 
    16 
    21 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    17 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    22 pub struct CircleBounds {
    18 pub struct CircleBounds {
    23     pub center: FPPoint,
    19     pub center: FPPoint,
    24     pub radius: FPNum
    20     pub radius: FPNum,
    25 }
    21 }
    26 
    22 
    27 impl CircleBounds {
    23 impl CircleBounds {
    28     pub fn intersects(&self, other: &CircleBounds) -> bool {
    24     pub fn intersects(&self, other: &CircleBounds) -> bool {
    29         (other.center - self.center).is_in_range(self.radius + other.radius)
    25         (other.center - self.center).is_in_range(self.radius + other.radius)
    37     }
    33     }
    38 }
    34 }
    39 
    35 
    40 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    36 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    41 pub struct CollisionData {
    37 pub struct CollisionData {
    42     pub bounds: CircleBounds
    38     pub bounds: CircleBounds,
    43 }
    39 }
    44 
    40 
    45 impl GearData for CollisionData {}
    41 impl GearData for CollisionData {}
    46 
    42 
    47 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    43 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
    48 pub struct ContactData {
    44 pub struct ContactData {
    49     pub elasticity: FPNum,
    45     pub elasticity: FPNum,
    50     pub friction: FPNum
    46     pub friction: FPNum,
    51 }
    47 }
    52 
    48 
    53 impl GearData for ContactData {}
    49 impl GearData for ContactData {}
    54 
    50 
    55 struct EnabledCollisionsCollection {
    51 struct EnabledCollisionsCollection {
    56     gear_ids: Vec<GearId>,
    52     gear_ids: Vec<GearId>,
    57     collisions: Vec<CollisionData>
    53     collisions: Vec<CollisionData>,
    58 }
    54 }
    59 
    55 
    60 impl EnabledCollisionsCollection {
    56 impl EnabledCollisionsCollection {
    61     fn new() -> Self {
    57     fn new() -> Self {
    62         Self {
    58         Self {
    63             gear_ids: Vec::new(),
    59             gear_ids: Vec::new(),
    64             collisions: Vec::new()
    60             collisions: Vec::new(),
    65         }
    61         }
    66     }
    62     }
    67 
    63 
    68     fn push(&mut self, gear_id: GearId, collision: CollisionData) {
    64     fn push(&mut self, gear_id: GearId, collision: CollisionData) {
    69         self.gear_ids.push(gear_id);
    65         self.gear_ids.push(gear_id);
    82     detected_collisions: DetectedCollisions,
    78     detected_collisions: DetectedCollisions,
    83 }
    79 }
    84 
    80 
    85 pub struct DetectedCollisions {
    81 pub struct DetectedCollisions {
    86     pub pairs: Vec<(GearId, GearId)>,
    82     pub pairs: Vec<(GearId, GearId)>,
    87     pub positions: Vec<Point>
    83     pub positions: Vec<Point>,
    88 }
    84 }
    89 
    85 
    90 impl DetectedCollisions {
    86 impl DetectedCollisions {
    91     pub fn new(capacity: usize) -> Self {
    87     pub fn new(capacity: usize) -> Self {
    92         Self {
    88         Self {
   104 impl CollisionProcessor {
   100 impl CollisionProcessor {
   105     pub fn new(size: Size) -> Self {
   101     pub fn new(size: Size) -> Self {
   106         Self {
   102         Self {
   107             grid: Grid::new(size),
   103             grid: Grid::new(size),
   108             enabled_collisions: EnabledCollisionsCollection::new(),
   104             enabled_collisions: EnabledCollisionsCollection::new(),
   109             detected_collisions: DetectedCollisions::new(0)
   105             detected_collisions: DetectedCollisions::new(0),
   110         }
   106         }
   111     }
   107     }
   112 
   108 
   113     pub fn process(&mut self, land: &Land2D<u32>, updates: &crate::physics::PositionUpdates) {
   109     pub fn process(&mut self, land: &Land2D<u32>, updates: &crate::physics::PositionUpdates) {
   114         self.grid.check_collisions(&mut self.detected_collisions);
   110         self.grid.check_collisions(&mut self.detected_collisions);
   115 
   111 
   116         for (gear_id, collision) in self.enabled_collisions.iter() {
   112         for (gear_id, collision) in self.enabled_collisions.iter() {
   117             if collision.bounds.rows().any(|(y, r)| (&land[y][r]).iter().any(|v| *v != 0)) {
   113             if collision
   118                 self.detected_collisions.push(gear_id, 0, &collision.bounds.center)
   114                 .bounds
       
   115                 .rows()
       
   116                 .any(|(y, r)| (&land[y][r]).iter().any(|v| *v != 0))
       
   117             {
       
   118                 self.detected_collisions
       
   119                     .push(gear_id, 0, &collision.bounds.center)
   119             }
   120             }
   120         }
   121         }
   121     }
   122     }
   122 }
   123 }
   123 
   124