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