1#[cfg(feature = "f64")]
4use crate::DMat3;
5
6use crate::{
7 EulerRot, Mat2, Mat3A, Mat4, Quat, Vec2, Vec3, Vec3A,
8 euler::{FromEuler, ToEuler},
9 f32::math,
10 swizzles::*,
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-08")]
17use zerocopy_derive_08::*;
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-08",
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)]
98 #[must_use]
99 pub const fn from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
100 Self {
101 x_axis,
102 y_axis,
103 z_axis,
104 }
105 }
106
107 #[inline(always)]
113 #[must_use]
114 pub const fn from_rows(row0: Vec3, row1: Vec3, row2: Vec3) -> Self {
115 let [m00, m01, m02] = row0.to_array();
116 let [m10, m11, m12] = row1.to_array();
117 let [m20, m21, m22] = row2.to_array();
118 Self::new(m00, m10, m20, m01, m11, m21, m02, m12, m22)
119 }
120
121 #[inline]
125 #[must_use]
126 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
127 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
128 }
129
130 #[inline]
134 #[must_use]
135 pub const fn to_cols_array(&self) -> [f32; 9] {
136 [
137 self.x_axis.x,
138 self.x_axis.y,
139 self.x_axis.z,
140 self.y_axis.x,
141 self.y_axis.y,
142 self.y_axis.z,
143 self.z_axis.x,
144 self.z_axis.y,
145 self.z_axis.z,
146 ]
147 }
148
149 #[inline]
153 #[must_use]
154 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
155 Self::from_cols(
156 Vec3::from_array(m[0]),
157 Vec3::from_array(m[1]),
158 Vec3::from_array(m[2]),
159 )
160 }
161
162 #[inline]
166 #[must_use]
167 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
168 [
169 self.x_axis.to_array(),
170 self.y_axis.to_array(),
171 self.z_axis.to_array(),
172 ]
173 }
174
175 #[inline]
181 #[must_use]
182 pub const fn from_rows_array(m: &[f32; 9]) -> Self {
183 Self::new(m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8])
184 }
185
186 #[inline]
192 #[must_use]
193 pub const fn to_rows_array(&self) -> [f32; 9] {
194 let m = self.to_cols_array();
195 [m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8]]
196 }
197
198 #[doc(alias = "scale")]
200 #[inline]
201 #[must_use]
202 pub const fn from_diagonal(diagonal: Vec3) -> Self {
203 Self::new(
204 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
205 )
206 }
207
208 #[inline]
210 #[must_use]
211 pub fn from_mat4(m: Mat4) -> Self {
212 Self::from_cols(
213 Vec3::from_vec4(m.x_axis),
214 Vec3::from_vec4(m.y_axis),
215 Vec3::from_vec4(m.z_axis),
216 )
217 }
218
219 #[inline]
226 #[must_use]
227 #[track_caller]
228 pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
229 match (i, j) {
230 (0, 0) => Self::from_cols(m.y_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
231 (0, 1) => Self::from_cols(m.y_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
232 (0, 2) => Self::from_cols(m.y_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
233 (0, 3) => Self::from_cols(m.y_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
234 (1, 0) => Self::from_cols(m.x_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
235 (1, 1) => Self::from_cols(m.x_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
236 (1, 2) => Self::from_cols(m.x_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
237 (1, 3) => Self::from_cols(m.x_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
238 (2, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.w_axis.yzw()),
239 (2, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.w_axis.xzw()),
240 (2, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.w_axis.xyw()),
241 (2, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.w_axis.xyz()),
242 (3, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.z_axis.yzw()),
243 (3, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.z_axis.xzw()),
244 (3, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.z_axis.xyw()),
245 (3, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz()),
246 _ => panic!("index out of bounds"),
247 }
248 }
249
250 #[inline]
256 #[must_use]
257 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
258 pub fn from_quat(rotation: Quat) -> Self {
259 glam_assert!(rotation.is_normalized());
260
261 let x2 = rotation.x + rotation.x;
262 let y2 = rotation.y + rotation.y;
263 let z2 = rotation.z + rotation.z;
264 let xx = rotation.x * x2;
265 let xy = rotation.x * y2;
266 let xz = rotation.x * z2;
267 let yy = rotation.y * y2;
268 let yz = rotation.y * z2;
269 let zz = rotation.z * z2;
270 let wx = rotation.w * x2;
271 let wy = rotation.w * y2;
272 let wz = rotation.w * z2;
273
274 Self::from_cols(
275 Vec3::new(1.0 - (yy + zz), xy + wz, xz - wy),
276 Vec3::new(xy - wz, 1.0 - (xx + zz), yz + wx),
277 Vec3::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
278 )
279 }
280
281 #[inline]
288 #[must_use]
289 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
290 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
291 glam_assert!(axis.is_normalized());
292
293 let (sin, cos) = math::sin_cos(angle);
294 let (xsin, ysin, zsin) = axis.mul(sin).into();
295 let (x, y, z) = axis.into();
296 let (x2, y2, z2) = axis.mul(axis).into();
297 let omc = 1.0 - cos;
298 let xyomc = x * y * omc;
299 let xzomc = x * z * omc;
300 let yzomc = y * z * omc;
301 Self::from_cols(
302 Vec3::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
303 Vec3::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
304 Vec3::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
305 )
306 }
307
308 #[inline]
311 #[must_use]
312 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
313 Self::from_euler_angles(order, a, b, c)
314 }
315
316 #[inline]
325 #[must_use]
326 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
327 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
328 glam_assert!(
329 self.x_axis.is_normalized()
330 && self.y_axis.is_normalized()
331 && self.z_axis.is_normalized()
332 );
333 self.to_euler_angles(order)
334 }
335
336 #[inline]
338 #[must_use]
339 pub fn from_rotation_x(angle: f32) -> Self {
340 let (sina, cosa) = math::sin_cos(angle);
341 Self::from_cols(
342 Vec3::X,
343 Vec3::new(0.0, cosa, sina),
344 Vec3::new(0.0, -sina, cosa),
345 )
346 }
347
348 #[inline]
350 #[must_use]
351 pub fn from_rotation_y(angle: f32) -> Self {
352 let (sina, cosa) = math::sin_cos(angle);
353 Self::from_cols(
354 Vec3::new(cosa, 0.0, -sina),
355 Vec3::Y,
356 Vec3::new(sina, 0.0, cosa),
357 )
358 }
359
360 #[inline]
362 #[must_use]
363 pub fn from_rotation_z(angle: f32) -> Self {
364 let (sina, cosa) = math::sin_cos(angle);
365 Self::from_cols(
366 Vec3::new(cosa, sina, 0.0),
367 Vec3::new(-sina, cosa, 0.0),
368 Vec3::Z,
369 )
370 }
371
372 #[inline]
377 #[must_use]
378 pub fn from_translation(translation: Vec2) -> Self {
379 Self::from_cols(
380 Vec3::X,
381 Vec3::Y,
382 Vec3::new(translation.x, translation.y, 1.0),
383 )
384 }
385
386 #[inline]
392 #[must_use]
393 pub fn from_angle(angle: f32) -> Self {
394 let (sin, cos) = math::sin_cos(angle);
395 Self::from_cols(Vec3::new(cos, sin, 0.0), Vec3::new(-sin, cos, 0.0), Vec3::Z)
396 }
397
398 #[inline]
404 #[must_use]
405 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
406 let (sin, cos) = math::sin_cos(angle);
407 Self::from_cols(
408 Vec3::new(cos * scale.x, sin * scale.x, 0.0),
409 Vec3::new(-sin * scale.y, cos * scale.y, 0.0),
410 Vec3::new(translation.x, translation.y, 1.0),
411 )
412 }
413
414 #[inline]
423 #[must_use]
424 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
425 pub fn from_scale(scale: Vec2) -> Self {
426 glam_assert!(scale.cmpne(Vec2::ZERO).any());
428
429 Self::from_cols(
430 Vec3::new(scale.x, 0.0, 0.0),
431 Vec3::new(0.0, scale.y, 0.0),
432 Vec3::Z,
433 )
434 }
435
436 #[inline]
441 pub fn from_mat2(m: Mat2) -> Self {
442 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3::Z)
443 }
444
445 #[inline]
453 #[must_use]
454 #[track_caller]
455 pub const fn from_cols_slice(slice: &[f32]) -> Self {
456 Self::new(
457 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
458 slice[8],
459 )
460 }
461
462 #[inline]
468 #[track_caller]
469 pub fn write_cols_to_slice(&self, slice: &mut [f32]) {
470 slice[0] = self.x_axis.x;
471 slice[1] = self.x_axis.y;
472 slice[2] = self.x_axis.z;
473 slice[3] = self.y_axis.x;
474 slice[4] = self.y_axis.y;
475 slice[5] = self.y_axis.z;
476 slice[6] = self.z_axis.x;
477 slice[7] = self.z_axis.y;
478 slice[8] = self.z_axis.z;
479 }
480
481 #[inline]
492 #[must_use]
493 #[track_caller]
494 pub const fn from_rows_slice(slice: &[f32]) -> Self {
495 Self::new(
496 slice[0], slice[3], slice[6], slice[1], slice[4], slice[7], slice[2], slice[5],
497 slice[8],
498 )
499 }
500
501 #[inline]
507 #[must_use]
508 #[track_caller]
509 pub fn col(&self, index: usize) -> Vec3 {
510 match index {
511 0 => self.x_axis,
512 1 => self.y_axis,
513 2 => self.z_axis,
514 _ => panic!("index out of bounds"),
515 }
516 }
517
518 #[inline]
524 #[track_caller]
525 pub fn col_mut(&mut self, index: usize) -> &mut Vec3 {
526 match index {
527 0 => &mut self.x_axis,
528 1 => &mut self.y_axis,
529 2 => &mut self.z_axis,
530 _ => panic!("index out of bounds"),
531 }
532 }
533
534 #[inline]
542 #[must_use]
543 #[track_caller]
544 pub fn row(&self, index: usize) -> Vec3 {
545 match index {
546 0 => Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
547 1 => Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
548 2 => Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
549 _ => panic!("index out of bounds"),
550 }
551 }
552
553 #[inline]
563 #[track_caller]
564 pub fn set_row(&mut self, index: usize, row: Vec3) {
565 match index {
566 0 => {
567 self.x_axis.x = row.x;
568 self.y_axis.x = row.y;
569 self.z_axis.x = row.z;
570 }
571 1 => {
572 self.x_axis.y = row.x;
573 self.y_axis.y = row.y;
574 self.z_axis.y = row.z;
575 }
576 2 => {
577 self.x_axis.z = row.x;
578 self.y_axis.z = row.y;
579 self.z_axis.z = row.z;
580 }
581 _ => panic!("index out of bounds"),
582 }
583 }
584
585 #[inline]
588 #[must_use]
589 pub fn is_finite(&self) -> bool {
590 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
591 }
592
593 #[inline]
595 #[must_use]
596 pub fn is_nan(&self) -> bool {
597 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
598 }
599
600 #[inline]
602 #[must_use]
603 pub fn transpose(&self) -> Self {
604 Self {
605 x_axis: Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
606 y_axis: Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
607 z_axis: Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
608 }
609 }
610
611 #[inline]
613 #[must_use]
614 pub fn diagonal(&self) -> Vec3 {
615 Vec3::new(self.x_axis.x, self.y_axis.y, self.z_axis.z)
616 }
617
618 #[inline]
620 #[must_use]
621 pub fn determinant(&self) -> f32 {
622 self.x_axis.dot(self.y_axis.cross(self.z_axis))
623 }
624
625 #[inline(always)]
637 #[must_use]
638 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
639 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
640 let tmp0 = self.y_axis.cross(self.z_axis);
641 let tmp1 = self.z_axis.cross(self.x_axis);
642 let tmp2 = self.x_axis.cross(self.y_axis);
643 let inv_det = Vec3::splat(1.0 / self.x_axis.dot(tmp0));
644 let m =
645 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose();
646 if CHECKED {
647 if !m.is_finite() {
648 return (Self::ZERO, false);
649 }
650 } else {
651 glam_assert!(m.is_finite());
652 }
653 (m, true)
654 }
655
656 #[inline]
668 #[must_use]
669 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
670 pub fn inverse(&self) -> Self {
671 self.inverse_checked::<false>().0
672 }
673
674 #[inline]
677 #[must_use]
678 pub fn try_inverse(&self) -> Option<Self> {
679 let (m, is_valid) = self.inverse_checked::<true>();
680 if is_valid { Some(m) } else { None }
681 }
682
683 #[inline]
686 #[must_use]
687 pub fn inverse_or_zero(&self) -> Self {
688 self.inverse_checked::<true>().0
689 }
690
691 #[inline]
701 #[must_use]
702 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
703 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
704 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
705 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
706 }
707
708 #[inline]
718 #[must_use]
719 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
720 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
721 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
722 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
723 }
724
725 #[inline]
727 #[must_use]
728 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
729 let mut res = self.x_axis.mul(rhs.x);
730 res = res.add(self.y_axis.mul(rhs.y));
731 res = res.add(self.z_axis.mul(rhs.z));
732 res
733 }
734
735 #[inline]
737 #[must_use]
738 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
739 self.mul_vec3(rhs.into()).into()
740 }
741
742 #[inline]
744 #[must_use]
745 pub fn transpose_mul_vec3(&self, rhs: Vec3) -> Vec3 {
746 Vec3::new(
747 self.x_axis.dot(rhs),
748 self.y_axis.dot(rhs),
749 self.z_axis.dot(rhs),
750 )
751 }
752
753 #[inline]
755 #[must_use]
756 #[deprecated(
757 since = "0.34.2",
758 note = "Use `transpose_mul_vec3` instead, whose word order matches its order of operations and is consistent with `transpose().mul_vec3`."
759 )]
760 pub fn mul_transpose_vec3(&self, rhs: Vec3) -> Vec3 {
761 self.transpose_mul_vec3(rhs)
762 }
763
764 #[inline]
766 #[must_use]
767 pub fn mul_mat3(&self, rhs: &Self) -> Self {
768 self.mul(rhs)
769 }
770
771 #[inline]
773 #[must_use]
774 pub fn add_mat3(&self, rhs: &Self) -> Self {
775 self.add(rhs)
776 }
777
778 #[inline]
780 #[must_use]
781 pub fn sub_mat3(&self, rhs: &Self) -> Self {
782 self.sub(rhs)
783 }
784
785 #[inline]
787 #[must_use]
788 pub fn mul_scalar(&self, rhs: f32) -> Self {
789 Self::from_cols(
790 self.x_axis.mul(rhs),
791 self.y_axis.mul(rhs),
792 self.z_axis.mul(rhs),
793 )
794 }
795
796 #[inline]
800 #[must_use]
801 pub fn mul_diagonal_scale(&self, scale: Vec3) -> Self {
802 Self::from_cols(
803 self.x_axis * scale.x,
804 self.y_axis * scale.y,
805 self.z_axis * scale.z,
806 )
807 }
808
809 #[inline]
811 #[must_use]
812 pub fn div_scalar(&self, rhs: f32) -> Self {
813 let rhs = Vec3::splat(rhs);
814 Self::from_cols(
815 self.x_axis.div(rhs),
816 self.y_axis.div(rhs),
817 self.z_axis.div(rhs),
818 )
819 }
820
821 #[inline]
823 #[must_use]
824 pub fn recip(&self) -> Self {
825 Self::from_cols(
826 self.x_axis.recip(),
827 self.y_axis.recip(),
828 self.z_axis.recip(),
829 )
830 }
831
832 #[inline]
842 #[must_use]
843 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
844 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
845 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
846 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
847 }
848
849 #[inline]
851 #[must_use]
852 pub fn abs(&self) -> Self {
853 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
854 }
855
856 #[cfg(feature = "f64")]
857 #[inline]
858 #[must_use]
859 pub fn as_dmat3(&self) -> DMat3 {
860 DMat3::from_cols(
861 self.x_axis.as_dvec3(),
862 self.y_axis.as_dvec3(),
863 self.z_axis.as_dvec3(),
864 )
865 }
866}
867
868impl Default for Mat3 {
869 #[inline]
870 fn default() -> Self {
871 Self::IDENTITY
872 }
873}
874
875impl Add for Mat3 {
876 type Output = Self;
877 #[inline]
878 fn add(self, rhs: Self) -> Self {
879 Self::from_cols(
880 self.x_axis.add(rhs.x_axis),
881 self.y_axis.add(rhs.y_axis),
882 self.z_axis.add(rhs.z_axis),
883 )
884 }
885}
886
887impl Add<&Self> for Mat3 {
888 type Output = Self;
889 #[inline]
890 fn add(self, rhs: &Self) -> Self {
891 self.add(*rhs)
892 }
893}
894
895impl Add<&Mat3> for &Mat3 {
896 type Output = Mat3;
897 #[inline]
898 fn add(self, rhs: &Mat3) -> Mat3 {
899 (*self).add(*rhs)
900 }
901}
902
903impl Add<Mat3> for &Mat3 {
904 type Output = Mat3;
905 #[inline]
906 fn add(self, rhs: Mat3) -> Mat3 {
907 (*self).add(rhs)
908 }
909}
910
911impl AddAssign for Mat3 {
912 #[inline]
913 fn add_assign(&mut self, rhs: Self) {
914 *self = self.add(rhs);
915 }
916}
917
918impl AddAssign<&Self> for Mat3 {
919 #[inline]
920 fn add_assign(&mut self, rhs: &Self) {
921 self.add_assign(*rhs);
922 }
923}
924
925impl Sub for Mat3 {
926 type Output = Self;
927 #[inline]
928 fn sub(self, rhs: Self) -> Self {
929 Self::from_cols(
930 self.x_axis.sub(rhs.x_axis),
931 self.y_axis.sub(rhs.y_axis),
932 self.z_axis.sub(rhs.z_axis),
933 )
934 }
935}
936
937impl Sub<&Self> for Mat3 {
938 type Output = Self;
939 #[inline]
940 fn sub(self, rhs: &Self) -> Self {
941 self.sub(*rhs)
942 }
943}
944
945impl Sub<&Mat3> for &Mat3 {
946 type Output = Mat3;
947 #[inline]
948 fn sub(self, rhs: &Mat3) -> Mat3 {
949 (*self).sub(*rhs)
950 }
951}
952
953impl Sub<Mat3> for &Mat3 {
954 type Output = Mat3;
955 #[inline]
956 fn sub(self, rhs: Mat3) -> Mat3 {
957 (*self).sub(rhs)
958 }
959}
960
961impl SubAssign for Mat3 {
962 #[inline]
963 fn sub_assign(&mut self, rhs: Self) {
964 *self = self.sub(rhs);
965 }
966}
967
968impl SubAssign<&Self> for Mat3 {
969 #[inline]
970 fn sub_assign(&mut self, rhs: &Self) {
971 self.sub_assign(*rhs);
972 }
973}
974
975impl Neg for Mat3 {
976 type Output = Self;
977 #[inline]
978 fn neg(self) -> Self::Output {
979 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
980 }
981}
982
983impl Neg for &Mat3 {
984 type Output = Mat3;
985 #[inline]
986 fn neg(self) -> Mat3 {
987 (*self).neg()
988 }
989}
990
991impl Mul for Mat3 {
992 type Output = Self;
993 #[inline]
994 fn mul(self, rhs: Self) -> Self {
995 Self::from_cols(
996 self.mul(rhs.x_axis),
997 self.mul(rhs.y_axis),
998 self.mul(rhs.z_axis),
999 )
1000 }
1001}
1002
1003impl Mul<&Self> for Mat3 {
1004 type Output = Self;
1005 #[inline]
1006 fn mul(self, rhs: &Self) -> Self {
1007 self.mul(*rhs)
1008 }
1009}
1010
1011impl Mul<&Mat3> for &Mat3 {
1012 type Output = Mat3;
1013 #[inline]
1014 fn mul(self, rhs: &Mat3) -> Mat3 {
1015 (*self).mul(*rhs)
1016 }
1017}
1018
1019impl Mul<Mat3> for &Mat3 {
1020 type Output = Mat3;
1021 #[inline]
1022 fn mul(self, rhs: Mat3) -> Mat3 {
1023 (*self).mul(rhs)
1024 }
1025}
1026
1027impl MulAssign for Mat3 {
1028 #[inline]
1029 fn mul_assign(&mut self, rhs: Self) {
1030 *self = self.mul(rhs);
1031 }
1032}
1033
1034impl MulAssign<&Self> for Mat3 {
1035 #[inline]
1036 fn mul_assign(&mut self, rhs: &Self) {
1037 self.mul_assign(*rhs);
1038 }
1039}
1040
1041impl Mul<Vec3> for Mat3 {
1042 type Output = Vec3;
1043 #[inline]
1044 fn mul(self, rhs: Vec3) -> Self::Output {
1045 self.mul_vec3(rhs)
1046 }
1047}
1048
1049impl Mul<&Vec3> for Mat3 {
1050 type Output = Vec3;
1051 #[inline]
1052 fn mul(self, rhs: &Vec3) -> Vec3 {
1053 self.mul(*rhs)
1054 }
1055}
1056
1057impl Mul<&Vec3> for &Mat3 {
1058 type Output = Vec3;
1059 #[inline]
1060 fn mul(self, rhs: &Vec3) -> Vec3 {
1061 (*self).mul(*rhs)
1062 }
1063}
1064
1065impl Mul<Vec3> for &Mat3 {
1066 type Output = Vec3;
1067 #[inline]
1068 fn mul(self, rhs: Vec3) -> Vec3 {
1069 (*self).mul(rhs)
1070 }
1071}
1072
1073impl Mul<Mat3> for f32 {
1074 type Output = Mat3;
1075 #[inline]
1076 fn mul(self, rhs: Mat3) -> Self::Output {
1077 rhs.mul_scalar(self)
1078 }
1079}
1080
1081impl Mul<&Mat3> for f32 {
1082 type Output = Mat3;
1083 #[inline]
1084 fn mul(self, rhs: &Mat3) -> Mat3 {
1085 self.mul(*rhs)
1086 }
1087}
1088
1089impl Mul<&Mat3> for &f32 {
1090 type Output = Mat3;
1091 #[inline]
1092 fn mul(self, rhs: &Mat3) -> Mat3 {
1093 (*self).mul(*rhs)
1094 }
1095}
1096
1097impl Mul<Mat3> for &f32 {
1098 type Output = Mat3;
1099 #[inline]
1100 fn mul(self, rhs: Mat3) -> Mat3 {
1101 (*self).mul(rhs)
1102 }
1103}
1104
1105impl Mul<f32> for Mat3 {
1106 type Output = Self;
1107 #[inline]
1108 fn mul(self, rhs: f32) -> Self {
1109 self.mul_scalar(rhs)
1110 }
1111}
1112
1113impl Mul<&f32> for Mat3 {
1114 type Output = Self;
1115 #[inline]
1116 fn mul(self, rhs: &f32) -> Self {
1117 self.mul(*rhs)
1118 }
1119}
1120
1121impl Mul<&f32> for &Mat3 {
1122 type Output = Mat3;
1123 #[inline]
1124 fn mul(self, rhs: &f32) -> Mat3 {
1125 (*self).mul(*rhs)
1126 }
1127}
1128
1129impl Mul<f32> for &Mat3 {
1130 type Output = Mat3;
1131 #[inline]
1132 fn mul(self, rhs: f32) -> Mat3 {
1133 (*self).mul(rhs)
1134 }
1135}
1136
1137impl MulAssign<f32> for Mat3 {
1138 #[inline]
1139 fn mul_assign(&mut self, rhs: f32) {
1140 *self = self.mul(rhs);
1141 }
1142}
1143
1144impl MulAssign<&f32> for Mat3 {
1145 #[inline]
1146 fn mul_assign(&mut self, rhs: &f32) {
1147 self.mul_assign(*rhs);
1148 }
1149}
1150
1151impl Div<Mat3> for f32 {
1152 type Output = Mat3;
1153 #[inline]
1154 fn div(self, rhs: Mat3) -> Self::Output {
1155 Mat3::from_cols(
1156 self.div(rhs.x_axis),
1157 self.div(rhs.y_axis),
1158 self.div(rhs.z_axis),
1159 )
1160 }
1161}
1162
1163impl Div<&Mat3> for f32 {
1164 type Output = Mat3;
1165 #[inline]
1166 fn div(self, rhs: &Mat3) -> Mat3 {
1167 self.div(*rhs)
1168 }
1169}
1170
1171impl Div<&Mat3> for &f32 {
1172 type Output = Mat3;
1173 #[inline]
1174 fn div(self, rhs: &Mat3) -> Mat3 {
1175 (*self).div(*rhs)
1176 }
1177}
1178
1179impl Div<Mat3> for &f32 {
1180 type Output = Mat3;
1181 #[inline]
1182 fn div(self, rhs: Mat3) -> Mat3 {
1183 (*self).div(rhs)
1184 }
1185}
1186
1187impl Div<f32> for Mat3 {
1188 type Output = Self;
1189 #[inline]
1190 fn div(self, rhs: f32) -> Self {
1191 self.div_scalar(rhs)
1192 }
1193}
1194
1195impl Div<&f32> for Mat3 {
1196 type Output = Self;
1197 #[inline]
1198 fn div(self, rhs: &f32) -> Self {
1199 self.div(*rhs)
1200 }
1201}
1202
1203impl Div<&f32> for &Mat3 {
1204 type Output = Mat3;
1205 #[inline]
1206 fn div(self, rhs: &f32) -> Mat3 {
1207 (*self).div(*rhs)
1208 }
1209}
1210
1211impl Div<f32> for &Mat3 {
1212 type Output = Mat3;
1213 #[inline]
1214 fn div(self, rhs: f32) -> Mat3 {
1215 (*self).div(rhs)
1216 }
1217}
1218
1219impl DivAssign<f32> for Mat3 {
1220 #[inline]
1221 fn div_assign(&mut self, rhs: f32) {
1222 *self = self.div(rhs);
1223 }
1224}
1225
1226impl DivAssign<&f32> for Mat3 {
1227 #[inline]
1228 fn div_assign(&mut self, rhs: &f32) {
1229 self.div_assign(*rhs);
1230 }
1231}
1232
1233impl Mul<Vec3A> for Mat3 {
1234 type Output = Vec3A;
1235 #[inline]
1236 fn mul(self, rhs: Vec3A) -> Vec3A {
1237 self.mul_vec3a(rhs)
1238 }
1239}
1240
1241impl Mul<&Vec3A> for Mat3 {
1242 type Output = Vec3A;
1243 #[inline]
1244 fn mul(self, rhs: &Vec3A) -> Vec3A {
1245 self.mul(*rhs)
1246 }
1247}
1248
1249impl Mul<&Vec3A> for &Mat3 {
1250 type Output = Vec3A;
1251 #[inline]
1252 fn mul(self, rhs: &Vec3A) -> Vec3A {
1253 (*self).mul(*rhs)
1254 }
1255}
1256
1257impl Mul<Vec3A> for &Mat3 {
1258 type Output = Vec3A;
1259 #[inline]
1260 fn mul(self, rhs: Vec3A) -> Vec3A {
1261 (*self).mul(rhs)
1262 }
1263}
1264
1265impl From<Mat3A> for Mat3 {
1266 #[inline]
1267 fn from(m: Mat3A) -> Self {
1268 Self {
1269 x_axis: m.x_axis.into(),
1270 y_axis: m.y_axis.into(),
1271 z_axis: m.z_axis.into(),
1272 }
1273 }
1274}
1275
1276impl Sum<Self> for Mat3 {
1277 fn sum<I>(iter: I) -> Self
1278 where
1279 I: Iterator<Item = Self>,
1280 {
1281 iter.fold(Self::ZERO, Self::add)
1282 }
1283}
1284
1285impl<'a> Sum<&'a Self> for Mat3 {
1286 fn sum<I>(iter: I) -> Self
1287 where
1288 I: Iterator<Item = &'a Self>,
1289 {
1290 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1291 }
1292}
1293
1294impl Product for Mat3 {
1295 fn product<I>(iter: I) -> Self
1296 where
1297 I: Iterator<Item = Self>,
1298 {
1299 iter.fold(Self::IDENTITY, Self::mul)
1300 }
1301}
1302
1303impl<'a> Product<&'a Self> for Mat3 {
1304 fn product<I>(iter: I) -> Self
1305 where
1306 I: Iterator<Item = &'a Self>,
1307 {
1308 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1309 }
1310}
1311
1312impl PartialEq for Mat3 {
1313 #[inline]
1314 fn eq(&self, rhs: &Self) -> bool {
1315 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1316 }
1317}
1318
1319impl AsRef<[f32; 9]> for Mat3 {
1320 #[inline]
1321 fn as_ref(&self) -> &[f32; 9] {
1322 unsafe { &*(self as *const Self as *const [f32; 9]) }
1323 }
1324}
1325
1326impl AsMut<[f32; 9]> for Mat3 {
1327 #[inline]
1328 fn as_mut(&mut self) -> &mut [f32; 9] {
1329 unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
1330 }
1331}
1332
1333impl fmt::Debug for Mat3 {
1334 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1335 fmt.debug_struct(stringify!(Mat3))
1336 .field("x_axis", &self.x_axis)
1337 .field("y_axis", &self.y_axis)
1338 .field("z_axis", &self.z_axis)
1339 .finish()
1340 }
1341}
1342
1343impl fmt::Display for Mat3 {
1344 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1345 if let Some(p) = f.precision() {
1346 write!(
1347 f,
1348 "[{:.*}, {:.*}, {:.*}]",
1349 p, self.x_axis, p, self.y_axis, p, self.z_axis
1350 )
1351 } else {
1352 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1353 }
1354 }
1355}