rust/hwphysics/src/lib.rs
branchhedgeroid
changeset 15510 7030706266df
parent 15383 701ad89a9f2a
child 15762 84c07aa94b61
equal deleted inserted replaced
7861:bc7b6aa5d67a 15510:7030706266df
       
     1 pub mod collision;
       
     2 pub mod common;
       
     3 mod data;
       
     4 mod grid;
       
     5 pub mod physics;
       
     6 pub mod time;
       
     7 
       
     8 use integral_geometry::Size;
       
     9 use land2d::Land2D;
       
    10 
       
    11 use crate::{
       
    12     collision::CollisionProcessor,
       
    13     common::{GearAllocator, GearId, Millis},
       
    14     data::GearDataManager,
       
    15     physics::PhysicsProcessor,
       
    16     time::TimeProcessor,
       
    17 };
       
    18 
       
    19 pub struct World {
       
    20     allocator: GearAllocator,
       
    21     data: GearDataManager,
       
    22     physics: PhysicsProcessor,
       
    23     collision: CollisionProcessor,
       
    24     time: TimeProcessor,
       
    25 }
       
    26 
       
    27 impl World {
       
    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 
       
    33         Self {
       
    34             data,
       
    35             allocator: GearAllocator::new(),
       
    36             physics: PhysicsProcessor::new(),
       
    37             collision: CollisionProcessor::new(world_size),
       
    38             time: TimeProcessor::new(),
       
    39         }
       
    40     }
       
    41 
       
    42     #[inline]
       
    43     pub fn new_gear(&mut self) -> Option<GearId> {
       
    44         self.allocator.alloc()
       
    45     }
       
    46 
       
    47     #[inline]
       
    48     pub fn delete_gear(&mut self, gear_id: GearId) {
       
    49         self.data.remove_all(gear_id);
       
    50         self.collision.remove(gear_id);
       
    51         self.time.cancel(gear_id);
       
    52         self.allocator.free(gear_id)
       
    53     }
       
    54 
       
    55     pub fn step(&mut self, time_step: Millis, land: &Land2D<u32>) {
       
    56         let updates = if time_step == Millis::new(1) {
       
    57             self.physics.process_single_tick(&mut self.data)
       
    58         } else {
       
    59             self.physics
       
    60                 .process_multiple_ticks(&mut self.data, time_step)
       
    61         };
       
    62         let collisions = self.collision.process(land, &updates);
       
    63         let events = self.time.process(time_step);
       
    64     }
       
    65 
       
    66     #[inline]
       
    67     pub fn add_gear_data<T: Clone + 'static>(&mut self, gear_id: GearId, data: &T) {
       
    68         self.data.add(gear_id, data);
       
    69     }
       
    70 }
       
    71 
       
    72 #[cfg(test)]
       
    73 mod tests {
       
    74     use crate::{
       
    75         collision::{CircleBounds, CollisionData},
       
    76         common::Millis,
       
    77         physics::{PositionData, VelocityData},
       
    78         World,
       
    79     };
       
    80     use fpnum::{fp, FPNum, FPPoint};
       
    81     use integral_geometry::Size;
       
    82     use land2d::Land2D;
       
    83 
       
    84     #[test]
       
    85     fn data_flow() {
       
    86         let world_size = Size::new(2048, 2048);
       
    87 
       
    88         let mut world = World::new(world_size);
       
    89         let gear_id = world.new_gear().unwrap();
       
    90 
       
    91         world.add_gear_data(gear_id, &PositionData(FPPoint::zero()));
       
    92         world.add_gear_data(gear_id, &VelocityData(FPPoint::unit_y()));
       
    93 
       
    94         world.add_gear_data(
       
    95             gear_id,
       
    96             &CollisionData {
       
    97                 bounds: CircleBounds {
       
    98                     center: FPPoint::zero(),
       
    99                     radius: fp!(10),
       
   100                 },
       
   101             },
       
   102         );
       
   103 
       
   104         let land = Land2D::new(Size::new(world_size.width - 2, world_size.height - 2), 0);
       
   105 
       
   106         world.step(Millis::new(1), &land);
       
   107     }
       
   108 }