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