1use crate::{FArray, Float, Quaternion, SqMatrix3, SqMatrix4, Transform, Vector3, Vector4, vector};
2
3#[derive(Clone, Copy, Debug, PartialEq)]
7pub struct Transformation<F, Q>
8where
9 F: Float,
10 Q: Quaternion<F>,
11{
12 rotation: Q,
14 translation: FArray<F, 3>,
16 scale: FArray<F, 3>,
18}
19
20impl<F, Q> std::default::Default for Transformation<F, Q>
21where
22 F: Float,
23 Q: Quaternion<F>,
24 FArray<F, 3>: Vector3<F>,
25{
26 fn default() -> Self {
27 Self {
28 rotation: Q::default(),
29 translation: FArray::<F, 3>::default(),
30 scale: [F::ONE; 3].into(),
31 }
32 }
33}
34
35impl<F, Q> std::fmt::Display for Transformation<F, Q>
36where
37 F: Float,
38 Q: Quaternion<F>,
39 FArray<F, 3>: Vector3<F>,
40{
41 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
42 write!(
43 f,
44 "trans[+({},{},{}) rot{} *{}]",
45 self.translation[0],
46 self.translation[1],
47 self.translation[2],
48 self.rotation,
49 self.scale,
50 )
51 }
52}
53
54impl<F, Q> std::ops::Mul<FArray<F, 4>> for Transformation<F, Q>
55where
56 F: Float,
57 Q: Quaternion<F>,
58 FArray<F, 3>: Vector3<F>,
59 FArray<F, 4>: Vector4<F>,
60{
61 type Output = FArray<F, 4>;
62 fn mul(self, v: FArray<F, 4>) -> Self::Output {
63 let v_sc: FArray<F, 3> = [
64 self.scale[0] * v[0],
65 self.scale[1] * v[1],
66 self.scale[2] * v[2],
67 ]
68 .into();
69 let r = self.rotation.apply3(&v_sc) + (self.translation * v[3]);
70 [r[0], r[1], r[2], v[3]].into()
71 }
72}
73
74impl<F, Q> std::ops::Mul<F> for Transformation<F, Q>
75where
76 F: Float,
77 Q: Quaternion<F>,
78 FArray<F, 3>: Vector3<F>,
79{
80 type Output = Self;
81 fn mul(mut self, f: F) -> Self::Output {
82 self.scale *= f;
83 self.translation *= f;
84 self
85 }
86}
87
88impl<F, Q> std::ops::MulAssign<F> for Transformation<F, Q>
89where
90 F: Float,
91 Q: Quaternion<F>,
92 FArray<F, 3>: Vector3<F>,
93{
94 fn mul_assign(&mut self, f: F) {
95 *self = *self * f;
96 }
97}
98
99impl<F, Q> std::ops::Div<F> for Transformation<F, Q>
100where
101 F: Float,
102 Q: Quaternion<F>,
103 FArray<F, 3>: Vector3<F>,
104{
105 type Output = Self;
106 fn div(mut self, f: F) -> Self::Output {
107 self.scale /= f;
108 self.translation /= f;
109 self
110 }
111}
112
113impl<F, Q> std::ops::DivAssign<F> for Transformation<F, Q>
114where
115 F: Float,
116 Q: Quaternion<F>,
117 FArray<F, 3>: Vector3<F>,
118{
119 fn div_assign(&mut self, f: F) {
120 *self = *self / f;
121 }
122}
123
124impl<F, Q> Transform<F> for Transformation<F, Q>
125where
126 F: Float,
127 Q: Quaternion<F>,
128 FArray<F, 3>: Vector3<F>,
129 FArray<F, 4>: Vector4<F>,
130{
131 const UNIFORM_SCALING: bool = false;
132 type Vec3 = FArray<F, 3>;
133 type Vec4 = FArray<F, 4>;
134 type Quat = Q;
135 fn of_trs<A: AsRef<[F; 3]>>(t: A, r: Q, s: A) -> Option<Self> {
136 Some(Self {
137 rotation: r,
138 translation: t.as_ref().into(),
139 scale: s.as_ref().into(),
140 })
141 }
142
143 fn of_trsu<A: AsRef<[F; 3]>>(t: A, r: Q, s: F) -> Self {
144 Self {
145 rotation: r,
146 translation: t.as_ref().into(),
147 scale: [s; 3].into(),
148 }
149 }
150
151 fn is_uniform_scale(&self) -> bool {
152 self.scale[0] == self.scale[1] && self.scale[0] == self.scale[2]
153 }
154
155 fn scale(&self) -> Option<Self::Vec3> {
156 Some(self.scale)
157 }
158
159 fn uniform_scale(&self) -> Option<F> {
160 if self.is_uniform_scale() {
161 Some(self.scale[0])
162 } else {
163 None
164 }
165 }
166
167 fn translation(&self) -> Self::Vec3 {
168 self.translation
169 }
170
171 fn rotation(&self) -> Option<Q> {
172 Some(self.rotation)
173 }
174
175 fn set_identity(&mut self) {
176 self.rotation.set_identity();
177 self.translation = FArray::default();
178 self.scale = [F::ONE; 3].into();
179 }
180
181 fn set_scale<A: AsRef<[F; 3]>>(&mut self, scale: A) -> bool {
182 self.scale = scale.as_ref().into();
183 true
184 }
185
186 fn set_uniform_scale(&mut self, scale: F) {
187 self.scale = [scale; 3].into();
188 }
189
190 fn set_translation<A: AsRef<[F; 3]>>(&mut self, translation: A) {
191 self.translation = translation.as_ref().into();
192 }
193
194 fn set_rotation(&mut self, rotation: Q) {
195 self.rotation = rotation;
196 }
197
198 fn scale_uniform_by(&mut self, scale: F) {
199 self.translation *= scale;
200 self.scale *= scale;
201 }
202
203 fn scale_by<A: AsRef<[F; 3]>>(&mut self, scale: A) -> bool {
204 if self.rotation.as_rijk().0 != F::ONE {
205 return false;
206 }
207 let scale = scale.as_ref();
208 self.translation[0] = self.translation[0] * scale[0];
209 self.translation[1] = self.translation[1] * scale[1];
210 self.translation[2] = self.translation[2] * scale[2];
211 self.scale[0] = self.scale[0] * scale[0];
212 self.scale[1] = self.scale[1] * scale[1];
213 self.scale[2] = self.scale[2] * scale[2];
214 true
215 }
216
217 fn translate_by<A: AsRef<[F; 3]>>(&mut self, translation: A, scale: F) {
218 let translation: Self::Vec3 = translation.as_ref().into();
219 self.translation += translation * scale;
220 }
221
222 fn rotate_by(&mut self, quaternion: &Q) {
223 self.translation = quaternion.apply3(&self.translation);
224 self.rotation = *quaternion * self.rotation;
225 }
226
227 fn transform_by<T: Transform<F, Quat = Self::Quat>>(&mut self, transformer: &T) -> bool {
228 let Some(scale) = transformer.uniform_scale() else {
229 return false;
230 };
231 let Some(rotation) = transformer.rotation() else {
232 return false;
233 };
234 self.scale *= scale;
235 self.translation *= scale;
236 self.rotation = rotation * self.rotation;
237 let translation: [F; 3] = transformer.translation().into();
238 self.translation = rotation.apply3(&self.translation) + &translation;
239 true
240 }
241
242 fn inverse_transform(&self) -> Option<Self> {
243 if !self.is_uniform_scale() {
244 return None;
245 }
246 let scale = self.scale[0];
247 if scale.abs() < F::epsilon() {
248 Some(Self::default())
249 } else {
250 let scale = scale.recip();
251 let iquat = self.rotation.conjugate();
252 let trans = iquat.apply3(&self.translation);
253 let trans = trans * -scale;
254 Self::of_trs(trans, iquat, [scale; 3].into())
255 }
256 }
257
258 fn apply3_arr(&self, other: &[F; 3]) -> [F; 3] {
259 let v: Self::Vec3 = vector::comp_mult(*self.scale, other).into();
260 *(self.rotation.apply3(&v) + self.translation)
261 }
262
263 fn apply4_arr(&self, other: &[F; 4]) -> [F; 4] {
264 let v: Self::Vec3 = vector::comp_mult(*self.scale, &[other[0], other[1], other[2]]).into();
265 let r = self.rotation.apply3(&v) + (self.translation * other[3]);
266 [r[0], r[1], r[2], other[3]]
267 }
268
269 fn as_mat3<M: SqMatrix3<F>>(&self) -> M {
270 let mut m = M::default();
271 self.rotation.set_rotation3(&mut m);
272 for (i, c) in m.iter_mut().enumerate() {
273 *c = *c * self.scale[i % 3];
274 }
275 m
276 }
277
278 fn as_mat4<M: SqMatrix4<F>>(&self) -> M {
279 let mut m = M::default();
280 self.rotation.set_rotation4(&mut m);
281 for (i, c) in m.iter_mut().take(12).enumerate() {
282 if (i % 4) == 3 {
283 *c = self.translation[i / 4];
284 } else {
285 *c = *c * self.scale[i % 4];
286 }
287 }
288 m
289 }
290}
291
292#[cfg(feature = "serde")]
293#[derive(serde::Deserialize, serde::Serialize)]
294#[serde(rename = "Transformation")]
295struct X<F, Q>
296where
297 F: Float,
298 Q: Quaternion<F>,
299 FArray<F, 3>: Vector3<F> + serde::de::DeserializeOwned + serde::Serialize,
300{
301 rotation: Q,
302 translation: FArray<F, 3>,
304 scale: FArray<F, 3>,
306}
307
308#[cfg(feature = "serde")]
309impl<F, Q> serde::Serialize for Transformation<F, Q>
310where
311 F: Float + for<'de> serde::de::Deserialize<'de> + serde::Serialize,
312 Q: Quaternion<F> + for<'de> serde::de::Deserialize<'de> + serde::Serialize,
313 FArray<F, 3>: Vector3<F> + serde::de::DeserializeOwned + serde::Serialize,
314 FArray<F, 4>: Vector4<F> + serde::Serialize,
315{
316 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
317 where
318 S: serde::Serializer,
319 {
320 (X {
321 rotation: self.rotation,
322 translation: self.translation,
323 scale: self.scale,
324 })
325 .serialize(serializer)
326 }
327}
328
329#[cfg(feature = "serde")]
330impl<'de, F, Q> serde::Deserialize<'de> for Transformation<F, Q>
331where
332 F: Float + serde::de::Deserialize<'de> + serde::Serialize,
333 Q: Quaternion<F> + serde::de::Deserialize<'de> + serde::Serialize,
334 FArray<F, 3>: Vector3<F> + serde::de::DeserializeOwned + serde::Serialize,
335 FArray<F, 4>: Vector4<F>,
336{
337 fn deserialize<DE>(deserializer: DE) -> Result<Self, DE::Error>
338 where
339 DE: serde::Deserializer<'de>,
340 {
341 let x = X::<F, Q>::deserialize(deserializer)?;
342 Ok(Self {
343 rotation: x.rotation,
344 translation: x.translation,
345 scale: x.scale,
346 })
347 }
348}