author | alfadur |
Sat, 31 Aug 2019 22:30:29 +0300 | |
changeset 15408 | 90a79670de52 |
parent 15404 | 701ad89a9f2a |
child 15413 | b387a51705ac |
permissions | -rw-r--r-- |
15401 | 1 |
use crate::{ |
2 |
common::{GearId, Millis}, |
|
3 |
data::GearDataManager, |
|
4 |
}; |
|
15141 | 5 |
use fpnum::*; |
6 |
||
7 |
#[derive(PartialEq, Eq, Clone, Copy, Debug)] |
|
15401 | 8 |
#[repr(transparent)] |
9 |
pub struct PositionData(pub FPPoint); |
|
15141 | 10 |
|
15401 | 11 |
#[derive(PartialEq, Eq, Clone, Copy, Debug)] |
12 |
#[repr(transparent)] |
|
13 |
pub struct VelocityData(pub FPPoint); |
|
15141 | 14 |
|
15 |
pub struct PositionUpdates { |
|
16 |
pub gear_ids: Vec<GearId>, |
|
15281 | 17 |
pub shifts: Vec<(FPPoint, FPPoint)>, |
15141 | 18 |
} |
19 |
||
20 |
impl PositionUpdates { |
|
21 |
pub fn new(capacity: usize) -> Self { |
|
22 |
Self { |
|
23 |
gear_ids: Vec::with_capacity(capacity), |
|
15281 | 24 |
shifts: Vec::with_capacity(capacity), |
15141 | 25 |
} |
26 |
} |
|
27 |
||
15281 | 28 |
pub fn push(&mut self, gear_id: GearId, old_position: &FPPoint, new_position: &FPPoint) { |
15141 | 29 |
self.gear_ids.push(gear_id); |
15281 | 30 |
self.shifts.push((*old_position, *new_position)); |
15141 | 31 |
} |
15282 | 32 |
|
33 |
pub fn iter(&self) -> impl Iterator<Item = (GearId, &FPPoint, &FPPoint)> { |
|
34 |
self.gear_ids |
|
35 |
.iter() |
|
36 |
.cloned() |
|
37 |
.zip(self.shifts.iter()) |
|
38 |
.map(|(id, (from, to))| (id, from, to)) |
|
39 |
} |
|
15287
b58f98bbc120
clear intermediate result structures between iterations
alfadur
parents:
15282
diff
changeset
|
40 |
|
b58f98bbc120
clear intermediate result structures between iterations
alfadur
parents:
15282
diff
changeset
|
41 |
pub fn clear(&mut self) { |
b58f98bbc120
clear intermediate result structures between iterations
alfadur
parents:
15282
diff
changeset
|
42 |
self.gear_ids.clear(); |
b58f98bbc120
clear intermediate result structures between iterations
alfadur
parents:
15282
diff
changeset
|
43 |
self.shifts.clear(); |
b58f98bbc120
clear intermediate result structures between iterations
alfadur
parents:
15282
diff
changeset
|
44 |
} |
15141 | 45 |
} |
46 |
||
15402 | 47 |
pub struct PhysicsProcessor { |
48 |
gravity: FPNum, |
|
49 |
position_updates: PositionUpdates, |
|
50 |
} |
|
51 |
||
15141 | 52 |
impl PhysicsProcessor { |
15401 | 53 |
pub fn register_components(data: &mut GearDataManager) { |
54 |
data.register::<PositionData>(); |
|
55 |
data.register::<VelocityData>(); |
|
56 |
} |
|
57 |
||
15141 | 58 |
pub fn new() -> Self { |
15291 | 59 |
Self { |
15404
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
60 |
gravity: fp!(1 / 10), |
15401 | 61 |
position_updates: PositionUpdates::new(64), |
15141 | 62 |
} |
63 |
} |
|
64 |
||
15404
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
65 |
pub fn process_single_tick(&mut self, data: &mut GearDataManager) -> &PositionUpdates { |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
66 |
self.position_updates.clear(); |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
67 |
|
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
68 |
data.iter_id( |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
69 |
|gear_id, (pos, vel): (&mut PositionData, &mut VelocityData)| { |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
70 |
let old_pos = pos.0; |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
71 |
vel.0 -= self.gravity; |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
72 |
pos.0 += vel.0; |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
73 |
self.position_updates.push(gear_id, &old_pos, &pos.0) |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
74 |
}, |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
75 |
); |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
76 |
|
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
77 |
&self.position_updates |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
78 |
} |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
79 |
|
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
80 |
pub fn process_multiple_ticks( |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
81 |
&mut self, |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
82 |
data: &mut GearDataManager, |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
83 |
time_step: Millis, |
701ad89a9f2a
avoid time multiplication when not skipping ticks
alfadur
parents:
15403
diff
changeset
|
84 |
) -> &PositionUpdates { |
15296 | 85 |
let fp_step = time_step.to_fixed(); |
15287
b58f98bbc120
clear intermediate result structures between iterations
alfadur
parents:
15282
diff
changeset
|
86 |
self.position_updates.clear(); |
15401 | 87 |
|
88 |
data.iter_id( |
|
89 |
|gear_id, (pos, vel): (&mut PositionData, &mut VelocityData)| { |
|
15403 | 90 |
let old_pos = pos.0; |
91 |
vel.0 -= self.gravity * fp_step; |
|
92 |
pos.0 += vel.0 * fp_step; |
|
93 |
self.position_updates.push(gear_id, &old_pos, &pos.0) |
|
15401 | 94 |
}, |
95 |
); |
|
96 |
||
15141 | 97 |
&self.position_updates |
98 |
} |
|
99 |
} |