1#[cfg(feature = "f64")]
4use crate::DMat3;
5
6use crate::{
7 euler::{FromEuler, ToEuler},
8 f32::math,
9 swizzles::*,
10 EulerRot, Mat2, Mat3A, Mat4, Quat, Vec2, Vec3, Vec3A,
11};
12use core::fmt;
13use core::iter::{Product, Sum};
14use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
15
16#[cfg(feature = "zerocopy")]
17use zerocopy_derive::*;
18
19#[inline(always)]
21#[must_use]
22pub const fn mat3(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Mat3 {
23 Mat3::from_cols(x_axis, y_axis, z_axis)
24}
25
26#[derive(Clone, Copy)]
51#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
52#[cfg_attr(
53 feature = "zerocopy",
54 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
55)]
56#[repr(C)]
57pub struct Mat3 {
58 pub x_axis: Vec3,
59 pub y_axis: Vec3,
60 pub z_axis: Vec3,
61}
62
63impl Mat3 {
64 pub const ZERO: Self = Self::from_cols(Vec3::ZERO, Vec3::ZERO, Vec3::ZERO);
66
67 pub const IDENTITY: Self = Self::from_cols(Vec3::X, Vec3::Y, Vec3::Z);
69
70 pub const NAN: Self = Self::from_cols(Vec3::NAN, Vec3::NAN, Vec3::NAN);
72
73 #[allow(clippy::too_many_arguments)]
74 #[inline(always)]
75 #[must_use]
76 const fn new(
77 m00: f32,
78 m01: f32,
79 m02: f32,
80 m10: f32,
81 m11: f32,
82 m12: f32,
83 m20: f32,
84 m21: f32,
85 m22: f32,
86 ) -> Self {
87 Self {
88 x_axis: Vec3::new(m00, m01, m02),
89 y_axis: Vec3::new(m10, m11, m12),
90 z_axis: Vec3::new(m20, m21, m22),
91 }
92 }
93
94 #[inline(always)]
96 #[must_use]
97 pub const fn from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
98 Self {
99 x_axis,
100 y_axis,
101 z_axis,
102 }
103 }
104
105 #[inline]
109 #[must_use]
110 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
111 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
112 }
113
114 #[inline]
117 #[must_use]
118 pub const fn to_cols_array(&self) -> [f32; 9] {
119 [
120 self.x_axis.x,
121 self.x_axis.y,
122 self.x_axis.z,
123 self.y_axis.x,
124 self.y_axis.y,
125 self.y_axis.z,
126 self.z_axis.x,
127 self.z_axis.y,
128 self.z_axis.z,
129 ]
130 }
131
132 #[inline]
136 #[must_use]
137 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
138 Self::from_cols(
139 Vec3::from_array(m[0]),
140 Vec3::from_array(m[1]),
141 Vec3::from_array(m[2]),
142 )
143 }
144
145 #[inline]
148 #[must_use]
149 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
150 [
151 self.x_axis.to_array(),
152 self.y_axis.to_array(),
153 self.z_axis.to_array(),
154 ]
155 }
156
157 #[doc(alias = "scale")]
159 #[inline]
160 #[must_use]
161 pub const fn from_diagonal(diagonal: Vec3) -> Self {
162 Self::new(
163 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
164 )
165 }
166
167 #[inline]
169 #[must_use]
170 pub fn from_mat4(m: Mat4) -> Self {
171 Self::from_cols(
172 Vec3::from_vec4(m.x_axis),
173 Vec3::from_vec4(m.y_axis),
174 Vec3::from_vec4(m.z_axis),
175 )
176 }
177
178 #[inline]
185 #[must_use]
186 pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
187 match (i, j) {
188 (0, 0) => Self::from_cols(m.y_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
189 (0, 1) => Self::from_cols(m.y_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
190 (0, 2) => Self::from_cols(m.y_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
191 (0, 3) => Self::from_cols(m.y_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
192 (1, 0) => Self::from_cols(m.x_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
193 (1, 1) => Self::from_cols(m.x_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
194 (1, 2) => Self::from_cols(m.x_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
195 (1, 3) => Self::from_cols(m.x_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
196 (2, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.w_axis.yzw()),
197 (2, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.w_axis.xzw()),
198 (2, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.w_axis.xyw()),
199 (2, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.w_axis.xyz()),
200 (3, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.z_axis.yzw()),
201 (3, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.z_axis.xzw()),
202 (3, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.z_axis.xyw()),
203 (3, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz()),
204 _ => panic!("index out of bounds"),
205 }
206 }
207
208 #[inline]
214 #[must_use]
215 pub fn from_quat(rotation: Quat) -> Self {
216 glam_assert!(rotation.is_normalized());
217
218 let x2 = rotation.x + rotation.x;
219 let y2 = rotation.y + rotation.y;
220 let z2 = rotation.z + rotation.z;
221 let xx = rotation.x * x2;
222 let xy = rotation.x * y2;
223 let xz = rotation.x * z2;
224 let yy = rotation.y * y2;
225 let yz = rotation.y * z2;
226 let zz = rotation.z * z2;
227 let wx = rotation.w * x2;
228 let wy = rotation.w * y2;
229 let wz = rotation.w * z2;
230
231 Self::from_cols(
232 Vec3::new(1.0 - (yy + zz), xy + wz, xz - wy),
233 Vec3::new(xy - wz, 1.0 - (xx + zz), yz + wx),
234 Vec3::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
235 )
236 }
237
238 #[inline]
245 #[must_use]
246 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
247 glam_assert!(axis.is_normalized());
248
249 let (sin, cos) = math::sin_cos(angle);
250 let (xsin, ysin, zsin) = axis.mul(sin).into();
251 let (x, y, z) = axis.into();
252 let (x2, y2, z2) = axis.mul(axis).into();
253 let omc = 1.0 - cos;
254 let xyomc = x * y * omc;
255 let xzomc = x * z * omc;
256 let yzomc = y * z * omc;
257 Self::from_cols(
258 Vec3::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
259 Vec3::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
260 Vec3::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
261 )
262 }
263
264 #[inline]
267 #[must_use]
268 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
269 Self::from_euler_angles(order, a, b, c)
270 }
271
272 #[inline]
281 #[must_use]
282 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
283 glam_assert!(
284 self.x_axis.is_normalized()
285 && self.y_axis.is_normalized()
286 && self.z_axis.is_normalized()
287 );
288 self.to_euler_angles(order)
289 }
290
291 #[inline]
293 #[must_use]
294 pub fn from_rotation_x(angle: f32) -> Self {
295 let (sina, cosa) = math::sin_cos(angle);
296 Self::from_cols(
297 Vec3::X,
298 Vec3::new(0.0, cosa, sina),
299 Vec3::new(0.0, -sina, cosa),
300 )
301 }
302
303 #[inline]
305 #[must_use]
306 pub fn from_rotation_y(angle: f32) -> Self {
307 let (sina, cosa) = math::sin_cos(angle);
308 Self::from_cols(
309 Vec3::new(cosa, 0.0, -sina),
310 Vec3::Y,
311 Vec3::new(sina, 0.0, cosa),
312 )
313 }
314
315 #[inline]
317 #[must_use]
318 pub fn from_rotation_z(angle: f32) -> Self {
319 let (sina, cosa) = math::sin_cos(angle);
320 Self::from_cols(
321 Vec3::new(cosa, sina, 0.0),
322 Vec3::new(-sina, cosa, 0.0),
323 Vec3::Z,
324 )
325 }
326
327 #[inline]
332 #[must_use]
333 pub fn from_translation(translation: Vec2) -> Self {
334 Self::from_cols(
335 Vec3::X,
336 Vec3::Y,
337 Vec3::new(translation.x, translation.y, 1.0),
338 )
339 }
340
341 #[inline]
347 #[must_use]
348 pub fn from_angle(angle: f32) -> Self {
349 let (sin, cos) = math::sin_cos(angle);
350 Self::from_cols(Vec3::new(cos, sin, 0.0), Vec3::new(-sin, cos, 0.0), Vec3::Z)
351 }
352
353 #[inline]
359 #[must_use]
360 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
361 let (sin, cos) = math::sin_cos(angle);
362 Self::from_cols(
363 Vec3::new(cos * scale.x, sin * scale.x, 0.0),
364 Vec3::new(-sin * scale.y, cos * scale.y, 0.0),
365 Vec3::new(translation.x, translation.y, 1.0),
366 )
367 }
368
369 #[inline]
378 #[must_use]
379 pub fn from_scale(scale: Vec2) -> Self {
380 glam_assert!(scale.cmpne(Vec2::ZERO).any());
382
383 Self::from_cols(
384 Vec3::new(scale.x, 0.0, 0.0),
385 Vec3::new(0.0, scale.y, 0.0),
386 Vec3::Z,
387 )
388 }
389
390 #[inline]
395 pub fn from_mat2(m: Mat2) -> Self {
396 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3::Z)
397 }
398
399 #[inline]
405 #[must_use]
406 pub const fn from_cols_slice(slice: &[f32]) -> Self {
407 Self::new(
408 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
409 slice[8],
410 )
411 }
412
413 #[inline]
419 pub fn write_cols_to_slice(&self, slice: &mut [f32]) {
420 slice[0] = self.x_axis.x;
421 slice[1] = self.x_axis.y;
422 slice[2] = self.x_axis.z;
423 slice[3] = self.y_axis.x;
424 slice[4] = self.y_axis.y;
425 slice[5] = self.y_axis.z;
426 slice[6] = self.z_axis.x;
427 slice[7] = self.z_axis.y;
428 slice[8] = self.z_axis.z;
429 }
430
431 #[inline]
437 #[must_use]
438 pub fn col(&self, index: usize) -> Vec3 {
439 match index {
440 0 => self.x_axis,
441 1 => self.y_axis,
442 2 => self.z_axis,
443 _ => panic!("index out of bounds"),
444 }
445 }
446
447 #[inline]
453 pub fn col_mut(&mut self, index: usize) -> &mut Vec3 {
454 match index {
455 0 => &mut self.x_axis,
456 1 => &mut self.y_axis,
457 2 => &mut self.z_axis,
458 _ => panic!("index out of bounds"),
459 }
460 }
461
462 #[inline]
468 #[must_use]
469 pub fn row(&self, index: usize) -> Vec3 {
470 match index {
471 0 => Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
472 1 => Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
473 2 => Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
474 _ => panic!("index out of bounds"),
475 }
476 }
477
478 #[inline]
481 #[must_use]
482 pub fn is_finite(&self) -> bool {
483 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
484 }
485
486 #[inline]
488 #[must_use]
489 pub fn is_nan(&self) -> bool {
490 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
491 }
492
493 #[inline]
495 #[must_use]
496 pub fn transpose(&self) -> Self {
497 Self {
498 x_axis: Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
499 y_axis: Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
500 z_axis: Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
501 }
502 }
503
504 #[inline]
506 #[must_use]
507 pub fn diagonal(&self) -> Vec3 {
508 Vec3::new(self.x_axis.x, self.y_axis.y, self.z_axis.z)
509 }
510
511 #[inline]
513 #[must_use]
514 pub fn determinant(&self) -> f32 {
515 self.z_axis.dot(self.x_axis.cross(self.y_axis))
516 }
517
518 #[inline(always)]
530 #[must_use]
531 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
532 let tmp0 = self.y_axis.cross(self.z_axis);
533 let tmp1 = self.z_axis.cross(self.x_axis);
534 let tmp2 = self.x_axis.cross(self.y_axis);
535 let det = self.z_axis.dot(tmp2);
536 if CHECKED {
537 if det == 0.0 {
538 return (Self::ZERO, false);
539 }
540 } else {
541 glam_assert!(det != 0.0);
542 }
543 let inv_det = Vec3::splat(det.recip());
544 (
545 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose(),
546 true,
547 )
548 }
549
550 #[inline]
558 #[must_use]
559 pub fn inverse(&self) -> Self {
560 self.inverse_checked::<false>().0
561 }
562
563 #[inline]
565 #[must_use]
566 pub fn try_inverse(&self) -> Option<Self> {
567 let (m, is_valid) = self.inverse_checked::<true>();
568 if is_valid {
569 Some(m)
570 } else {
571 None
572 }
573 }
574
575 #[inline]
577 #[must_use]
578 pub fn inverse_or_zero(&self) -> Self {
579 self.inverse_checked::<true>().0
580 }
581
582 #[inline]
592 #[must_use]
593 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
594 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
595 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
596 }
597
598 #[inline]
608 #[must_use]
609 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
610 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
611 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
612 }
613
614 #[inline]
622 #[must_use]
623 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
624 Self::look_to_rh(-dir, up)
625 }
626
627 #[inline]
635 #[must_use]
636 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
637 glam_assert!(dir.is_normalized());
638 glam_assert!(up.is_normalized());
639 let f = dir;
640 let s = f.cross(up).normalize();
641 let u = s.cross(f);
642
643 Self::from_cols(
644 Vec3::new(s.x, u.x, -f.x),
645 Vec3::new(s.y, u.y, -f.y),
646 Vec3::new(s.z, u.z, -f.z),
647 )
648 }
649
650 #[inline]
659 #[must_use]
660 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
661 Self::look_to_lh(center.sub(eye).normalize(), up)
662 }
663
664 #[inline]
673 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
674 Self::look_to_rh(center.sub(eye).normalize(), up)
675 }
676
677 #[inline]
679 #[must_use]
680 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
681 let mut res = self.x_axis.mul(rhs.x);
682 res = res.add(self.y_axis.mul(rhs.y));
683 res = res.add(self.z_axis.mul(rhs.z));
684 res
685 }
686
687 #[inline]
689 #[must_use]
690 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
691 self.mul_vec3(rhs.into()).into()
692 }
693
694 #[inline]
696 #[must_use]
697 pub fn mul_transpose_vec3(&self, rhs: Vec3) -> Vec3 {
698 Vec3::new(
699 self.x_axis.dot(rhs),
700 self.y_axis.dot(rhs),
701 self.z_axis.dot(rhs),
702 )
703 }
704
705 #[inline]
707 #[must_use]
708 pub fn mul_mat3(&self, rhs: &Self) -> Self {
709 self.mul(rhs)
710 }
711
712 #[inline]
714 #[must_use]
715 pub fn add_mat3(&self, rhs: &Self) -> Self {
716 self.add(rhs)
717 }
718
719 #[inline]
721 #[must_use]
722 pub fn sub_mat3(&self, rhs: &Self) -> Self {
723 self.sub(rhs)
724 }
725
726 #[inline]
728 #[must_use]
729 pub fn mul_scalar(&self, rhs: f32) -> Self {
730 Self::from_cols(
731 self.x_axis.mul(rhs),
732 self.y_axis.mul(rhs),
733 self.z_axis.mul(rhs),
734 )
735 }
736
737 #[inline]
741 #[must_use]
742 pub fn mul_diagonal_scale(&self, scale: Vec3) -> Self {
743 Self::from_cols(
744 self.x_axis * scale.x,
745 self.y_axis * scale.y,
746 self.z_axis * scale.z,
747 )
748 }
749
750 #[inline]
752 #[must_use]
753 pub fn div_scalar(&self, rhs: f32) -> Self {
754 let rhs = Vec3::splat(rhs);
755 Self::from_cols(
756 self.x_axis.div(rhs),
757 self.y_axis.div(rhs),
758 self.z_axis.div(rhs),
759 )
760 }
761
762 #[inline]
764 #[must_use]
765 pub fn recip(&self) -> Self {
766 Self::from_cols(
767 self.x_axis.recip(),
768 self.y_axis.recip(),
769 self.z_axis.recip(),
770 )
771 }
772
773 #[inline]
783 #[must_use]
784 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
785 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
786 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
787 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
788 }
789
790 #[inline]
792 #[must_use]
793 pub fn abs(&self) -> Self {
794 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
795 }
796
797 #[cfg(feature = "f64")]
798 #[inline]
799 #[must_use]
800 pub fn as_dmat3(&self) -> DMat3 {
801 DMat3::from_cols(
802 self.x_axis.as_dvec3(),
803 self.y_axis.as_dvec3(),
804 self.z_axis.as_dvec3(),
805 )
806 }
807}
808
809impl Default for Mat3 {
810 #[inline]
811 fn default() -> Self {
812 Self::IDENTITY
813 }
814}
815
816impl Add for Mat3 {
817 type Output = Self;
818 #[inline]
819 fn add(self, rhs: Self) -> Self {
820 Self::from_cols(
821 self.x_axis.add(rhs.x_axis),
822 self.y_axis.add(rhs.y_axis),
823 self.z_axis.add(rhs.z_axis),
824 )
825 }
826}
827
828impl Add<&Self> for Mat3 {
829 type Output = Self;
830 #[inline]
831 fn add(self, rhs: &Self) -> Self {
832 self.add(*rhs)
833 }
834}
835
836impl Add<&Mat3> for &Mat3 {
837 type Output = Mat3;
838 #[inline]
839 fn add(self, rhs: &Mat3) -> Mat3 {
840 (*self).add(*rhs)
841 }
842}
843
844impl Add<Mat3> for &Mat3 {
845 type Output = Mat3;
846 #[inline]
847 fn add(self, rhs: Mat3) -> Mat3 {
848 (*self).add(rhs)
849 }
850}
851
852impl AddAssign for Mat3 {
853 #[inline]
854 fn add_assign(&mut self, rhs: Self) {
855 *self = self.add(rhs);
856 }
857}
858
859impl AddAssign<&Self> for Mat3 {
860 #[inline]
861 fn add_assign(&mut self, rhs: &Self) {
862 self.add_assign(*rhs);
863 }
864}
865
866impl Sub for Mat3 {
867 type Output = Self;
868 #[inline]
869 fn sub(self, rhs: Self) -> Self {
870 Self::from_cols(
871 self.x_axis.sub(rhs.x_axis),
872 self.y_axis.sub(rhs.y_axis),
873 self.z_axis.sub(rhs.z_axis),
874 )
875 }
876}
877
878impl Sub<&Self> for Mat3 {
879 type Output = Self;
880 #[inline]
881 fn sub(self, rhs: &Self) -> Self {
882 self.sub(*rhs)
883 }
884}
885
886impl Sub<&Mat3> for &Mat3 {
887 type Output = Mat3;
888 #[inline]
889 fn sub(self, rhs: &Mat3) -> Mat3 {
890 (*self).sub(*rhs)
891 }
892}
893
894impl Sub<Mat3> for &Mat3 {
895 type Output = Mat3;
896 #[inline]
897 fn sub(self, rhs: Mat3) -> Mat3 {
898 (*self).sub(rhs)
899 }
900}
901
902impl SubAssign for Mat3 {
903 #[inline]
904 fn sub_assign(&mut self, rhs: Self) {
905 *self = self.sub(rhs);
906 }
907}
908
909impl SubAssign<&Self> for Mat3 {
910 #[inline]
911 fn sub_assign(&mut self, rhs: &Self) {
912 self.sub_assign(*rhs);
913 }
914}
915
916impl Neg for Mat3 {
917 type Output = Self;
918 #[inline]
919 fn neg(self) -> Self::Output {
920 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
921 }
922}
923
924impl Neg for &Mat3 {
925 type Output = Mat3;
926 #[inline]
927 fn neg(self) -> Mat3 {
928 (*self).neg()
929 }
930}
931
932impl Mul for Mat3 {
933 type Output = Self;
934 #[inline]
935 fn mul(self, rhs: Self) -> Self {
936 Self::from_cols(
937 self.mul(rhs.x_axis),
938 self.mul(rhs.y_axis),
939 self.mul(rhs.z_axis),
940 )
941 }
942}
943
944impl Mul<&Self> for Mat3 {
945 type Output = Self;
946 #[inline]
947 fn mul(self, rhs: &Self) -> Self {
948 self.mul(*rhs)
949 }
950}
951
952impl Mul<&Mat3> for &Mat3 {
953 type Output = Mat3;
954 #[inline]
955 fn mul(self, rhs: &Mat3) -> Mat3 {
956 (*self).mul(*rhs)
957 }
958}
959
960impl Mul<Mat3> for &Mat3 {
961 type Output = Mat3;
962 #[inline]
963 fn mul(self, rhs: Mat3) -> Mat3 {
964 (*self).mul(rhs)
965 }
966}
967
968impl MulAssign for Mat3 {
969 #[inline]
970 fn mul_assign(&mut self, rhs: Self) {
971 *self = self.mul(rhs);
972 }
973}
974
975impl MulAssign<&Self> for Mat3 {
976 #[inline]
977 fn mul_assign(&mut self, rhs: &Self) {
978 self.mul_assign(*rhs);
979 }
980}
981
982impl Mul<Vec3> for Mat3 {
983 type Output = Vec3;
984 #[inline]
985 fn mul(self, rhs: Vec3) -> Self::Output {
986 self.mul_vec3(rhs)
987 }
988}
989
990impl Mul<&Vec3> for Mat3 {
991 type Output = Vec3;
992 #[inline]
993 fn mul(self, rhs: &Vec3) -> Vec3 {
994 self.mul(*rhs)
995 }
996}
997
998impl Mul<&Vec3> for &Mat3 {
999 type Output = Vec3;
1000 #[inline]
1001 fn mul(self, rhs: &Vec3) -> Vec3 {
1002 (*self).mul(*rhs)
1003 }
1004}
1005
1006impl Mul<Vec3> for &Mat3 {
1007 type Output = Vec3;
1008 #[inline]
1009 fn mul(self, rhs: Vec3) -> Vec3 {
1010 (*self).mul(rhs)
1011 }
1012}
1013
1014impl Mul<Mat3> for f32 {
1015 type Output = Mat3;
1016 #[inline]
1017 fn mul(self, rhs: Mat3) -> Self::Output {
1018 rhs.mul_scalar(self)
1019 }
1020}
1021
1022impl Mul<&Mat3> for f32 {
1023 type Output = Mat3;
1024 #[inline]
1025 fn mul(self, rhs: &Mat3) -> Mat3 {
1026 self.mul(*rhs)
1027 }
1028}
1029
1030impl Mul<&Mat3> for &f32 {
1031 type Output = Mat3;
1032 #[inline]
1033 fn mul(self, rhs: &Mat3) -> Mat3 {
1034 (*self).mul(*rhs)
1035 }
1036}
1037
1038impl Mul<Mat3> for &f32 {
1039 type Output = Mat3;
1040 #[inline]
1041 fn mul(self, rhs: Mat3) -> Mat3 {
1042 (*self).mul(rhs)
1043 }
1044}
1045
1046impl Mul<f32> for Mat3 {
1047 type Output = Self;
1048 #[inline]
1049 fn mul(self, rhs: f32) -> Self {
1050 self.mul_scalar(rhs)
1051 }
1052}
1053
1054impl Mul<&f32> for Mat3 {
1055 type Output = Self;
1056 #[inline]
1057 fn mul(self, rhs: &f32) -> Self {
1058 self.mul(*rhs)
1059 }
1060}
1061
1062impl Mul<&f32> for &Mat3 {
1063 type Output = Mat3;
1064 #[inline]
1065 fn mul(self, rhs: &f32) -> Mat3 {
1066 (*self).mul(*rhs)
1067 }
1068}
1069
1070impl Mul<f32> for &Mat3 {
1071 type Output = Mat3;
1072 #[inline]
1073 fn mul(self, rhs: f32) -> Mat3 {
1074 (*self).mul(rhs)
1075 }
1076}
1077
1078impl MulAssign<f32> for Mat3 {
1079 #[inline]
1080 fn mul_assign(&mut self, rhs: f32) {
1081 *self = self.mul(rhs);
1082 }
1083}
1084
1085impl MulAssign<&f32> for Mat3 {
1086 #[inline]
1087 fn mul_assign(&mut self, rhs: &f32) {
1088 self.mul_assign(*rhs);
1089 }
1090}
1091
1092impl Div<Mat3> for f32 {
1093 type Output = Mat3;
1094 #[inline]
1095 fn div(self, rhs: Mat3) -> Self::Output {
1096 Mat3::from_cols(
1097 self.div(rhs.x_axis),
1098 self.div(rhs.y_axis),
1099 self.div(rhs.z_axis),
1100 )
1101 }
1102}
1103
1104impl Div<&Mat3> for f32 {
1105 type Output = Mat3;
1106 #[inline]
1107 fn div(self, rhs: &Mat3) -> Mat3 {
1108 self.div(*rhs)
1109 }
1110}
1111
1112impl Div<&Mat3> for &f32 {
1113 type Output = Mat3;
1114 #[inline]
1115 fn div(self, rhs: &Mat3) -> Mat3 {
1116 (*self).div(*rhs)
1117 }
1118}
1119
1120impl Div<Mat3> for &f32 {
1121 type Output = Mat3;
1122 #[inline]
1123 fn div(self, rhs: Mat3) -> Mat3 {
1124 (*self).div(rhs)
1125 }
1126}
1127
1128impl Div<f32> for Mat3 {
1129 type Output = Self;
1130 #[inline]
1131 fn div(self, rhs: f32) -> Self {
1132 self.div_scalar(rhs)
1133 }
1134}
1135
1136impl Div<&f32> for Mat3 {
1137 type Output = Self;
1138 #[inline]
1139 fn div(self, rhs: &f32) -> Self {
1140 self.div(*rhs)
1141 }
1142}
1143
1144impl Div<&f32> for &Mat3 {
1145 type Output = Mat3;
1146 #[inline]
1147 fn div(self, rhs: &f32) -> Mat3 {
1148 (*self).div(*rhs)
1149 }
1150}
1151
1152impl Div<f32> for &Mat3 {
1153 type Output = Mat3;
1154 #[inline]
1155 fn div(self, rhs: f32) -> Mat3 {
1156 (*self).div(rhs)
1157 }
1158}
1159
1160impl DivAssign<f32> for Mat3 {
1161 #[inline]
1162 fn div_assign(&mut self, rhs: f32) {
1163 *self = self.div(rhs);
1164 }
1165}
1166
1167impl DivAssign<&f32> for Mat3 {
1168 #[inline]
1169 fn div_assign(&mut self, rhs: &f32) {
1170 self.div_assign(*rhs);
1171 }
1172}
1173
1174impl Mul<Vec3A> for Mat3 {
1175 type Output = Vec3A;
1176 #[inline]
1177 fn mul(self, rhs: Vec3A) -> Vec3A {
1178 self.mul_vec3a(rhs)
1179 }
1180}
1181
1182impl Mul<&Vec3A> for Mat3 {
1183 type Output = Vec3A;
1184 #[inline]
1185 fn mul(self, rhs: &Vec3A) -> Vec3A {
1186 self.mul(*rhs)
1187 }
1188}
1189
1190impl Mul<&Vec3A> for &Mat3 {
1191 type Output = Vec3A;
1192 #[inline]
1193 fn mul(self, rhs: &Vec3A) -> Vec3A {
1194 (*self).mul(*rhs)
1195 }
1196}
1197
1198impl Mul<Vec3A> for &Mat3 {
1199 type Output = Vec3A;
1200 #[inline]
1201 fn mul(self, rhs: Vec3A) -> Vec3A {
1202 (*self).mul(rhs)
1203 }
1204}
1205
1206impl From<Mat3A> for Mat3 {
1207 #[inline]
1208 fn from(m: Mat3A) -> Self {
1209 Self {
1210 x_axis: m.x_axis.into(),
1211 y_axis: m.y_axis.into(),
1212 z_axis: m.z_axis.into(),
1213 }
1214 }
1215}
1216
1217impl Sum<Self> for Mat3 {
1218 fn sum<I>(iter: I) -> Self
1219 where
1220 I: Iterator<Item = Self>,
1221 {
1222 iter.fold(Self::ZERO, Self::add)
1223 }
1224}
1225
1226impl<'a> Sum<&'a Self> for Mat3 {
1227 fn sum<I>(iter: I) -> Self
1228 where
1229 I: Iterator<Item = &'a Self>,
1230 {
1231 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1232 }
1233}
1234
1235impl Product for Mat3 {
1236 fn product<I>(iter: I) -> Self
1237 where
1238 I: Iterator<Item = Self>,
1239 {
1240 iter.fold(Self::IDENTITY, Self::mul)
1241 }
1242}
1243
1244impl<'a> Product<&'a Self> for Mat3 {
1245 fn product<I>(iter: I) -> Self
1246 where
1247 I: Iterator<Item = &'a Self>,
1248 {
1249 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1250 }
1251}
1252
1253impl PartialEq for Mat3 {
1254 #[inline]
1255 fn eq(&self, rhs: &Self) -> bool {
1256 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1257 }
1258}
1259
1260impl AsRef<[f32; 9]> for Mat3 {
1261 #[inline]
1262 fn as_ref(&self) -> &[f32; 9] {
1263 unsafe { &*(self as *const Self as *const [f32; 9]) }
1264 }
1265}
1266
1267impl AsMut<[f32; 9]> for Mat3 {
1268 #[inline]
1269 fn as_mut(&mut self) -> &mut [f32; 9] {
1270 unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
1271 }
1272}
1273
1274impl fmt::Debug for Mat3 {
1275 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1276 fmt.debug_struct(stringify!(Mat3))
1277 .field("x_axis", &self.x_axis)
1278 .field("y_axis", &self.y_axis)
1279 .field("z_axis", &self.z_axis)
1280 .finish()
1281 }
1282}
1283
1284impl fmt::Display for Mat3 {
1285 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1286 if let Some(p) = f.precision() {
1287 write!(
1288 f,
1289 "[{:.*}, {:.*}, {:.*}]",
1290 p, self.x_axis, p, self.y_axis, p, self.z_axis
1291 )
1292 } else {
1293 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1294 }
1295 }
1296}