|
1 use crate::{ |
|
2 common::GearId |
|
3 }; |
|
4 use fpnum::*; |
|
5 use integral_geometry::{ |
|
6 Point, Size, GridIndex |
|
7 }; |
|
8 |
|
9 #[derive(PartialEq, Eq, Clone, Copy, Debug)] |
|
10 pub struct PhysicsData { |
|
11 pub position: FPPoint, |
|
12 pub velocity: FPPoint, |
|
13 } |
|
14 |
|
15 |
|
16 pub struct DynamicPhysicsCollection { |
|
17 gear_ids: Vec<GearId>, |
|
18 positions: Vec<FPPoint>, |
|
19 velocities: Vec<FPPoint>, |
|
20 } |
|
21 |
|
22 impl DynamicPhysicsCollection { |
|
23 fn len(&self) -> usize { |
|
24 self.gear_ids.len() |
|
25 } |
|
26 |
|
27 fn push(&mut self, id: GearId, physics: PhysicsData) { |
|
28 self.gear_ids.push(id); |
|
29 self.positions.push(physics.position); |
|
30 self.velocities.push(physics.velocity); |
|
31 } |
|
32 |
|
33 fn iter_pos_update(&mut self) -> impl Iterator<Item = (GearId, (&mut FPPoint, &FPPoint))> { |
|
34 self.gear_ids.iter().cloned() |
|
35 .zip(self.positions.iter_mut() |
|
36 .zip(self.velocities.iter())) |
|
37 } |
|
38 } |
|
39 |
|
40 pub struct StaticPhysicsCollection { |
|
41 gear_ids: Vec<GearId>, |
|
42 positions: Vec<FPPoint> |
|
43 } |
|
44 |
|
45 impl StaticPhysicsCollection { |
|
46 fn push(&mut self, gear_id: GearId, physics: PhysicsData) { |
|
47 self.gear_ids.push(gear_id); |
|
48 self.positions.push(physics.position); |
|
49 } |
|
50 } |
|
51 |
|
52 pub struct PhysicsProcessor { |
|
53 dynamic_physics: DynamicPhysicsCollection, |
|
54 static_physics: StaticPhysicsCollection, |
|
55 |
|
56 physics_cleanup: Vec<GearId>, |
|
57 position_updates: PositionUpdate |
|
58 } |
|
59 |
|
60 pub struct PositionUpdate { |
|
61 pub gear_ids: Vec<GearId>, |
|
62 pub positions: Vec<FPPoint> |
|
63 } |
|
64 |
|
65 impl PositionUpdate { |
|
66 pub fn new(capacity: usize) -> Self { |
|
67 Self { |
|
68 gear_ids: Vec::with_capacity(capacity), |
|
69 positions: Vec::with_capacity(capacity), |
|
70 } |
|
71 } |
|
72 |
|
73 pub fn push(&mut self, gear_id: GearId, position: &FPPoint) { |
|
74 self.gear_ids.push(gear_id); |
|
75 self.positions.push(*position); |
|
76 } |
|
77 } |
|
78 |
|
79 impl PhysicsProcessor { |
|
80 pub fn process(&mut self, time_step: FPNum) -> &PositionUpdate { |
|
81 for (gear_id, (pos, vel)) in self.dynamic_physics.iter_pos_update() { |
|
82 *pos += *vel * time_step; |
|
83 if !vel.is_zero() { |
|
84 self.position_updates.push(gear_id, pos) |
|
85 } else { |
|
86 self.physics_cleanup.push(gear_id) |
|
87 } |
|
88 } |
|
89 &self.position_updates |
|
90 } |
|
91 |
|
92 pub fn push(&mut self, gear_id: GearId, physics_data: PhysicsData) { |
|
93 if physics_data.velocity.is_zero() { |
|
94 self.static_physics.push(gear_id, physics_data); |
|
95 } else { |
|
96 self.dynamic_physics.push(gear_id, physics_data); |
|
97 } |
|
98 } |
|
99 } |