1#[cfg(feature = "f64")]
4use crate::DMat3;
5
6use crate::{
7 euler::{FromEuler, ToEuler},
8 f32::math,
9 swizzles::*,
10 EulerRot, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec3A,
11};
12use core::fmt;
13use core::iter::{Product, Sum};
14use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
15
16#[cfg(target_arch = "x86")]
17use core::arch::x86::*;
18#[cfg(target_arch = "x86_64")]
19use core::arch::x86_64::*;
20
21#[cfg(feature = "zerocopy")]
22use zerocopy_derive::*;
23
24#[inline(always)]
26#[must_use]
27pub const fn mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A {
28 Mat3A::from_cols(x_axis, y_axis, z_axis)
29}
30
31#[derive(Clone, Copy)]
56#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
57#[cfg_attr(
58 feature = "zerocopy",
59 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
60)]
61#[repr(C)]
62pub struct Mat3A {
63 pub x_axis: Vec3A,
64 pub y_axis: Vec3A,
65 pub z_axis: Vec3A,
66}
67
68impl Mat3A {
69 pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
71
72 pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
74
75 pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::NAN);
77
78 #[allow(clippy::too_many_arguments)]
79 #[inline(always)]
80 #[must_use]
81 const fn new(
82 m00: f32,
83 m01: f32,
84 m02: f32,
85 m10: f32,
86 m11: f32,
87 m12: f32,
88 m20: f32,
89 m21: f32,
90 m22: f32,
91 ) -> Self {
92 Self {
93 x_axis: Vec3A::new(m00, m01, m02),
94 y_axis: Vec3A::new(m10, m11, m12),
95 z_axis: Vec3A::new(m20, m21, m22),
96 }
97 }
98
99 #[inline(always)]
101 #[must_use]
102 pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self {
103 Self {
104 x_axis,
105 y_axis,
106 z_axis,
107 }
108 }
109
110 #[inline]
114 #[must_use]
115 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
116 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
117 }
118
119 #[inline]
122 #[must_use]
123 pub const fn to_cols_array(&self) -> [f32; 9] {
124 let [x_axis_x, x_axis_y, x_axis_z] = self.x_axis.to_array();
125 let [y_axis_x, y_axis_y, y_axis_z] = self.y_axis.to_array();
126 let [z_axis_x, z_axis_y, z_axis_z] = self.z_axis.to_array();
127
128 [
129 x_axis_x, x_axis_y, x_axis_z, y_axis_x, y_axis_y, y_axis_z, z_axis_x, z_axis_y,
130 z_axis_z,
131 ]
132 }
133
134 #[inline]
138 #[must_use]
139 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
140 Self::from_cols(
141 Vec3A::from_array(m[0]),
142 Vec3A::from_array(m[1]),
143 Vec3A::from_array(m[2]),
144 )
145 }
146
147 #[inline]
150 #[must_use]
151 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
152 [
153 self.x_axis.to_array(),
154 self.y_axis.to_array(),
155 self.z_axis.to_array(),
156 ]
157 }
158
159 #[doc(alias = "scale")]
161 #[inline]
162 #[must_use]
163 pub const fn from_diagonal(diagonal: Vec3) -> Self {
164 Self::new(
165 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
166 )
167 }
168
169 #[inline]
171 #[must_use]
172 pub fn from_mat4(m: Mat4) -> Self {
173 Self::from_cols(
174 Vec3A::from_vec4(m.x_axis),
175 Vec3A::from_vec4(m.y_axis),
176 Vec3A::from_vec4(m.z_axis),
177 )
178 }
179
180 #[inline]
187 #[must_use]
188 pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
189 match (i, j) {
190 (0, 0) => Self::from_cols(
191 Vec3A::from_vec4(m.y_axis.yzww()),
192 Vec3A::from_vec4(m.z_axis.yzww()),
193 Vec3A::from_vec4(m.w_axis.yzww()),
194 ),
195 (0, 1) => Self::from_cols(
196 Vec3A::from_vec4(m.y_axis.xzww()),
197 Vec3A::from_vec4(m.z_axis.xzww()),
198 Vec3A::from_vec4(m.w_axis.xzww()),
199 ),
200 (0, 2) => Self::from_cols(
201 Vec3A::from_vec4(m.y_axis.xyww()),
202 Vec3A::from_vec4(m.z_axis.xyww()),
203 Vec3A::from_vec4(m.w_axis.xyww()),
204 ),
205 (0, 3) => Self::from_cols(
206 Vec3A::from_vec4(m.y_axis.xyzw()),
207 Vec3A::from_vec4(m.z_axis.xyzw()),
208 Vec3A::from_vec4(m.w_axis.xyzw()),
209 ),
210 (1, 0) => Self::from_cols(
211 Vec3A::from_vec4(m.x_axis.yzww()),
212 Vec3A::from_vec4(m.z_axis.yzww()),
213 Vec3A::from_vec4(m.w_axis.yzww()),
214 ),
215 (1, 1) => Self::from_cols(
216 Vec3A::from_vec4(m.x_axis.xzww()),
217 Vec3A::from_vec4(m.z_axis.xzww()),
218 Vec3A::from_vec4(m.w_axis.xzww()),
219 ),
220 (1, 2) => Self::from_cols(
221 Vec3A::from_vec4(m.x_axis.xyww()),
222 Vec3A::from_vec4(m.z_axis.xyww()),
223 Vec3A::from_vec4(m.w_axis.xyww()),
224 ),
225 (1, 3) => Self::from_cols(
226 Vec3A::from_vec4(m.x_axis.xyzw()),
227 Vec3A::from_vec4(m.z_axis.xyzw()),
228 Vec3A::from_vec4(m.w_axis.xyzw()),
229 ),
230 (2, 0) => Self::from_cols(
231 Vec3A::from_vec4(m.x_axis.yzww()),
232 Vec3A::from_vec4(m.y_axis.yzww()),
233 Vec3A::from_vec4(m.w_axis.yzww()),
234 ),
235 (2, 1) => Self::from_cols(
236 Vec3A::from_vec4(m.x_axis.xzww()),
237 Vec3A::from_vec4(m.y_axis.xzww()),
238 Vec3A::from_vec4(m.w_axis.xzww()),
239 ),
240 (2, 2) => Self::from_cols(
241 Vec3A::from_vec4(m.x_axis.xyww()),
242 Vec3A::from_vec4(m.y_axis.xyww()),
243 Vec3A::from_vec4(m.w_axis.xyww()),
244 ),
245 (2, 3) => Self::from_cols(
246 Vec3A::from_vec4(m.x_axis.xyzw()),
247 Vec3A::from_vec4(m.y_axis.xyzw()),
248 Vec3A::from_vec4(m.w_axis.xyzw()),
249 ),
250 (3, 0) => Self::from_cols(
251 Vec3A::from_vec4(m.x_axis.yzww()),
252 Vec3A::from_vec4(m.y_axis.yzww()),
253 Vec3A::from_vec4(m.z_axis.yzww()),
254 ),
255 (3, 1) => Self::from_cols(
256 Vec3A::from_vec4(m.x_axis.xzww()),
257 Vec3A::from_vec4(m.y_axis.xzww()),
258 Vec3A::from_vec4(m.z_axis.xzww()),
259 ),
260 (3, 2) => Self::from_cols(
261 Vec3A::from_vec4(m.x_axis.xyww()),
262 Vec3A::from_vec4(m.y_axis.xyww()),
263 Vec3A::from_vec4(m.z_axis.xyww()),
264 ),
265 (3, 3) => Self::from_cols(
266 Vec3A::from_vec4(m.x_axis.xyzw()),
267 Vec3A::from_vec4(m.y_axis.xyzw()),
268 Vec3A::from_vec4(m.z_axis.xyzw()),
269 ),
270 _ => panic!("index out of bounds"),
271 }
272 }
273
274 #[inline]
280 #[must_use]
281 pub fn from_quat(rotation: Quat) -> Self {
282 glam_assert!(rotation.is_normalized());
283
284 let x2 = rotation.x + rotation.x;
285 let y2 = rotation.y + rotation.y;
286 let z2 = rotation.z + rotation.z;
287 let xx = rotation.x * x2;
288 let xy = rotation.x * y2;
289 let xz = rotation.x * z2;
290 let yy = rotation.y * y2;
291 let yz = rotation.y * z2;
292 let zz = rotation.z * z2;
293 let wx = rotation.w * x2;
294 let wy = rotation.w * y2;
295 let wz = rotation.w * z2;
296
297 Self::from_cols(
298 Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
299 Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
300 Vec3A::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
301 )
302 }
303
304 #[inline]
311 #[must_use]
312 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
313 glam_assert!(axis.is_normalized());
314
315 let (sin, cos) = math::sin_cos(angle);
316 let (xsin, ysin, zsin) = axis.mul(sin).into();
317 let (x, y, z) = axis.into();
318 let (x2, y2, z2) = axis.mul(axis).into();
319 let omc = 1.0 - cos;
320 let xyomc = x * y * omc;
321 let xzomc = x * z * omc;
322 let yzomc = y * z * omc;
323 Self::from_cols(
324 Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
325 Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
326 Vec3A::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
327 )
328 }
329
330 #[inline]
333 #[must_use]
334 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
335 Self::from_euler_angles(order, a, b, c)
336 }
337
338 #[inline]
347 #[must_use]
348 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
349 glam_assert!(
350 self.x_axis.is_normalized()
351 && self.y_axis.is_normalized()
352 && self.z_axis.is_normalized()
353 );
354 self.to_euler_angles(order)
355 }
356
357 #[inline]
359 #[must_use]
360 pub fn from_rotation_x(angle: f32) -> Self {
361 let (sina, cosa) = math::sin_cos(angle);
362 Self::from_cols(
363 Vec3A::X,
364 Vec3A::new(0.0, cosa, sina),
365 Vec3A::new(0.0, -sina, cosa),
366 )
367 }
368
369 #[inline]
371 #[must_use]
372 pub fn from_rotation_y(angle: f32) -> Self {
373 let (sina, cosa) = math::sin_cos(angle);
374 Self::from_cols(
375 Vec3A::new(cosa, 0.0, -sina),
376 Vec3A::Y,
377 Vec3A::new(sina, 0.0, cosa),
378 )
379 }
380
381 #[inline]
383 #[must_use]
384 pub fn from_rotation_z(angle: f32) -> Self {
385 let (sina, cosa) = math::sin_cos(angle);
386 Self::from_cols(
387 Vec3A::new(cosa, sina, 0.0),
388 Vec3A::new(-sina, cosa, 0.0),
389 Vec3A::Z,
390 )
391 }
392
393 #[inline]
398 #[must_use]
399 pub fn from_translation(translation: Vec2) -> Self {
400 Self::from_cols(
401 Vec3A::X,
402 Vec3A::Y,
403 Vec3A::new(translation.x, translation.y, 1.0),
404 )
405 }
406
407 #[inline]
413 #[must_use]
414 pub fn from_angle(angle: f32) -> Self {
415 let (sin, cos) = math::sin_cos(angle);
416 Self::from_cols(
417 Vec3A::new(cos, sin, 0.0),
418 Vec3A::new(-sin, cos, 0.0),
419 Vec3A::Z,
420 )
421 }
422
423 #[inline]
429 #[must_use]
430 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
431 let (sin, cos) = math::sin_cos(angle);
432 Self::from_cols(
433 Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
434 Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
435 Vec3A::new(translation.x, translation.y, 1.0),
436 )
437 }
438
439 #[inline]
448 #[must_use]
449 pub fn from_scale(scale: Vec2) -> Self {
450 glam_assert!(scale.cmpne(Vec2::ZERO).any());
452
453 Self::from_cols(
454 Vec3A::new(scale.x, 0.0, 0.0),
455 Vec3A::new(0.0, scale.y, 0.0),
456 Vec3A::Z,
457 )
458 }
459
460 #[inline]
465 pub fn from_mat2(m: Mat2) -> Self {
466 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
467 }
468
469 #[inline]
475 #[must_use]
476 pub const fn from_cols_slice(slice: &[f32]) -> Self {
477 Self::new(
478 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
479 slice[8],
480 )
481 }
482
483 #[inline]
489 pub fn write_cols_to_slice(&self, slice: &mut [f32]) {
490 slice[0] = self.x_axis.x;
491 slice[1] = self.x_axis.y;
492 slice[2] = self.x_axis.z;
493 slice[3] = self.y_axis.x;
494 slice[4] = self.y_axis.y;
495 slice[5] = self.y_axis.z;
496 slice[6] = self.z_axis.x;
497 slice[7] = self.z_axis.y;
498 slice[8] = self.z_axis.z;
499 }
500
501 #[inline]
507 #[must_use]
508 pub fn col(&self, index: usize) -> Vec3A {
509 match index {
510 0 => self.x_axis,
511 1 => self.y_axis,
512 2 => self.z_axis,
513 _ => panic!("index out of bounds"),
514 }
515 }
516
517 #[inline]
523 pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
524 match index {
525 0 => &mut self.x_axis,
526 1 => &mut self.y_axis,
527 2 => &mut self.z_axis,
528 _ => panic!("index out of bounds"),
529 }
530 }
531
532 #[inline]
538 #[must_use]
539 pub fn row(&self, index: usize) -> Vec3A {
540 match index {
541 0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
542 1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
543 2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
544 _ => panic!("index out of bounds"),
545 }
546 }
547
548 #[inline]
551 #[must_use]
552 pub fn is_finite(&self) -> bool {
553 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
554 }
555
556 #[inline]
558 #[must_use]
559 pub fn is_nan(&self) -> bool {
560 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
561 }
562
563 #[inline]
565 #[must_use]
566 pub fn transpose(&self) -> Self {
567 unsafe {
568 let tmp0 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b01_00_01_00);
569 let tmp1 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b11_10_11_10);
570
571 Self {
572 x_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b00_00_10_00)),
573 y_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b01_01_11_01)),
574 z_axis: Vec3A(_mm_shuffle_ps(tmp1, self.z_axis.0, 0b10_10_10_00)),
575 }
576 }
577 }
578
579 #[inline]
581 #[must_use]
582 pub fn diagonal(&self) -> Vec3A {
583 Vec3A::new(self.x_axis.x, self.y_axis.y, self.z_axis.z)
584 }
585
586 #[inline]
588 #[must_use]
589 pub fn determinant(&self) -> f32 {
590 self.z_axis.dot(self.x_axis.cross(self.y_axis))
591 }
592
593 #[inline(always)]
605 #[must_use]
606 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
607 let tmp0 = self.y_axis.cross(self.z_axis);
608 let tmp1 = self.z_axis.cross(self.x_axis);
609 let tmp2 = self.x_axis.cross(self.y_axis);
610 let det = self.z_axis.dot(tmp2);
611 if CHECKED {
612 if det == 0.0 {
613 return (Self::ZERO, false);
614 }
615 } else {
616 glam_assert!(det != 0.0);
617 }
618 let inv_det = Vec3A::splat(det.recip());
619 (
620 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose(),
621 true,
622 )
623 }
624
625 #[inline]
633 #[must_use]
634 pub fn inverse(&self) -> Self {
635 self.inverse_checked::<false>().0
636 }
637
638 #[inline]
640 #[must_use]
641 pub fn try_inverse(&self) -> Option<Self> {
642 let (m, is_valid) = self.inverse_checked::<true>();
643 if is_valid {
644 Some(m)
645 } else {
646 None
647 }
648 }
649
650 #[inline]
652 #[must_use]
653 pub fn inverse_or_zero(&self) -> Self {
654 self.inverse_checked::<true>().0
655 }
656
657 #[inline]
667 #[must_use]
668 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
669 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
670 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
671 }
672
673 #[inline]
683 #[must_use]
684 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
685 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
686 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
687 }
688
689 #[inline]
697 #[must_use]
698 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
699 Self::look_to_rh(-dir, up)
700 }
701
702 #[inline]
710 #[must_use]
711 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
712 glam_assert!(dir.is_normalized());
713 glam_assert!(up.is_normalized());
714 let f = dir;
715 let s = f.cross(up).normalize();
716 let u = s.cross(f);
717
718 Self::from_cols(
719 Vec3A::new(s.x, u.x, -f.x),
720 Vec3A::new(s.y, u.y, -f.y),
721 Vec3A::new(s.z, u.z, -f.z),
722 )
723 }
724
725 #[inline]
734 #[must_use]
735 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
736 Self::look_to_lh(center.sub(eye).normalize(), up)
737 }
738
739 #[inline]
748 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
749 Self::look_to_rh(center.sub(eye).normalize(), up)
750 }
751
752 #[inline]
754 #[must_use]
755 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
756 self.mul_vec3a(rhs.into()).into()
757 }
758
759 #[inline]
761 #[must_use]
762 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
763 let mut res = self.x_axis.mul(rhs.xxx());
764 res = res.add(self.y_axis.mul(rhs.yyy()));
765 res = res.add(self.z_axis.mul(rhs.zzz()));
766 res
767 }
768
769 #[inline]
771 #[must_use]
772 pub fn mul_transpose_vec3(&self, rhs: Vec3) -> Vec3 {
773 self.mul_transpose_vec3a(rhs.into()).into()
774 }
775
776 #[inline]
778 #[must_use]
779 pub fn mul_transpose_vec3a(&self, rhs: Vec3A) -> Vec3A {
780 Vec3A::new(
781 self.x_axis.dot(rhs),
782 self.y_axis.dot(rhs),
783 self.z_axis.dot(rhs),
784 )
785 }
786
787 #[inline]
789 #[must_use]
790 pub fn mul_mat3(&self, rhs: &Self) -> Self {
791 self.mul(rhs)
792 }
793
794 #[inline]
796 #[must_use]
797 pub fn add_mat3(&self, rhs: &Self) -> Self {
798 self.add(rhs)
799 }
800
801 #[inline]
803 #[must_use]
804 pub fn sub_mat3(&self, rhs: &Self) -> Self {
805 self.sub(rhs)
806 }
807
808 #[inline]
810 #[must_use]
811 pub fn mul_scalar(&self, rhs: f32) -> Self {
812 Self::from_cols(
813 self.x_axis.mul(rhs),
814 self.y_axis.mul(rhs),
815 self.z_axis.mul(rhs),
816 )
817 }
818
819 #[inline]
823 #[must_use]
824 pub fn mul_diagonal_scale(&self, scale: Vec3) -> Self {
825 Self::from_cols(
826 self.x_axis * scale.x,
827 self.y_axis * scale.y,
828 self.z_axis * scale.z,
829 )
830 }
831
832 #[inline]
834 #[must_use]
835 pub fn div_scalar(&self, rhs: f32) -> Self {
836 let rhs = Vec3A::splat(rhs);
837 Self::from_cols(
838 self.x_axis.div(rhs),
839 self.y_axis.div(rhs),
840 self.z_axis.div(rhs),
841 )
842 }
843
844 #[inline]
846 #[must_use]
847 pub fn recip(&self) -> Self {
848 Self::from_cols(
849 self.x_axis.recip(),
850 self.y_axis.recip(),
851 self.z_axis.recip(),
852 )
853 }
854
855 #[inline]
865 #[must_use]
866 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
867 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
868 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
869 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
870 }
871
872 #[inline]
874 #[must_use]
875 pub fn abs(&self) -> Self {
876 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
877 }
878
879 #[cfg(feature = "f64")]
880 #[inline]
881 #[must_use]
882 pub fn as_dmat3(&self) -> DMat3 {
883 DMat3::from_cols(
884 self.x_axis.as_dvec3(),
885 self.y_axis.as_dvec3(),
886 self.z_axis.as_dvec3(),
887 )
888 }
889}
890
891impl Default for Mat3A {
892 #[inline]
893 fn default() -> Self {
894 Self::IDENTITY
895 }
896}
897
898impl Add for Mat3A {
899 type Output = Self;
900 #[inline]
901 fn add(self, rhs: Self) -> Self {
902 Self::from_cols(
903 self.x_axis.add(rhs.x_axis),
904 self.y_axis.add(rhs.y_axis),
905 self.z_axis.add(rhs.z_axis),
906 )
907 }
908}
909
910impl Add<&Self> for Mat3A {
911 type Output = Self;
912 #[inline]
913 fn add(self, rhs: &Self) -> Self {
914 self.add(*rhs)
915 }
916}
917
918impl Add<&Mat3A> for &Mat3A {
919 type Output = Mat3A;
920 #[inline]
921 fn add(self, rhs: &Mat3A) -> Mat3A {
922 (*self).add(*rhs)
923 }
924}
925
926impl Add<Mat3A> for &Mat3A {
927 type Output = Mat3A;
928 #[inline]
929 fn add(self, rhs: Mat3A) -> Mat3A {
930 (*self).add(rhs)
931 }
932}
933
934impl AddAssign for Mat3A {
935 #[inline]
936 fn add_assign(&mut self, rhs: Self) {
937 *self = self.add(rhs);
938 }
939}
940
941impl AddAssign<&Self> for Mat3A {
942 #[inline]
943 fn add_assign(&mut self, rhs: &Self) {
944 self.add_assign(*rhs);
945 }
946}
947
948impl Sub for Mat3A {
949 type Output = Self;
950 #[inline]
951 fn sub(self, rhs: Self) -> Self {
952 Self::from_cols(
953 self.x_axis.sub(rhs.x_axis),
954 self.y_axis.sub(rhs.y_axis),
955 self.z_axis.sub(rhs.z_axis),
956 )
957 }
958}
959
960impl Sub<&Self> for Mat3A {
961 type Output = Self;
962 #[inline]
963 fn sub(self, rhs: &Self) -> Self {
964 self.sub(*rhs)
965 }
966}
967
968impl Sub<&Mat3A> for &Mat3A {
969 type Output = Mat3A;
970 #[inline]
971 fn sub(self, rhs: &Mat3A) -> Mat3A {
972 (*self).sub(*rhs)
973 }
974}
975
976impl Sub<Mat3A> for &Mat3A {
977 type Output = Mat3A;
978 #[inline]
979 fn sub(self, rhs: Mat3A) -> Mat3A {
980 (*self).sub(rhs)
981 }
982}
983
984impl SubAssign for Mat3A {
985 #[inline]
986 fn sub_assign(&mut self, rhs: Self) {
987 *self = self.sub(rhs);
988 }
989}
990
991impl SubAssign<&Self> for Mat3A {
992 #[inline]
993 fn sub_assign(&mut self, rhs: &Self) {
994 self.sub_assign(*rhs);
995 }
996}
997
998impl Neg for Mat3A {
999 type Output = Self;
1000 #[inline]
1001 fn neg(self) -> Self::Output {
1002 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
1003 }
1004}
1005
1006impl Neg for &Mat3A {
1007 type Output = Mat3A;
1008 #[inline]
1009 fn neg(self) -> Mat3A {
1010 (*self).neg()
1011 }
1012}
1013
1014impl Mul for Mat3A {
1015 type Output = Self;
1016 #[inline]
1017 fn mul(self, rhs: Self) -> Self {
1018 Self::from_cols(
1019 self.mul(rhs.x_axis),
1020 self.mul(rhs.y_axis),
1021 self.mul(rhs.z_axis),
1022 )
1023 }
1024}
1025
1026impl Mul<&Self> for Mat3A {
1027 type Output = Self;
1028 #[inline]
1029 fn mul(self, rhs: &Self) -> Self {
1030 self.mul(*rhs)
1031 }
1032}
1033
1034impl Mul<&Mat3A> for &Mat3A {
1035 type Output = Mat3A;
1036 #[inline]
1037 fn mul(self, rhs: &Mat3A) -> Mat3A {
1038 (*self).mul(*rhs)
1039 }
1040}
1041
1042impl Mul<Mat3A> for &Mat3A {
1043 type Output = Mat3A;
1044 #[inline]
1045 fn mul(self, rhs: Mat3A) -> Mat3A {
1046 (*self).mul(rhs)
1047 }
1048}
1049
1050impl MulAssign for Mat3A {
1051 #[inline]
1052 fn mul_assign(&mut self, rhs: Self) {
1053 *self = self.mul(rhs);
1054 }
1055}
1056
1057impl MulAssign<&Self> for Mat3A {
1058 #[inline]
1059 fn mul_assign(&mut self, rhs: &Self) {
1060 self.mul_assign(*rhs);
1061 }
1062}
1063
1064impl Mul<Vec3A> for Mat3A {
1065 type Output = Vec3A;
1066 #[inline]
1067 fn mul(self, rhs: Vec3A) -> Self::Output {
1068 self.mul_vec3a(rhs)
1069 }
1070}
1071
1072impl Mul<&Vec3A> for Mat3A {
1073 type Output = Vec3A;
1074 #[inline]
1075 fn mul(self, rhs: &Vec3A) -> Vec3A {
1076 self.mul(*rhs)
1077 }
1078}
1079
1080impl Mul<&Vec3A> for &Mat3A {
1081 type Output = Vec3A;
1082 #[inline]
1083 fn mul(self, rhs: &Vec3A) -> Vec3A {
1084 (*self).mul(*rhs)
1085 }
1086}
1087
1088impl Mul<Vec3A> for &Mat3A {
1089 type Output = Vec3A;
1090 #[inline]
1091 fn mul(self, rhs: Vec3A) -> Vec3A {
1092 (*self).mul(rhs)
1093 }
1094}
1095
1096impl Mul<Mat3A> for f32 {
1097 type Output = Mat3A;
1098 #[inline]
1099 fn mul(self, rhs: Mat3A) -> Self::Output {
1100 rhs.mul_scalar(self)
1101 }
1102}
1103
1104impl Mul<&Mat3A> for f32 {
1105 type Output = Mat3A;
1106 #[inline]
1107 fn mul(self, rhs: &Mat3A) -> Mat3A {
1108 self.mul(*rhs)
1109 }
1110}
1111
1112impl Mul<&Mat3A> for &f32 {
1113 type Output = Mat3A;
1114 #[inline]
1115 fn mul(self, rhs: &Mat3A) -> Mat3A {
1116 (*self).mul(*rhs)
1117 }
1118}
1119
1120impl Mul<Mat3A> for &f32 {
1121 type Output = Mat3A;
1122 #[inline]
1123 fn mul(self, rhs: Mat3A) -> Mat3A {
1124 (*self).mul(rhs)
1125 }
1126}
1127
1128impl Mul<f32> for Mat3A {
1129 type Output = Self;
1130 #[inline]
1131 fn mul(self, rhs: f32) -> Self {
1132 self.mul_scalar(rhs)
1133 }
1134}
1135
1136impl Mul<&f32> for Mat3A {
1137 type Output = Self;
1138 #[inline]
1139 fn mul(self, rhs: &f32) -> Self {
1140 self.mul(*rhs)
1141 }
1142}
1143
1144impl Mul<&f32> for &Mat3A {
1145 type Output = Mat3A;
1146 #[inline]
1147 fn mul(self, rhs: &f32) -> Mat3A {
1148 (*self).mul(*rhs)
1149 }
1150}
1151
1152impl Mul<f32> for &Mat3A {
1153 type Output = Mat3A;
1154 #[inline]
1155 fn mul(self, rhs: f32) -> Mat3A {
1156 (*self).mul(rhs)
1157 }
1158}
1159
1160impl MulAssign<f32> for Mat3A {
1161 #[inline]
1162 fn mul_assign(&mut self, rhs: f32) {
1163 *self = self.mul(rhs);
1164 }
1165}
1166
1167impl MulAssign<&f32> for Mat3A {
1168 #[inline]
1169 fn mul_assign(&mut self, rhs: &f32) {
1170 self.mul_assign(*rhs);
1171 }
1172}
1173
1174impl Div<Mat3A> for f32 {
1175 type Output = Mat3A;
1176 #[inline]
1177 fn div(self, rhs: Mat3A) -> Self::Output {
1178 Mat3A::from_cols(
1179 self.div(rhs.x_axis),
1180 self.div(rhs.y_axis),
1181 self.div(rhs.z_axis),
1182 )
1183 }
1184}
1185
1186impl Div<&Mat3A> for f32 {
1187 type Output = Mat3A;
1188 #[inline]
1189 fn div(self, rhs: &Mat3A) -> Mat3A {
1190 self.div(*rhs)
1191 }
1192}
1193
1194impl Div<&Mat3A> for &f32 {
1195 type Output = Mat3A;
1196 #[inline]
1197 fn div(self, rhs: &Mat3A) -> Mat3A {
1198 (*self).div(*rhs)
1199 }
1200}
1201
1202impl Div<Mat3A> for &f32 {
1203 type Output = Mat3A;
1204 #[inline]
1205 fn div(self, rhs: Mat3A) -> Mat3A {
1206 (*self).div(rhs)
1207 }
1208}
1209
1210impl Div<f32> for Mat3A {
1211 type Output = Self;
1212 #[inline]
1213 fn div(self, rhs: f32) -> Self {
1214 self.div_scalar(rhs)
1215 }
1216}
1217
1218impl Div<&f32> for Mat3A {
1219 type Output = Self;
1220 #[inline]
1221 fn div(self, rhs: &f32) -> Self {
1222 self.div(*rhs)
1223 }
1224}
1225
1226impl Div<&f32> for &Mat3A {
1227 type Output = Mat3A;
1228 #[inline]
1229 fn div(self, rhs: &f32) -> Mat3A {
1230 (*self).div(*rhs)
1231 }
1232}
1233
1234impl Div<f32> for &Mat3A {
1235 type Output = Mat3A;
1236 #[inline]
1237 fn div(self, rhs: f32) -> Mat3A {
1238 (*self).div(rhs)
1239 }
1240}
1241
1242impl DivAssign<f32> for Mat3A {
1243 #[inline]
1244 fn div_assign(&mut self, rhs: f32) {
1245 *self = self.div(rhs);
1246 }
1247}
1248
1249impl DivAssign<&f32> for Mat3A {
1250 #[inline]
1251 fn div_assign(&mut self, rhs: &f32) {
1252 self.div_assign(*rhs);
1253 }
1254}
1255
1256impl Mul<Vec3> for Mat3A {
1257 type Output = Vec3;
1258 #[inline]
1259 fn mul(self, rhs: Vec3) -> Vec3 {
1260 self.mul_vec3a(rhs.into()).into()
1261 }
1262}
1263
1264impl Mul<&Vec3> for Mat3A {
1265 type Output = Vec3;
1266 #[inline]
1267 fn mul(self, rhs: &Vec3) -> Vec3 {
1268 self.mul(*rhs)
1269 }
1270}
1271
1272impl Mul<&Vec3> for &Mat3A {
1273 type Output = Vec3;
1274 #[inline]
1275 fn mul(self, rhs: &Vec3) -> Vec3 {
1276 (*self).mul(*rhs)
1277 }
1278}
1279
1280impl Mul<Vec3> for &Mat3A {
1281 type Output = Vec3;
1282 #[inline]
1283 fn mul(self, rhs: Vec3) -> Vec3 {
1284 (*self).mul(rhs)
1285 }
1286}
1287
1288impl From<Mat3> for Mat3A {
1289 #[inline]
1290 fn from(m: Mat3) -> Self {
1291 Self {
1292 x_axis: m.x_axis.into(),
1293 y_axis: m.y_axis.into(),
1294 z_axis: m.z_axis.into(),
1295 }
1296 }
1297}
1298
1299impl Sum<Self> for Mat3A {
1300 fn sum<I>(iter: I) -> Self
1301 where
1302 I: Iterator<Item = Self>,
1303 {
1304 iter.fold(Self::ZERO, Self::add)
1305 }
1306}
1307
1308impl<'a> Sum<&'a Self> for Mat3A {
1309 fn sum<I>(iter: I) -> Self
1310 where
1311 I: Iterator<Item = &'a Self>,
1312 {
1313 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1314 }
1315}
1316
1317impl Product for Mat3A {
1318 fn product<I>(iter: I) -> Self
1319 where
1320 I: Iterator<Item = Self>,
1321 {
1322 iter.fold(Self::IDENTITY, Self::mul)
1323 }
1324}
1325
1326impl<'a> Product<&'a Self> for Mat3A {
1327 fn product<I>(iter: I) -> Self
1328 where
1329 I: Iterator<Item = &'a Self>,
1330 {
1331 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1332 }
1333}
1334
1335impl PartialEq for Mat3A {
1336 #[inline]
1337 fn eq(&self, rhs: &Self) -> bool {
1338 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1339 }
1340}
1341
1342impl fmt::Debug for Mat3A {
1343 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1344 fmt.debug_struct(stringify!(Mat3A))
1345 .field("x_axis", &self.x_axis)
1346 .field("y_axis", &self.y_axis)
1347 .field("z_axis", &self.z_axis)
1348 .finish()
1349 }
1350}
1351
1352impl fmt::Display for Mat3A {
1353 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1354 if let Some(p) = f.precision() {
1355 write!(
1356 f,
1357 "[{:.*}, {:.*}, {:.*}]",
1358 p, self.x_axis, p, self.y_axis, p, self.z_axis
1359 )
1360 } else {
1361 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1362 }
1363 }
1364}