rust/hwphysics/src/lib.rs
changeset 15401 6e3e5be8b2e2
parent 15374 35c331f9308e
child 15402 52844baced17
equal deleted inserted replaced
15400:27915135f87f 15401:6e3e5be8b2e2
     8 use integral_geometry::Size;
     8 use integral_geometry::Size;
     9 use land2d::Land2D;
     9 use land2d::Land2D;
    10 
    10 
    11 use crate::{
    11 use crate::{
    12     collision::{CollisionData, CollisionProcessor, ContactData},
    12     collision::{CollisionData, CollisionProcessor, ContactData},
    13     common::{GearAllocator, GearData, GearDataAggregator, GearDataProcessor, GearId, Millis},
    13     common::{GearAllocator, GearId, Millis},
    14     physics::{PhysicsData, PhysicsProcessor},
    14     data::GearDataManager,
       
    15     physics::PhysicsProcessor,
    15     time::TimeProcessor,
    16     time::TimeProcessor,
    16 };
    17 };
    17 
    18 
    18 pub struct JoinedData {
       
    19     gear_id: GearId,
       
    20     physics: PhysicsData,
       
    21     collision: CollisionData,
       
    22     contact: ContactData,
       
    23 }
       
    24 
       
    25 pub struct World {
    19 pub struct World {
    26     allocator: GearAllocator,
    20     allocator: GearAllocator,
       
    21     data: GearDataManager,
    27     physics: PhysicsProcessor,
    22     physics: PhysicsProcessor,
    28     collision: CollisionProcessor,
    23     collision: CollisionProcessor,
    29     time: TimeProcessor,
    24     time: TimeProcessor,
    30 }
    25 }
    31 
    26 
    32 macro_rules! processor_map {
       
    33     ( $data_type: ident => $field: ident ) => {
       
    34         impl GearDataAggregator<$data_type> for World {
       
    35             fn find_processor(&mut self) -> &mut GearDataProcessor<$data_type> {
       
    36                 &mut self.$field
       
    37             }
       
    38         }
       
    39     };
       
    40 }
       
    41 
       
    42 processor_map!(PhysicsData => physics);
       
    43 processor_map!(CollisionData => collision);
       
    44 
       
    45 impl World {
    27 impl World {
    46     pub fn new(world_size: Size) -> Self {
    28     pub fn new(world_size: Size) -> Self {
       
    29         let mut data = GearDataManager::new();
       
    30         PhysicsProcessor::register_components(&mut data);
       
    31         CollisionProcessor::register_components(&mut data);
       
    32 
    47         Self {
    33         Self {
       
    34             data,
    48             allocator: GearAllocator::new(),
    35             allocator: GearAllocator::new(),
    49             physics: PhysicsProcessor::new(),
    36             physics: PhysicsProcessor::new(),
    50             collision: CollisionProcessor::new(world_size),
    37             collision: CollisionProcessor::new(world_size),
    51             time: TimeProcessor::new(),
    38             time: TimeProcessor::new(),
    52         }
    39         }
    57         self.allocator.alloc()
    44         self.allocator.alloc()
    58     }
    45     }
    59 
    46 
    60     #[inline]
    47     #[inline]
    61     pub fn delete_gear(&mut self, gear_id: GearId) {
    48     pub fn delete_gear(&mut self, gear_id: GearId) {
    62         self.physics.remove(gear_id);
    49         self.data.remove_all(gear_id);
    63         self.collision.remove(gear_id);
    50         self.collision.remove(gear_id);
    64         self.time.cancel(gear_id);
    51         self.time.cancel(gear_id);
    65         self.allocator.free(gear_id)
    52         self.allocator.free(gear_id)
    66     }
    53     }
    67 
    54 
    68     pub fn step(&mut self, time_step: Millis, land: &Land2D<u32>) {
    55     pub fn step(&mut self, time_step: Millis, land: &Land2D<u32>) {
    69         let updates = self.physics.process(time_step);
    56         let updates = self.physics.process(&mut self.data, time_step);
    70         let collision = self.collision.process(land, &updates);
    57         let collisions = self.collision.process(land, &updates);
    71         let events = self.time.process(time_step);
    58         let events = self.time.process(time_step);
    72     }
    59     }
    73 
    60 
    74     pub fn add_gear_data<T>(&mut self, gear_id: GearId, data: T)
    61     #[inline]
    75     where
    62     pub fn add_gear_data<T: Clone + 'static>(&mut self, gear_id: GearId, data: &T) {
    76         T: GearData,
    63         self.data.add(gear_id, data);
    77         Self: GearDataAggregator<T>,
       
    78     {
       
    79         self.find_processor().add(gear_id, data);
       
    80     }
    64     }
    81 }
    65 }
    82 
    66 
    83 #[cfg(test)]
    67 #[cfg(test)]
    84 mod tests {
    68 mod tests {
    85     use crate::{
    69     use crate::{
    86         collision::{CircleBounds, CollisionData},
    70         collision::{CircleBounds, CollisionData},
    87         common::Millis,
    71         common::Millis,
    88         physics::PhysicsData,
    72         physics::{PositionData, VelocityData},
    89         World,
    73         World,
    90     };
    74     };
    91     use fpnum::{fp, FPNum, FPPoint};
    75     use fpnum::{fp, FPNum, FPPoint};
    92     use integral_geometry::Size;
    76     use integral_geometry::Size;
    93     use land2d::Land2D;
    77     use land2d::Land2D;
    95     #[test]
    79     #[test]
    96     fn data_flow() {
    80     fn data_flow() {
    97         let world_size = Size::new(2048, 2048);
    81         let world_size = Size::new(2048, 2048);
    98 
    82 
    99         let mut world = World::new(world_size);
    83         let mut world = World::new(world_size);
   100         let gear_id = std::num::NonZeroU16::new(46631).unwrap();
    84         let gear_id = world.new_gear().unwrap();
       
    85 
       
    86         world.add_gear_data(gear_id, &PositionData(FPPoint::zero()));
       
    87         world.add_gear_data(gear_id, &VelocityData(FPPoint::unit_y()));
   101 
    88 
   102         world.add_gear_data(
    89         world.add_gear_data(
   103             gear_id,
    90             gear_id,
   104             PhysicsData {
    91             &CollisionData {
   105                 position: FPPoint::zero(),
       
   106                 velocity: FPPoint::unit_y(),
       
   107             },
       
   108         );
       
   109 
       
   110         world.add_gear_data(
       
   111             gear_id,
       
   112             CollisionData {
       
   113                 bounds: CircleBounds {
    92                 bounds: CircleBounds {
   114                     center: FPPoint::zero(),
    93                     center: FPPoint::zero(),
   115                     radius: fp!(10),
    94                     radius: fp!(10),
   116                 },
    95                 },
   117             },
    96             },