1use crate::types::*;
2
3pub trait Delta: Sized {
5 type DeltaType;
6
7 fn compute_delta(start: &Self, end: &Self) -> Self::DeltaType;
10
11 fn apply_delta(start: &Self, delta: &Self::DeltaType) -> Self;
14}
15
16impl Delta for Position3D {
17 type DeltaType = PositionDelta;
18
19 fn compute_delta(start: &Self, end: &Self) -> Self::DeltaType {
20 PositionDelta {
21 dx: end.x - start.x,
22 dy: end.y - start.y,
23 dz: end.z - start.z,
24 }
25 }
26
27 fn apply_delta(start: &Self, delta: &Self::DeltaType) -> Self {
28 Self {
29 x: start.x + delta.dx,
30 y: start.y + delta.dy,
31 z: start.z + delta.dz,
32 }
33 }
34}
35
36impl Delta for Rotation {
37 type DeltaType = RotationDelta;
38
39 fn compute_delta(start: &Self, end: &Self) -> Self::DeltaType {
40 RotationDelta {
41 d_pitch: end.pitch - start.pitch,
42 d_yaw: end.yaw - start.yaw,
43 d_roll: end.roll - start.roll,
44 }
45 }
46
47 fn apply_delta(start: &Self, delta: &Self::DeltaType) -> Self {
48 Self {
49 pitch: start.pitch + delta.d_pitch,
50 yaw: start.yaw + delta.d_yaw,
51 roll: start.roll + delta.d_roll,
52 }
53 }
54}
55
56impl Delta for SpatialState {
57 type DeltaType = SpatialDelta;
58
59 fn compute_delta(start: &Self, end: &Self) -> Self::DeltaType {
60 let pos_delta = match (&start.position, &end.position) {
61 (Some(s), Some(e)) => Some(Position3D::compute_delta(s, e)),
62 _ => None,
63 };
64
65 let rot_delta = match (&start.rotation, &end.rotation) {
66 (Some(s), Some(e)) => Some(Rotation::compute_delta(s, e)),
67 _ => None,
68 };
69
70 SpatialDelta::State {
76 position: pos_delta,
77 rotation: rot_delta,
78 velocity: end.velocity,
79 acceleration: end.acceleration,
80 }
81 }
82
83 fn apply_delta(start: &Self, delta: &Self::DeltaType) -> Self {
84 match delta {
85 SpatialDelta::State {
86 position,
87 rotation,
88 velocity,
89 acceleration,
90 } => {
91 let new_pos = match (start.position, position) {
92 (Some(p), Some(d)) => Some(Position3D::apply_delta(&p, d)),
93 (p, _) => p,
94 };
95
96 let new_rot = match (start.rotation, rotation) {
97 (Some(r), Some(d)) => Some(Rotation::apply_delta(&r, d)),
98 (r, _) => r,
99 };
100
101 Self {
102 position: new_pos,
103 rotation: new_rot,
104 velocity: velocity.or(start.velocity),
105 acceleration: acceleration.or(start.acceleration),
106 }
107 }
108 _ => start.clone(), }
110 }
111}