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 #[deprecated(
622 since = "0.33.1",
623 note = "use the `glam::camera::lh::view::look_to_mat3` function instead"
624 )]
625 #[inline]
626 #[must_use]
627 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
628 #[allow(deprecated)]
629 Self::look_to_rh(-dir, up)
630 }
631
632 #[deprecated(
640 since = "0.33.1",
641 note = "use the `glam::camera::rh::view::look_to_mat3` function instead"
642 )]
643 #[inline]
644 #[must_use]
645 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
646 glam_assert!(dir.is_normalized());
647 glam_assert!(up.is_normalized());
648 let f = dir;
649 let s = f.cross(up).normalize();
650 let u = s.cross(f);
651
652 Self::from_cols(
653 Vec3::new(s.x, u.x, -f.x),
654 Vec3::new(s.y, u.y, -f.y),
655 Vec3::new(s.z, u.z, -f.z),
656 )
657 }
658
659 #[deprecated(
668 since = "0.33.1",
669 note = "use the `glam::camera::lh::view::look_at_mat3` function instead"
670 )]
671 #[inline]
672 #[must_use]
673 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
674 #[allow(deprecated)]
675 Self::look_to_lh(center.sub(eye).normalize(), up)
676 }
677
678 #[deprecated(
687 since = "0.33.1",
688 note = "use the `glam::camera::rh::view::look_at_mat3` function instead"
689 )]
690 #[inline]
691 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
692 #[allow(deprecated)]
693 Self::look_to_rh(center.sub(eye).normalize(), up)
694 }
695
696 #[inline]
698 #[must_use]
699 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
700 let mut res = self.x_axis.mul(rhs.x);
701 res = res.add(self.y_axis.mul(rhs.y));
702 res = res.add(self.z_axis.mul(rhs.z));
703 res
704 }
705
706 #[inline]
708 #[must_use]
709 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
710 self.mul_vec3(rhs.into()).into()
711 }
712
713 #[inline]
715 #[must_use]
716 pub fn mul_transpose_vec3(&self, rhs: Vec3) -> Vec3 {
717 Vec3::new(
718 self.x_axis.dot(rhs),
719 self.y_axis.dot(rhs),
720 self.z_axis.dot(rhs),
721 )
722 }
723
724 #[inline]
726 #[must_use]
727 pub fn mul_mat3(&self, rhs: &Self) -> Self {
728 self.mul(rhs)
729 }
730
731 #[inline]
733 #[must_use]
734 pub fn add_mat3(&self, rhs: &Self) -> Self {
735 self.add(rhs)
736 }
737
738 #[inline]
740 #[must_use]
741 pub fn sub_mat3(&self, rhs: &Self) -> Self {
742 self.sub(rhs)
743 }
744
745 #[inline]
747 #[must_use]
748 pub fn mul_scalar(&self, rhs: f32) -> Self {
749 Self::from_cols(
750 self.x_axis.mul(rhs),
751 self.y_axis.mul(rhs),
752 self.z_axis.mul(rhs),
753 )
754 }
755
756 #[inline]
760 #[must_use]
761 pub fn mul_diagonal_scale(&self, scale: Vec3) -> Self {
762 Self::from_cols(
763 self.x_axis * scale.x,
764 self.y_axis * scale.y,
765 self.z_axis * scale.z,
766 )
767 }
768
769 #[inline]
771 #[must_use]
772 pub fn div_scalar(&self, rhs: f32) -> Self {
773 let rhs = Vec3::splat(rhs);
774 Self::from_cols(
775 self.x_axis.div(rhs),
776 self.y_axis.div(rhs),
777 self.z_axis.div(rhs),
778 )
779 }
780
781 #[inline]
783 #[must_use]
784 pub fn recip(&self) -> Self {
785 Self::from_cols(
786 self.x_axis.recip(),
787 self.y_axis.recip(),
788 self.z_axis.recip(),
789 )
790 }
791
792 #[inline]
802 #[must_use]
803 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
804 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
805 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
806 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
807 }
808
809 #[inline]
811 #[must_use]
812 pub fn abs(&self) -> Self {
813 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
814 }
815
816 #[cfg(feature = "f64")]
817 #[inline]
818 #[must_use]
819 pub fn as_dmat3(&self) -> DMat3 {
820 DMat3::from_cols(
821 self.x_axis.as_dvec3(),
822 self.y_axis.as_dvec3(),
823 self.z_axis.as_dvec3(),
824 )
825 }
826}
827
828impl Default for Mat3 {
829 #[inline]
830 fn default() -> Self {
831 Self::IDENTITY
832 }
833}
834
835impl Add for Mat3 {
836 type Output = Self;
837 #[inline]
838 fn add(self, rhs: Self) -> Self {
839 Self::from_cols(
840 self.x_axis.add(rhs.x_axis),
841 self.y_axis.add(rhs.y_axis),
842 self.z_axis.add(rhs.z_axis),
843 )
844 }
845}
846
847impl Add<&Self> for Mat3 {
848 type Output = Self;
849 #[inline]
850 fn add(self, rhs: &Self) -> Self {
851 self.add(*rhs)
852 }
853}
854
855impl Add<&Mat3> for &Mat3 {
856 type Output = Mat3;
857 #[inline]
858 fn add(self, rhs: &Mat3) -> Mat3 {
859 (*self).add(*rhs)
860 }
861}
862
863impl Add<Mat3> for &Mat3 {
864 type Output = Mat3;
865 #[inline]
866 fn add(self, rhs: Mat3) -> Mat3 {
867 (*self).add(rhs)
868 }
869}
870
871impl AddAssign for Mat3 {
872 #[inline]
873 fn add_assign(&mut self, rhs: Self) {
874 *self = self.add(rhs);
875 }
876}
877
878impl AddAssign<&Self> for Mat3 {
879 #[inline]
880 fn add_assign(&mut self, rhs: &Self) {
881 self.add_assign(*rhs);
882 }
883}
884
885impl Sub for Mat3 {
886 type Output = Self;
887 #[inline]
888 fn sub(self, rhs: Self) -> Self {
889 Self::from_cols(
890 self.x_axis.sub(rhs.x_axis),
891 self.y_axis.sub(rhs.y_axis),
892 self.z_axis.sub(rhs.z_axis),
893 )
894 }
895}
896
897impl Sub<&Self> for Mat3 {
898 type Output = Self;
899 #[inline]
900 fn sub(self, rhs: &Self) -> Self {
901 self.sub(*rhs)
902 }
903}
904
905impl Sub<&Mat3> for &Mat3 {
906 type Output = Mat3;
907 #[inline]
908 fn sub(self, rhs: &Mat3) -> Mat3 {
909 (*self).sub(*rhs)
910 }
911}
912
913impl Sub<Mat3> for &Mat3 {
914 type Output = Mat3;
915 #[inline]
916 fn sub(self, rhs: Mat3) -> Mat3 {
917 (*self).sub(rhs)
918 }
919}
920
921impl SubAssign for Mat3 {
922 #[inline]
923 fn sub_assign(&mut self, rhs: Self) {
924 *self = self.sub(rhs);
925 }
926}
927
928impl SubAssign<&Self> for Mat3 {
929 #[inline]
930 fn sub_assign(&mut self, rhs: &Self) {
931 self.sub_assign(*rhs);
932 }
933}
934
935impl Neg for Mat3 {
936 type Output = Self;
937 #[inline]
938 fn neg(self) -> Self::Output {
939 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
940 }
941}
942
943impl Neg for &Mat3 {
944 type Output = Mat3;
945 #[inline]
946 fn neg(self) -> Mat3 {
947 (*self).neg()
948 }
949}
950
951impl Mul for Mat3 {
952 type Output = Self;
953 #[inline]
954 fn mul(self, rhs: Self) -> Self {
955 Self::from_cols(
956 self.mul(rhs.x_axis),
957 self.mul(rhs.y_axis),
958 self.mul(rhs.z_axis),
959 )
960 }
961}
962
963impl Mul<&Self> for Mat3 {
964 type Output = Self;
965 #[inline]
966 fn mul(self, rhs: &Self) -> Self {
967 self.mul(*rhs)
968 }
969}
970
971impl Mul<&Mat3> for &Mat3 {
972 type Output = Mat3;
973 #[inline]
974 fn mul(self, rhs: &Mat3) -> Mat3 {
975 (*self).mul(*rhs)
976 }
977}
978
979impl Mul<Mat3> for &Mat3 {
980 type Output = Mat3;
981 #[inline]
982 fn mul(self, rhs: Mat3) -> Mat3 {
983 (*self).mul(rhs)
984 }
985}
986
987impl MulAssign for Mat3 {
988 #[inline]
989 fn mul_assign(&mut self, rhs: Self) {
990 *self = self.mul(rhs);
991 }
992}
993
994impl MulAssign<&Self> for Mat3 {
995 #[inline]
996 fn mul_assign(&mut self, rhs: &Self) {
997 self.mul_assign(*rhs);
998 }
999}
1000
1001impl Mul<Vec3> for Mat3 {
1002 type Output = Vec3;
1003 #[inline]
1004 fn mul(self, rhs: Vec3) -> Self::Output {
1005 self.mul_vec3(rhs)
1006 }
1007}
1008
1009impl Mul<&Vec3> for Mat3 {
1010 type Output = Vec3;
1011 #[inline]
1012 fn mul(self, rhs: &Vec3) -> Vec3 {
1013 self.mul(*rhs)
1014 }
1015}
1016
1017impl Mul<&Vec3> for &Mat3 {
1018 type Output = Vec3;
1019 #[inline]
1020 fn mul(self, rhs: &Vec3) -> Vec3 {
1021 (*self).mul(*rhs)
1022 }
1023}
1024
1025impl Mul<Vec3> for &Mat3 {
1026 type Output = Vec3;
1027 #[inline]
1028 fn mul(self, rhs: Vec3) -> Vec3 {
1029 (*self).mul(rhs)
1030 }
1031}
1032
1033impl Mul<Mat3> for f32 {
1034 type Output = Mat3;
1035 #[inline]
1036 fn mul(self, rhs: Mat3) -> Self::Output {
1037 rhs.mul_scalar(self)
1038 }
1039}
1040
1041impl Mul<&Mat3> for f32 {
1042 type Output = Mat3;
1043 #[inline]
1044 fn mul(self, rhs: &Mat3) -> Mat3 {
1045 self.mul(*rhs)
1046 }
1047}
1048
1049impl Mul<&Mat3> for &f32 {
1050 type Output = Mat3;
1051 #[inline]
1052 fn mul(self, rhs: &Mat3) -> Mat3 {
1053 (*self).mul(*rhs)
1054 }
1055}
1056
1057impl Mul<Mat3> for &f32 {
1058 type Output = Mat3;
1059 #[inline]
1060 fn mul(self, rhs: Mat3) -> Mat3 {
1061 (*self).mul(rhs)
1062 }
1063}
1064
1065impl Mul<f32> for Mat3 {
1066 type Output = Self;
1067 #[inline]
1068 fn mul(self, rhs: f32) -> Self {
1069 self.mul_scalar(rhs)
1070 }
1071}
1072
1073impl Mul<&f32> for Mat3 {
1074 type Output = Self;
1075 #[inline]
1076 fn mul(self, rhs: &f32) -> Self {
1077 self.mul(*rhs)
1078 }
1079}
1080
1081impl Mul<&f32> for &Mat3 {
1082 type Output = Mat3;
1083 #[inline]
1084 fn mul(self, rhs: &f32) -> Mat3 {
1085 (*self).mul(*rhs)
1086 }
1087}
1088
1089impl Mul<f32> for &Mat3 {
1090 type Output = Mat3;
1091 #[inline]
1092 fn mul(self, rhs: f32) -> Mat3 {
1093 (*self).mul(rhs)
1094 }
1095}
1096
1097impl MulAssign<f32> for Mat3 {
1098 #[inline]
1099 fn mul_assign(&mut self, rhs: f32) {
1100 *self = self.mul(rhs);
1101 }
1102}
1103
1104impl MulAssign<&f32> for Mat3 {
1105 #[inline]
1106 fn mul_assign(&mut self, rhs: &f32) {
1107 self.mul_assign(*rhs);
1108 }
1109}
1110
1111impl Div<Mat3> for f32 {
1112 type Output = Mat3;
1113 #[inline]
1114 fn div(self, rhs: Mat3) -> Self::Output {
1115 Mat3::from_cols(
1116 self.div(rhs.x_axis),
1117 self.div(rhs.y_axis),
1118 self.div(rhs.z_axis),
1119 )
1120 }
1121}
1122
1123impl Div<&Mat3> for f32 {
1124 type Output = Mat3;
1125 #[inline]
1126 fn div(self, rhs: &Mat3) -> Mat3 {
1127 self.div(*rhs)
1128 }
1129}
1130
1131impl Div<&Mat3> for &f32 {
1132 type Output = Mat3;
1133 #[inline]
1134 fn div(self, rhs: &Mat3) -> Mat3 {
1135 (*self).div(*rhs)
1136 }
1137}
1138
1139impl Div<Mat3> for &f32 {
1140 type Output = Mat3;
1141 #[inline]
1142 fn div(self, rhs: Mat3) -> Mat3 {
1143 (*self).div(rhs)
1144 }
1145}
1146
1147impl Div<f32> for Mat3 {
1148 type Output = Self;
1149 #[inline]
1150 fn div(self, rhs: f32) -> Self {
1151 self.div_scalar(rhs)
1152 }
1153}
1154
1155impl Div<&f32> for Mat3 {
1156 type Output = Self;
1157 #[inline]
1158 fn div(self, rhs: &f32) -> Self {
1159 self.div(*rhs)
1160 }
1161}
1162
1163impl Div<&f32> for &Mat3 {
1164 type Output = Mat3;
1165 #[inline]
1166 fn div(self, rhs: &f32) -> Mat3 {
1167 (*self).div(*rhs)
1168 }
1169}
1170
1171impl Div<f32> for &Mat3 {
1172 type Output = Mat3;
1173 #[inline]
1174 fn div(self, rhs: f32) -> Mat3 {
1175 (*self).div(rhs)
1176 }
1177}
1178
1179impl DivAssign<f32> for Mat3 {
1180 #[inline]
1181 fn div_assign(&mut self, rhs: f32) {
1182 *self = self.div(rhs);
1183 }
1184}
1185
1186impl DivAssign<&f32> for Mat3 {
1187 #[inline]
1188 fn div_assign(&mut self, rhs: &f32) {
1189 self.div_assign(*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_vec3a(rhs)
1198 }
1199}
1200
1201impl Mul<&Vec3A> for Mat3 {
1202 type Output = Vec3A;
1203 #[inline]
1204 fn mul(self, rhs: &Vec3A) -> Vec3A {
1205 self.mul(*rhs)
1206 }
1207}
1208
1209impl Mul<&Vec3A> for &Mat3 {
1210 type Output = Vec3A;
1211 #[inline]
1212 fn mul(self, rhs: &Vec3A) -> Vec3A {
1213 (*self).mul(*rhs)
1214 }
1215}
1216
1217impl Mul<Vec3A> for &Mat3 {
1218 type Output = Vec3A;
1219 #[inline]
1220 fn mul(self, rhs: Vec3A) -> Vec3A {
1221 (*self).mul(rhs)
1222 }
1223}
1224
1225impl From<Mat3A> for Mat3 {
1226 #[inline]
1227 fn from(m: Mat3A) -> Self {
1228 Self {
1229 x_axis: m.x_axis.into(),
1230 y_axis: m.y_axis.into(),
1231 z_axis: m.z_axis.into(),
1232 }
1233 }
1234}
1235
1236impl Sum<Self> for Mat3 {
1237 fn sum<I>(iter: I) -> Self
1238 where
1239 I: Iterator<Item = Self>,
1240 {
1241 iter.fold(Self::ZERO, Self::add)
1242 }
1243}
1244
1245impl<'a> Sum<&'a Self> for Mat3 {
1246 fn sum<I>(iter: I) -> Self
1247 where
1248 I: Iterator<Item = &'a Self>,
1249 {
1250 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1251 }
1252}
1253
1254impl Product for Mat3 {
1255 fn product<I>(iter: I) -> Self
1256 where
1257 I: Iterator<Item = Self>,
1258 {
1259 iter.fold(Self::IDENTITY, Self::mul)
1260 }
1261}
1262
1263impl<'a> Product<&'a Self> for Mat3 {
1264 fn product<I>(iter: I) -> Self
1265 where
1266 I: Iterator<Item = &'a Self>,
1267 {
1268 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1269 }
1270}
1271
1272impl PartialEq for Mat3 {
1273 #[inline]
1274 fn eq(&self, rhs: &Self) -> bool {
1275 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1276 }
1277}
1278
1279impl AsRef<[f32; 9]> for Mat3 {
1280 #[inline]
1281 fn as_ref(&self) -> &[f32; 9] {
1282 unsafe { &*(self as *const Self as *const [f32; 9]) }
1283 }
1284}
1285
1286impl AsMut<[f32; 9]> for Mat3 {
1287 #[inline]
1288 fn as_mut(&mut self) -> &mut [f32; 9] {
1289 unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
1290 }
1291}
1292
1293impl fmt::Debug for Mat3 {
1294 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1295 fmt.debug_struct(stringify!(Mat3))
1296 .field("x_axis", &self.x_axis)
1297 .field("y_axis", &self.y_axis)
1298 .field("z_axis", &self.z_axis)
1299 .finish()
1300 }
1301}
1302
1303impl fmt::Display for Mat3 {
1304 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1305 if let Some(p) = f.precision() {
1306 write!(
1307 f,
1308 "[{:.*}, {:.*}, {:.*}]",
1309 p, self.x_axis, p, self.y_axis, p, self.z_axis
1310 )
1311 } else {
1312 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1313 }
1314 }
1315}