rust/hwphysics/src/physics.rs
changeset 15281 8095853811a6
parent 15275 66c987015f2d
child 15282 478d5372eb4a
equal deleted inserted replaced
15280:b12f63054c94 15281:8095853811a6
     1 use crate::common::{GearData, GearDataProcessor, GearId, Millis};
     1 use crate::common::{GearData, GearDataLookup, GearDataProcessor, GearId, LookupEntry, Millis};
     2 use fpnum::*;
     2 use fpnum::*;
     3 use integral_geometry::{GridIndex, Point, Size};
     3 use integral_geometry::{GridIndex, Point, Size};
     4 
     4 
     5 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
     5 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
     6 pub struct PhysicsData {
     6 pub struct PhysicsData {
    33 
    33 
    34     fn len(&self) -> usize {
    34     fn len(&self) -> usize {
    35         self.gear_ids.len()
    35         self.gear_ids.len()
    36     }
    36     }
    37 
    37 
    38     fn push(&mut self, gear_id: GearId, physics: PhysicsData) {
    38     fn push(&mut self, gear_id: GearId, physics: PhysicsData) -> u16 {
    39         self.gear_ids.push(gear_id);
    39         self.gear_ids.push(gear_id);
    40         self.positions.push(physics.position);
    40         self.positions.push(physics.position);
    41         self.velocities.push(physics.velocity);
    41         self.velocities.push(physics.velocity);
       
    42 
       
    43         (self.gear_ids.len() - 1) as u16
    42     }
    44     }
    43 
    45 
    44     fn remove(&mut self, gear_id: GearId) {
    46     fn remove(&mut self, index: usize) -> Option<GearId> {
    45         if let Some(index) = self.gear_ids.iter().position(|id| *id == gear_id) {
    47         self.gear_ids.swap_remove(index);
    46             self.gear_ids.swap_remove(index);
    48         self.positions.swap_remove(index);
    47             self.positions.swap_remove(index);
    49         self.velocities.swap_remove(index);
    48             self.velocities.swap_remove(index);
    50 
    49         }
    51         self.gear_ids.get(index).cloned()
    50     }
    52     }
    51 
    53 
    52     fn iter_pos_update(&mut self) -> impl Iterator<Item = (GearId, (&mut FPPoint, &FPPoint))> {
    54     fn iter_pos_update(&mut self) -> impl Iterator<Item = (GearId, (&mut FPPoint, &FPPoint))> {
    53         self.gear_ids
    55         self.gear_ids
    54             .iter()
    56             .iter()
    68             gear_ids: Vec::new(),
    70             gear_ids: Vec::new(),
    69             positions: Vec::new(),
    71             positions: Vec::new(),
    70         }
    72         }
    71     }
    73     }
    72 
    74 
    73     fn push(&mut self, gear_id: GearId, physics: PhysicsData) {
    75     fn push(&mut self, gear_id: GearId, physics: PhysicsData) -> u16 {
    74         self.gear_ids.push(gear_id);
    76         self.gear_ids.push(gear_id);
    75         self.positions.push(physics.position);
    77         self.positions.push(physics.position);
       
    78 
       
    79         (self.gear_ids.len() - 1) as u16
    76     }
    80     }
    77 
    81 
    78     fn remove(&mut self, gear_id: GearId) {
    82     fn remove(&mut self, index: usize) -> Option<GearId> {
    79         if let Some(index) = self.gear_ids.iter().position(|id| *id == gear_id) {
    83         self.gear_ids.swap_remove(index);
    80             self.gear_ids.swap_remove(index);
    84         self.positions.swap_remove(index);
    81             self.positions.swap_remove(index);
    85 
    82         }
    86         self.gear_ids.get(index).cloned()
    83     }
    87     }
    84 }
    88 }
    85 
    89 
    86 pub struct PhysicsProcessor {
    90 pub struct PhysicsProcessor {
       
    91     gear_lookup: GearDataLookup<bool>,
    87     dynamic_physics: DynamicPhysicsCollection,
    92     dynamic_physics: DynamicPhysicsCollection,
    88     static_physics: StaticPhysicsCollection,
    93     static_physics: StaticPhysicsCollection,
    89 
    94 
    90     physics_cleanup: Vec<GearId>,
    95     physics_cleanup: Vec<GearId>,
    91     position_updates: PositionUpdates,
    96     position_updates: PositionUpdates,
   124 }
   129 }
   125 
   130 
   126 impl PhysicsProcessor {
   131 impl PhysicsProcessor {
   127     pub fn new() -> Self {
   132     pub fn new() -> Self {
   128         Self {
   133         Self {
       
   134             gear_lookup: GearDataLookup::new(),
   129             dynamic_physics: DynamicPhysicsCollection::new(),
   135             dynamic_physics: DynamicPhysicsCollection::new(),
   130             static_physics: StaticPhysicsCollection::new(),
   136             static_physics: StaticPhysicsCollection::new(),
   131             physics_cleanup: Vec::new(),
   137             physics_cleanup: Vec::new(),
   132             position_updates: PositionUpdates::new(0),
   138             position_updates: PositionUpdates::new(0),
   133         }
   139         }
   145                 self.physics_cleanup.push(gear_id)
   151                 self.physics_cleanup.push(gear_id)
   146             }
   152             }
   147         }
   153         }
   148         &self.position_updates
   154         &self.position_updates
   149     }
   155     }
   150 
       
   151     pub fn push(&mut self, gear_id: GearId, physics_data: PhysicsData) {
       
   152         if physics_data.velocity.is_zero() {
       
   153             self.static_physics.push(gear_id, physics_data);
       
   154         } else {
       
   155             self.dynamic_physics.push(gear_id, physics_data);
       
   156         }
       
   157     }
       
   158 }
   156 }
   159 
   157 
   160 impl GearDataProcessor<PhysicsData> for PhysicsProcessor {
   158 impl GearDataProcessor<PhysicsData> for PhysicsProcessor {
   161     fn add(&mut self, gear_id: GearId, gear_data: PhysicsData) {
   159     fn add(&mut self, gear_id: GearId, gear_data: PhysicsData) {
   162         if gear_data.velocity.is_zero() {
   160         let is_dynamic = !gear_data.velocity.is_zero();
   163             self.static_physics.push(gear_id, gear_data);
   161         let index = if is_dynamic {
       
   162             self.dynamic_physics.push(gear_id, gear_data)
   164         } else {
   163         } else {
   165             self.dynamic_physics.push(gear_id, gear_data);
   164             self.static_physics.push(gear_id, gear_data)
   166         }
   165         };
       
   166 
       
   167         self.gear_lookup[gear_id] = LookupEntry::new(index, is_dynamic);
   167     }
   168     }
   168 
   169 
   169     fn remove(&mut self, gear_id: GearId) {
   170     fn remove(&mut self, gear_id: GearId) {
   170         self.static_physics.remove(gear_id);
   171         let location = self.gear_lookup[gear_id];
   171         self.dynamic_physics.remove(gear_id)
   172         let relocated_gear_id = if location.value {
       
   173             self.dynamic_physics.remove(location.index as usize)
       
   174         } else {
       
   175             self.static_physics.remove(location.index as usize)
       
   176         };
       
   177 
       
   178         if let Some(id) = relocated_gear_id {
       
   179             self.gear_lookup[id].index = location.index;
       
   180         }
   172     }
   181     }
   173 }
   182 }