1 use crate::common::{GearData, GearDataProcessor, GearId, Millis}; |
1 use crate::common::{GearData, GearDataLookup, GearDataProcessor, GearId, LookupEntry, Millis}; |
2 use fpnum::*; |
2 use fpnum::*; |
3 use integral_geometry::{GridIndex, Point, Size}; |
3 use integral_geometry::{GridIndex, Point, Size}; |
4 |
4 |
5 #[derive(PartialEq, Eq, Clone, Copy, Debug)] |
5 #[derive(PartialEq, Eq, Clone, Copy, Debug)] |
6 pub struct PhysicsData { |
6 pub struct PhysicsData { |
33 |
33 |
34 fn len(&self) -> usize { |
34 fn len(&self) -> usize { |
35 self.gear_ids.len() |
35 self.gear_ids.len() |
36 } |
36 } |
37 |
37 |
38 fn push(&mut self, gear_id: GearId, physics: PhysicsData) { |
38 fn push(&mut self, gear_id: GearId, physics: PhysicsData) -> u16 { |
39 self.gear_ids.push(gear_id); |
39 self.gear_ids.push(gear_id); |
40 self.positions.push(physics.position); |
40 self.positions.push(physics.position); |
41 self.velocities.push(physics.velocity); |
41 self.velocities.push(physics.velocity); |
|
42 |
|
43 (self.gear_ids.len() - 1) as u16 |
42 } |
44 } |
43 |
45 |
44 fn remove(&mut self, gear_id: GearId) { |
46 fn remove(&mut self, index: usize) -> Option<GearId> { |
45 if let Some(index) = self.gear_ids.iter().position(|id| *id == gear_id) { |
47 self.gear_ids.swap_remove(index); |
46 self.gear_ids.swap_remove(index); |
48 self.positions.swap_remove(index); |
47 self.positions.swap_remove(index); |
49 self.velocities.swap_remove(index); |
48 self.velocities.swap_remove(index); |
50 |
49 } |
51 self.gear_ids.get(index).cloned() |
50 } |
52 } |
51 |
53 |
52 fn iter_pos_update(&mut self) -> impl Iterator<Item = (GearId, (&mut FPPoint, &FPPoint))> { |
54 fn iter_pos_update(&mut self) -> impl Iterator<Item = (GearId, (&mut FPPoint, &FPPoint))> { |
53 self.gear_ids |
55 self.gear_ids |
54 .iter() |
56 .iter() |
68 gear_ids: Vec::new(), |
70 gear_ids: Vec::new(), |
69 positions: Vec::new(), |
71 positions: Vec::new(), |
70 } |
72 } |
71 } |
73 } |
72 |
74 |
73 fn push(&mut self, gear_id: GearId, physics: PhysicsData) { |
75 fn push(&mut self, gear_id: GearId, physics: PhysicsData) -> u16 { |
74 self.gear_ids.push(gear_id); |
76 self.gear_ids.push(gear_id); |
75 self.positions.push(physics.position); |
77 self.positions.push(physics.position); |
|
78 |
|
79 (self.gear_ids.len() - 1) as u16 |
76 } |
80 } |
77 |
81 |
78 fn remove(&mut self, gear_id: GearId) { |
82 fn remove(&mut self, index: usize) -> Option<GearId> { |
79 if let Some(index) = self.gear_ids.iter().position(|id| *id == gear_id) { |
83 self.gear_ids.swap_remove(index); |
80 self.gear_ids.swap_remove(index); |
84 self.positions.swap_remove(index); |
81 self.positions.swap_remove(index); |
85 |
82 } |
86 self.gear_ids.get(index).cloned() |
83 } |
87 } |
84 } |
88 } |
85 |
89 |
86 pub struct PhysicsProcessor { |
90 pub struct PhysicsProcessor { |
|
91 gear_lookup: GearDataLookup<bool>, |
87 dynamic_physics: DynamicPhysicsCollection, |
92 dynamic_physics: DynamicPhysicsCollection, |
88 static_physics: StaticPhysicsCollection, |
93 static_physics: StaticPhysicsCollection, |
89 |
94 |
90 physics_cleanup: Vec<GearId>, |
95 physics_cleanup: Vec<GearId>, |
91 position_updates: PositionUpdates, |
96 position_updates: PositionUpdates, |
124 } |
129 } |
125 |
130 |
126 impl PhysicsProcessor { |
131 impl PhysicsProcessor { |
127 pub fn new() -> Self { |
132 pub fn new() -> Self { |
128 Self { |
133 Self { |
|
134 gear_lookup: GearDataLookup::new(), |
129 dynamic_physics: DynamicPhysicsCollection::new(), |
135 dynamic_physics: DynamicPhysicsCollection::new(), |
130 static_physics: StaticPhysicsCollection::new(), |
136 static_physics: StaticPhysicsCollection::new(), |
131 physics_cleanup: Vec::new(), |
137 physics_cleanup: Vec::new(), |
132 position_updates: PositionUpdates::new(0), |
138 position_updates: PositionUpdates::new(0), |
133 } |
139 } |
145 self.physics_cleanup.push(gear_id) |
151 self.physics_cleanup.push(gear_id) |
146 } |
152 } |
147 } |
153 } |
148 &self.position_updates |
154 &self.position_updates |
149 } |
155 } |
150 |
|
151 pub fn push(&mut self, gear_id: GearId, physics_data: PhysicsData) { |
|
152 if physics_data.velocity.is_zero() { |
|
153 self.static_physics.push(gear_id, physics_data); |
|
154 } else { |
|
155 self.dynamic_physics.push(gear_id, physics_data); |
|
156 } |
|
157 } |
|
158 } |
156 } |
159 |
157 |
160 impl GearDataProcessor<PhysicsData> for PhysicsProcessor { |
158 impl GearDataProcessor<PhysicsData> for PhysicsProcessor { |
161 fn add(&mut self, gear_id: GearId, gear_data: PhysicsData) { |
159 fn add(&mut self, gear_id: GearId, gear_data: PhysicsData) { |
162 if gear_data.velocity.is_zero() { |
160 let is_dynamic = !gear_data.velocity.is_zero(); |
163 self.static_physics.push(gear_id, gear_data); |
161 let index = if is_dynamic { |
|
162 self.dynamic_physics.push(gear_id, gear_data) |
164 } else { |
163 } else { |
165 self.dynamic_physics.push(gear_id, gear_data); |
164 self.static_physics.push(gear_id, gear_data) |
166 } |
165 }; |
|
166 |
|
167 self.gear_lookup[gear_id] = LookupEntry::new(index, is_dynamic); |
167 } |
168 } |
168 |
169 |
169 fn remove(&mut self, gear_id: GearId) { |
170 fn remove(&mut self, gear_id: GearId) { |
170 self.static_physics.remove(gear_id); |
171 let location = self.gear_lookup[gear_id]; |
171 self.dynamic_physics.remove(gear_id) |
172 let relocated_gear_id = if location.value { |
|
173 self.dynamic_physics.remove(location.index as usize) |
|
174 } else { |
|
175 self.static_physics.remove(location.index as usize) |
|
176 }; |
|
177 |
|
178 if let Some(id) = relocated_gear_id { |
|
179 self.gear_lookup[id].index = location.index; |
|
180 } |
172 } |
181 } |
173 } |
182 } |