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