1use crate::{
4 euler::{FromEuler, ToEuler},
5 f32::math,
6 swizzles::*,
7 DMat3, EulerRot, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec3A,
8};
9use core::fmt;
10use core::iter::{Product, Sum};
11use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
12
13use core::arch::aarch64::*;
14
15#[inline(always)]
17#[must_use]
18pub const fn mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A {
19 Mat3A::from_cols(x_axis, y_axis, z_axis)
20}
21
22#[derive(Clone, Copy)]
47#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
48#[repr(C)]
49pub struct Mat3A {
50 pub x_axis: Vec3A,
51 pub y_axis: Vec3A,
52 pub z_axis: Vec3A,
53}
54
55impl Mat3A {
56 pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
58
59 pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
61
62 pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::NAN);
64
65 #[allow(clippy::too_many_arguments)]
66 #[inline(always)]
67 #[must_use]
68 const fn new(
69 m00: f32,
70 m01: f32,
71 m02: f32,
72 m10: f32,
73 m11: f32,
74 m12: f32,
75 m20: f32,
76 m21: f32,
77 m22: f32,
78 ) -> Self {
79 Self {
80 x_axis: Vec3A::new(m00, m01, m02),
81 y_axis: Vec3A::new(m10, m11, m12),
82 z_axis: Vec3A::new(m20, m21, m22),
83 }
84 }
85
86 #[inline(always)]
88 #[must_use]
89 pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self {
90 Self {
91 x_axis,
92 y_axis,
93 z_axis,
94 }
95 }
96
97 #[inline]
101 #[must_use]
102 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
103 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
104 }
105
106 #[inline]
109 #[must_use]
110 pub const fn to_cols_array(&self) -> [f32; 9] {
111 let [x_axis_x, x_axis_y, x_axis_z] = self.x_axis.to_array();
112 let [y_axis_x, y_axis_y, y_axis_z] = self.y_axis.to_array();
113 let [z_axis_x, z_axis_y, z_axis_z] = self.z_axis.to_array();
114
115 [
116 x_axis_x, x_axis_y, x_axis_z, y_axis_x, y_axis_y, y_axis_z, z_axis_x, z_axis_y,
117 z_axis_z,
118 ]
119 }
120
121 #[inline]
125 #[must_use]
126 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
127 Self::from_cols(
128 Vec3A::from_array(m[0]),
129 Vec3A::from_array(m[1]),
130 Vec3A::from_array(m[2]),
131 )
132 }
133
134 #[inline]
137 #[must_use]
138 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
139 [
140 self.x_axis.to_array(),
141 self.y_axis.to_array(),
142 self.z_axis.to_array(),
143 ]
144 }
145
146 #[doc(alias = "scale")]
148 #[inline]
149 #[must_use]
150 pub const fn from_diagonal(diagonal: Vec3) -> Self {
151 Self::new(
152 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
153 )
154 }
155
156 #[inline]
158 #[must_use]
159 pub fn from_mat4(m: Mat4) -> Self {
160 Self::from_cols(
161 Vec3A::from_vec4(m.x_axis),
162 Vec3A::from_vec4(m.y_axis),
163 Vec3A::from_vec4(m.z_axis),
164 )
165 }
166
167 #[inline]
174 #[must_use]
175 pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
176 match (i, j) {
177 (0, 0) => Self::from_cols(
178 Vec3A::from_vec4(m.y_axis.yzww()),
179 Vec3A::from_vec4(m.z_axis.yzww()),
180 Vec3A::from_vec4(m.w_axis.yzww()),
181 ),
182 (0, 1) => Self::from_cols(
183 Vec3A::from_vec4(m.y_axis.xzww()),
184 Vec3A::from_vec4(m.z_axis.xzww()),
185 Vec3A::from_vec4(m.w_axis.xzww()),
186 ),
187 (0, 2) => Self::from_cols(
188 Vec3A::from_vec4(m.y_axis.xyww()),
189 Vec3A::from_vec4(m.z_axis.xyww()),
190 Vec3A::from_vec4(m.w_axis.xyww()),
191 ),
192 (0, 3) => Self::from_cols(
193 Vec3A::from_vec4(m.y_axis.xyzw()),
194 Vec3A::from_vec4(m.z_axis.xyzw()),
195 Vec3A::from_vec4(m.w_axis.xyzw()),
196 ),
197 (1, 0) => Self::from_cols(
198 Vec3A::from_vec4(m.x_axis.yzww()),
199 Vec3A::from_vec4(m.z_axis.yzww()),
200 Vec3A::from_vec4(m.w_axis.yzww()),
201 ),
202 (1, 1) => Self::from_cols(
203 Vec3A::from_vec4(m.x_axis.xzww()),
204 Vec3A::from_vec4(m.z_axis.xzww()),
205 Vec3A::from_vec4(m.w_axis.xzww()),
206 ),
207 (1, 2) => Self::from_cols(
208 Vec3A::from_vec4(m.x_axis.xyww()),
209 Vec3A::from_vec4(m.z_axis.xyww()),
210 Vec3A::from_vec4(m.w_axis.xyww()),
211 ),
212 (1, 3) => Self::from_cols(
213 Vec3A::from_vec4(m.x_axis.xyzw()),
214 Vec3A::from_vec4(m.z_axis.xyzw()),
215 Vec3A::from_vec4(m.w_axis.xyzw()),
216 ),
217 (2, 0) => Self::from_cols(
218 Vec3A::from_vec4(m.x_axis.yzww()),
219 Vec3A::from_vec4(m.y_axis.yzww()),
220 Vec3A::from_vec4(m.w_axis.yzww()),
221 ),
222 (2, 1) => Self::from_cols(
223 Vec3A::from_vec4(m.x_axis.xzww()),
224 Vec3A::from_vec4(m.y_axis.xzww()),
225 Vec3A::from_vec4(m.w_axis.xzww()),
226 ),
227 (2, 2) => Self::from_cols(
228 Vec3A::from_vec4(m.x_axis.xyww()),
229 Vec3A::from_vec4(m.y_axis.xyww()),
230 Vec3A::from_vec4(m.w_axis.xyww()),
231 ),
232 (2, 3) => Self::from_cols(
233 Vec3A::from_vec4(m.x_axis.xyzw()),
234 Vec3A::from_vec4(m.y_axis.xyzw()),
235 Vec3A::from_vec4(m.w_axis.xyzw()),
236 ),
237 (3, 0) => Self::from_cols(
238 Vec3A::from_vec4(m.x_axis.yzww()),
239 Vec3A::from_vec4(m.y_axis.yzww()),
240 Vec3A::from_vec4(m.z_axis.yzww()),
241 ),
242 (3, 1) => Self::from_cols(
243 Vec3A::from_vec4(m.x_axis.xzww()),
244 Vec3A::from_vec4(m.y_axis.xzww()),
245 Vec3A::from_vec4(m.z_axis.xzww()),
246 ),
247 (3, 2) => Self::from_cols(
248 Vec3A::from_vec4(m.x_axis.xyww()),
249 Vec3A::from_vec4(m.y_axis.xyww()),
250 Vec3A::from_vec4(m.z_axis.xyww()),
251 ),
252 (3, 3) => Self::from_cols(
253 Vec3A::from_vec4(m.x_axis.xyzw()),
254 Vec3A::from_vec4(m.y_axis.xyzw()),
255 Vec3A::from_vec4(m.z_axis.xyzw()),
256 ),
257 _ => panic!("index out of bounds"),
258 }
259 }
260
261 #[inline]
267 #[must_use]
268 pub fn from_quat(rotation: Quat) -> Self {
269 glam_assert!(rotation.is_normalized());
270
271 let x2 = rotation.x + rotation.x;
272 let y2 = rotation.y + rotation.y;
273 let z2 = rotation.z + rotation.z;
274 let xx = rotation.x * x2;
275 let xy = rotation.x * y2;
276 let xz = rotation.x * z2;
277 let yy = rotation.y * y2;
278 let yz = rotation.y * z2;
279 let zz = rotation.z * z2;
280 let wx = rotation.w * x2;
281 let wy = rotation.w * y2;
282 let wz = rotation.w * z2;
283
284 Self::from_cols(
285 Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
286 Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
287 Vec3A::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
288 )
289 }
290
291 #[inline]
298 #[must_use]
299 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
300 glam_assert!(axis.is_normalized());
301
302 let (sin, cos) = math::sin_cos(angle);
303 let (xsin, ysin, zsin) = axis.mul(sin).into();
304 let (x, y, z) = axis.into();
305 let (x2, y2, z2) = axis.mul(axis).into();
306 let omc = 1.0 - cos;
307 let xyomc = x * y * omc;
308 let xzomc = x * z * omc;
309 let yzomc = y * z * omc;
310 Self::from_cols(
311 Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
312 Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
313 Vec3A::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
314 )
315 }
316
317 #[inline]
320 #[must_use]
321 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
322 Self::from_euler_angles(order, a, b, c)
323 }
324
325 #[inline]
334 #[must_use]
335 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
336 glam_assert!(
337 self.x_axis.is_normalized()
338 && self.y_axis.is_normalized()
339 && self.z_axis.is_normalized()
340 );
341 self.to_euler_angles(order)
342 }
343
344 #[inline]
346 #[must_use]
347 pub fn from_rotation_x(angle: f32) -> Self {
348 let (sina, cosa) = math::sin_cos(angle);
349 Self::from_cols(
350 Vec3A::X,
351 Vec3A::new(0.0, cosa, sina),
352 Vec3A::new(0.0, -sina, cosa),
353 )
354 }
355
356 #[inline]
358 #[must_use]
359 pub fn from_rotation_y(angle: f32) -> Self {
360 let (sina, cosa) = math::sin_cos(angle);
361 Self::from_cols(
362 Vec3A::new(cosa, 0.0, -sina),
363 Vec3A::Y,
364 Vec3A::new(sina, 0.0, cosa),
365 )
366 }
367
368 #[inline]
370 #[must_use]
371 pub fn from_rotation_z(angle: f32) -> Self {
372 let (sina, cosa) = math::sin_cos(angle);
373 Self::from_cols(
374 Vec3A::new(cosa, sina, 0.0),
375 Vec3A::new(-sina, cosa, 0.0),
376 Vec3A::Z,
377 )
378 }
379
380 #[inline]
385 #[must_use]
386 pub fn from_translation(translation: Vec2) -> Self {
387 Self::from_cols(
388 Vec3A::X,
389 Vec3A::Y,
390 Vec3A::new(translation.x, translation.y, 1.0),
391 )
392 }
393
394 #[inline]
400 #[must_use]
401 pub fn from_angle(angle: f32) -> Self {
402 let (sin, cos) = math::sin_cos(angle);
403 Self::from_cols(
404 Vec3A::new(cos, sin, 0.0),
405 Vec3A::new(-sin, cos, 0.0),
406 Vec3A::Z,
407 )
408 }
409
410 #[inline]
416 #[must_use]
417 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
418 let (sin, cos) = math::sin_cos(angle);
419 Self::from_cols(
420 Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
421 Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
422 Vec3A::new(translation.x, translation.y, 1.0),
423 )
424 }
425
426 #[inline]
435 #[must_use]
436 pub fn from_scale(scale: Vec2) -> Self {
437 glam_assert!(scale.cmpne(Vec2::ZERO).any());
439
440 Self::from_cols(
441 Vec3A::new(scale.x, 0.0, 0.0),
442 Vec3A::new(0.0, scale.y, 0.0),
443 Vec3A::Z,
444 )
445 }
446
447 #[inline]
452 pub fn from_mat2(m: Mat2) -> Self {
453 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
454 }
455
456 #[inline]
462 #[must_use]
463 pub const fn from_cols_slice(slice: &[f32]) -> Self {
464 Self::new(
465 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
466 slice[8],
467 )
468 }
469
470 #[inline]
476 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
477 slice[0] = self.x_axis.x;
478 slice[1] = self.x_axis.y;
479 slice[2] = self.x_axis.z;
480 slice[3] = self.y_axis.x;
481 slice[4] = self.y_axis.y;
482 slice[5] = self.y_axis.z;
483 slice[6] = self.z_axis.x;
484 slice[7] = self.z_axis.y;
485 slice[8] = self.z_axis.z;
486 }
487
488 #[inline]
494 #[must_use]
495 pub fn col(&self, index: usize) -> Vec3A {
496 match index {
497 0 => self.x_axis,
498 1 => self.y_axis,
499 2 => self.z_axis,
500 _ => panic!("index out of bounds"),
501 }
502 }
503
504 #[inline]
510 pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
511 match index {
512 0 => &mut self.x_axis,
513 1 => &mut self.y_axis,
514 2 => &mut self.z_axis,
515 _ => panic!("index out of bounds"),
516 }
517 }
518
519 #[inline]
525 #[must_use]
526 pub fn row(&self, index: usize) -> Vec3A {
527 match index {
528 0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
529 1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
530 2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
531 _ => panic!("index out of bounds"),
532 }
533 }
534
535 #[inline]
538 #[must_use]
539 pub fn is_finite(&self) -> bool {
540 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
541 }
542
543 #[inline]
545 #[must_use]
546 pub fn is_nan(&self) -> bool {
547 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
548 }
549
550 #[inline]
552 #[must_use]
553 pub fn transpose(&self) -> Self {
554 let x = self.x_axis.0;
555 let y = self.y_axis.0;
556 let z = self.z_axis.0;
557 unsafe {
558 let tmp0 = vreinterpretq_f32_u64(vsetq_lane_u64(
559 vgetq_lane_u64(vreinterpretq_u64_f32(y), 0),
560 vreinterpretq_u64_f32(x),
561 1,
562 ));
563 let tmp1 = vreinterpretq_f32_u64(vzip2q_u64(
564 vreinterpretq_u64_f32(x),
565 vreinterpretq_u64_f32(y),
566 ));
567 Mat3A::from_cols(
568 Vec3A::from(vsetq_lane_f32(vgetq_lane_f32(z, 0), vuzp1q_f32(tmp0, z), 3)),
569 Vec3A::from(vuzp2q_f32(tmp0, vdupq_laneq_f32(z, 1))),
570 Vec3A::from(vsetq_lane_f32(vgetq_lane_f32(z, 2), vuzp1q_f32(tmp1, z), 2)),
571 )
572 }
573 }
574
575 #[inline]
577 #[must_use]
578 pub fn determinant(&self) -> f32 {
579 self.z_axis.dot(self.x_axis.cross(self.y_axis))
580 }
581
582 #[inline]
590 #[must_use]
591 pub fn inverse(&self) -> Self {
592 let tmp0 = self.y_axis.cross(self.z_axis);
593 let tmp1 = self.z_axis.cross(self.x_axis);
594 let tmp2 = self.x_axis.cross(self.y_axis);
595 let det = self.z_axis.dot(tmp2);
596 glam_assert!(det != 0.0);
597 let inv_det = Vec3A::splat(det.recip());
598 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
599 }
600
601 #[inline]
611 #[must_use]
612 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
613 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
614 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
615 }
616
617 #[inline]
627 #[must_use]
628 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
629 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
630 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
631 }
632
633 #[inline]
641 #[must_use]
642 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
643 Self::look_to_rh(-dir, up)
644 }
645
646 #[inline]
654 #[must_use]
655 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
656 glam_assert!(dir.is_normalized());
657 glam_assert!(up.is_normalized());
658 let f = dir;
659 let s = f.cross(up).normalize();
660 let u = s.cross(f);
661
662 Self::from_cols(
663 Vec3A::new(s.x, u.x, -f.x),
664 Vec3A::new(s.y, u.y, -f.y),
665 Vec3A::new(s.z, u.z, -f.z),
666 )
667 }
668
669 #[inline]
678 #[must_use]
679 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
680 Self::look_to_lh(center.sub(eye).normalize(), up)
681 }
682
683 #[inline]
692 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
693 Self::look_to_rh(center.sub(eye).normalize(), up)
694 }
695
696 #[inline]
698 #[must_use]
699 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
700 self.mul_vec3a(rhs.into()).into()
701 }
702
703 #[inline]
705 #[must_use]
706 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
707 let mut res = self.x_axis.mul(rhs.xxx());
708 res = res.add(self.y_axis.mul(rhs.yyy()));
709 res = res.add(self.z_axis.mul(rhs.zzz()));
710 res
711 }
712
713 #[inline]
715 #[must_use]
716 pub fn mul_mat3(&self, rhs: &Self) -> Self {
717 self.mul(rhs)
718 }
719
720 #[inline]
722 #[must_use]
723 pub fn add_mat3(&self, rhs: &Self) -> Self {
724 self.add(rhs)
725 }
726
727 #[inline]
729 #[must_use]
730 pub fn sub_mat3(&self, rhs: &Self) -> Self {
731 self.sub(rhs)
732 }
733
734 #[inline]
736 #[must_use]
737 pub fn mul_scalar(&self, rhs: f32) -> Self {
738 Self::from_cols(
739 self.x_axis.mul(rhs),
740 self.y_axis.mul(rhs),
741 self.z_axis.mul(rhs),
742 )
743 }
744
745 #[inline]
747 #[must_use]
748 pub fn div_scalar(&self, rhs: f32) -> Self {
749 let rhs = Vec3A::splat(rhs);
750 Self::from_cols(
751 self.x_axis.div(rhs),
752 self.y_axis.div(rhs),
753 self.z_axis.div(rhs),
754 )
755 }
756
757 #[inline]
767 #[must_use]
768 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
769 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
770 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
771 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
772 }
773
774 #[inline]
776 #[must_use]
777 pub fn abs(&self) -> Self {
778 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
779 }
780
781 #[inline]
782 pub fn as_dmat3(&self) -> DMat3 {
783 DMat3::from_cols(
784 self.x_axis.as_dvec3(),
785 self.y_axis.as_dvec3(),
786 self.z_axis.as_dvec3(),
787 )
788 }
789}
790
791impl Default for Mat3A {
792 #[inline]
793 fn default() -> Self {
794 Self::IDENTITY
795 }
796}
797
798impl Add for Mat3A {
799 type Output = Self;
800 #[inline]
801 fn add(self, rhs: Self) -> Self {
802 Self::from_cols(
803 self.x_axis.add(rhs.x_axis),
804 self.y_axis.add(rhs.y_axis),
805 self.z_axis.add(rhs.z_axis),
806 )
807 }
808}
809
810impl Add<&Self> for Mat3A {
811 type Output = Self;
812 #[inline]
813 fn add(self, rhs: &Self) -> Self {
814 self.add(*rhs)
815 }
816}
817
818impl Add<&Mat3A> for &Mat3A {
819 type Output = Mat3A;
820 #[inline]
821 fn add(self, rhs: &Mat3A) -> Mat3A {
822 (*self).add(*rhs)
823 }
824}
825
826impl Add<Mat3A> for &Mat3A {
827 type Output = Mat3A;
828 #[inline]
829 fn add(self, rhs: Mat3A) -> Mat3A {
830 (*self).add(rhs)
831 }
832}
833
834impl AddAssign for Mat3A {
835 #[inline]
836 fn add_assign(&mut self, rhs: Self) {
837 *self = self.add(rhs);
838 }
839}
840
841impl AddAssign<&Self> for Mat3A {
842 #[inline]
843 fn add_assign(&mut self, rhs: &Self) {
844 self.add_assign(*rhs);
845 }
846}
847
848impl Sub for Mat3A {
849 type Output = Self;
850 #[inline]
851 fn sub(self, rhs: Self) -> Self {
852 Self::from_cols(
853 self.x_axis.sub(rhs.x_axis),
854 self.y_axis.sub(rhs.y_axis),
855 self.z_axis.sub(rhs.z_axis),
856 )
857 }
858}
859
860impl Sub<&Self> for Mat3A {
861 type Output = Self;
862 #[inline]
863 fn sub(self, rhs: &Self) -> Self {
864 self.sub(*rhs)
865 }
866}
867
868impl Sub<&Mat3A> for &Mat3A {
869 type Output = Mat3A;
870 #[inline]
871 fn sub(self, rhs: &Mat3A) -> Mat3A {
872 (*self).sub(*rhs)
873 }
874}
875
876impl Sub<Mat3A> for &Mat3A {
877 type Output = Mat3A;
878 #[inline]
879 fn sub(self, rhs: Mat3A) -> Mat3A {
880 (*self).sub(rhs)
881 }
882}
883
884impl SubAssign for Mat3A {
885 #[inline]
886 fn sub_assign(&mut self, rhs: Self) {
887 *self = self.sub(rhs);
888 }
889}
890
891impl SubAssign<&Self> for Mat3A {
892 #[inline]
893 fn sub_assign(&mut self, rhs: &Self) {
894 self.sub_assign(*rhs);
895 }
896}
897
898impl Neg for Mat3A {
899 type Output = Self;
900 #[inline]
901 fn neg(self) -> Self::Output {
902 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
903 }
904}
905
906impl Neg for &Mat3A {
907 type Output = Mat3A;
908 #[inline]
909 fn neg(self) -> Mat3A {
910 (*self).neg()
911 }
912}
913
914impl Mul for Mat3A {
915 type Output = Self;
916 #[inline]
917 fn mul(self, rhs: Self) -> Self {
918 Self::from_cols(
919 self.mul(rhs.x_axis),
920 self.mul(rhs.y_axis),
921 self.mul(rhs.z_axis),
922 )
923 }
924}
925
926impl Mul<&Self> for Mat3A {
927 type Output = Self;
928 #[inline]
929 fn mul(self, rhs: &Self) -> Self {
930 self.mul(*rhs)
931 }
932}
933
934impl Mul<&Mat3A> for &Mat3A {
935 type Output = Mat3A;
936 #[inline]
937 fn mul(self, rhs: &Mat3A) -> Mat3A {
938 (*self).mul(*rhs)
939 }
940}
941
942impl Mul<Mat3A> for &Mat3A {
943 type Output = Mat3A;
944 #[inline]
945 fn mul(self, rhs: Mat3A) -> Mat3A {
946 (*self).mul(rhs)
947 }
948}
949
950impl MulAssign for Mat3A {
951 #[inline]
952 fn mul_assign(&mut self, rhs: Self) {
953 *self = self.mul(rhs);
954 }
955}
956
957impl MulAssign<&Self> for Mat3A {
958 #[inline]
959 fn mul_assign(&mut self, rhs: &Self) {
960 self.mul_assign(*rhs);
961 }
962}
963
964impl Mul<Vec3A> for Mat3A {
965 type Output = Vec3A;
966 #[inline]
967 fn mul(self, rhs: Vec3A) -> Self::Output {
968 self.mul_vec3a(rhs)
969 }
970}
971
972impl Mul<&Vec3A> for Mat3A {
973 type Output = Vec3A;
974 #[inline]
975 fn mul(self, rhs: &Vec3A) -> Vec3A {
976 self.mul(*rhs)
977 }
978}
979
980impl Mul<&Vec3A> for &Mat3A {
981 type Output = Vec3A;
982 #[inline]
983 fn mul(self, rhs: &Vec3A) -> Vec3A {
984 (*self).mul(*rhs)
985 }
986}
987
988impl Mul<Vec3A> for &Mat3A {
989 type Output = Vec3A;
990 #[inline]
991 fn mul(self, rhs: Vec3A) -> Vec3A {
992 (*self).mul(rhs)
993 }
994}
995
996impl Mul<Mat3A> for f32 {
997 type Output = Mat3A;
998 #[inline]
999 fn mul(self, rhs: Mat3A) -> Self::Output {
1000 rhs.mul_scalar(self)
1001 }
1002}
1003
1004impl Mul<&Mat3A> for f32 {
1005 type Output = Mat3A;
1006 #[inline]
1007 fn mul(self, rhs: &Mat3A) -> Mat3A {
1008 self.mul(*rhs)
1009 }
1010}
1011
1012impl Mul<&Mat3A> for &f32 {
1013 type Output = Mat3A;
1014 #[inline]
1015 fn mul(self, rhs: &Mat3A) -> Mat3A {
1016 (*self).mul(*rhs)
1017 }
1018}
1019
1020impl Mul<Mat3A> for &f32 {
1021 type Output = Mat3A;
1022 #[inline]
1023 fn mul(self, rhs: Mat3A) -> Mat3A {
1024 (*self).mul(rhs)
1025 }
1026}
1027
1028impl Mul<f32> for Mat3A {
1029 type Output = Self;
1030 #[inline]
1031 fn mul(self, rhs: f32) -> Self {
1032 self.mul_scalar(rhs)
1033 }
1034}
1035
1036impl Mul<&f32> for Mat3A {
1037 type Output = Self;
1038 #[inline]
1039 fn mul(self, rhs: &f32) -> Self {
1040 self.mul(*rhs)
1041 }
1042}
1043
1044impl Mul<&f32> for &Mat3A {
1045 type Output = Mat3A;
1046 #[inline]
1047 fn mul(self, rhs: &f32) -> Mat3A {
1048 (*self).mul(*rhs)
1049 }
1050}
1051
1052impl Mul<f32> for &Mat3A {
1053 type Output = Mat3A;
1054 #[inline]
1055 fn mul(self, rhs: f32) -> Mat3A {
1056 (*self).mul(rhs)
1057 }
1058}
1059
1060impl MulAssign<f32> for Mat3A {
1061 #[inline]
1062 fn mul_assign(&mut self, rhs: f32) {
1063 *self = self.mul(rhs);
1064 }
1065}
1066
1067impl MulAssign<&f32> for Mat3A {
1068 #[inline]
1069 fn mul_assign(&mut self, rhs: &f32) {
1070 self.mul_assign(*rhs);
1071 }
1072}
1073
1074impl Div<Mat3A> for f32 {
1075 type Output = Mat3A;
1076 #[inline]
1077 fn div(self, rhs: Mat3A) -> Self::Output {
1078 rhs.div_scalar(self)
1079 }
1080}
1081
1082impl Div<&Mat3A> for f32 {
1083 type Output = Mat3A;
1084 #[inline]
1085 fn div(self, rhs: &Mat3A) -> Mat3A {
1086 self.div(*rhs)
1087 }
1088}
1089
1090impl Div<&Mat3A> for &f32 {
1091 type Output = Mat3A;
1092 #[inline]
1093 fn div(self, rhs: &Mat3A) -> Mat3A {
1094 (*self).div(*rhs)
1095 }
1096}
1097
1098impl Div<Mat3A> for &f32 {
1099 type Output = Mat3A;
1100 #[inline]
1101 fn div(self, rhs: Mat3A) -> Mat3A {
1102 (*self).div(rhs)
1103 }
1104}
1105
1106impl Div<f32> for Mat3A {
1107 type Output = Self;
1108 #[inline]
1109 fn div(self, rhs: f32) -> Self {
1110 self.div_scalar(rhs)
1111 }
1112}
1113
1114impl Div<&f32> for Mat3A {
1115 type Output = Self;
1116 #[inline]
1117 fn div(self, rhs: &f32) -> Self {
1118 self.div(*rhs)
1119 }
1120}
1121
1122impl Div<&f32> for &Mat3A {
1123 type Output = Mat3A;
1124 #[inline]
1125 fn div(self, rhs: &f32) -> Mat3A {
1126 (*self).div(*rhs)
1127 }
1128}
1129
1130impl Div<f32> for &Mat3A {
1131 type Output = Mat3A;
1132 #[inline]
1133 fn div(self, rhs: f32) -> Mat3A {
1134 (*self).div(rhs)
1135 }
1136}
1137
1138impl DivAssign<f32> for Mat3A {
1139 #[inline]
1140 fn div_assign(&mut self, rhs: f32) {
1141 *self = self.div(rhs);
1142 }
1143}
1144
1145impl DivAssign<&f32> for Mat3A {
1146 #[inline]
1147 fn div_assign(&mut self, rhs: &f32) {
1148 self.div_assign(*rhs);
1149 }
1150}
1151
1152impl Mul<Vec3> for Mat3A {
1153 type Output = Vec3;
1154 #[inline]
1155 fn mul(self, rhs: Vec3) -> Vec3 {
1156 self.mul_vec3a(rhs.into()).into()
1157 }
1158}
1159
1160impl Mul<&Vec3> for Mat3A {
1161 type Output = Vec3;
1162 #[inline]
1163 fn mul(self, rhs: &Vec3) -> Vec3 {
1164 self.mul(*rhs)
1165 }
1166}
1167
1168impl Mul<&Vec3> for &Mat3A {
1169 type Output = Vec3;
1170 #[inline]
1171 fn mul(self, rhs: &Vec3) -> Vec3 {
1172 (*self).mul(*rhs)
1173 }
1174}
1175
1176impl Mul<Vec3> for &Mat3A {
1177 type Output = Vec3;
1178 #[inline]
1179 fn mul(self, rhs: Vec3) -> Vec3 {
1180 (*self).mul(rhs)
1181 }
1182}
1183
1184impl From<Mat3> for Mat3A {
1185 #[inline]
1186 fn from(m: Mat3) -> Self {
1187 Self {
1188 x_axis: m.x_axis.into(),
1189 y_axis: m.y_axis.into(),
1190 z_axis: m.z_axis.into(),
1191 }
1192 }
1193}
1194
1195impl Sum<Self> for Mat3A {
1196 fn sum<I>(iter: I) -> Self
1197 where
1198 I: Iterator<Item = Self>,
1199 {
1200 iter.fold(Self::ZERO, Self::add)
1201 }
1202}
1203
1204impl<'a> Sum<&'a Self> for Mat3A {
1205 fn sum<I>(iter: I) -> Self
1206 where
1207 I: Iterator<Item = &'a Self>,
1208 {
1209 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1210 }
1211}
1212
1213impl Product for Mat3A {
1214 fn product<I>(iter: I) -> Self
1215 where
1216 I: Iterator<Item = Self>,
1217 {
1218 iter.fold(Self::IDENTITY, Self::mul)
1219 }
1220}
1221
1222impl<'a> Product<&'a Self> for Mat3A {
1223 fn product<I>(iter: I) -> Self
1224 where
1225 I: Iterator<Item = &'a Self>,
1226 {
1227 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1228 }
1229}
1230
1231impl PartialEq for Mat3A {
1232 #[inline]
1233 fn eq(&self, rhs: &Self) -> bool {
1234 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1235 }
1236}
1237
1238impl fmt::Debug for Mat3A {
1239 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1240 fmt.debug_struct(stringify!(Mat3A))
1241 .field("x_axis", &self.x_axis)
1242 .field("y_axis", &self.y_axis)
1243 .field("z_axis", &self.z_axis)
1244 .finish()
1245 }
1246}
1247
1248impl fmt::Display for Mat3A {
1249 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1250 if let Some(p) = f.precision() {
1251 write!(
1252 f,
1253 "[{:.*}, {:.*}, {:.*}]",
1254 p, self.x_axis, p, self.y_axis, p, self.z_axis
1255 )
1256 } else {
1257 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1258 }
1259 }
1260}