1use super::*;
6
7#[derive(Copy, Clone, Default, PartialEq)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18#[repr(C)]
19pub struct Mat3<T> {
20 pub a11: T, pub a12: T, pub a13: T,
21 pub a21: T, pub a22: T, pub a23: T,
22 pub a31: T, pub a32: T, pub a33: T,
23}
24
25#[allow(non_snake_case)]
27#[inline]
28pub const fn Mat3<T>(
29 a11: T, a12: T, a13: T,
30 a21: T, a22: T, a23: T,
31 a31: T, a32: T, a33: T,
32) -> Mat3<T> {
33 Mat3 { a11, a12, a13, a21, a22, a23, a31, a32, a33 }
34}
35
36#[cfg(feature = "dataview")]
37unsafe impl<T: dataview::Pod> dataview::Pod for Mat3<T> {}
38
39impl<T> Mat3<T> {
43 #[inline]
45 pub const fn new(
46 a11: T, a12: T, a13: T,
47 a21: T, a22: T, a23: T,
48 a31: T, a32: T, a33: T,
49 ) -> Mat3<T> {
50 Mat3 {
51 a11, a12, a13,
52 a21, a22, a23,
53 a31, a32, a33,
54 }
55 }
56}
57
58impl<T: Zero> Mat3<T> {
59 pub const ZERO: Mat3<T> = Mat3 {
61 a11: T::ZERO, a12: T::ZERO, a13: T::ZERO,
62 a21: T::ZERO, a22: T::ZERO, a23: T::ZERO,
63 a31: T::ZERO, a32: T::ZERO, a33: T::ZERO,
64 };
65}
66
67impl<T: Zero + One> Mat3<T> {
68 pub const IDENTITY: Mat3<T> = Mat3 {
70 a11: T::ONE, a12: T::ZERO, a13: T::ZERO,
71 a21: T::ZERO, a22: T::ONE, a23: T::ZERO,
72 a31: T::ZERO, a32: T::ZERO, a33: T::ONE,
73 };
74}
75
76impl<T: Float> Mat3<T> {
77 #[inline]
86 pub fn scaling(scale: Vec3<T>) -> Mat3<T> {
87 let Vec3 { x: a11, y: a22, z: a33 } = scale;
88 Mat3 { a11, a22, a33, ..Mat3::IDENTITY }
89 }
90
91 #[inline]
100 pub fn rotation(axis: Vec3<T>, angle: Angle<T>) -> Mat3<T> {
101 let (s, c) = angle.sin_cos();
102 let Vec3 { x, y, z } = axis;
103 let t = T::ONE - c;
104 Mat3 {
105 a11: t * x * x + c, a12: t * x * y - s * z, a13: t * x * z + s * y,
106 a21: t * x * y + s * z, a22: t * y * y + c, a23: t * y * z - s * x,
107 a31: t * x * z - s * y, a32: t * y * z + s * x, a33: t * z * z + c,
108 }
109 }
110
111 #[inline]
137 pub fn rotation_between(from: Vec3<T>, to: Vec3<T>) -> Mat3<T> {
138 let Vec3 { x, y, z } = from.cross(to);
139 let c = from.dot(to);
140 let k = T::ONE / (T::ONE + c);
141 Mat3 {
142 a11: x * x * k + c, a12: x * y * k - z, a13: x * z * k + y,
143 a21: y * x * k + z, a22: y * y * k + c, a23: y * z * k - x,
144 a31: z * x * k - y, a32: z * y * k + x, a33: z * z * k + c,
145 }
146 }
147}
148
149impl<T: Zero + One> From<Transform2<T>> for Mat3<T> {
150 #[inline]
151 fn from(mat: Transform2<T>) -> Mat3<T> {
152 Mat3 {
153 a11: mat.a11, a12: mat.a12, a13: mat.a13,
154 a21: mat.a21, a22: mat.a22, a23: mat.a23,
155 ..Mat3::IDENTITY
156 }
157 }
158}
159
160impl<T> Mat3<T> {
164 #[inline]
172 pub fn mat2(self) -> Mat2<T> {
173 Mat2 {
174 a11: self.a11, a12: self.a12,
175 a21: self.a21, a22: self.a22,
176 }
177 }
178 #[inline]
187 pub fn transform3(self) -> Transform3<T> where T: Zero {
188 Transform3 {
189 a11: self.a11, a12: self.a12, a13: self.a13, a14: T::ZERO,
190 a21: self.a21, a22: self.a22, a23: self.a23, a24: T::ZERO,
191 a31: self.a31, a32: self.a32, a33: self.a33, a34: T::ZERO,
192 }
193 }
194 #[inline]
203 pub fn translate(self, trans: Vec3<T>) -> Transform3<T> {
204 let Vec3 { x: a14, y: a24, z: a34 } = trans;
205 Transform3 {
206 a11: self.a11, a12: self.a12, a13: self.a13, a14,
207 a21: self.a21, a22: self.a22, a23: self.a23, a24,
208 a31: self.a31, a32: self.a32, a33: self.a33, a34,
209 }
210 }
211}
212
213impl<T> Mat3<T> {
214 #[inline]
215 fn as_array(&self) -> &[T; 9] {
216 unsafe { mem::transmute(self) }
217 }
218 #[inline]
226 pub fn from_row_major(mat: [[T; 3]; 3]) -> Mat3<T> {
227 let [[a11, a12, a13], [a21, a22, a23], [a31, a32, a33]] = mat;
228 Mat3 {
229 a11, a12, a13,
230 a21, a22, a23,
231 a31, a32, a33,
232 }
233 }
234 #[inline]
242 pub fn from_column_major(mat: [[T; 3]; 3]) -> Mat3<T> {
243 let [[a11, a21, a31], [a12, a22, a32], [a13, a23, a33]] = mat;
244 Mat3 {
245 a11, a12, a13,
246 a21, a22, a23,
247 a31, a32, a33,
248 }
249 }
250 #[inline]
258 pub fn into_row_major(self) -> [[T; 3]; 3] {
259 [
260 [self.a11, self.a12, self.a13],
261 [self.a21, self.a22, self.a23],
262 [self.a31, self.a32, self.a33],
263 ]
264 }
265 #[inline]
273 pub fn into_column_major(self) -> [[T; 3]; 3] {
274 [
275 [self.a11, self.a21, self.a31],
276 [self.a12, self.a22, self.a32],
277 [self.a13, self.a23, self.a33],
278 ]
279 }
280}
281
282impl<T> Mat3<T> {
286 #[inline]
295 pub fn compose(x: Vec3<T>, y: Vec3<T>, z: Vec3<T>) -> Mat3<T> {
296 Mat3 {
297 a11: x.x, a12: y.x, a13: z.x,
298 a21: x.y, a22: y.y, a23: z.y,
299 a31: x.z, a32: y.z, a33: z.z,
300 }
301 }
302 #[inline]
310 pub fn x(self) -> Vec3<T> {
311 Vec3 { x: self.a11, y: self.a21, z: self.a31 }
312 }
313 #[inline]
321 pub fn y(self) -> Vec3<T> {
322 Vec3 { x: self.a12, y: self.a22, z: self.a32 }
323 }
324 #[inline]
332 pub fn z(self) -> Vec3<T> {
333 Vec3 { x: self.a13, y: self.a23, z: self.a33 }
334 }
335}
336
337impl<T: Scalar> Mat3<T> {
341 #[inline]
348 pub fn det(self) -> T {
349 self.a11 * (self.a22 * self.a33 - self.a23 * self.a32) +
350 self.a12 * (self.a23 * self.a31 - self.a21 * self.a33) +
351 self.a13 * (self.a21 * self.a32 - self.a22 * self.a31)
352 }
353 #[inline]
360 pub fn trace(self) -> T {
361 self.a11 + self.a22 + self.a33
362 }
363 #[inline]
374 pub fn flat_norm_sqr(self) -> T {
375 self.a11 * self.a11 + self.a12 * self.a12 + self.a13 * self.a13 +
376 self.a21 * self.a21 + self.a22 * self.a22 + self.a23 * self.a23 +
377 self.a31 * self.a31 + self.a32 * self.a32 + self.a33 * self.a33
378 }
379 #[inline]
387 pub fn try_invert(self) -> Option<Mat3<T>> where T: Float {
388 let det = self.det();
389 if det == T::ZERO {
390 return None;
391 }
392 Some(self.adjugate() * (T::ONE / det))
393 }
394 #[inline]
404 pub fn inverse(self) -> Mat3<T> where T: Float {
405 self.try_invert().unwrap_or(Mat3::ZERO)
406 }
407 #[inline]
416 pub fn transpose(self) -> Mat3<T> {
417 Mat3 {
418 a11: self.a11, a12: self.a21, a13: self.a31,
419 a21: self.a12, a22: self.a22, a23: self.a32,
420 a31: self.a13, a32: self.a23, a33: self.a33,
421 }
422 }
423 #[inline]
431 pub fn adjugate(self) -> Mat3<T> {
432 Mat3 {
433 a11: self.a22 * self.a33 - self.a23 * self.a32,
434 a12: self.a13 * self.a32 - self.a12 * self.a33,
435 a13: self.a12 * self.a23 - self.a13 * self.a22,
436
437 a21: self.a23 * self.a31 - self.a21 * self.a33,
438 a22: self.a11 * self.a33 - self.a13 * self.a31,
439 a23: self.a13 * self.a21 - self.a11 * self.a23,
440
441 a31: self.a21 * self.a32 - self.a22 * self.a31,
442 a32: self.a12 * self.a31 - self.a11 * self.a32,
443 a33: self.a11 * self.a22 - self.a12 * self.a21,
444 }
445 }
446 #[inline]
456 pub fn lerp(self, rhs: Mat3<T>, t: T) -> Mat3<T> where T: Float {
457 Mat3 {
458 a11: self.a11 + (rhs.a11 - self.a11) * t,
459 a12: self.a12 + (rhs.a12 - self.a12) * t,
460 a13: self.a13 + (rhs.a13 - self.a13) * t,
461 a21: self.a21 + (rhs.a21 - self.a21) * t,
462 a22: self.a22 + (rhs.a22 - self.a22) * t,
463 a23: self.a23 + (rhs.a23 - self.a23) * t,
464 a31: self.a31 + (rhs.a31 - self.a31) * t,
465 a32: self.a32 + (rhs.a32 - self.a32) * t,
466 a33: self.a33 + (rhs.a33 - self.a33) * t,
467 }
468 }
469 #[inline]
479 pub fn around(self, origin: Vec3<T>) -> Transform3<T> where T: Float {
480 let to_origin = Transform3::translation(-origin);
481 let from_origin = Transform3::translation(origin);
482 from_origin * self * to_origin
483 }
484}
485
486impl<T: Copy + ops::Mul<Output = T>> ops::Mul<T> for Mat3<T> {
490 type Output = Mat3<T>;
491 #[inline]
492 fn mul(self, rhs: T) -> Mat3<T> {
493 Mat3 {
494 a11: self.a11 * rhs, a12: self.a12 * rhs, a13: self.a13 * rhs,
495 a21: self.a21 * rhs, a22: self.a22 * rhs, a23: self.a23 * rhs,
496 a31: self.a31 * rhs, a32: self.a32 * rhs, a33: self.a33 * rhs,
497 }
498 }
499}
500impl<T: Copy + ops::MulAssign> ops::MulAssign<T> for Mat3<T> {
501 #[inline]
502 fn mul_assign(&mut self, rhs: T) {
503 self.a11 *= rhs; self.a12 *= rhs; self.a13 *= rhs;
504 self.a21 *= rhs; self.a22 *= rhs; self.a23 *= rhs;
505 self.a31 *= rhs; self.a32 *= rhs; self.a33 *= rhs;
506 }
507}
508
509impl<T: ops::Neg<Output = T>> ops::Neg for Mat3<T> {
510 type Output = Mat3<T>;
511 #[inline]
512 fn neg(self) -> Mat3<T> {
513 Mat3 {
514 a11: -self.a11, a12: -self.a12, a13: -self.a13,
515 a21: -self.a21, a22: -self.a22, a23: -self.a23,
516 a31: -self.a31, a32: -self.a32, a33: -self.a33,
517 }
518 }
519}
520
521impl<T: Copy + ops::Add<Output = T>> ops::Add<Mat3<T>> for Mat3<T> {
522 type Output = Mat3<T>;
523 #[inline]
524 fn add(self, rhs: Mat3<T>) -> Mat3<T> {
525 Mat3 {
526 a11: self.a11 + rhs.a11, a12: self.a12 + rhs.a12, a13: self.a13 + rhs.a13,
527 a21: self.a21 + rhs.a21, a22: self.a22 + rhs.a22, a23: self.a23 + rhs.a23,
528 a31: self.a31 + rhs.a31, a32: self.a32 + rhs.a32, a33: self.a33 + rhs.a33,
529 }
530 }
531}
532impl<T: Copy + ops::AddAssign> ops::AddAssign<Mat3<T>> for Mat3<T> {
533 #[inline]
534 fn add_assign(&mut self, rhs: Mat3<T>) {
535 self.a11 += rhs.a11; self.a12 += rhs.a12; self.a13 += rhs.a13;
536 self.a21 += rhs.a21; self.a22 += rhs.a22; self.a23 += rhs.a23;
537 self.a31 += rhs.a31; self.a32 += rhs.a32; self.a33 += rhs.a33;
538 }
539}
540impl<T: Copy + ops::Sub<Output = T>> ops::Sub<Mat3<T>> for Mat3<T> {
541 type Output = Mat3<T>;
542 #[inline]
543 fn sub(self, rhs: Mat3<T>) -> Mat3<T> {
544 Mat3 {
545 a11: self.a11 - rhs.a11, a12: self.a12 - rhs.a12, a13: self.a13 - rhs.a13,
546 a21: self.a21 - rhs.a21, a22: self.a22 - rhs.a22, a23: self.a23 - rhs.a23,
547 a31: self.a31 - rhs.a31, a32: self.a32 - rhs.a32, a33: self.a33 - rhs.a33,
548 }
549 }
550}
551impl<T: Copy + ops::SubAssign> ops::SubAssign<Mat3<T>> for Mat3<T> {
552 #[inline]
553 fn sub_assign(&mut self, rhs: Mat3<T>) {
554 self.a11 -= rhs.a11; self.a12 -= rhs.a12; self.a13 -= rhs.a13;
555 self.a21 -= rhs.a21; self.a22 -= rhs.a22; self.a23 -= rhs.a23;
556 self.a31 -= rhs.a31; self.a32 -= rhs.a32; self.a33 -= rhs.a33;
557 }
558}
559
560impl<T: Copy + ops::Add<Output = T> + ops::Mul<Output = T>> ops::Mul<Vec3<T>> for Mat3<T> {
561 type Output = Vec3<T>;
562 #[inline]
563 fn mul(self, rhs: Vec3<T>) -> Vec3<T> {
564 Vec3 {
565 x: self.a11 * rhs.x + self.a12 * rhs.y + self.a13 * rhs.z,
566 y: self.a21 * rhs.x + self.a22 * rhs.y + self.a23 * rhs.z,
567 z: self.a31 * rhs.x + self.a32 * rhs.y + self.a33 * rhs.z,
568 }
569 }
570}
571
572impl<T: Copy + ops::Add<Output = T> + ops::Mul<Output = T>> ops::Mul<Mat3<T>> for Mat3<T> {
573 type Output = Mat3<T>;
574 #[inline]
575 fn mul(self, rhs: Mat3<T>) -> Mat3<T> {
576 Mat3 {
577 a11: self.a11 * rhs.a11 + self.a12 * rhs.a21 + self.a13 * rhs.a31,
578 a12: self.a11 * rhs.a12 + self.a12 * rhs.a22 + self.a13 * rhs.a32,
579 a13: self.a11 * rhs.a13 + self.a12 * rhs.a23 + self.a13 * rhs.a33,
580
581 a21: self.a21 * rhs.a11 + self.a22 * rhs.a21 + self.a23 * rhs.a31,
582 a22: self.a21 * rhs.a12 + self.a22 * rhs.a22 + self.a23 * rhs.a32,
583 a23: self.a21 * rhs.a13 + self.a22 * rhs.a23 + self.a23 * rhs.a33,
584
585 a31: self.a31 * rhs.a11 + self.a32 * rhs.a21 + self.a33 * rhs.a31,
586 a32: self.a31 * rhs.a12 + self.a32 * rhs.a22 + self.a33 * rhs.a32,
587 a33: self.a31 * rhs.a13 + self.a32 * rhs.a23 + self.a33 * rhs.a33,
588 }
589 }
590}
591impl<T: Copy + ops::Add<Output = T> + ops::Mul<Output = T>> ops::MulAssign<Mat3<T>> for Mat3<T> {
592 #[inline]
593 fn mul_assign(&mut self, rhs: Mat3<T>) {
594 *self = *self * rhs;
595 }
596}
597
598impl<T: Copy + ops::Add<Output = T> + ops::Mul<Output = T>> ops::Mul<Transform2<T>> for Mat3<T> {
599 type Output = Mat3<T>;
600 #[inline]
601 fn mul(self, rhs: Transform2<T>) -> Mat3<T> {
602 Mat3 {
603 a11: self.a11 * rhs.a11 + self.a12 * rhs.a21,
604 a12: self.a11 * rhs.a12 + self.a12 * rhs.a22,
605 a13: self.a11 * rhs.a13 + self.a12 * rhs.a23 + self.a13,
606
607 a21: self.a21 * rhs.a11 + self.a22 * rhs.a21,
608 a22: self.a21 * rhs.a12 + self.a22 * rhs.a22,
609 a23: self.a21 * rhs.a13 + self.a22 * rhs.a23 + self.a23,
610
611 a31: self.a31 * rhs.a11 + self.a32 * rhs.a21,
612 a32: self.a31 * rhs.a12 + self.a32 * rhs.a22,
613 a33: self.a31 * rhs.a13 + self.a32 * rhs.a23 + self.a33,
614 }
615 }
616}
617impl<T: Copy + ops::Add<Output = T> + ops::Mul<Output = T>> ops::MulAssign<Transform2<T>> for Mat3<T> {
618 #[inline]
619 fn mul_assign(&mut self, rhs: Transform2<T>) {
620 *self = *self * rhs;
621 }
622}
623
624impl_mat_neg!(Mat3);
625impl_mat_add_mat!(Mat3);
626impl_mat_sub_mat!(Mat3);
627impl_mat_mul_scalar!(Mat3);
628impl_mat_mul_vec!(Mat3, Vec3);
629impl_mat_mul_mat!(Mat3);
630
631impl<T: fmt::Display> fmt::Display for Mat3<T> {
635 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
636 f.write_str("Mat3(")?;
637 print::print(&move |i| &self.as_array()[i], 0x33, f)?;
638 f.write_str(")")
639 }
640}
641impl<T: fmt::Debug> fmt::Debug for Mat3<T> {
642 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
643 f.write_str("Mat3(")?;
644 print::print(&move |i| print::Debug(&self.as_array()[i]), 0x33, f)?;
645 f.write_str(")")
646 }
647}
648
649#[test]
653fn test_inverse() {
654 let mut rng = urandom::seeded(42);
655
656 for _ in 0..1000 {
657 let a11 = rng.range(-10.0..10.0);
658 let a12 = rng.range(-10.0..10.0);
659 let a13 = rng.range(-10.0..10.0);
660 let a21 = rng.range(-10.0..10.0);
661 let a22 = rng.range(-10.0..10.0);
662 let a23 = rng.range(-10.0..10.0);
663 let a31 = rng.range(-10.0..10.0);
664 let a32 = rng.range(-10.0..10.0);
665 let a33 = rng.range(-10.0..10.0);
666
667 let mat = Mat3(a11, a12, a13, a21, a22, a23, a31, a32, a33);
668 let inv = mat.inverse();
669 let _identity = mat * inv;
670
671 let p = Vec3(
672 rng.range(-10.0..10.0),
673 rng.range(-10.0..10.0),
674 rng.range(-10.0..10.0),
675 );
676
677 let projected = mat * p;
678 let unprojected = inv * projected;
679
680 let error = (unprojected - p).len();
681 assert!(error < 1e-6, "Failed for mat: {mat:?}, p: {p:?}, error: {error}");
682 }
683}
684
685#[test]
686fn test_add() {
687 let lhs = Mat3(1, 2, 3, 4, 5, 6, 7, 8, 9);
688 let rhs = Mat3(10, 20, 30, 40, 50, 60, 70, 80, 90);
689 let expected = Mat3(11, 22, 33, 44, 55, 66, 77, 88, 99);
690
691 assert_eq!(lhs + rhs, expected);
692 assert_eq!(lhs + &rhs, expected);
693 assert_eq!(&lhs + rhs, expected);
694 assert_eq!(&lhs + &rhs, expected);
695
696 let mut value = lhs;
697 value += rhs;
698 assert_eq!(value, expected);
699
700 let mut value = lhs;
701 value += &rhs;
702 assert_eq!(value, expected);
703}
704
705#[test]
706fn test_sub() {
707 let lhs = Mat3(11, 22, 33, 44, 55, 66, 77, 88, 99);
708 let rhs = Mat3(10, 20, 30, 40, 50, 60, 70, 80, 90);
709 let expected = Mat3(1, 2, 3, 4, 5, 6, 7, 8, 9);
710
711 assert_eq!(lhs - rhs, expected);
712 assert_eq!(lhs - &rhs, expected);
713 assert_eq!(&lhs - rhs, expected);
714 assert_eq!(&lhs - &rhs, expected);
715
716 let mut value = lhs;
717 value -= rhs;
718 assert_eq!(value, expected);
719
720 let mut value = lhs;
721 value -= &rhs;
722 assert_eq!(value, expected);
723}
724
725#[test]
726fn test_neg() {
727 let value = Mat3(1, -2, 3, -4, 5, -6, 7, -8, 9);
728 let expected = Mat3(-1, 2, -3, 4, -5, 6, -7, 8, -9);
729 assert_eq!(-value, expected);
730 assert_eq!(-&value, expected);
731}