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