1use super::*;
6
7#[derive(Copy, Clone, Default, PartialEq)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20#[repr(C)]
21pub struct Transform3<T> {
22 pub a11: T, pub a12: T, pub a13: T, pub a14: T,
23 pub a21: T, pub a22: T, pub a23: T, pub a24: T,
24 pub a31: T, pub a32: T, pub a33: T, pub a34: T,
25}
26
27#[allow(non_snake_case)]
29#[inline]
30pub const fn Transform3<T>(
31 a11: T, a12: T, a13: T, a14: T,
32 a21: T, a22: T, a23: T, a24: T,
33 a31: T, a32: T, a33: T, a34: T,
34) -> Transform3<T> {
35 Transform3 { a11, a12, a13, a14, a21, a22, a23, a24, a31, a32, a33, a34 }
36}
37
38#[cfg(feature = "dataview")]
39unsafe impl<T: dataview::Pod> dataview::Pod for Transform3<T> {}
40
41impl<T> Transform3<T> {
45 #[inline]
47 pub const fn new(
48 a11: T, a12: T, a13: T, a14: T,
49 a21: T, a22: T, a23: T, a24: T,
50 a31: T, a32: T, a33: T, a34: T,
51 ) -> Transform3<T> {
52 Transform3 {
53 a11, a12, a13, a14,
54 a21, a22, a23, a24,
55 a31, a32, a33, a34,
56 }
57 }
58}
59
60impl<T: Zero> Transform3<T> {
61 pub const ZERO: Transform3<T> = Transform3 {
63 a11: T::ZERO, a12: T::ZERO, a13: T::ZERO, a14: T::ZERO,
64 a21: T::ZERO, a22: T::ZERO, a23: T::ZERO, a24: T::ZERO,
65 a31: T::ZERO, a32: T::ZERO, a33: T::ZERO, a34: T::ZERO,
66 };
67}
68
69impl<T: Zero + One> Transform3<T> {
70 pub const IDENTITY: Transform3<T> = Transform3 {
72 a11: T::ONE, a12: T::ZERO, a13: T::ZERO, a14: T::ZERO,
73 a21: T::ZERO, a22: T::ONE, a23: T::ZERO, a24: T::ZERO,
74 a31: T::ZERO, a32: T::ZERO, a33: T::ONE, a34: T::ZERO,
75 };
76}
77
78impl<T: Float> Transform3<T> {
79 #[inline]
81 pub fn translate(trans: Vec3<T>) -> Transform3<T> {
82 let Vec3 { x: a14, y: a24, z: a34 } = trans;
83 Transform3 { a14, a24, a34, ..Transform3::IDENTITY }
84 }
85
86 #[inline]
90 pub fn scale(scale: Vec3<T>) -> Transform3<T> {
91 let Vec3 { x: a11, y: a22, z: a33 } = scale;
92 Transform3 { a11, a22, a33, ..Transform3::IDENTITY }
93 }
94
95 #[inline]
97 pub fn rotate(axis: Vec3<T>, angle: Angle<T>) -> Transform3<T> {
98 Mat3::rotate(axis, angle).transform3()
99 }
100}
101
102impl<T: Float> Transform3<T> {
103 #[inline]
105 pub fn look_at(position: Vec3<T>, target: Vec3<T>, ref_up: Vec3<T>, hand: Hand) -> Transform3<T> {
106 let forward = match hand {
107 Hand::LH => target - position,
108 Hand::RH => position - target,
109 }.norm();
110
111 let side = ref_up.cross(forward).norm();
112 let up = forward.cross(side);
113
114 let Vec3 { x: a11, y: a12, z: a13 } = side;
115 let a14 = -side.dot(position);
116
117 let Vec3 { x: a21, y: a22, z: a23 } = up;
118 let a24 = -up.dot(position);
119
120 let Vec3 { x: a31, y: a32, z: a33 } = forward;
121 let a34 = -forward.dot(position);
122
123 Transform3 {
124 a11, a12, a13, a14,
125 a21, a22, a23, a24,
126 a31, a32, a33, a34,
127 }
128 }
129
130 #[inline]
134 pub fn ortho(bounds: Bounds3<T>, (hand, clip): (Hand, Clip)) -> Transform3<T> {
135 let Bounds3 {
136 mins: Vec3 { x: left, y: bottom, z: near },
137 maxs: Vec3 { x: right, y: top, z: far },
138 } = bounds;
139
140 debug_assert!(T::ZERO < near && near < far);
141
142 let a11 = T::TWO / (right - left);
143 let a14 = -(right + left) / (right - left);
144 let a22 = T::TWO / (top - bottom);
145 let a24 = -(top + bottom) / (top - bottom);
146 let a33 = match clip { Clip::ZO => T::ONE, Clip::NO => T::TWO } / (far - near);
147 let a33 = match hand { Hand::LH => a33, Hand::RH => -a33 };
148 let a34 = -match clip { Clip::ZO => near, Clip::NO => far + near } / (far - near);
149
150 Transform3 { a11, a14, a22, a24, a33, a34, ..Self::IDENTITY }
151 }
152}
153
154impl<T: Zero + One> Transform3<T> {
158 #[inline]
160 pub fn mat4(self) -> Mat4<T> {
161 self.into()
162 }
163}
164
165impl<T> Transform3<T> {
166 #[inline]
167 fn as_array(&self) -> &[T; 12] {
168 unsafe { mem::transmute(self)}
169 }
170 #[inline]
172 pub fn from_row_major(mat: [[T; 4]; 3]) -> Transform3<T> {
173 let [[a11, a12, a13, a14], [a21, a22, a23, a24], [a31, a32, a33, a34]] = mat;
174 Transform3 {
175 a11, a12, a13, a14,
176 a21, a22, a23, a24,
177 a31, a32, a33, a34,
178 }
179 }
180 #[inline]
182 pub fn from_column_major(mat: [[T; 3]; 4]) -> Transform3<T> {
183 let [[a11, a21, a31], [a12, a22, a32], [a13, a23, a33], [a14, a24, a34]] = mat;
184 Transform3 {
185 a11, a12, a13, a14,
186 a21, a22, a23, a24,
187 a31, a32, a33, a34,
188 }
189 }
190 #[inline]
192 pub fn into_row_major(self) -> [[T; 4]; 3] {
193 [
194 [self.a11, self.a12, self.a13, self.a14],
195 [self.a21, self.a22, self.a23, self.a24],
196 [self.a31, self.a32, self.a33, self.a34],
197 ]
198 }
199 #[inline]
201 pub fn into_column_major(self) -> [[T; 3]; 4] {
202 [
203 [self.a11, self.a21, self.a31],
204 [self.a12, self.a22, self.a32],
205 [self.a13, self.a23, self.a33],
206 [self.a14, self.a24, self.a34],
207 ]
208 }
209}
210
211impl<T> Transform3<T> {
215 #[inline]
217 pub fn compose(x: Vec3<T>, y: Vec3<T>, z: Vec3<T>, t: Vec3<T>) -> Transform3<T> {
218 Transform3 {
219 a11: x.x, a12: y.x, a13: z.x, a14: t.x,
220 a21: x.y, a22: y.y, a23: z.y, a24: t.y,
221 a31: x.z, a32: y.z, a33: z.z, a34: t.z,
222 }
223 }
224 #[inline]
226 pub fn x(self) -> Vec3<T> {
227 Vec3 { x: self.a11, y: self.a21, z: self.a31 }
228 }
229 #[inline]
231 pub fn y(self) -> Vec3<T> {
232 Vec3 { x: self.a12, y: self.a22, z: self.a32 }
233 }
234 #[inline]
236 pub fn z(self) -> Vec3<T> {
237 Vec3 { x: self.a13, y: self.a23, z: self.a33 }
238 }
239 #[inline]
241 pub fn t(self) -> Vec3<T> {
242 Vec3 { x: self.a14, y: self.a24, z: self.a34 }
243 }
244 #[inline]
246 pub fn mat3(self) -> Mat3<T> {
247 Mat3 {
248 a11: self.a11, a12: self.a12, a13: self.a13,
249 a21: self.a21, a22: self.a22, a23: self.a23,
250 a31: self.a31, a32: self.a32, a33: self.a33,
251 }
252 }
253}
254
255impl<T: Scalar> Transform3<T> {
259 #[inline]
261 pub fn det(self) -> T {
262 self.a11 * (self.a22 * self.a33 - self.a23 * self.a32) +
263 self.a12 * (self.a23 * self.a31 - self.a21 * self.a33) +
264 self.a13 * (self.a21 * self.a32 - self.a22 * self.a31)
265 }
266 #[inline]
268 pub fn trace(self) -> T {
269 self.a11 + self.a22 + self.a33 + T::ONE
270 }
271 #[inline]
277 pub fn flat_norm_sqr(self) -> T {
278 self.a11 * self.a11 + self.a12 * self.a12 + self.a13 * self.a13 + self.a14 * self.a14 +
279 self.a21 * self.a21 + self.a22 * self.a22 + self.a23 * self.a23 + self.a24 * self.a24 +
280 self.a31 * self.a31 + self.a32 * self.a32 + self.a33 * self.a33 + self.a34 * self.a34
281 }
282 #[inline]
283 pub fn try_invert(self) -> Option<Transform3<T>> where T: Float {
284 let det = self.det();
285 if det == T::ZERO {
286 return None;
287 }
288
289 let inv_det = T::ONE / det;
290 Some(Transform3 {
291 a11: (self.a22 * self.a33 - self.a23 * self.a32) * inv_det,
292 a12: (self.a13 * self.a32 - self.a12 * self.a33) * inv_det,
293 a13: (self.a12 * self.a23 - self.a13 * self.a22) * inv_det,
294 a14: (self.a12 * (self.a24 * self.a33 - self.a23 * self.a34) +
295 self.a13 * (self.a22 * self.a34 - self.a24 * self.a32) +
296 self.a14 * (self.a23 * self.a32 - self.a22 * self.a33)) * inv_det,
297 a21: (self.a23 * self.a31 - self.a21 * self.a33) * inv_det,
298 a22: (self.a11 * self.a33 - self.a13 * self.a31) * inv_det,
299 a23: (self.a13 * self.a21 - self.a11 * self.a23) * inv_det,
300 a24: (self.a11 * (self.a23 * self.a34 - self.a24 * self.a33) +
301 self.a13 * (self.a24 * self.a31 - self.a21 * self.a34) +
302 self.a14 * (self.a21 * self.a33 - self.a23 * self.a31)) * inv_det,
303 a31: (self.a21 * self.a32 - self.a22 * self.a31) * inv_det,
304 a32: (self.a12 * self.a31 - self.a11 * self.a32) * inv_det,
305 a33: (self.a11 * self.a22 - self.a12 * self.a21) * inv_det,
306 a34: (self.a11 * (self.a24 * self.a32 - self.a22 * self.a34) +
307 self.a12 * (self.a21 * self.a34 - self.a24 * self.a31) +
308 self.a14 * (self.a22 * self.a31 - self.a21 * self.a32)) * inv_det,
309 })
310 }
311 #[inline]
315 pub fn inverse(self) -> Transform3<T> where T: Float {
316 self.try_invert().unwrap_or(Transform3::ZERO)
317 }
318 #[inline]
320 pub fn lerp(self, rhs: Transform3<T>, t: T) -> Transform3<T> where T: Float {
321 Transform3 {
322 a11: self.a11 + (rhs.a11 - self.a11) * t,
323 a12: self.a12 + (rhs.a12 - self.a12) * t,
324 a13: self.a13 + (rhs.a13 - self.a13) * t,
325 a14: self.a14 + (rhs.a14 - self.a14) * t,
326
327 a21: self.a21 + (rhs.a21 - self.a21) * t,
328 a22: self.a22 + (rhs.a22 - self.a22) * t,
329 a23: self.a23 + (rhs.a23 - self.a23) * t,
330 a24: self.a24 + (rhs.a24 - self.a24) * t,
331
332 a31: self.a31 + (rhs.a31 - self.a31) * t,
333 a32: self.a32 + (rhs.a32 - self.a32) * t,
334 a33: self.a33 + (rhs.a33 - self.a33) * t,
335 a34: self.a34 + (rhs.a34 - self.a34) * t,
336 }
337 }
338}
339
340impl<T: Copy + ops::Add<Output = T> + ops::Mul<Output = T>> ops::Mul<Vec3<T>> for Transform3<T> {
344 type Output = Vec3<T>;
345 #[inline]
346 fn mul(self, rhs: Vec3<T>) -> Vec3<T> {
347 Vec3 {
348 x: rhs.x * self.a11 + rhs.y * self.a12 + rhs.z * self.a13 + self.a14,
349 y: rhs.x * self.a21 + rhs.y * self.a22 + rhs.z * self.a23 + self.a24,
350 z: rhs.x * self.a31 + rhs.y * self.a32 + rhs.z * self.a33 + self.a34,
351 }
352 }
353}
354
355impl<T: Copy + ops::Add<Output = T> + ops::Mul<Output = T>> ops::Mul<Vec4<T>> for Transform3<T> {
356 type Output = Vec3<T>;
357 #[inline]
358 fn mul(self, rhs: Vec4<T>) -> Vec3<T> {
359 Vec3 {
360 x: rhs.x * self.a11 + rhs.y * self.a12 + rhs.z * self.a13 + rhs.w * self.a14,
361 y: rhs.x * self.a21 + rhs.y * self.a22 + rhs.z * self.a23 + rhs.w * self.a24,
362 z: rhs.x * self.a31 + rhs.y * self.a32 + rhs.z * self.a33 + rhs.w * self.a34,
363 }
364 }
365}
366
367impl<T: Copy + ops::Add<Output = T> + ops::Mul<Output = T>> ops::Mul<Transform3<T>> for Transform3<T> {
368 type Output = Transform3<T>;
369 #[inline]
370 fn mul(self, rhs: Transform3<T>) -> Transform3<T> {
371 Transform3 {
372 a11: self.a11 * rhs.a11 + self.a12 * rhs.a21 + self.a13 * rhs.a31,
373 a12: self.a11 * rhs.a12 + self.a12 * rhs.a22 + self.a13 * rhs.a32,
374 a13: self.a11 * rhs.a13 + self.a12 * rhs.a23 + self.a13 * rhs.a33,
375 a14: self.a11 * rhs.a14 + self.a12 * rhs.a24 + self.a13 * rhs.a34 + self.a14,
376
377 a21: self.a21 * rhs.a11 + self.a22 * rhs.a21 + self.a23 * rhs.a31,
378 a22: self.a21 * rhs.a12 + self.a22 * rhs.a22 + self.a23 * rhs.a32,
379 a23: self.a21 * rhs.a13 + self.a22 * rhs.a23 + self.a23 * rhs.a33,
380 a24: self.a21 * rhs.a14 + self.a22 * rhs.a24 + self.a23 * rhs.a34 + self.a24,
381
382 a31: self.a31 * rhs.a11 + self.a32 * rhs.a21 + self.a33 * rhs.a31,
383 a32: self.a31 * rhs.a12 + self.a32 * rhs.a22 + self.a33 * rhs.a32,
384 a33: self.a31 * rhs.a13 + self.a32 * rhs.a23 + self.a33 * rhs.a33,
385 a34: self.a31 * rhs.a14 + self.a32 * rhs.a24 + self.a33 * rhs.a34 + self.a34,
386 }
387 }
388}
389impl<T: Copy + ops::Add<Output = T> + ops::Mul<Output = T>> ops::Mul<Mat3<T>> for Transform3<T> {
390 type Output = Transform3<T>;
391 #[inline]
392 fn mul(self, rhs: Mat3<T>) -> Transform3<T> {
393 Transform3 {
394 a11: self.a11 * rhs.a11 + self.a12 * rhs.a21 + self.a13 * rhs.a31,
395 a12: self.a11 * rhs.a12 + self.a12 * rhs.a22 + self.a13 * rhs.a32,
396 a13: self.a11 * rhs.a13 + self.a12 * rhs.a23 + self.a13 * rhs.a33,
397 a14: self.a14,
398
399 a21: self.a21 * rhs.a11 + self.a22 * rhs.a21 + self.a23 * rhs.a31,
400 a22: self.a21 * rhs.a12 + self.a22 * rhs.a22 + self.a23 * rhs.a32,
401 a23: self.a21 * rhs.a13 + self.a22 * rhs.a23 + self.a23 * rhs.a33,
402 a24: self.a24,
403
404 a31: self.a31 * rhs.a11 + self.a32 * rhs.a21 + self.a33 * rhs.a31,
405 a32: self.a31 * rhs.a12 + self.a32 * rhs.a22 + self.a33 * rhs.a32,
406 a33: self.a31 * rhs.a13 + self.a32 * rhs.a23 + self.a33 * rhs.a33,
407 a34: self.a34,
408 }
409 }
410}
411impl<T: Copy + ops::Add<Output = T> + ops::Mul<Output = T>> ops::MulAssign<Mat3<T>> for Transform3<T> {
412 #[inline]
413 fn mul_assign(&mut self, rhs: Mat3<T>) {
414 *self = *self * rhs;
415 }
416}
417impl<T: Copy + ops::Add<Output = T> + ops::Mul<Output = T>> ops::MulAssign<Transform3<T>> for Transform3<T> {
418 #[inline]
419 fn mul_assign(&mut self, rhs: Transform3<T>) {
420 *self = *self * rhs;
421 }
422}
423
424impl_mat_mul_scalar!(Transform3);
425impl_mat_mul_vec!(Transform3, Vec3);
426impl_mat_mul_vec!(Transform3, Vec4);
427impl_mat_mul_mat!(Transform3);
428
429impl<T: fmt::Display> fmt::Display for Transform3<T> {
433 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
434 f.write_str("Transform3(")?;
435 print::print(&move |i| &self.as_array()[i], 0x23, f)?;
436 f.write_str(")")
437 }
438}
439impl<T: fmt::Debug> fmt::Debug for Transform3<T> {
440 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
441 f.write_str("Transform3(")?;
442 print::print(&move |i| print::Debug(&self.as_array()[i]), 0x23, f)?;
443 f.write_str(")")
444 }
445}
446
447#[test]
451fn test_inverse() {
452 let mut rng = urandom::seeded(42);
453
454 for _ in 0..1000 {
455 let x = Vec3(
456 rng.range(-10.0..10.0),
457 rng.range(-10.0..10.0),
458 rng.range(-10.0..10.0),
459 );
460 let y = Vec3(
461 rng.range(-10.0..10.0),
462 rng.range(-10.0..10.0),
463 rng.range(-10.0..10.0),
464 );
465 let z = Vec3(
466 rng.range(-10.0..10.0),
467 rng.range(-10.0..10.0),
468 rng.range(-10.0..10.0),
469 );
470 let t = Vec3(
471 rng.range(-10.0..10.0),
472 rng.range(-10.0..10.0),
473 rng.range(-10.0..10.0),
474 );
475
476 let mat = Transform3::compose(x, y, z, t);
477 let inv = mat.inverse();
478 let _identity = mat * inv;
479
480 let p = Vec3(
481 rng.range(-10.0..10.0),
482 rng.range(-10.0..10.0),
483 rng.range(-1.0..1.0),
484 );
485 let projected = mat * p;
486 let unprojected = inv * projected;
487 let error = (unprojected - p).len();
488 assert!(error < 1e-6, "Failed for mat: {mat:?}, p: {p:?}, error: {error}");
489 }
490}