1use crate::Frame;
2use nalgebra::{Point3, RealField, Unit, UnitQuaternion, Vector3};
3use simba::scalar::SubsetOf;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub enum Delta<N: Copy + RealField> {
9 Frame,
11 First {
15 pitch: N,
17 yaw: N,
19 yaw_axis: Unit<Vector3<N>>,
21 },
22 Track {
26 vec: Vector3<N>,
28 },
29 Orbit {
33 rot: UnitQuaternion<N>,
35 pos: Point3<N>,
37 },
38 Slide {
42 vec: Vector3<N>,
44 },
45 Scale {
49 rat: N,
51 pos: Point3<N>,
53 },
54}
55
56impl<N: Copy + RealField> Delta<N> {
57 #[must_use]
59 pub fn transform(&self, frame: &Frame<N>) -> Frame<N> {
60 let mut frame = *frame;
61 match self {
62 Self::Frame => {}
63 Self::First {
64 pitch,
65 yaw,
66 yaw_axis,
67 } => frame.look_around(*pitch, *yaw, yaw_axis),
68 Self::Track { vec } => frame.set_target(frame.target() + vec),
69 Self::Orbit { rot, pos } => frame.local_orbit_around(rot, pos),
70 Self::Slide { vec } => frame.local_slide(vec),
71 Self::Scale { rat, pos } => frame.local_scale_around(*rat, pos),
72 }
73 frame
74 }
75 #[must_use]
79 pub fn inverse(self) -> Self {
80 match self {
81 Self::Frame => Self::Frame,
82 Self::First {
83 pitch,
84 yaw,
85 yaw_axis,
86 } => Self::First {
87 pitch: -pitch,
88 yaw: -yaw,
89 yaw_axis,
90 },
91 Self::Track { vec } => Self::Track { vec: -vec },
92 Self::Orbit { rot, pos } => Self::Orbit {
93 rot: rot.inverse(),
94 pos,
95 },
96 Self::Slide { vec } => Self::Slide { vec: -vec },
97 Self::Scale { rat, pos } => Self::Scale {
98 rat: N::one() + N::one() - rat,
99 pos,
100 },
101 }
102 }
103 #[must_use]
111 pub fn lerp_slerp(&self, t: N) -> Self {
112 match *self {
113 Self::Frame => Self::Frame,
114 Self::First {
115 pitch,
116 yaw,
117 yaw_axis,
118 } => Self::First {
119 pitch: pitch * t,
120 yaw: yaw * t,
121 yaw_axis,
122 },
123 Self::Track { vec } => Self::Track { vec: vec * t },
124 Self::Orbit { rot, pos } => Self::Orbit {
125 rot: rot.powf(t),
126 pos,
127 },
128 Self::Slide { vec } => Self::Slide { vec: vec * t },
129 Self::Scale { rat, pos } => Self::Scale {
130 rat: (rat - N::one()) * t + N::one(),
131 pos,
132 },
133 }
134 }
135 #[must_use]
137 pub fn cast<M: Copy + RealField>(self) -> Delta<M>
138 where
139 N: SubsetOf<M>,
140 {
141 match self {
142 Self::Frame => Delta::Frame,
143 Self::First {
144 pitch,
145 yaw,
146 yaw_axis,
147 } => Delta::First {
148 pitch: pitch.to_superset(),
149 yaw: yaw.to_superset(),
150 yaw_axis: yaw_axis.cast(),
151 },
152 Self::Track { vec } => Delta::Track { vec: vec.cast() },
153 Self::Orbit { rot, pos } => Delta::Orbit {
154 rot: rot.cast(),
155 pos: pos.cast(),
156 },
157 Self::Slide { vec } => Delta::Slide { vec: vec.cast() },
158 Self::Scale { rat, pos } => Delta::Scale {
159 rat: rat.to_superset(),
160 pos: pos.cast(),
161 },
162 }
163 }
164}
165
166impl<N: Copy + RealField> Default for Delta<N> {
167 fn default() -> Self {
168 Self::Frame
169 }
170}
171
172#[cfg(feature = "rkyv")]
173impl<N: Copy + RealField> rkyv::Archive for Delta<N> {
174 type Archived = Self;
175 type Resolver = ();
176
177 #[inline]
178 #[allow(unsafe_code)]
179 unsafe fn resolve(&self, _: usize, (): Self::Resolver, out: *mut Self::Archived) {
180 unsafe {
181 out.write(rkyv::to_archived!(*self as Self));
182 }
183 }
184}
185
186#[cfg(feature = "rkyv")]
187impl<Ser: rkyv::Fallible + ?Sized, N: Copy + RealField> rkyv::Serialize<Ser> for Delta<N> {
188 #[inline]
189 fn serialize(&self, _: &mut Ser) -> Result<Self::Resolver, Ser::Error> {
190 Ok(())
191 }
192}
193
194#[cfg(feature = "rkyv")]
195impl<De: rkyv::Fallible + ?Sized, N: Copy + RealField> rkyv::Deserialize<Self, De> for Delta<N> {
196 #[inline]
197 fn deserialize(&self, _: &mut De) -> Result<Self, De::Error> {
198 Ok(rkyv::from_archived!(*self))
199 }
200}