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