rust/hwphysics/src/physics.rs
changeset 14187 fae0dd90663b
parent 14184 abbb74b9cb62
child 14721 8e74d4eb89f5
equal deleted inserted replaced
14186:ec07ddc1a4a4 14187:fae0dd90663b
       
     1 use crate::{
       
     2     common::{GearId, GearData, GearDataProcessor}
       
     3 };
       
     4 use fpnum::*;
       
     5 use integral_geometry::{
       
     6     Point, Size, GridIndex
       
     7 };
       
     8 
       
     9 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
       
    10 pub struct PhysicsData {
       
    11     pub position: FPPoint,
       
    12     pub velocity: FPPoint,
       
    13 }
       
    14 
       
    15 impl GearData for PhysicsData {}
       
    16 
       
    17 pub struct DynamicPhysicsCollection {
       
    18     gear_ids: Vec<GearId>,
       
    19     positions: Vec<FPPoint>,
       
    20     velocities: Vec<FPPoint>,
       
    21 }
       
    22 
       
    23 impl DynamicPhysicsCollection {
       
    24     fn new() -> Self {
       
    25         Self {
       
    26             gear_ids: Vec::new(),
       
    27             positions: Vec::new(),
       
    28             velocities: Vec::new()
       
    29         }
       
    30     }
       
    31 
       
    32     fn len(&self) -> usize {
       
    33         self.gear_ids.len()
       
    34     }
       
    35 
       
    36     fn push(&mut self, id: GearId, physics: PhysicsData) {
       
    37         self.gear_ids.push(id);
       
    38         self.positions.push(physics.position);
       
    39         self.velocities.push(physics.velocity);
       
    40     }
       
    41 
       
    42     fn iter_pos_update(&mut self) -> impl Iterator<Item = (GearId, (&mut FPPoint, &FPPoint))> {
       
    43         self.gear_ids.iter().cloned()
       
    44             .zip(self.positions.iter_mut()
       
    45                 .zip(self.velocities.iter()))
       
    46     }
       
    47 }
       
    48 
       
    49 pub struct StaticPhysicsCollection {
       
    50     gear_ids: Vec<GearId>,
       
    51     positions: Vec<FPPoint>
       
    52 }
       
    53 
       
    54 impl StaticPhysicsCollection {
       
    55     fn new() -> Self {
       
    56         Self {
       
    57             gear_ids: Vec::new(),
       
    58             positions: Vec::new()
       
    59         }
       
    60     }
       
    61 
       
    62     fn push(&mut self, gear_id: GearId, physics: PhysicsData) {
       
    63         self.gear_ids.push(gear_id);
       
    64         self.positions.push(physics.position);
       
    65     }
       
    66 }
       
    67 
       
    68 pub struct PhysicsProcessor {
       
    69     dynamic_physics: DynamicPhysicsCollection,
       
    70     static_physics: StaticPhysicsCollection,
       
    71 
       
    72     physics_cleanup: Vec<GearId>,
       
    73     position_updates: PositionUpdates
       
    74 }
       
    75 
       
    76 pub struct PositionUpdates {
       
    77     pub gear_ids: Vec<GearId>,
       
    78     pub positions: Vec<FPPoint>
       
    79 }
       
    80 
       
    81 impl PositionUpdates {
       
    82     pub fn new(capacity: usize) -> Self {
       
    83         Self {
       
    84             gear_ids: Vec::with_capacity(capacity),
       
    85             positions: Vec::with_capacity(capacity),
       
    86         }
       
    87     }
       
    88 
       
    89     pub fn push(&mut self, gear_id: GearId, position: &FPPoint) {
       
    90         self.gear_ids.push(gear_id);
       
    91         self.positions.push(*position);
       
    92     }
       
    93 }
       
    94 
       
    95 impl PhysicsProcessor {
       
    96     pub fn new() -> Self {
       
    97         PhysicsProcessor {
       
    98             dynamic_physics: DynamicPhysicsCollection::new(),
       
    99             static_physics: StaticPhysicsCollection::new(),
       
   100             physics_cleanup: Vec::new(),
       
   101             position_updates: PositionUpdates::new(0)
       
   102         }
       
   103     }
       
   104 
       
   105     pub fn process(&mut self, time_step: FPNum) -> &PositionUpdates {
       
   106         for (gear_id, (pos, vel)) in self.dynamic_physics.iter_pos_update() {
       
   107             *pos += *vel * time_step;
       
   108             if !vel.is_zero() {
       
   109                 self.position_updates.push(gear_id, pos)
       
   110             } else {
       
   111                 self.physics_cleanup.push(gear_id)
       
   112             }
       
   113         }
       
   114         &self.position_updates
       
   115     }
       
   116 
       
   117     pub fn push(&mut self, gear_id: GearId, physics_data: PhysicsData) {
       
   118         if physics_data.velocity.is_zero() {
       
   119             self.static_physics.push(gear_id, physics_data);
       
   120         } else {
       
   121             self.dynamic_physics.push(gear_id, physics_data);
       
   122         }
       
   123     }
       
   124 }
       
   125 
       
   126 impl GearDataProcessor<PhysicsData> for PhysicsProcessor {
       
   127     fn add(&mut self, gear_id: GearId, gear_data: PhysicsData) {
       
   128         if gear_data.velocity.is_zero() {
       
   129             self.static_physics.push(gear_id, gear_data);
       
   130         } else {
       
   131             self.dynamic_physics.push(gear_id, gear_data);
       
   132         }
       
   133     }
       
   134 }