1#[cfg(feature = "f64")]
4use crate::DMat3;
5
6use crate::{
7 euler::{FromEuler, ToEuler},
8 f32::math,
9 swizzles::*,
10 EulerRot, Mat2, Mat3, 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(target_arch = "x86")]
17use core::arch::x86::*;
18#[cfg(target_arch = "x86_64")]
19use core::arch::x86_64::*;
20
21#[cfg(feature = "zerocopy")]
22use zerocopy_derive::*;
23
24#[inline(always)]
26#[must_use]
27pub const fn mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A {
28 Mat3A::from_cols(x_axis, y_axis, z_axis)
29}
30
31#[derive(Clone, Copy)]
56#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
57#[cfg_attr(
58 feature = "zerocopy",
59 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
60)]
61#[repr(C)]
62pub struct Mat3A {
63 pub x_axis: Vec3A,
64 pub y_axis: Vec3A,
65 pub z_axis: Vec3A,
66}
67
68impl Mat3A {
69 pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
71
72 pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
74
75 pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::NAN);
77
78 #[allow(clippy::too_many_arguments)]
79 #[inline(always)]
80 #[must_use]
81 const fn new(
82 m00: f32,
83 m01: f32,
84 m02: f32,
85 m10: f32,
86 m11: f32,
87 m12: f32,
88 m20: f32,
89 m21: f32,
90 m22: f32,
91 ) -> Self {
92 Self {
93 x_axis: Vec3A::new(m00, m01, m02),
94 y_axis: Vec3A::new(m10, m11, m12),
95 z_axis: Vec3A::new(m20, m21, m22),
96 }
97 }
98
99 #[inline(always)]
101 #[must_use]
102 pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self {
103 Self {
104 x_axis,
105 y_axis,
106 z_axis,
107 }
108 }
109
110 #[inline]
114 #[must_use]
115 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
116 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
117 }
118
119 #[inline]
122 #[must_use]
123 pub const fn to_cols_array(&self) -> [f32; 9] {
124 let [x_axis_x, x_axis_y, x_axis_z] = self.x_axis.to_array();
125 let [y_axis_x, y_axis_y, y_axis_z] = self.y_axis.to_array();
126 let [z_axis_x, z_axis_y, z_axis_z] = self.z_axis.to_array();
127
128 [
129 x_axis_x, x_axis_y, x_axis_z, y_axis_x, y_axis_y, y_axis_z, z_axis_x, z_axis_y,
130 z_axis_z,
131 ]
132 }
133
134 #[inline]
138 #[must_use]
139 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
140 Self::from_cols(
141 Vec3A::from_array(m[0]),
142 Vec3A::from_array(m[1]),
143 Vec3A::from_array(m[2]),
144 )
145 }
146
147 #[inline]
150 #[must_use]
151 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
152 [
153 self.x_axis.to_array(),
154 self.y_axis.to_array(),
155 self.z_axis.to_array(),
156 ]
157 }
158
159 #[doc(alias = "scale")]
161 #[inline]
162 #[must_use]
163 pub const fn from_diagonal(diagonal: Vec3) -> Self {
164 Self::new(
165 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
166 )
167 }
168
169 #[inline]
171 #[must_use]
172 pub fn from_mat4(m: Mat4) -> Self {
173 Self::from_cols(
174 Vec3A::from_vec4(m.x_axis),
175 Vec3A::from_vec4(m.y_axis),
176 Vec3A::from_vec4(m.z_axis),
177 )
178 }
179
180 #[inline]
187 #[must_use]
188 pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
189 match (i, j) {
190 (0, 0) => Self::from_cols(
191 Vec3A::from_vec4(m.y_axis.yzww()),
192 Vec3A::from_vec4(m.z_axis.yzww()),
193 Vec3A::from_vec4(m.w_axis.yzww()),
194 ),
195 (0, 1) => Self::from_cols(
196 Vec3A::from_vec4(m.y_axis.xzww()),
197 Vec3A::from_vec4(m.z_axis.xzww()),
198 Vec3A::from_vec4(m.w_axis.xzww()),
199 ),
200 (0, 2) => Self::from_cols(
201 Vec3A::from_vec4(m.y_axis.xyww()),
202 Vec3A::from_vec4(m.z_axis.xyww()),
203 Vec3A::from_vec4(m.w_axis.xyww()),
204 ),
205 (0, 3) => Self::from_cols(
206 Vec3A::from_vec4(m.y_axis.xyzw()),
207 Vec3A::from_vec4(m.z_axis.xyzw()),
208 Vec3A::from_vec4(m.w_axis.xyzw()),
209 ),
210 (1, 0) => Self::from_cols(
211 Vec3A::from_vec4(m.x_axis.yzww()),
212 Vec3A::from_vec4(m.z_axis.yzww()),
213 Vec3A::from_vec4(m.w_axis.yzww()),
214 ),
215 (1, 1) => Self::from_cols(
216 Vec3A::from_vec4(m.x_axis.xzww()),
217 Vec3A::from_vec4(m.z_axis.xzww()),
218 Vec3A::from_vec4(m.w_axis.xzww()),
219 ),
220 (1, 2) => Self::from_cols(
221 Vec3A::from_vec4(m.x_axis.xyww()),
222 Vec3A::from_vec4(m.z_axis.xyww()),
223 Vec3A::from_vec4(m.w_axis.xyww()),
224 ),
225 (1, 3) => Self::from_cols(
226 Vec3A::from_vec4(m.x_axis.xyzw()),
227 Vec3A::from_vec4(m.z_axis.xyzw()),
228 Vec3A::from_vec4(m.w_axis.xyzw()),
229 ),
230 (2, 0) => Self::from_cols(
231 Vec3A::from_vec4(m.x_axis.yzww()),
232 Vec3A::from_vec4(m.y_axis.yzww()),
233 Vec3A::from_vec4(m.w_axis.yzww()),
234 ),
235 (2, 1) => Self::from_cols(
236 Vec3A::from_vec4(m.x_axis.xzww()),
237 Vec3A::from_vec4(m.y_axis.xzww()),
238 Vec3A::from_vec4(m.w_axis.xzww()),
239 ),
240 (2, 2) => Self::from_cols(
241 Vec3A::from_vec4(m.x_axis.xyww()),
242 Vec3A::from_vec4(m.y_axis.xyww()),
243 Vec3A::from_vec4(m.w_axis.xyww()),
244 ),
245 (2, 3) => Self::from_cols(
246 Vec3A::from_vec4(m.x_axis.xyzw()),
247 Vec3A::from_vec4(m.y_axis.xyzw()),
248 Vec3A::from_vec4(m.w_axis.xyzw()),
249 ),
250 (3, 0) => Self::from_cols(
251 Vec3A::from_vec4(m.x_axis.yzww()),
252 Vec3A::from_vec4(m.y_axis.yzww()),
253 Vec3A::from_vec4(m.z_axis.yzww()),
254 ),
255 (3, 1) => Self::from_cols(
256 Vec3A::from_vec4(m.x_axis.xzww()),
257 Vec3A::from_vec4(m.y_axis.xzww()),
258 Vec3A::from_vec4(m.z_axis.xzww()),
259 ),
260 (3, 2) => Self::from_cols(
261 Vec3A::from_vec4(m.x_axis.xyww()),
262 Vec3A::from_vec4(m.y_axis.xyww()),
263 Vec3A::from_vec4(m.z_axis.xyww()),
264 ),
265 (3, 3) => Self::from_cols(
266 Vec3A::from_vec4(m.x_axis.xyzw()),
267 Vec3A::from_vec4(m.y_axis.xyzw()),
268 Vec3A::from_vec4(m.z_axis.xyzw()),
269 ),
270 _ => panic!("index out of bounds"),
271 }
272 }
273
274 #[inline]
280 #[must_use]
281 pub fn from_quat(rotation: Quat) -> Self {
282 glam_assert!(rotation.is_normalized());
283
284 let x2 = rotation.x + rotation.x;
285 let y2 = rotation.y + rotation.y;
286 let z2 = rotation.z + rotation.z;
287 let xx = rotation.x * x2;
288 let xy = rotation.x * y2;
289 let xz = rotation.x * z2;
290 let yy = rotation.y * y2;
291 let yz = rotation.y * z2;
292 let zz = rotation.z * z2;
293 let wx = rotation.w * x2;
294 let wy = rotation.w * y2;
295 let wz = rotation.w * z2;
296
297 Self::from_cols(
298 Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
299 Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
300 Vec3A::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
301 )
302 }
303
304 #[inline]
311 #[must_use]
312 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
313 glam_assert!(axis.is_normalized());
314
315 let (sin, cos) = math::sin_cos(angle);
316 let (xsin, ysin, zsin) = axis.mul(sin).into();
317 let (x, y, z) = axis.into();
318 let (x2, y2, z2) = axis.mul(axis).into();
319 let omc = 1.0 - cos;
320 let xyomc = x * y * omc;
321 let xzomc = x * z * omc;
322 let yzomc = y * z * omc;
323 Self::from_cols(
324 Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
325 Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
326 Vec3A::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
327 )
328 }
329
330 #[inline]
333 #[must_use]
334 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
335 Self::from_euler_angles(order, a, b, c)
336 }
337
338 #[inline]
347 #[must_use]
348 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
349 glam_assert!(
350 self.x_axis.is_normalized()
351 && self.y_axis.is_normalized()
352 && self.z_axis.is_normalized()
353 );
354 self.to_euler_angles(order)
355 }
356
357 #[inline]
359 #[must_use]
360 pub fn from_rotation_x(angle: f32) -> Self {
361 let (sina, cosa) = math::sin_cos(angle);
362 Self::from_cols(
363 Vec3A::X,
364 Vec3A::new(0.0, cosa, sina),
365 Vec3A::new(0.0, -sina, cosa),
366 )
367 }
368
369 #[inline]
371 #[must_use]
372 pub fn from_rotation_y(angle: f32) -> Self {
373 let (sina, cosa) = math::sin_cos(angle);
374 Self::from_cols(
375 Vec3A::new(cosa, 0.0, -sina),
376 Vec3A::Y,
377 Vec3A::new(sina, 0.0, cosa),
378 )
379 }
380
381 #[inline]
383 #[must_use]
384 pub fn from_rotation_z(angle: f32) -> Self {
385 let (sina, cosa) = math::sin_cos(angle);
386 Self::from_cols(
387 Vec3A::new(cosa, sina, 0.0),
388 Vec3A::new(-sina, cosa, 0.0),
389 Vec3A::Z,
390 )
391 }
392
393 #[inline]
398 #[must_use]
399 pub fn from_translation(translation: Vec2) -> Self {
400 Self::from_cols(
401 Vec3A::X,
402 Vec3A::Y,
403 Vec3A::new(translation.x, translation.y, 1.0),
404 )
405 }
406
407 #[inline]
413 #[must_use]
414 pub fn from_angle(angle: f32) -> Self {
415 let (sin, cos) = math::sin_cos(angle);
416 Self::from_cols(
417 Vec3A::new(cos, sin, 0.0),
418 Vec3A::new(-sin, cos, 0.0),
419 Vec3A::Z,
420 )
421 }
422
423 #[inline]
429 #[must_use]
430 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
431 let (sin, cos) = math::sin_cos(angle);
432 Self::from_cols(
433 Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
434 Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
435 Vec3A::new(translation.x, translation.y, 1.0),
436 )
437 }
438
439 #[inline]
448 #[must_use]
449 pub fn from_scale(scale: Vec2) -> Self {
450 glam_assert!(scale.cmpne(Vec2::ZERO).any());
452
453 Self::from_cols(
454 Vec3A::new(scale.x, 0.0, 0.0),
455 Vec3A::new(0.0, scale.y, 0.0),
456 Vec3A::Z,
457 )
458 }
459
460 #[inline]
465 pub fn from_mat2(m: Mat2) -> Self {
466 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
467 }
468
469 #[inline]
475 #[must_use]
476 pub const fn from_cols_slice(slice: &[f32]) -> Self {
477 Self::new(
478 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
479 slice[8],
480 )
481 }
482
483 #[inline]
489 pub fn write_cols_to_slice(&self, slice: &mut [f32]) {
490 slice[0] = self.x_axis.x;
491 slice[1] = self.x_axis.y;
492 slice[2] = self.x_axis.z;
493 slice[3] = self.y_axis.x;
494 slice[4] = self.y_axis.y;
495 slice[5] = self.y_axis.z;
496 slice[6] = self.z_axis.x;
497 slice[7] = self.z_axis.y;
498 slice[8] = self.z_axis.z;
499 }
500
501 #[inline]
507 #[must_use]
508 pub fn col(&self, index: usize) -> Vec3A {
509 match index {
510 0 => self.x_axis,
511 1 => self.y_axis,
512 2 => self.z_axis,
513 _ => panic!("index out of bounds"),
514 }
515 }
516
517 #[inline]
523 pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
524 match index {
525 0 => &mut self.x_axis,
526 1 => &mut self.y_axis,
527 2 => &mut self.z_axis,
528 _ => panic!("index out of bounds"),
529 }
530 }
531
532 #[inline]
538 #[must_use]
539 pub fn row(&self, index: usize) -> Vec3A {
540 match index {
541 0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
542 1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
543 2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
544 _ => panic!("index out of bounds"),
545 }
546 }
547
548 #[inline]
551 #[must_use]
552 pub fn is_finite(&self) -> bool {
553 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
554 }
555
556 #[inline]
558 #[must_use]
559 pub fn is_nan(&self) -> bool {
560 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
561 }
562
563 #[inline]
565 #[must_use]
566 pub fn transpose(&self) -> Self {
567 unsafe {
568 let tmp0 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b01_00_01_00);
569 let tmp1 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b11_10_11_10);
570
571 Self {
572 x_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b00_00_10_00)),
573 y_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b01_01_11_01)),
574 z_axis: Vec3A(_mm_shuffle_ps(tmp1, self.z_axis.0, 0b10_10_10_00)),
575 }
576 }
577 }
578
579 #[inline]
581 #[must_use]
582 pub fn diagonal(&self) -> Vec3A {
583 Vec3A::new(self.x_axis.x, self.y_axis.y, self.z_axis.z)
584 }
585
586 #[inline]
588 #[must_use]
589 pub fn determinant(&self) -> f32 {
590 self.z_axis.dot(self.x_axis.cross(self.y_axis))
591 }
592
593 #[inline(always)]
605 #[must_use]
606 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
607 let tmp0 = self.y_axis.cross(self.z_axis);
608 let tmp1 = self.z_axis.cross(self.x_axis);
609 let tmp2 = self.x_axis.cross(self.y_axis);
610 let det = self.z_axis.dot(tmp2);
611 if CHECKED {
612 if det == 0.0 {
613 return (Self::ZERO, false);
614 }
615 } else {
616 glam_assert!(det != 0.0);
617 }
618 let inv_det = Vec3A::splat(det.recip());
619 (
620 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose(),
621 true,
622 )
623 }
624
625 #[inline]
633 #[must_use]
634 pub fn inverse(&self) -> Self {
635 self.inverse_checked::<false>().0
636 }
637
638 #[inline]
640 #[must_use]
641 pub fn try_inverse(&self) -> Option<Self> {
642 let (m, is_valid) = self.inverse_checked::<true>();
643 if is_valid {
644 Some(m)
645 } else {
646 None
647 }
648 }
649
650 #[inline]
652 #[must_use]
653 pub fn inverse_or_zero(&self) -> Self {
654 self.inverse_checked::<true>().0
655 }
656
657 #[inline]
667 #[must_use]
668 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
669 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
670 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
671 }
672
673 #[inline]
683 #[must_use]
684 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
685 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
686 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
687 }
688
689 #[deprecated(
697 since = "0.33.1",
698 note = "use the `glam::camera::lh::view::look_to_mat3` function instead"
699 )]
700 #[inline]
701 #[must_use]
702 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
703 #[allow(deprecated)]
704 Self::look_to_rh(-dir, up)
705 }
706
707 #[deprecated(
715 since = "0.33.1",
716 note = "use the `glam::camera::rh::view::look_to_mat3` function instead"
717 )]
718 #[inline]
719 #[must_use]
720 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
721 glam_assert!(dir.is_normalized());
722 glam_assert!(up.is_normalized());
723 let f = dir;
724 let s = f.cross(up).normalize();
725 let u = s.cross(f);
726
727 Self::from_cols(
728 Vec3A::new(s.x, u.x, -f.x),
729 Vec3A::new(s.y, u.y, -f.y),
730 Vec3A::new(s.z, u.z, -f.z),
731 )
732 }
733
734 #[deprecated(
743 since = "0.33.1",
744 note = "use the `glam::camera::lh::view::look_at_mat3` function instead"
745 )]
746 #[inline]
747 #[must_use]
748 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
749 #[allow(deprecated)]
750 Self::look_to_lh(center.sub(eye).normalize(), up)
751 }
752
753 #[deprecated(
762 since = "0.33.1",
763 note = "use the `glam::camera::rh::view::look_at_mat3` function instead"
764 )]
765 #[inline]
766 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
767 #[allow(deprecated)]
768 Self::look_to_rh(center.sub(eye).normalize(), up)
769 }
770
771 #[inline]
773 #[must_use]
774 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
775 self.mul_vec3a(rhs.into()).into()
776 }
777
778 #[inline]
780 #[must_use]
781 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
782 let mut res = self.x_axis.mul(rhs.xxx());
783 res = res.add(self.y_axis.mul(rhs.yyy()));
784 res = res.add(self.z_axis.mul(rhs.zzz()));
785 res
786 }
787
788 #[inline]
790 #[must_use]
791 pub fn mul_transpose_vec3(&self, rhs: Vec3) -> Vec3 {
792 self.mul_transpose_vec3a(rhs.into()).into()
793 }
794
795 #[inline]
797 #[must_use]
798 pub fn mul_transpose_vec3a(&self, rhs: Vec3A) -> Vec3A {
799 Vec3A::new(
800 self.x_axis.dot(rhs),
801 self.y_axis.dot(rhs),
802 self.z_axis.dot(rhs),
803 )
804 }
805
806 #[inline]
808 #[must_use]
809 pub fn mul_mat3(&self, rhs: &Self) -> Self {
810 self.mul(rhs)
811 }
812
813 #[inline]
815 #[must_use]
816 pub fn add_mat3(&self, rhs: &Self) -> Self {
817 self.add(rhs)
818 }
819
820 #[inline]
822 #[must_use]
823 pub fn sub_mat3(&self, rhs: &Self) -> Self {
824 self.sub(rhs)
825 }
826
827 #[inline]
829 #[must_use]
830 pub fn mul_scalar(&self, rhs: f32) -> Self {
831 Self::from_cols(
832 self.x_axis.mul(rhs),
833 self.y_axis.mul(rhs),
834 self.z_axis.mul(rhs),
835 )
836 }
837
838 #[inline]
842 #[must_use]
843 pub fn mul_diagonal_scale(&self, scale: Vec3) -> Self {
844 Self::from_cols(
845 self.x_axis * scale.x,
846 self.y_axis * scale.y,
847 self.z_axis * scale.z,
848 )
849 }
850
851 #[inline]
853 #[must_use]
854 pub fn div_scalar(&self, rhs: f32) -> Self {
855 let rhs = Vec3A::splat(rhs);
856 Self::from_cols(
857 self.x_axis.div(rhs),
858 self.y_axis.div(rhs),
859 self.z_axis.div(rhs),
860 )
861 }
862
863 #[inline]
865 #[must_use]
866 pub fn recip(&self) -> Self {
867 Self::from_cols(
868 self.x_axis.recip(),
869 self.y_axis.recip(),
870 self.z_axis.recip(),
871 )
872 }
873
874 #[inline]
884 #[must_use]
885 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
886 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
887 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
888 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
889 }
890
891 #[inline]
893 #[must_use]
894 pub fn abs(&self) -> Self {
895 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
896 }
897
898 #[cfg(feature = "f64")]
899 #[inline]
900 #[must_use]
901 pub fn as_dmat3(&self) -> DMat3 {
902 DMat3::from_cols(
903 self.x_axis.as_dvec3(),
904 self.y_axis.as_dvec3(),
905 self.z_axis.as_dvec3(),
906 )
907 }
908}
909
910impl Default for Mat3A {
911 #[inline]
912 fn default() -> Self {
913 Self::IDENTITY
914 }
915}
916
917impl Add for Mat3A {
918 type Output = Self;
919 #[inline]
920 fn add(self, rhs: Self) -> Self {
921 Self::from_cols(
922 self.x_axis.add(rhs.x_axis),
923 self.y_axis.add(rhs.y_axis),
924 self.z_axis.add(rhs.z_axis),
925 )
926 }
927}
928
929impl Add<&Self> for Mat3A {
930 type Output = Self;
931 #[inline]
932 fn add(self, rhs: &Self) -> Self {
933 self.add(*rhs)
934 }
935}
936
937impl Add<&Mat3A> for &Mat3A {
938 type Output = Mat3A;
939 #[inline]
940 fn add(self, rhs: &Mat3A) -> Mat3A {
941 (*self).add(*rhs)
942 }
943}
944
945impl Add<Mat3A> for &Mat3A {
946 type Output = Mat3A;
947 #[inline]
948 fn add(self, rhs: Mat3A) -> Mat3A {
949 (*self).add(rhs)
950 }
951}
952
953impl AddAssign for Mat3A {
954 #[inline]
955 fn add_assign(&mut self, rhs: Self) {
956 *self = self.add(rhs);
957 }
958}
959
960impl AddAssign<&Self> for Mat3A {
961 #[inline]
962 fn add_assign(&mut self, rhs: &Self) {
963 self.add_assign(*rhs);
964 }
965}
966
967impl Sub for Mat3A {
968 type Output = Self;
969 #[inline]
970 fn sub(self, rhs: Self) -> Self {
971 Self::from_cols(
972 self.x_axis.sub(rhs.x_axis),
973 self.y_axis.sub(rhs.y_axis),
974 self.z_axis.sub(rhs.z_axis),
975 )
976 }
977}
978
979impl Sub<&Self> for Mat3A {
980 type Output = Self;
981 #[inline]
982 fn sub(self, rhs: &Self) -> Self {
983 self.sub(*rhs)
984 }
985}
986
987impl Sub<&Mat3A> for &Mat3A {
988 type Output = Mat3A;
989 #[inline]
990 fn sub(self, rhs: &Mat3A) -> Mat3A {
991 (*self).sub(*rhs)
992 }
993}
994
995impl Sub<Mat3A> for &Mat3A {
996 type Output = Mat3A;
997 #[inline]
998 fn sub(self, rhs: Mat3A) -> Mat3A {
999 (*self).sub(rhs)
1000 }
1001}
1002
1003impl SubAssign for Mat3A {
1004 #[inline]
1005 fn sub_assign(&mut self, rhs: Self) {
1006 *self = self.sub(rhs);
1007 }
1008}
1009
1010impl SubAssign<&Self> for Mat3A {
1011 #[inline]
1012 fn sub_assign(&mut self, rhs: &Self) {
1013 self.sub_assign(*rhs);
1014 }
1015}
1016
1017impl Neg for Mat3A {
1018 type Output = Self;
1019 #[inline]
1020 fn neg(self) -> Self::Output {
1021 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
1022 }
1023}
1024
1025impl Neg for &Mat3A {
1026 type Output = Mat3A;
1027 #[inline]
1028 fn neg(self) -> Mat3A {
1029 (*self).neg()
1030 }
1031}
1032
1033impl Mul for Mat3A {
1034 type Output = Self;
1035 #[inline]
1036 fn mul(self, rhs: Self) -> Self {
1037 Self::from_cols(
1038 self.mul(rhs.x_axis),
1039 self.mul(rhs.y_axis),
1040 self.mul(rhs.z_axis),
1041 )
1042 }
1043}
1044
1045impl Mul<&Self> for Mat3A {
1046 type Output = Self;
1047 #[inline]
1048 fn mul(self, rhs: &Self) -> Self {
1049 self.mul(*rhs)
1050 }
1051}
1052
1053impl Mul<&Mat3A> for &Mat3A {
1054 type Output = Mat3A;
1055 #[inline]
1056 fn mul(self, rhs: &Mat3A) -> Mat3A {
1057 (*self).mul(*rhs)
1058 }
1059}
1060
1061impl Mul<Mat3A> for &Mat3A {
1062 type Output = Mat3A;
1063 #[inline]
1064 fn mul(self, rhs: Mat3A) -> Mat3A {
1065 (*self).mul(rhs)
1066 }
1067}
1068
1069impl MulAssign for Mat3A {
1070 #[inline]
1071 fn mul_assign(&mut self, rhs: Self) {
1072 *self = self.mul(rhs);
1073 }
1074}
1075
1076impl MulAssign<&Self> for Mat3A {
1077 #[inline]
1078 fn mul_assign(&mut self, rhs: &Self) {
1079 self.mul_assign(*rhs);
1080 }
1081}
1082
1083impl Mul<Vec3A> for Mat3A {
1084 type Output = Vec3A;
1085 #[inline]
1086 fn mul(self, rhs: Vec3A) -> Self::Output {
1087 self.mul_vec3a(rhs)
1088 }
1089}
1090
1091impl Mul<&Vec3A> for Mat3A {
1092 type Output = Vec3A;
1093 #[inline]
1094 fn mul(self, rhs: &Vec3A) -> Vec3A {
1095 self.mul(*rhs)
1096 }
1097}
1098
1099impl Mul<&Vec3A> for &Mat3A {
1100 type Output = Vec3A;
1101 #[inline]
1102 fn mul(self, rhs: &Vec3A) -> Vec3A {
1103 (*self).mul(*rhs)
1104 }
1105}
1106
1107impl Mul<Vec3A> for &Mat3A {
1108 type Output = Vec3A;
1109 #[inline]
1110 fn mul(self, rhs: Vec3A) -> Vec3A {
1111 (*self).mul(rhs)
1112 }
1113}
1114
1115impl Mul<Mat3A> for f32 {
1116 type Output = Mat3A;
1117 #[inline]
1118 fn mul(self, rhs: Mat3A) -> Self::Output {
1119 rhs.mul_scalar(self)
1120 }
1121}
1122
1123impl Mul<&Mat3A> for f32 {
1124 type Output = Mat3A;
1125 #[inline]
1126 fn mul(self, rhs: &Mat3A) -> Mat3A {
1127 self.mul(*rhs)
1128 }
1129}
1130
1131impl Mul<&Mat3A> for &f32 {
1132 type Output = Mat3A;
1133 #[inline]
1134 fn mul(self, rhs: &Mat3A) -> Mat3A {
1135 (*self).mul(*rhs)
1136 }
1137}
1138
1139impl Mul<Mat3A> for &f32 {
1140 type Output = Mat3A;
1141 #[inline]
1142 fn mul(self, rhs: Mat3A) -> Mat3A {
1143 (*self).mul(rhs)
1144 }
1145}
1146
1147impl Mul<f32> for Mat3A {
1148 type Output = Self;
1149 #[inline]
1150 fn mul(self, rhs: f32) -> Self {
1151 self.mul_scalar(rhs)
1152 }
1153}
1154
1155impl Mul<&f32> for Mat3A {
1156 type Output = Self;
1157 #[inline]
1158 fn mul(self, rhs: &f32) -> Self {
1159 self.mul(*rhs)
1160 }
1161}
1162
1163impl Mul<&f32> for &Mat3A {
1164 type Output = Mat3A;
1165 #[inline]
1166 fn mul(self, rhs: &f32) -> Mat3A {
1167 (*self).mul(*rhs)
1168 }
1169}
1170
1171impl Mul<f32> for &Mat3A {
1172 type Output = Mat3A;
1173 #[inline]
1174 fn mul(self, rhs: f32) -> Mat3A {
1175 (*self).mul(rhs)
1176 }
1177}
1178
1179impl MulAssign<f32> for Mat3A {
1180 #[inline]
1181 fn mul_assign(&mut self, rhs: f32) {
1182 *self = self.mul(rhs);
1183 }
1184}
1185
1186impl MulAssign<&f32> for Mat3A {
1187 #[inline]
1188 fn mul_assign(&mut self, rhs: &f32) {
1189 self.mul_assign(*rhs);
1190 }
1191}
1192
1193impl Div<Mat3A> for f32 {
1194 type Output = Mat3A;
1195 #[inline]
1196 fn div(self, rhs: Mat3A) -> Self::Output {
1197 Mat3A::from_cols(
1198 self.div(rhs.x_axis),
1199 self.div(rhs.y_axis),
1200 self.div(rhs.z_axis),
1201 )
1202 }
1203}
1204
1205impl Div<&Mat3A> for f32 {
1206 type Output = Mat3A;
1207 #[inline]
1208 fn div(self, rhs: &Mat3A) -> Mat3A {
1209 self.div(*rhs)
1210 }
1211}
1212
1213impl Div<&Mat3A> for &f32 {
1214 type Output = Mat3A;
1215 #[inline]
1216 fn div(self, rhs: &Mat3A) -> Mat3A {
1217 (*self).div(*rhs)
1218 }
1219}
1220
1221impl Div<Mat3A> for &f32 {
1222 type Output = Mat3A;
1223 #[inline]
1224 fn div(self, rhs: Mat3A) -> Mat3A {
1225 (*self).div(rhs)
1226 }
1227}
1228
1229impl Div<f32> for Mat3A {
1230 type Output = Self;
1231 #[inline]
1232 fn div(self, rhs: f32) -> Self {
1233 self.div_scalar(rhs)
1234 }
1235}
1236
1237impl Div<&f32> for Mat3A {
1238 type Output = Self;
1239 #[inline]
1240 fn div(self, rhs: &f32) -> Self {
1241 self.div(*rhs)
1242 }
1243}
1244
1245impl Div<&f32> for &Mat3A {
1246 type Output = Mat3A;
1247 #[inline]
1248 fn div(self, rhs: &f32) -> Mat3A {
1249 (*self).div(*rhs)
1250 }
1251}
1252
1253impl Div<f32> for &Mat3A {
1254 type Output = Mat3A;
1255 #[inline]
1256 fn div(self, rhs: f32) -> Mat3A {
1257 (*self).div(rhs)
1258 }
1259}
1260
1261impl DivAssign<f32> for Mat3A {
1262 #[inline]
1263 fn div_assign(&mut self, rhs: f32) {
1264 *self = self.div(rhs);
1265 }
1266}
1267
1268impl DivAssign<&f32> for Mat3A {
1269 #[inline]
1270 fn div_assign(&mut self, rhs: &f32) {
1271 self.div_assign(*rhs);
1272 }
1273}
1274
1275impl Mul<Vec3> for Mat3A {
1276 type Output = Vec3;
1277 #[inline]
1278 fn mul(self, rhs: Vec3) -> Vec3 {
1279 self.mul_vec3a(rhs.into()).into()
1280 }
1281}
1282
1283impl Mul<&Vec3> for Mat3A {
1284 type Output = Vec3;
1285 #[inline]
1286 fn mul(self, rhs: &Vec3) -> Vec3 {
1287 self.mul(*rhs)
1288 }
1289}
1290
1291impl Mul<&Vec3> for &Mat3A {
1292 type Output = Vec3;
1293 #[inline]
1294 fn mul(self, rhs: &Vec3) -> Vec3 {
1295 (*self).mul(*rhs)
1296 }
1297}
1298
1299impl Mul<Vec3> for &Mat3A {
1300 type Output = Vec3;
1301 #[inline]
1302 fn mul(self, rhs: Vec3) -> Vec3 {
1303 (*self).mul(rhs)
1304 }
1305}
1306
1307impl From<Mat3> for Mat3A {
1308 #[inline]
1309 fn from(m: Mat3) -> Self {
1310 Self {
1311 x_axis: m.x_axis.into(),
1312 y_axis: m.y_axis.into(),
1313 z_axis: m.z_axis.into(),
1314 }
1315 }
1316}
1317
1318impl Sum<Self> for Mat3A {
1319 fn sum<I>(iter: I) -> Self
1320 where
1321 I: Iterator<Item = Self>,
1322 {
1323 iter.fold(Self::ZERO, Self::add)
1324 }
1325}
1326
1327impl<'a> Sum<&'a Self> for Mat3A {
1328 fn sum<I>(iter: I) -> Self
1329 where
1330 I: Iterator<Item = &'a Self>,
1331 {
1332 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1333 }
1334}
1335
1336impl Product for Mat3A {
1337 fn product<I>(iter: I) -> Self
1338 where
1339 I: Iterator<Item = Self>,
1340 {
1341 iter.fold(Self::IDENTITY, Self::mul)
1342 }
1343}
1344
1345impl<'a> Product<&'a Self> for Mat3A {
1346 fn product<I>(iter: I) -> Self
1347 where
1348 I: Iterator<Item = &'a Self>,
1349 {
1350 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1351 }
1352}
1353
1354impl PartialEq for Mat3A {
1355 #[inline]
1356 fn eq(&self, rhs: &Self) -> bool {
1357 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1358 }
1359}
1360
1361impl fmt::Debug for Mat3A {
1362 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1363 fmt.debug_struct(stringify!(Mat3A))
1364 .field("x_axis", &self.x_axis)
1365 .field("y_axis", &self.y_axis)
1366 .field("z_axis", &self.z_axis)
1367 .finish()
1368 }
1369}
1370
1371impl fmt::Display for Mat3A {
1372 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1373 if let Some(p) = f.precision() {
1374 write!(
1375 f,
1376 "[{:.*}, {:.*}, {:.*}]",
1377 p, self.x_axis, p, self.y_axis, p, self.z_axis
1378 )
1379 } else {
1380 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1381 }
1382 }
1383}