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