rust/hwphysics/src/lib.rs
changeset 14179 abbb74b9cb62
parent 14178 a4c17cfaa4c9
child 14716 8e74d4eb89f5
equal deleted inserted replaced
14178:a4c17cfaa4c9 14179:abbb74b9cb62
     2 mod physics;
     2 mod physics;
     3 mod grid;
     3 mod grid;
     4 mod collision;
     4 mod collision;
     5 
     5 
     6 use fpnum::FPNum;
     6 use fpnum::FPNum;
       
     7 use integral_geometry::Size;
     7 use land2d::Land2D;
     8 use land2d::Land2D;
     8 
     9 
     9 use crate::{
    10 use crate::{
    10     common::GearId,
    11     common::{
       
    12         GearId,
       
    13         GearData,
       
    14         GearDataAggregator,
       
    15         GearDataProcessor
       
    16     },
    11     physics::{
    17     physics::{
    12         PhysicsProcessor,
    18         PhysicsProcessor,
    13         PhysicsData
    19         PhysicsData
    14     },
    20     },
    15     collision::{
    21     collision::{
    29 pub struct World {
    35 pub struct World {
    30     physics: PhysicsProcessor,
    36     physics: PhysicsProcessor,
    31     collision: CollisionProcessor,
    37     collision: CollisionProcessor,
    32 }
    38 }
    33 
    39 
       
    40 macro_rules! processor_map {
       
    41     ( $data_type: ident => $field: ident ) => {
       
    42         impl GearDataAggregator<$data_type> for World {
       
    43             fn find_processor(&mut self) -> &mut GearDataProcessor<$data_type> {
       
    44                 &mut self.$field
       
    45             }
       
    46         }
       
    47     }
       
    48 }
       
    49 
       
    50 processor_map!(PhysicsData => physics);
       
    51 processor_map!(CollisionData => collision);
       
    52 
    34 impl World {
    53 impl World {
       
    54     pub fn new(world_size: Size) -> Self {
       
    55         Self {
       
    56             physics: PhysicsProcessor::new(),
       
    57             collision: CollisionProcessor::new(world_size)
       
    58         }
       
    59     }
       
    60 
    35     pub fn step(&mut self, time_step: FPNum, land: &Land2D<u32>) {
    61     pub fn step(&mut self, time_step: FPNum, land: &Land2D<u32>) {
    36         let updates = self.physics.process(time_step);
    62         let updates = self.physics.process(time_step);
    37         self.collision.process(land, &updates);
    63         self.collision.process(land, &updates);
    38     }
    64     }
    39 
    65 
    40     pub fn add_gear(&mut self, data: JoinedData) {
    66     pub fn add_gear_data<T>(&mut self, gear_id: GearId, data: T)
    41         self.physics.push(data.gear_id, data.physics);
    67         where T: GearData,
    42         self.collision.push(data.gear_id, data.physics, data.collision);
    68               Self: GearDataAggregator<T>
       
    69     {
       
    70         self.find_processor().add(gear_id, data);
    43     }
    71     }
    44 }
    72 }
    45 
    73 
    46 #[cfg(test)]
    74 #[cfg(test)]
    47 mod tests {
    75 mod tests {
       
    76     use crate::{
       
    77         World,
       
    78         physics::PhysicsData,
       
    79         collision::{CollisionData, CircleBounds}
       
    80     };
       
    81     use fpnum::{FPNum, FPPoint, fp};
       
    82     use integral_geometry::Size;
       
    83     use land2d::Land2D;
    48 
    84 
       
    85     #[test]
       
    86     fn data_flow() {
       
    87         let world_size = Size::new(2048, 2048);
       
    88 
       
    89         let mut world = World::new(world_size);
       
    90         let gear_id = 46631;
       
    91 
       
    92         world.add_gear_data(gear_id, PhysicsData {
       
    93             position: FPPoint::zero(),
       
    94             velocity: FPPoint::unit_y()
       
    95         });
       
    96 
       
    97         world.add_gear_data(gear_id, CollisionData {
       
    98             bounds: CircleBounds {
       
    99                 center: FPPoint::zero(),
       
   100                 radius: fp!(10)
       
   101             }
       
   102         });
       
   103 
       
   104         let land = Land2D::new(Size::new(world_size.width - 2, world_size.height - 2), 0);
       
   105 
       
   106         world.step(fp!(1), &land);
       
   107     }
    49 }
   108 }