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-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 {
681 Some(m)
682 } else {
683 None
684 }
685 }
686
687 #[inline]
690 #[must_use]
691 pub fn inverse_or_zero(&self) -> Self {
692 self.inverse_checked::<true>().0
693 }
694
695 #[inline]
705 #[must_use]
706 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
707 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
708 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
709 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
710 }
711
712 #[inline]
722 #[must_use]
723 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
724 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
725 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
726 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
727 }
728
729 #[deprecated(
738 since = "0.33.1",
739 note = "use the `glam::camera::lh::view::look_to_mat3` function instead"
740 )]
741 #[inline]
742 #[must_use]
743 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
744 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
745 #[allow(deprecated)]
746 Self::look_to_rh(-dir, up)
747 }
748
749 #[deprecated(
758 since = "0.33.1",
759 note = "use the `glam::camera::rh::view::look_to_mat3` function instead"
760 )]
761 #[inline]
762 #[must_use]
763 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
764 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
765 glam_assert!(dir.is_normalized());
766 glam_assert!(up.is_normalized());
767 let f = dir;
768 let s = f.cross(up).normalize();
769 let u = s.cross(f);
770
771 Self::from_cols(
772 Vec3::new(s.x, u.x, -f.x),
773 Vec3::new(s.y, u.y, -f.y),
774 Vec3::new(s.z, u.z, -f.z),
775 )
776 }
777
778 #[deprecated(
788 since = "0.33.1",
789 note = "use the `glam::camera::lh::view::look_at_mat3` function instead"
790 )]
791 #[inline]
792 #[must_use]
793 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
794 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
795 #[allow(deprecated)]
796 Self::look_to_lh(center.sub(eye).normalize(), up)
797 }
798
799 #[deprecated(
809 since = "0.33.1",
810 note = "use the `glam::camera::rh::view::look_at_mat3` function instead"
811 )]
812 #[inline]
813 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
814 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
815 #[allow(deprecated)]
816 Self::look_to_rh(center.sub(eye).normalize(), up)
817 }
818
819 #[inline]
821 #[must_use]
822 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
823 let mut res = self.x_axis.mul(rhs.x);
824 res = res.add(self.y_axis.mul(rhs.y));
825 res = res.add(self.z_axis.mul(rhs.z));
826 res
827 }
828
829 #[inline]
831 #[must_use]
832 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
833 self.mul_vec3(rhs.into()).into()
834 }
835
836 #[inline]
838 #[must_use]
839 pub fn mul_transpose_vec3(&self, rhs: Vec3) -> Vec3 {
840 Vec3::new(
841 self.x_axis.dot(rhs),
842 self.y_axis.dot(rhs),
843 self.z_axis.dot(rhs),
844 )
845 }
846
847 #[inline]
849 #[must_use]
850 pub fn mul_mat3(&self, rhs: &Self) -> Self {
851 self.mul(rhs)
852 }
853
854 #[inline]
856 #[must_use]
857 pub fn add_mat3(&self, rhs: &Self) -> Self {
858 self.add(rhs)
859 }
860
861 #[inline]
863 #[must_use]
864 pub fn sub_mat3(&self, rhs: &Self) -> Self {
865 self.sub(rhs)
866 }
867
868 #[inline]
870 #[must_use]
871 pub fn mul_scalar(&self, rhs: f32) -> Self {
872 Self::from_cols(
873 self.x_axis.mul(rhs),
874 self.y_axis.mul(rhs),
875 self.z_axis.mul(rhs),
876 )
877 }
878
879 #[inline]
883 #[must_use]
884 pub fn mul_diagonal_scale(&self, scale: Vec3) -> Self {
885 Self::from_cols(
886 self.x_axis * scale.x,
887 self.y_axis * scale.y,
888 self.z_axis * scale.z,
889 )
890 }
891
892 #[inline]
894 #[must_use]
895 pub fn div_scalar(&self, rhs: f32) -> Self {
896 let rhs = Vec3::splat(rhs);
897 Self::from_cols(
898 self.x_axis.div(rhs),
899 self.y_axis.div(rhs),
900 self.z_axis.div(rhs),
901 )
902 }
903
904 #[inline]
906 #[must_use]
907 pub fn recip(&self) -> Self {
908 Self::from_cols(
909 self.x_axis.recip(),
910 self.y_axis.recip(),
911 self.z_axis.recip(),
912 )
913 }
914
915 #[inline]
925 #[must_use]
926 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
927 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
928 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
929 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
930 }
931
932 #[inline]
934 #[must_use]
935 pub fn abs(&self) -> Self {
936 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
937 }
938
939 #[cfg(feature = "f64")]
940 #[inline]
941 #[must_use]
942 pub fn as_dmat3(&self) -> DMat3 {
943 DMat3::from_cols(
944 self.x_axis.as_dvec3(),
945 self.y_axis.as_dvec3(),
946 self.z_axis.as_dvec3(),
947 )
948 }
949}
950
951impl Default for Mat3 {
952 #[inline]
953 fn default() -> Self {
954 Self::IDENTITY
955 }
956}
957
958impl Add for Mat3 {
959 type Output = Self;
960 #[inline]
961 fn add(self, rhs: Self) -> Self {
962 Self::from_cols(
963 self.x_axis.add(rhs.x_axis),
964 self.y_axis.add(rhs.y_axis),
965 self.z_axis.add(rhs.z_axis),
966 )
967 }
968}
969
970impl Add<&Self> for Mat3 {
971 type Output = Self;
972 #[inline]
973 fn add(self, rhs: &Self) -> Self {
974 self.add(*rhs)
975 }
976}
977
978impl Add<&Mat3> for &Mat3 {
979 type Output = Mat3;
980 #[inline]
981 fn add(self, rhs: &Mat3) -> Mat3 {
982 (*self).add(*rhs)
983 }
984}
985
986impl Add<Mat3> for &Mat3 {
987 type Output = Mat3;
988 #[inline]
989 fn add(self, rhs: Mat3) -> Mat3 {
990 (*self).add(rhs)
991 }
992}
993
994impl AddAssign for Mat3 {
995 #[inline]
996 fn add_assign(&mut self, rhs: Self) {
997 *self = self.add(rhs);
998 }
999}
1000
1001impl AddAssign<&Self> for Mat3 {
1002 #[inline]
1003 fn add_assign(&mut self, rhs: &Self) {
1004 self.add_assign(*rhs);
1005 }
1006}
1007
1008impl Sub for Mat3 {
1009 type Output = Self;
1010 #[inline]
1011 fn sub(self, rhs: Self) -> Self {
1012 Self::from_cols(
1013 self.x_axis.sub(rhs.x_axis),
1014 self.y_axis.sub(rhs.y_axis),
1015 self.z_axis.sub(rhs.z_axis),
1016 )
1017 }
1018}
1019
1020impl Sub<&Self> for Mat3 {
1021 type Output = Self;
1022 #[inline]
1023 fn sub(self, rhs: &Self) -> Self {
1024 self.sub(*rhs)
1025 }
1026}
1027
1028impl Sub<&Mat3> for &Mat3 {
1029 type Output = Mat3;
1030 #[inline]
1031 fn sub(self, rhs: &Mat3) -> Mat3 {
1032 (*self).sub(*rhs)
1033 }
1034}
1035
1036impl Sub<Mat3> for &Mat3 {
1037 type Output = Mat3;
1038 #[inline]
1039 fn sub(self, rhs: Mat3) -> Mat3 {
1040 (*self).sub(rhs)
1041 }
1042}
1043
1044impl SubAssign for Mat3 {
1045 #[inline]
1046 fn sub_assign(&mut self, rhs: Self) {
1047 *self = self.sub(rhs);
1048 }
1049}
1050
1051impl SubAssign<&Self> for Mat3 {
1052 #[inline]
1053 fn sub_assign(&mut self, rhs: &Self) {
1054 self.sub_assign(*rhs);
1055 }
1056}
1057
1058impl Neg for Mat3 {
1059 type Output = Self;
1060 #[inline]
1061 fn neg(self) -> Self::Output {
1062 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
1063 }
1064}
1065
1066impl Neg for &Mat3 {
1067 type Output = Mat3;
1068 #[inline]
1069 fn neg(self) -> Mat3 {
1070 (*self).neg()
1071 }
1072}
1073
1074impl Mul for Mat3 {
1075 type Output = Self;
1076 #[inline]
1077 fn mul(self, rhs: Self) -> Self {
1078 Self::from_cols(
1079 self.mul(rhs.x_axis),
1080 self.mul(rhs.y_axis),
1081 self.mul(rhs.z_axis),
1082 )
1083 }
1084}
1085
1086impl Mul<&Self> for Mat3 {
1087 type Output = Self;
1088 #[inline]
1089 fn mul(self, rhs: &Self) -> Self {
1090 self.mul(*rhs)
1091 }
1092}
1093
1094impl Mul<&Mat3> for &Mat3 {
1095 type Output = Mat3;
1096 #[inline]
1097 fn mul(self, rhs: &Mat3) -> Mat3 {
1098 (*self).mul(*rhs)
1099 }
1100}
1101
1102impl Mul<Mat3> for &Mat3 {
1103 type Output = Mat3;
1104 #[inline]
1105 fn mul(self, rhs: Mat3) -> Mat3 {
1106 (*self).mul(rhs)
1107 }
1108}
1109
1110impl MulAssign for Mat3 {
1111 #[inline]
1112 fn mul_assign(&mut self, rhs: Self) {
1113 *self = self.mul(rhs);
1114 }
1115}
1116
1117impl MulAssign<&Self> for Mat3 {
1118 #[inline]
1119 fn mul_assign(&mut self, rhs: &Self) {
1120 self.mul_assign(*rhs);
1121 }
1122}
1123
1124impl Mul<Vec3> for Mat3 {
1125 type Output = Vec3;
1126 #[inline]
1127 fn mul(self, rhs: Vec3) -> Self::Output {
1128 self.mul_vec3(rhs)
1129 }
1130}
1131
1132impl Mul<&Vec3> for Mat3 {
1133 type Output = Vec3;
1134 #[inline]
1135 fn mul(self, rhs: &Vec3) -> Vec3 {
1136 self.mul(*rhs)
1137 }
1138}
1139
1140impl Mul<&Vec3> for &Mat3 {
1141 type Output = Vec3;
1142 #[inline]
1143 fn mul(self, rhs: &Vec3) -> Vec3 {
1144 (*self).mul(*rhs)
1145 }
1146}
1147
1148impl Mul<Vec3> for &Mat3 {
1149 type Output = Vec3;
1150 #[inline]
1151 fn mul(self, rhs: Vec3) -> Vec3 {
1152 (*self).mul(rhs)
1153 }
1154}
1155
1156impl Mul<Mat3> for f32 {
1157 type Output = Mat3;
1158 #[inline]
1159 fn mul(self, rhs: Mat3) -> Self::Output {
1160 rhs.mul_scalar(self)
1161 }
1162}
1163
1164impl Mul<&Mat3> for f32 {
1165 type Output = Mat3;
1166 #[inline]
1167 fn mul(self, rhs: &Mat3) -> Mat3 {
1168 self.mul(*rhs)
1169 }
1170}
1171
1172impl Mul<&Mat3> for &f32 {
1173 type Output = Mat3;
1174 #[inline]
1175 fn mul(self, rhs: &Mat3) -> Mat3 {
1176 (*self).mul(*rhs)
1177 }
1178}
1179
1180impl Mul<Mat3> for &f32 {
1181 type Output = Mat3;
1182 #[inline]
1183 fn mul(self, rhs: Mat3) -> Mat3 {
1184 (*self).mul(rhs)
1185 }
1186}
1187
1188impl Mul<f32> for Mat3 {
1189 type Output = Self;
1190 #[inline]
1191 fn mul(self, rhs: f32) -> Self {
1192 self.mul_scalar(rhs)
1193 }
1194}
1195
1196impl Mul<&f32> for Mat3 {
1197 type Output = Self;
1198 #[inline]
1199 fn mul(self, rhs: &f32) -> Self {
1200 self.mul(*rhs)
1201 }
1202}
1203
1204impl Mul<&f32> for &Mat3 {
1205 type Output = Mat3;
1206 #[inline]
1207 fn mul(self, rhs: &f32) -> Mat3 {
1208 (*self).mul(*rhs)
1209 }
1210}
1211
1212impl Mul<f32> for &Mat3 {
1213 type Output = Mat3;
1214 #[inline]
1215 fn mul(self, rhs: f32) -> Mat3 {
1216 (*self).mul(rhs)
1217 }
1218}
1219
1220impl MulAssign<f32> for Mat3 {
1221 #[inline]
1222 fn mul_assign(&mut self, rhs: f32) {
1223 *self = self.mul(rhs);
1224 }
1225}
1226
1227impl MulAssign<&f32> for Mat3 {
1228 #[inline]
1229 fn mul_assign(&mut self, rhs: &f32) {
1230 self.mul_assign(*rhs);
1231 }
1232}
1233
1234impl Div<Mat3> for f32 {
1235 type Output = Mat3;
1236 #[inline]
1237 fn div(self, rhs: Mat3) -> Self::Output {
1238 Mat3::from_cols(
1239 self.div(rhs.x_axis),
1240 self.div(rhs.y_axis),
1241 self.div(rhs.z_axis),
1242 )
1243 }
1244}
1245
1246impl Div<&Mat3> for f32 {
1247 type Output = Mat3;
1248 #[inline]
1249 fn div(self, rhs: &Mat3) -> Mat3 {
1250 self.div(*rhs)
1251 }
1252}
1253
1254impl Div<&Mat3> for &f32 {
1255 type Output = Mat3;
1256 #[inline]
1257 fn div(self, rhs: &Mat3) -> Mat3 {
1258 (*self).div(*rhs)
1259 }
1260}
1261
1262impl Div<Mat3> for &f32 {
1263 type Output = Mat3;
1264 #[inline]
1265 fn div(self, rhs: Mat3) -> Mat3 {
1266 (*self).div(rhs)
1267 }
1268}
1269
1270impl Div<f32> for Mat3 {
1271 type Output = Self;
1272 #[inline]
1273 fn div(self, rhs: f32) -> Self {
1274 self.div_scalar(rhs)
1275 }
1276}
1277
1278impl Div<&f32> for Mat3 {
1279 type Output = Self;
1280 #[inline]
1281 fn div(self, rhs: &f32) -> Self {
1282 self.div(*rhs)
1283 }
1284}
1285
1286impl Div<&f32> for &Mat3 {
1287 type Output = Mat3;
1288 #[inline]
1289 fn div(self, rhs: &f32) -> Mat3 {
1290 (*self).div(*rhs)
1291 }
1292}
1293
1294impl Div<f32> for &Mat3 {
1295 type Output = Mat3;
1296 #[inline]
1297 fn div(self, rhs: f32) -> Mat3 {
1298 (*self).div(rhs)
1299 }
1300}
1301
1302impl DivAssign<f32> for Mat3 {
1303 #[inline]
1304 fn div_assign(&mut self, rhs: f32) {
1305 *self = self.div(rhs);
1306 }
1307}
1308
1309impl DivAssign<&f32> for Mat3 {
1310 #[inline]
1311 fn div_assign(&mut self, rhs: &f32) {
1312 self.div_assign(*rhs);
1313 }
1314}
1315
1316impl Mul<Vec3A> for Mat3 {
1317 type Output = Vec3A;
1318 #[inline]
1319 fn mul(self, rhs: Vec3A) -> Vec3A {
1320 self.mul_vec3a(rhs)
1321 }
1322}
1323
1324impl Mul<&Vec3A> for Mat3 {
1325 type Output = Vec3A;
1326 #[inline]
1327 fn mul(self, rhs: &Vec3A) -> Vec3A {
1328 self.mul(*rhs)
1329 }
1330}
1331
1332impl Mul<&Vec3A> for &Mat3 {
1333 type Output = Vec3A;
1334 #[inline]
1335 fn mul(self, rhs: &Vec3A) -> Vec3A {
1336 (*self).mul(*rhs)
1337 }
1338}
1339
1340impl Mul<Vec3A> for &Mat3 {
1341 type Output = Vec3A;
1342 #[inline]
1343 fn mul(self, rhs: Vec3A) -> Vec3A {
1344 (*self).mul(rhs)
1345 }
1346}
1347
1348impl From<Mat3A> for Mat3 {
1349 #[inline]
1350 fn from(m: Mat3A) -> Self {
1351 Self {
1352 x_axis: m.x_axis.into(),
1353 y_axis: m.y_axis.into(),
1354 z_axis: m.z_axis.into(),
1355 }
1356 }
1357}
1358
1359impl Sum<Self> for Mat3 {
1360 fn sum<I>(iter: I) -> Self
1361 where
1362 I: Iterator<Item = Self>,
1363 {
1364 iter.fold(Self::ZERO, Self::add)
1365 }
1366}
1367
1368impl<'a> Sum<&'a Self> for Mat3 {
1369 fn sum<I>(iter: I) -> Self
1370 where
1371 I: Iterator<Item = &'a Self>,
1372 {
1373 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1374 }
1375}
1376
1377impl Product for Mat3 {
1378 fn product<I>(iter: I) -> Self
1379 where
1380 I: Iterator<Item = Self>,
1381 {
1382 iter.fold(Self::IDENTITY, Self::mul)
1383 }
1384}
1385
1386impl<'a> Product<&'a Self> for Mat3 {
1387 fn product<I>(iter: I) -> Self
1388 where
1389 I: Iterator<Item = &'a Self>,
1390 {
1391 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1392 }
1393}
1394
1395impl PartialEq for Mat3 {
1396 #[inline]
1397 fn eq(&self, rhs: &Self) -> bool {
1398 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1399 }
1400}
1401
1402impl AsRef<[f32; 9]> for Mat3 {
1403 #[inline]
1404 fn as_ref(&self) -> &[f32; 9] {
1405 unsafe { &*(self as *const Self as *const [f32; 9]) }
1406 }
1407}
1408
1409impl AsMut<[f32; 9]> for Mat3 {
1410 #[inline]
1411 fn as_mut(&mut self) -> &mut [f32; 9] {
1412 unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
1413 }
1414}
1415
1416impl fmt::Debug for Mat3 {
1417 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1418 fmt.debug_struct(stringify!(Mat3))
1419 .field("x_axis", &self.x_axis)
1420 .field("y_axis", &self.y_axis)
1421 .field("z_axis", &self.z_axis)
1422 .finish()
1423 }
1424}
1425
1426impl fmt::Display for Mat3 {
1427 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1428 if let Some(p) = f.precision() {
1429 write!(
1430 f,
1431 "[{:.*}, {:.*}, {:.*}]",
1432 p, self.x_axis, p, self.y_axis, p, self.z_axis
1433 )
1434 } else {
1435 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1436 }
1437 }
1438}