1#[cfg(feature = "f64")]
4use crate::DMat3;
5
6use crate::{
7 EulerRot, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec3A,
8 euler::{FromEuler, ToEuler},
9 f32::math,
10 swizzles::*,
11};
12use core::fmt;
13use core::iter::{Product, Sum};
14use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
15
16use core::arch::aarch64::*;
17
18#[cfg(feature = "zerocopy-08")]
19use zerocopy_derive_08::*;
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)]
57#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
58#[cfg_attr(
59 feature = "zerocopy-08",
60 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
61)]
62#[repr(C)]
63pub struct Mat3A {
64 pub x_axis: Vec3A,
65 pub y_axis: Vec3A,
66 pub z_axis: Vec3A,
67}
68
69impl Mat3A {
70 pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
72
73 pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
75
76 pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::NAN);
78
79 #[allow(clippy::too_many_arguments)]
80 #[inline(always)]
81 #[must_use]
82 const fn new(
83 m00: f32,
84 m01: f32,
85 m02: f32,
86 m10: f32,
87 m11: f32,
88 m12: f32,
89 m20: f32,
90 m21: f32,
91 m22: f32,
92 ) -> Self {
93 Self {
94 x_axis: Vec3A::new(m00, m01, m02),
95 y_axis: Vec3A::new(m10, m11, m12),
96 z_axis: Vec3A::new(m20, m21, m22),
97 }
98 }
99
100 #[inline(always)]
104 #[must_use]
105 pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self {
106 Self {
107 x_axis,
108 y_axis,
109 z_axis,
110 }
111 }
112
113 #[inline(always)]
119 #[must_use]
120 pub const fn from_rows(row0: Vec3A, row1: Vec3A, row2: Vec3A) -> Self {
121 let [m00, m01, m02] = row0.to_array();
122 let [m10, m11, m12] = row1.to_array();
123 let [m20, m21, m22] = row2.to_array();
124 Self::new(m00, m10, m20, m01, m11, m21, m02, m12, m22)
125 }
126
127 #[inline]
131 #[must_use]
132 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
133 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
134 }
135
136 #[inline]
140 #[must_use]
141 pub const fn to_cols_array(&self) -> [f32; 9] {
142 let [x_axis_x, x_axis_y, x_axis_z] = self.x_axis.to_array();
143 let [y_axis_x, y_axis_y, y_axis_z] = self.y_axis.to_array();
144 let [z_axis_x, z_axis_y, z_axis_z] = self.z_axis.to_array();
145
146 [
147 x_axis_x, x_axis_y, x_axis_z, y_axis_x, y_axis_y, y_axis_z, z_axis_x, z_axis_y,
148 z_axis_z,
149 ]
150 }
151
152 #[inline]
156 #[must_use]
157 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
158 Self::from_cols(
159 Vec3A::from_array(m[0]),
160 Vec3A::from_array(m[1]),
161 Vec3A::from_array(m[2]),
162 )
163 }
164
165 #[inline]
169 #[must_use]
170 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
171 [
172 self.x_axis.to_array(),
173 self.y_axis.to_array(),
174 self.z_axis.to_array(),
175 ]
176 }
177
178 #[inline]
184 #[must_use]
185 pub const fn from_rows_array(m: &[f32; 9]) -> Self {
186 Self::new(m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8])
187 }
188
189 #[inline]
195 #[must_use]
196 pub const fn to_rows_array(&self) -> [f32; 9] {
197 let m = self.to_cols_array();
198 [m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8]]
199 }
200
201 #[doc(alias = "scale")]
203 #[inline]
204 #[must_use]
205 pub const fn from_diagonal(diagonal: Vec3) -> Self {
206 Self::new(
207 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
208 )
209 }
210
211 #[inline]
213 #[must_use]
214 pub fn from_mat4(m: Mat4) -> Self {
215 Self::from_cols(
216 Vec3A::from_vec4(m.x_axis),
217 Vec3A::from_vec4(m.y_axis),
218 Vec3A::from_vec4(m.z_axis),
219 )
220 }
221
222 #[inline]
229 #[must_use]
230 #[track_caller]
231 pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
232 match (i, j) {
233 (0, 0) => Self::from_cols(
234 Vec3A::from_vec4(m.y_axis.yzww()),
235 Vec3A::from_vec4(m.z_axis.yzww()),
236 Vec3A::from_vec4(m.w_axis.yzww()),
237 ),
238 (0, 1) => Self::from_cols(
239 Vec3A::from_vec4(m.y_axis.xzww()),
240 Vec3A::from_vec4(m.z_axis.xzww()),
241 Vec3A::from_vec4(m.w_axis.xzww()),
242 ),
243 (0, 2) => Self::from_cols(
244 Vec3A::from_vec4(m.y_axis.xyww()),
245 Vec3A::from_vec4(m.z_axis.xyww()),
246 Vec3A::from_vec4(m.w_axis.xyww()),
247 ),
248 (0, 3) => Self::from_cols(
249 Vec3A::from_vec4(m.y_axis.xyzw()),
250 Vec3A::from_vec4(m.z_axis.xyzw()),
251 Vec3A::from_vec4(m.w_axis.xyzw()),
252 ),
253 (1, 0) => Self::from_cols(
254 Vec3A::from_vec4(m.x_axis.yzww()),
255 Vec3A::from_vec4(m.z_axis.yzww()),
256 Vec3A::from_vec4(m.w_axis.yzww()),
257 ),
258 (1, 1) => Self::from_cols(
259 Vec3A::from_vec4(m.x_axis.xzww()),
260 Vec3A::from_vec4(m.z_axis.xzww()),
261 Vec3A::from_vec4(m.w_axis.xzww()),
262 ),
263 (1, 2) => Self::from_cols(
264 Vec3A::from_vec4(m.x_axis.xyww()),
265 Vec3A::from_vec4(m.z_axis.xyww()),
266 Vec3A::from_vec4(m.w_axis.xyww()),
267 ),
268 (1, 3) => Self::from_cols(
269 Vec3A::from_vec4(m.x_axis.xyzw()),
270 Vec3A::from_vec4(m.z_axis.xyzw()),
271 Vec3A::from_vec4(m.w_axis.xyzw()),
272 ),
273 (2, 0) => Self::from_cols(
274 Vec3A::from_vec4(m.x_axis.yzww()),
275 Vec3A::from_vec4(m.y_axis.yzww()),
276 Vec3A::from_vec4(m.w_axis.yzww()),
277 ),
278 (2, 1) => Self::from_cols(
279 Vec3A::from_vec4(m.x_axis.xzww()),
280 Vec3A::from_vec4(m.y_axis.xzww()),
281 Vec3A::from_vec4(m.w_axis.xzww()),
282 ),
283 (2, 2) => Self::from_cols(
284 Vec3A::from_vec4(m.x_axis.xyww()),
285 Vec3A::from_vec4(m.y_axis.xyww()),
286 Vec3A::from_vec4(m.w_axis.xyww()),
287 ),
288 (2, 3) => Self::from_cols(
289 Vec3A::from_vec4(m.x_axis.xyzw()),
290 Vec3A::from_vec4(m.y_axis.xyzw()),
291 Vec3A::from_vec4(m.w_axis.xyzw()),
292 ),
293 (3, 0) => Self::from_cols(
294 Vec3A::from_vec4(m.x_axis.yzww()),
295 Vec3A::from_vec4(m.y_axis.yzww()),
296 Vec3A::from_vec4(m.z_axis.yzww()),
297 ),
298 (3, 1) => Self::from_cols(
299 Vec3A::from_vec4(m.x_axis.xzww()),
300 Vec3A::from_vec4(m.y_axis.xzww()),
301 Vec3A::from_vec4(m.z_axis.xzww()),
302 ),
303 (3, 2) => Self::from_cols(
304 Vec3A::from_vec4(m.x_axis.xyww()),
305 Vec3A::from_vec4(m.y_axis.xyww()),
306 Vec3A::from_vec4(m.z_axis.xyww()),
307 ),
308 (3, 3) => Self::from_cols(
309 Vec3A::from_vec4(m.x_axis.xyzw()),
310 Vec3A::from_vec4(m.y_axis.xyzw()),
311 Vec3A::from_vec4(m.z_axis.xyzw()),
312 ),
313 _ => panic!("index out of bounds"),
314 }
315 }
316
317 #[inline]
323 #[must_use]
324 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
325 pub fn from_quat(rotation: Quat) -> Self {
326 glam_assert!(rotation.is_normalized());
327
328 let x2 = rotation.x + rotation.x;
329 let y2 = rotation.y + rotation.y;
330 let z2 = rotation.z + rotation.z;
331 let xx = rotation.x * x2;
332 let xy = rotation.x * y2;
333 let xz = rotation.x * z2;
334 let yy = rotation.y * y2;
335 let yz = rotation.y * z2;
336 let zz = rotation.z * z2;
337 let wx = rotation.w * x2;
338 let wy = rotation.w * y2;
339 let wz = rotation.w * z2;
340
341 Self::from_cols(
342 Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
343 Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
344 Vec3A::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
345 )
346 }
347
348 #[inline]
355 #[must_use]
356 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
357 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
358 glam_assert!(axis.is_normalized());
359
360 let (sin, cos) = math::sin_cos(angle);
361 let (xsin, ysin, zsin) = axis.mul(sin).into();
362 let (x, y, z) = axis.into();
363 let (x2, y2, z2) = axis.mul(axis).into();
364 let omc = 1.0 - cos;
365 let xyomc = x * y * omc;
366 let xzomc = x * z * omc;
367 let yzomc = y * z * omc;
368 Self::from_cols(
369 Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
370 Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
371 Vec3A::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
372 )
373 }
374
375 #[inline]
378 #[must_use]
379 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
380 Self::from_euler_angles(order, a, b, c)
381 }
382
383 #[inline]
392 #[must_use]
393 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
394 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
395 glam_assert!(
396 self.x_axis.is_normalized()
397 && self.y_axis.is_normalized()
398 && self.z_axis.is_normalized()
399 );
400 self.to_euler_angles(order)
401 }
402
403 #[inline]
405 #[must_use]
406 pub fn from_rotation_x(angle: f32) -> Self {
407 let (sina, cosa) = math::sin_cos(angle);
408 Self::from_cols(
409 Vec3A::X,
410 Vec3A::new(0.0, cosa, sina),
411 Vec3A::new(0.0, -sina, cosa),
412 )
413 }
414
415 #[inline]
417 #[must_use]
418 pub fn from_rotation_y(angle: f32) -> Self {
419 let (sina, cosa) = math::sin_cos(angle);
420 Self::from_cols(
421 Vec3A::new(cosa, 0.0, -sina),
422 Vec3A::Y,
423 Vec3A::new(sina, 0.0, cosa),
424 )
425 }
426
427 #[inline]
429 #[must_use]
430 pub fn from_rotation_z(angle: f32) -> Self {
431 let (sina, cosa) = math::sin_cos(angle);
432 Self::from_cols(
433 Vec3A::new(cosa, sina, 0.0),
434 Vec3A::new(-sina, cosa, 0.0),
435 Vec3A::Z,
436 )
437 }
438
439 #[inline]
444 #[must_use]
445 pub fn from_translation(translation: Vec2) -> Self {
446 Self::from_cols(
447 Vec3A::X,
448 Vec3A::Y,
449 Vec3A::new(translation.x, translation.y, 1.0),
450 )
451 }
452
453 #[inline]
459 #[must_use]
460 pub fn from_angle(angle: f32) -> Self {
461 let (sin, cos) = math::sin_cos(angle);
462 Self::from_cols(
463 Vec3A::new(cos, sin, 0.0),
464 Vec3A::new(-sin, cos, 0.0),
465 Vec3A::Z,
466 )
467 }
468
469 #[inline]
475 #[must_use]
476 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
477 let (sin, cos) = math::sin_cos(angle);
478 Self::from_cols(
479 Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
480 Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
481 Vec3A::new(translation.x, translation.y, 1.0),
482 )
483 }
484
485 #[inline]
494 #[must_use]
495 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
496 pub fn from_scale(scale: Vec2) -> Self {
497 glam_assert!(scale.cmpne(Vec2::ZERO).any());
499
500 Self::from_cols(
501 Vec3A::new(scale.x, 0.0, 0.0),
502 Vec3A::new(0.0, scale.y, 0.0),
503 Vec3A::Z,
504 )
505 }
506
507 #[inline]
512 pub fn from_mat2(m: Mat2) -> Self {
513 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
514 }
515
516 #[inline]
524 #[must_use]
525 #[track_caller]
526 pub const fn from_cols_slice(slice: &[f32]) -> Self {
527 Self::new(
528 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
529 slice[8],
530 )
531 }
532
533 #[inline]
539 #[track_caller]
540 pub fn write_cols_to_slice(&self, slice: &mut [f32]) {
541 slice[0] = self.x_axis.x;
542 slice[1] = self.x_axis.y;
543 slice[2] = self.x_axis.z;
544 slice[3] = self.y_axis.x;
545 slice[4] = self.y_axis.y;
546 slice[5] = self.y_axis.z;
547 slice[6] = self.z_axis.x;
548 slice[7] = self.z_axis.y;
549 slice[8] = self.z_axis.z;
550 }
551
552 #[inline]
563 #[must_use]
564 #[track_caller]
565 pub const fn from_rows_slice(slice: &[f32]) -> Self {
566 Self::new(
567 slice[0], slice[3], slice[6], slice[1], slice[4], slice[7], slice[2], slice[5],
568 slice[8],
569 )
570 }
571
572 #[inline]
578 #[must_use]
579 #[track_caller]
580 pub fn col(&self, index: usize) -> Vec3A {
581 match index {
582 0 => self.x_axis,
583 1 => self.y_axis,
584 2 => self.z_axis,
585 _ => panic!("index out of bounds"),
586 }
587 }
588
589 #[inline]
595 #[track_caller]
596 pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
597 match index {
598 0 => &mut self.x_axis,
599 1 => &mut self.y_axis,
600 2 => &mut self.z_axis,
601 _ => panic!("index out of bounds"),
602 }
603 }
604
605 #[inline]
613 #[must_use]
614 #[track_caller]
615 pub fn row(&self, index: usize) -> Vec3A {
616 match index {
617 0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
618 1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
619 2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
620 _ => panic!("index out of bounds"),
621 }
622 }
623
624 #[inline]
634 #[track_caller]
635 pub fn set_row(&mut self, index: usize, row: Vec3A) {
636 match index {
637 0 => {
638 self.x_axis.x = row.x;
639 self.y_axis.x = row.y;
640 self.z_axis.x = row.z;
641 }
642 1 => {
643 self.x_axis.y = row.x;
644 self.y_axis.y = row.y;
645 self.z_axis.y = row.z;
646 }
647 2 => {
648 self.x_axis.z = row.x;
649 self.y_axis.z = row.y;
650 self.z_axis.z = row.z;
651 }
652 _ => panic!("index out of bounds"),
653 }
654 }
655
656 #[inline]
659 #[must_use]
660 pub fn is_finite(&self) -> bool {
661 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
662 }
663
664 #[inline]
666 #[must_use]
667 pub fn is_nan(&self) -> bool {
668 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
669 }
670
671 #[inline]
673 #[must_use]
674 pub fn transpose(&self) -> Self {
675 let x = self.x_axis.0;
676 let y = self.y_axis.0;
677 let z = self.z_axis.0;
678 unsafe {
679 let tmp0 = vreinterpretq_f32_u64(vsetq_lane_u64(
680 vgetq_lane_u64(vreinterpretq_u64_f32(y), 0),
681 vreinterpretq_u64_f32(x),
682 1,
683 ));
684 let tmp1 = vreinterpretq_f32_u64(vzip2q_u64(
685 vreinterpretq_u64_f32(x),
686 vreinterpretq_u64_f32(y),
687 ));
688 Mat3A::from_cols(
689 Vec3A::from(vsetq_lane_f32(vgetq_lane_f32(z, 0), vuzp1q_f32(tmp0, z), 3)),
690 Vec3A::from(vuzp2q_f32(tmp0, vdupq_laneq_f32(z, 1))),
691 Vec3A::from(vsetq_lane_f32(vgetq_lane_f32(z, 2), vuzp1q_f32(tmp1, z), 2)),
692 )
693 }
694 }
695
696 #[inline]
698 #[must_use]
699 pub fn diagonal(&self) -> Vec3A {
700 Vec3A::new(self.x_axis.x, self.y_axis.y, self.z_axis.z)
701 }
702
703 #[inline]
705 #[must_use]
706 pub fn determinant(&self) -> f32 {
707 self.x_axis.dot(self.y_axis.cross(self.z_axis))
708 }
709
710 #[inline(always)]
722 #[must_use]
723 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
724 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
725 let tmp0 = self.y_axis.cross(self.z_axis);
726 let tmp1 = self.z_axis.cross(self.x_axis);
727 let tmp2 = self.x_axis.cross(self.y_axis);
728 let inv_det = Vec3A::splat(1.0 / self.x_axis.dot(tmp0));
729 let m =
730 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose();
731 if CHECKED {
732 if !m.is_finite() {
733 return (Self::ZERO, false);
734 }
735 } else {
736 glam_assert!(m.is_finite());
737 }
738 (m, true)
739 }
740
741 #[inline]
753 #[must_use]
754 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
755 pub fn inverse(&self) -> Self {
756 self.inverse_checked::<false>().0
757 }
758
759 #[inline]
762 #[must_use]
763 pub fn try_inverse(&self) -> Option<Self> {
764 let (m, is_valid) = self.inverse_checked::<true>();
765 if is_valid { Some(m) } else { None }
766 }
767
768 #[inline]
771 #[must_use]
772 pub fn inverse_or_zero(&self) -> Self {
773 self.inverse_checked::<true>().0
774 }
775
776 #[inline]
786 #[must_use]
787 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
788 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
789 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
790 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
791 }
792
793 #[inline]
803 #[must_use]
804 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
805 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
806 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
807 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
808 }
809
810 #[inline]
812 #[must_use]
813 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
814 self.mul_vec3a(rhs.into()).into()
815 }
816
817 #[inline]
819 #[must_use]
820 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
821 let mut res = self.x_axis.mul(rhs.xxx());
822 res = res.add(self.y_axis.mul(rhs.yyy()));
823 res = res.add(self.z_axis.mul(rhs.zzz()));
824 res
825 }
826
827 #[inline]
829 #[must_use]
830 pub fn mul_transpose_vec3(&self, rhs: Vec3) -> Vec3 {
831 self.mul_transpose_vec3a(rhs.into()).into()
832 }
833
834 #[inline]
836 #[must_use]
837 pub fn mul_transpose_vec3a(&self, rhs: Vec3A) -> Vec3A {
838 Vec3A::new(
839 self.x_axis.dot(rhs),
840 self.y_axis.dot(rhs),
841 self.z_axis.dot(rhs),
842 )
843 }
844
845 #[inline]
847 #[must_use]
848 pub fn mul_mat3(&self, rhs: &Self) -> Self {
849 self.mul(rhs)
850 }
851
852 #[inline]
854 #[must_use]
855 pub fn add_mat3(&self, rhs: &Self) -> Self {
856 self.add(rhs)
857 }
858
859 #[inline]
861 #[must_use]
862 pub fn sub_mat3(&self, rhs: &Self) -> Self {
863 self.sub(rhs)
864 }
865
866 #[inline]
868 #[must_use]
869 pub fn mul_scalar(&self, rhs: f32) -> Self {
870 Self::from_cols(
871 self.x_axis.mul(rhs),
872 self.y_axis.mul(rhs),
873 self.z_axis.mul(rhs),
874 )
875 }
876
877 #[inline]
881 #[must_use]
882 pub fn mul_diagonal_scale(&self, scale: Vec3) -> Self {
883 Self::from_cols(
884 self.x_axis * scale.x,
885 self.y_axis * scale.y,
886 self.z_axis * scale.z,
887 )
888 }
889
890 #[inline]
892 #[must_use]
893 pub fn div_scalar(&self, rhs: f32) -> Self {
894 let rhs = Vec3A::splat(rhs);
895 Self::from_cols(
896 self.x_axis.div(rhs),
897 self.y_axis.div(rhs),
898 self.z_axis.div(rhs),
899 )
900 }
901
902 #[inline]
904 #[must_use]
905 pub fn recip(&self) -> Self {
906 Self::from_cols(
907 self.x_axis.recip(),
908 self.y_axis.recip(),
909 self.z_axis.recip(),
910 )
911 }
912
913 #[inline]
923 #[must_use]
924 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
925 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
926 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
927 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
928 }
929
930 #[inline]
932 #[must_use]
933 pub fn abs(&self) -> Self {
934 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
935 }
936
937 #[cfg(feature = "f64")]
938 #[inline]
939 #[must_use]
940 pub fn as_dmat3(&self) -> DMat3 {
941 DMat3::from_cols(
942 self.x_axis.as_dvec3(),
943 self.y_axis.as_dvec3(),
944 self.z_axis.as_dvec3(),
945 )
946 }
947}
948
949impl Default for Mat3A {
950 #[inline]
951 fn default() -> Self {
952 Self::IDENTITY
953 }
954}
955
956impl Add for Mat3A {
957 type Output = Self;
958 #[inline]
959 fn add(self, rhs: Self) -> Self {
960 Self::from_cols(
961 self.x_axis.add(rhs.x_axis),
962 self.y_axis.add(rhs.y_axis),
963 self.z_axis.add(rhs.z_axis),
964 )
965 }
966}
967
968impl Add<&Self> for Mat3A {
969 type Output = Self;
970 #[inline]
971 fn add(self, rhs: &Self) -> Self {
972 self.add(*rhs)
973 }
974}
975
976impl Add<&Mat3A> for &Mat3A {
977 type Output = Mat3A;
978 #[inline]
979 fn add(self, rhs: &Mat3A) -> Mat3A {
980 (*self).add(*rhs)
981 }
982}
983
984impl Add<Mat3A> for &Mat3A {
985 type Output = Mat3A;
986 #[inline]
987 fn add(self, rhs: Mat3A) -> Mat3A {
988 (*self).add(rhs)
989 }
990}
991
992impl AddAssign for Mat3A {
993 #[inline]
994 fn add_assign(&mut self, rhs: Self) {
995 *self = self.add(rhs);
996 }
997}
998
999impl AddAssign<&Self> for Mat3A {
1000 #[inline]
1001 fn add_assign(&mut self, rhs: &Self) {
1002 self.add_assign(*rhs);
1003 }
1004}
1005
1006impl Sub for Mat3A {
1007 type Output = Self;
1008 #[inline]
1009 fn sub(self, rhs: Self) -> Self {
1010 Self::from_cols(
1011 self.x_axis.sub(rhs.x_axis),
1012 self.y_axis.sub(rhs.y_axis),
1013 self.z_axis.sub(rhs.z_axis),
1014 )
1015 }
1016}
1017
1018impl Sub<&Self> for Mat3A {
1019 type Output = Self;
1020 #[inline]
1021 fn sub(self, rhs: &Self) -> Self {
1022 self.sub(*rhs)
1023 }
1024}
1025
1026impl Sub<&Mat3A> for &Mat3A {
1027 type Output = Mat3A;
1028 #[inline]
1029 fn sub(self, rhs: &Mat3A) -> Mat3A {
1030 (*self).sub(*rhs)
1031 }
1032}
1033
1034impl Sub<Mat3A> for &Mat3A {
1035 type Output = Mat3A;
1036 #[inline]
1037 fn sub(self, rhs: Mat3A) -> Mat3A {
1038 (*self).sub(rhs)
1039 }
1040}
1041
1042impl SubAssign for Mat3A {
1043 #[inline]
1044 fn sub_assign(&mut self, rhs: Self) {
1045 *self = self.sub(rhs);
1046 }
1047}
1048
1049impl SubAssign<&Self> for Mat3A {
1050 #[inline]
1051 fn sub_assign(&mut self, rhs: &Self) {
1052 self.sub_assign(*rhs);
1053 }
1054}
1055
1056impl Neg for Mat3A {
1057 type Output = Self;
1058 #[inline]
1059 fn neg(self) -> Self::Output {
1060 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
1061 }
1062}
1063
1064impl Neg for &Mat3A {
1065 type Output = Mat3A;
1066 #[inline]
1067 fn neg(self) -> Mat3A {
1068 (*self).neg()
1069 }
1070}
1071
1072impl Mul for Mat3A {
1073 type Output = Self;
1074 #[inline]
1075 fn mul(self, rhs: Self) -> Self {
1076 Self::from_cols(
1077 self.mul(rhs.x_axis),
1078 self.mul(rhs.y_axis),
1079 self.mul(rhs.z_axis),
1080 )
1081 }
1082}
1083
1084impl Mul<&Self> for Mat3A {
1085 type Output = Self;
1086 #[inline]
1087 fn mul(self, rhs: &Self) -> Self {
1088 self.mul(*rhs)
1089 }
1090}
1091
1092impl Mul<&Mat3A> for &Mat3A {
1093 type Output = Mat3A;
1094 #[inline]
1095 fn mul(self, rhs: &Mat3A) -> Mat3A {
1096 (*self).mul(*rhs)
1097 }
1098}
1099
1100impl Mul<Mat3A> for &Mat3A {
1101 type Output = Mat3A;
1102 #[inline]
1103 fn mul(self, rhs: Mat3A) -> Mat3A {
1104 (*self).mul(rhs)
1105 }
1106}
1107
1108impl MulAssign for Mat3A {
1109 #[inline]
1110 fn mul_assign(&mut self, rhs: Self) {
1111 *self = self.mul(rhs);
1112 }
1113}
1114
1115impl MulAssign<&Self> for Mat3A {
1116 #[inline]
1117 fn mul_assign(&mut self, rhs: &Self) {
1118 self.mul_assign(*rhs);
1119 }
1120}
1121
1122impl Mul<Vec3A> for Mat3A {
1123 type Output = Vec3A;
1124 #[inline]
1125 fn mul(self, rhs: Vec3A) -> Self::Output {
1126 self.mul_vec3a(rhs)
1127 }
1128}
1129
1130impl Mul<&Vec3A> for Mat3A {
1131 type Output = Vec3A;
1132 #[inline]
1133 fn mul(self, rhs: &Vec3A) -> Vec3A {
1134 self.mul(*rhs)
1135 }
1136}
1137
1138impl Mul<&Vec3A> for &Mat3A {
1139 type Output = Vec3A;
1140 #[inline]
1141 fn mul(self, rhs: &Vec3A) -> Vec3A {
1142 (*self).mul(*rhs)
1143 }
1144}
1145
1146impl Mul<Vec3A> for &Mat3A {
1147 type Output = Vec3A;
1148 #[inline]
1149 fn mul(self, rhs: Vec3A) -> Vec3A {
1150 (*self).mul(rhs)
1151 }
1152}
1153
1154impl Mul<Mat3A> for f32 {
1155 type Output = Mat3A;
1156 #[inline]
1157 fn mul(self, rhs: Mat3A) -> Self::Output {
1158 rhs.mul_scalar(self)
1159 }
1160}
1161
1162impl Mul<&Mat3A> for f32 {
1163 type Output = Mat3A;
1164 #[inline]
1165 fn mul(self, rhs: &Mat3A) -> Mat3A {
1166 self.mul(*rhs)
1167 }
1168}
1169
1170impl Mul<&Mat3A> for &f32 {
1171 type Output = Mat3A;
1172 #[inline]
1173 fn mul(self, rhs: &Mat3A) -> Mat3A {
1174 (*self).mul(*rhs)
1175 }
1176}
1177
1178impl Mul<Mat3A> for &f32 {
1179 type Output = Mat3A;
1180 #[inline]
1181 fn mul(self, rhs: Mat3A) -> Mat3A {
1182 (*self).mul(rhs)
1183 }
1184}
1185
1186impl Mul<f32> for Mat3A {
1187 type Output = Self;
1188 #[inline]
1189 fn mul(self, rhs: f32) -> Self {
1190 self.mul_scalar(rhs)
1191 }
1192}
1193
1194impl Mul<&f32> for Mat3A {
1195 type Output = Self;
1196 #[inline]
1197 fn mul(self, rhs: &f32) -> Self {
1198 self.mul(*rhs)
1199 }
1200}
1201
1202impl Mul<&f32> for &Mat3A {
1203 type Output = Mat3A;
1204 #[inline]
1205 fn mul(self, rhs: &f32) -> Mat3A {
1206 (*self).mul(*rhs)
1207 }
1208}
1209
1210impl Mul<f32> for &Mat3A {
1211 type Output = Mat3A;
1212 #[inline]
1213 fn mul(self, rhs: f32) -> Mat3A {
1214 (*self).mul(rhs)
1215 }
1216}
1217
1218impl MulAssign<f32> for Mat3A {
1219 #[inline]
1220 fn mul_assign(&mut self, rhs: f32) {
1221 *self = self.mul(rhs);
1222 }
1223}
1224
1225impl MulAssign<&f32> for Mat3A {
1226 #[inline]
1227 fn mul_assign(&mut self, rhs: &f32) {
1228 self.mul_assign(*rhs);
1229 }
1230}
1231
1232impl Div<Mat3A> for f32 {
1233 type Output = Mat3A;
1234 #[inline]
1235 fn div(self, rhs: Mat3A) -> Self::Output {
1236 Mat3A::from_cols(
1237 self.div(rhs.x_axis),
1238 self.div(rhs.y_axis),
1239 self.div(rhs.z_axis),
1240 )
1241 }
1242}
1243
1244impl Div<&Mat3A> for f32 {
1245 type Output = Mat3A;
1246 #[inline]
1247 fn div(self, rhs: &Mat3A) -> Mat3A {
1248 self.div(*rhs)
1249 }
1250}
1251
1252impl Div<&Mat3A> for &f32 {
1253 type Output = Mat3A;
1254 #[inline]
1255 fn div(self, rhs: &Mat3A) -> Mat3A {
1256 (*self).div(*rhs)
1257 }
1258}
1259
1260impl Div<Mat3A> for &f32 {
1261 type Output = Mat3A;
1262 #[inline]
1263 fn div(self, rhs: Mat3A) -> Mat3A {
1264 (*self).div(rhs)
1265 }
1266}
1267
1268impl Div<f32> for Mat3A {
1269 type Output = Self;
1270 #[inline]
1271 fn div(self, rhs: f32) -> Self {
1272 self.div_scalar(rhs)
1273 }
1274}
1275
1276impl Div<&f32> for Mat3A {
1277 type Output = Self;
1278 #[inline]
1279 fn div(self, rhs: &f32) -> Self {
1280 self.div(*rhs)
1281 }
1282}
1283
1284impl Div<&f32> for &Mat3A {
1285 type Output = Mat3A;
1286 #[inline]
1287 fn div(self, rhs: &f32) -> Mat3A {
1288 (*self).div(*rhs)
1289 }
1290}
1291
1292impl Div<f32> for &Mat3A {
1293 type Output = Mat3A;
1294 #[inline]
1295 fn div(self, rhs: f32) -> Mat3A {
1296 (*self).div(rhs)
1297 }
1298}
1299
1300impl DivAssign<f32> for Mat3A {
1301 #[inline]
1302 fn div_assign(&mut self, rhs: f32) {
1303 *self = self.div(rhs);
1304 }
1305}
1306
1307impl DivAssign<&f32> for Mat3A {
1308 #[inline]
1309 fn div_assign(&mut self, rhs: &f32) {
1310 self.div_assign(*rhs);
1311 }
1312}
1313
1314impl Mul<Vec3> for Mat3A {
1315 type Output = Vec3;
1316 #[inline]
1317 fn mul(self, rhs: Vec3) -> Vec3 {
1318 self.mul_vec3a(rhs.into()).into()
1319 }
1320}
1321
1322impl Mul<&Vec3> for Mat3A {
1323 type Output = Vec3;
1324 #[inline]
1325 fn mul(self, rhs: &Vec3) -> Vec3 {
1326 self.mul(*rhs)
1327 }
1328}
1329
1330impl Mul<&Vec3> for &Mat3A {
1331 type Output = Vec3;
1332 #[inline]
1333 fn mul(self, rhs: &Vec3) -> Vec3 {
1334 (*self).mul(*rhs)
1335 }
1336}
1337
1338impl Mul<Vec3> for &Mat3A {
1339 type Output = Vec3;
1340 #[inline]
1341 fn mul(self, rhs: Vec3) -> Vec3 {
1342 (*self).mul(rhs)
1343 }
1344}
1345
1346impl From<Mat3> for Mat3A {
1347 #[inline]
1348 fn from(m: Mat3) -> Self {
1349 Self {
1350 x_axis: m.x_axis.into(),
1351 y_axis: m.y_axis.into(),
1352 z_axis: m.z_axis.into(),
1353 }
1354 }
1355}
1356
1357impl Sum<Self> for Mat3A {
1358 fn sum<I>(iter: I) -> Self
1359 where
1360 I: Iterator<Item = Self>,
1361 {
1362 iter.fold(Self::ZERO, Self::add)
1363 }
1364}
1365
1366impl<'a> Sum<&'a Self> for Mat3A {
1367 fn sum<I>(iter: I) -> Self
1368 where
1369 I: Iterator<Item = &'a Self>,
1370 {
1371 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1372 }
1373}
1374
1375impl Product for Mat3A {
1376 fn product<I>(iter: I) -> Self
1377 where
1378 I: Iterator<Item = Self>,
1379 {
1380 iter.fold(Self::IDENTITY, Self::mul)
1381 }
1382}
1383
1384impl<'a> Product<&'a Self> for Mat3A {
1385 fn product<I>(iter: I) -> Self
1386 where
1387 I: Iterator<Item = &'a Self>,
1388 {
1389 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1390 }
1391}
1392
1393impl PartialEq for Mat3A {
1394 #[inline]
1395 fn eq(&self, rhs: &Self) -> bool {
1396 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1397 }
1398}
1399
1400impl fmt::Debug for Mat3A {
1401 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1402 fmt.debug_struct(stringify!(Mat3A))
1403 .field("x_axis", &self.x_axis)
1404 .field("y_axis", &self.y_axis)
1405 .field("z_axis", &self.z_axis)
1406 .finish()
1407 }
1408}
1409
1410impl fmt::Display for Mat3A {
1411 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1412 if let Some(p) = f.precision() {
1413 write!(
1414 f,
1415 "[{:.*}, {:.*}, {:.*}]",
1416 p, self.x_axis, p, self.y_axis, p, self.z_axis
1417 )
1418 } else {
1419 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1420 }
1421 }
1422}