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
13#[cfg(target_arch = "x86")]
14use core::arch::x86::*;
15#[cfg(target_arch = "x86_64")]
16use core::arch::x86_64::*;
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#[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 unsafe {
558 let tmp0 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b01_00_01_00);
559 let tmp1 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b11_10_11_10);
560
561 Self {
562 x_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b00_00_10_00)),
563 y_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b01_01_11_01)),
564 z_axis: Vec3A(_mm_shuffle_ps(tmp1, self.z_axis.0, 0b10_10_10_00)),
565 }
566 }
567 }
568
569 #[inline]
571 #[must_use]
572 pub fn determinant(&self) -> f32 {
573 self.z_axis.dot(self.x_axis.cross(self.y_axis))
574 }
575
576 #[inline]
584 #[must_use]
585 pub fn inverse(&self) -> Self {
586 let tmp0 = self.y_axis.cross(self.z_axis);
587 let tmp1 = self.z_axis.cross(self.x_axis);
588 let tmp2 = self.x_axis.cross(self.y_axis);
589 let det = self.z_axis.dot(tmp2);
590 glam_assert!(det != 0.0);
591 let inv_det = Vec3A::splat(det.recip());
592 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
593 }
594
595 #[inline]
605 #[must_use]
606 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
607 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
608 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
609 }
610
611 #[inline]
621 #[must_use]
622 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
623 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
624 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
625 }
626
627 #[inline]
635 #[must_use]
636 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
637 Self::look_to_rh(-dir, up)
638 }
639
640 #[inline]
648 #[must_use]
649 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
650 glam_assert!(dir.is_normalized());
651 glam_assert!(up.is_normalized());
652 let f = dir;
653 let s = f.cross(up).normalize();
654 let u = s.cross(f);
655
656 Self::from_cols(
657 Vec3A::new(s.x, u.x, -f.x),
658 Vec3A::new(s.y, u.y, -f.y),
659 Vec3A::new(s.z, u.z, -f.z),
660 )
661 }
662
663 #[inline]
672 #[must_use]
673 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
674 Self::look_to_lh(center.sub(eye).normalize(), up)
675 }
676
677 #[inline]
686 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
687 Self::look_to_rh(center.sub(eye).normalize(), up)
688 }
689
690 #[inline]
692 #[must_use]
693 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
694 self.mul_vec3a(rhs.into()).into()
695 }
696
697 #[inline]
699 #[must_use]
700 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
701 let mut res = self.x_axis.mul(rhs.xxx());
702 res = res.add(self.y_axis.mul(rhs.yyy()));
703 res = res.add(self.z_axis.mul(rhs.zzz()));
704 res
705 }
706
707 #[inline]
709 #[must_use]
710 pub fn mul_mat3(&self, rhs: &Self) -> Self {
711 self.mul(rhs)
712 }
713
714 #[inline]
716 #[must_use]
717 pub fn add_mat3(&self, rhs: &Self) -> Self {
718 self.add(rhs)
719 }
720
721 #[inline]
723 #[must_use]
724 pub fn sub_mat3(&self, rhs: &Self) -> Self {
725 self.sub(rhs)
726 }
727
728 #[inline]
730 #[must_use]
731 pub fn mul_scalar(&self, rhs: f32) -> Self {
732 Self::from_cols(
733 self.x_axis.mul(rhs),
734 self.y_axis.mul(rhs),
735 self.z_axis.mul(rhs),
736 )
737 }
738
739 #[inline]
741 #[must_use]
742 pub fn div_scalar(&self, rhs: f32) -> Self {
743 let rhs = Vec3A::splat(rhs);
744 Self::from_cols(
745 self.x_axis.div(rhs),
746 self.y_axis.div(rhs),
747 self.z_axis.div(rhs),
748 )
749 }
750
751 #[inline]
761 #[must_use]
762 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
763 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
764 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
765 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
766 }
767
768 #[inline]
770 #[must_use]
771 pub fn abs(&self) -> Self {
772 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
773 }
774
775 #[inline]
776 pub fn as_dmat3(&self) -> DMat3 {
777 DMat3::from_cols(
778 self.x_axis.as_dvec3(),
779 self.y_axis.as_dvec3(),
780 self.z_axis.as_dvec3(),
781 )
782 }
783}
784
785impl Default for Mat3A {
786 #[inline]
787 fn default() -> Self {
788 Self::IDENTITY
789 }
790}
791
792impl Add for Mat3A {
793 type Output = Self;
794 #[inline]
795 fn add(self, rhs: Self) -> Self {
796 Self::from_cols(
797 self.x_axis.add(rhs.x_axis),
798 self.y_axis.add(rhs.y_axis),
799 self.z_axis.add(rhs.z_axis),
800 )
801 }
802}
803
804impl Add<&Self> for Mat3A {
805 type Output = Self;
806 #[inline]
807 fn add(self, rhs: &Self) -> Self {
808 self.add(*rhs)
809 }
810}
811
812impl Add<&Mat3A> for &Mat3A {
813 type Output = Mat3A;
814 #[inline]
815 fn add(self, rhs: &Mat3A) -> Mat3A {
816 (*self).add(*rhs)
817 }
818}
819
820impl Add<Mat3A> for &Mat3A {
821 type Output = Mat3A;
822 #[inline]
823 fn add(self, rhs: Mat3A) -> Mat3A {
824 (*self).add(rhs)
825 }
826}
827
828impl AddAssign for Mat3A {
829 #[inline]
830 fn add_assign(&mut self, rhs: Self) {
831 *self = self.add(rhs);
832 }
833}
834
835impl AddAssign<&Self> for Mat3A {
836 #[inline]
837 fn add_assign(&mut self, rhs: &Self) {
838 self.add_assign(*rhs);
839 }
840}
841
842impl Sub for Mat3A {
843 type Output = Self;
844 #[inline]
845 fn sub(self, rhs: Self) -> Self {
846 Self::from_cols(
847 self.x_axis.sub(rhs.x_axis),
848 self.y_axis.sub(rhs.y_axis),
849 self.z_axis.sub(rhs.z_axis),
850 )
851 }
852}
853
854impl Sub<&Self> for Mat3A {
855 type Output = Self;
856 #[inline]
857 fn sub(self, rhs: &Self) -> Self {
858 self.sub(*rhs)
859 }
860}
861
862impl Sub<&Mat3A> for &Mat3A {
863 type Output = Mat3A;
864 #[inline]
865 fn sub(self, rhs: &Mat3A) -> Mat3A {
866 (*self).sub(*rhs)
867 }
868}
869
870impl Sub<Mat3A> for &Mat3A {
871 type Output = Mat3A;
872 #[inline]
873 fn sub(self, rhs: Mat3A) -> Mat3A {
874 (*self).sub(rhs)
875 }
876}
877
878impl SubAssign for Mat3A {
879 #[inline]
880 fn sub_assign(&mut self, rhs: Self) {
881 *self = self.sub(rhs);
882 }
883}
884
885impl SubAssign<&Self> for Mat3A {
886 #[inline]
887 fn sub_assign(&mut self, rhs: &Self) {
888 self.sub_assign(*rhs);
889 }
890}
891
892impl Neg for Mat3A {
893 type Output = Self;
894 #[inline]
895 fn neg(self) -> Self::Output {
896 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
897 }
898}
899
900impl Neg for &Mat3A {
901 type Output = Mat3A;
902 #[inline]
903 fn neg(self) -> Mat3A {
904 (*self).neg()
905 }
906}
907
908impl Mul for Mat3A {
909 type Output = Self;
910 #[inline]
911 fn mul(self, rhs: Self) -> Self {
912 Self::from_cols(
913 self.mul(rhs.x_axis),
914 self.mul(rhs.y_axis),
915 self.mul(rhs.z_axis),
916 )
917 }
918}
919
920impl Mul<&Self> for Mat3A {
921 type Output = Self;
922 #[inline]
923 fn mul(self, rhs: &Self) -> Self {
924 self.mul(*rhs)
925 }
926}
927
928impl Mul<&Mat3A> for &Mat3A {
929 type Output = Mat3A;
930 #[inline]
931 fn mul(self, rhs: &Mat3A) -> Mat3A {
932 (*self).mul(*rhs)
933 }
934}
935
936impl Mul<Mat3A> for &Mat3A {
937 type Output = Mat3A;
938 #[inline]
939 fn mul(self, rhs: Mat3A) -> Mat3A {
940 (*self).mul(rhs)
941 }
942}
943
944impl MulAssign for Mat3A {
945 #[inline]
946 fn mul_assign(&mut self, rhs: Self) {
947 *self = self.mul(rhs);
948 }
949}
950
951impl MulAssign<&Self> for Mat3A {
952 #[inline]
953 fn mul_assign(&mut self, rhs: &Self) {
954 self.mul_assign(*rhs);
955 }
956}
957
958impl Mul<Vec3A> for Mat3A {
959 type Output = Vec3A;
960 #[inline]
961 fn mul(self, rhs: Vec3A) -> Self::Output {
962 self.mul_vec3a(rhs)
963 }
964}
965
966impl Mul<&Vec3A> for Mat3A {
967 type Output = Vec3A;
968 #[inline]
969 fn mul(self, rhs: &Vec3A) -> Vec3A {
970 self.mul(*rhs)
971 }
972}
973
974impl Mul<&Vec3A> for &Mat3A {
975 type Output = Vec3A;
976 #[inline]
977 fn mul(self, rhs: &Vec3A) -> Vec3A {
978 (*self).mul(*rhs)
979 }
980}
981
982impl Mul<Vec3A> for &Mat3A {
983 type Output = Vec3A;
984 #[inline]
985 fn mul(self, rhs: Vec3A) -> Vec3A {
986 (*self).mul(rhs)
987 }
988}
989
990impl Mul<Mat3A> for f32 {
991 type Output = Mat3A;
992 #[inline]
993 fn mul(self, rhs: Mat3A) -> Self::Output {
994 rhs.mul_scalar(self)
995 }
996}
997
998impl Mul<&Mat3A> for f32 {
999 type Output = Mat3A;
1000 #[inline]
1001 fn mul(self, rhs: &Mat3A) -> Mat3A {
1002 self.mul(*rhs)
1003 }
1004}
1005
1006impl Mul<&Mat3A> for &f32 {
1007 type Output = Mat3A;
1008 #[inline]
1009 fn mul(self, rhs: &Mat3A) -> Mat3A {
1010 (*self).mul(*rhs)
1011 }
1012}
1013
1014impl Mul<Mat3A> for &f32 {
1015 type Output = Mat3A;
1016 #[inline]
1017 fn mul(self, rhs: Mat3A) -> Mat3A {
1018 (*self).mul(rhs)
1019 }
1020}
1021
1022impl Mul<f32> for Mat3A {
1023 type Output = Self;
1024 #[inline]
1025 fn mul(self, rhs: f32) -> Self {
1026 self.mul_scalar(rhs)
1027 }
1028}
1029
1030impl Mul<&f32> for Mat3A {
1031 type Output = Self;
1032 #[inline]
1033 fn mul(self, rhs: &f32) -> Self {
1034 self.mul(*rhs)
1035 }
1036}
1037
1038impl Mul<&f32> for &Mat3A {
1039 type Output = Mat3A;
1040 #[inline]
1041 fn mul(self, rhs: &f32) -> Mat3A {
1042 (*self).mul(*rhs)
1043 }
1044}
1045
1046impl Mul<f32> for &Mat3A {
1047 type Output = Mat3A;
1048 #[inline]
1049 fn mul(self, rhs: f32) -> Mat3A {
1050 (*self).mul(rhs)
1051 }
1052}
1053
1054impl MulAssign<f32> for Mat3A {
1055 #[inline]
1056 fn mul_assign(&mut self, rhs: f32) {
1057 *self = self.mul(rhs);
1058 }
1059}
1060
1061impl MulAssign<&f32> for Mat3A {
1062 #[inline]
1063 fn mul_assign(&mut self, rhs: &f32) {
1064 self.mul_assign(*rhs);
1065 }
1066}
1067
1068impl Div<Mat3A> for f32 {
1069 type Output = Mat3A;
1070 #[inline]
1071 fn div(self, rhs: Mat3A) -> Self::Output {
1072 rhs.div_scalar(self)
1073 }
1074}
1075
1076impl Div<&Mat3A> for f32 {
1077 type Output = Mat3A;
1078 #[inline]
1079 fn div(self, rhs: &Mat3A) -> Mat3A {
1080 self.div(*rhs)
1081 }
1082}
1083
1084impl Div<&Mat3A> for &f32 {
1085 type Output = Mat3A;
1086 #[inline]
1087 fn div(self, rhs: &Mat3A) -> Mat3A {
1088 (*self).div(*rhs)
1089 }
1090}
1091
1092impl Div<Mat3A> for &f32 {
1093 type Output = Mat3A;
1094 #[inline]
1095 fn div(self, rhs: Mat3A) -> Mat3A {
1096 (*self).div(rhs)
1097 }
1098}
1099
1100impl Div<f32> for Mat3A {
1101 type Output = Self;
1102 #[inline]
1103 fn div(self, rhs: f32) -> Self {
1104 self.div_scalar(rhs)
1105 }
1106}
1107
1108impl Div<&f32> for Mat3A {
1109 type Output = Self;
1110 #[inline]
1111 fn div(self, rhs: &f32) -> Self {
1112 self.div(*rhs)
1113 }
1114}
1115
1116impl Div<&f32> for &Mat3A {
1117 type Output = Mat3A;
1118 #[inline]
1119 fn div(self, rhs: &f32) -> Mat3A {
1120 (*self).div(*rhs)
1121 }
1122}
1123
1124impl Div<f32> for &Mat3A {
1125 type Output = Mat3A;
1126 #[inline]
1127 fn div(self, rhs: f32) -> Mat3A {
1128 (*self).div(rhs)
1129 }
1130}
1131
1132impl DivAssign<f32> for Mat3A {
1133 #[inline]
1134 fn div_assign(&mut self, rhs: f32) {
1135 *self = self.div(rhs);
1136 }
1137}
1138
1139impl DivAssign<&f32> for Mat3A {
1140 #[inline]
1141 fn div_assign(&mut self, rhs: &f32) {
1142 self.div_assign(*rhs);
1143 }
1144}
1145
1146impl Mul<Vec3> for Mat3A {
1147 type Output = Vec3;
1148 #[inline]
1149 fn mul(self, rhs: Vec3) -> Vec3 {
1150 self.mul_vec3a(rhs.into()).into()
1151 }
1152}
1153
1154impl Mul<&Vec3> for Mat3A {
1155 type Output = Vec3;
1156 #[inline]
1157 fn mul(self, rhs: &Vec3) -> Vec3 {
1158 self.mul(*rhs)
1159 }
1160}
1161
1162impl Mul<&Vec3> for &Mat3A {
1163 type Output = Vec3;
1164 #[inline]
1165 fn mul(self, rhs: &Vec3) -> Vec3 {
1166 (*self).mul(*rhs)
1167 }
1168}
1169
1170impl Mul<Vec3> for &Mat3A {
1171 type Output = Vec3;
1172 #[inline]
1173 fn mul(self, rhs: Vec3) -> Vec3 {
1174 (*self).mul(rhs)
1175 }
1176}
1177
1178impl From<Mat3> for Mat3A {
1179 #[inline]
1180 fn from(m: Mat3) -> Self {
1181 Self {
1182 x_axis: m.x_axis.into(),
1183 y_axis: m.y_axis.into(),
1184 z_axis: m.z_axis.into(),
1185 }
1186 }
1187}
1188
1189impl Sum<Self> for Mat3A {
1190 fn sum<I>(iter: I) -> Self
1191 where
1192 I: Iterator<Item = Self>,
1193 {
1194 iter.fold(Self::ZERO, Self::add)
1195 }
1196}
1197
1198impl<'a> Sum<&'a Self> for Mat3A {
1199 fn sum<I>(iter: I) -> Self
1200 where
1201 I: Iterator<Item = &'a Self>,
1202 {
1203 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1204 }
1205}
1206
1207impl Product for Mat3A {
1208 fn product<I>(iter: I) -> Self
1209 where
1210 I: Iterator<Item = Self>,
1211 {
1212 iter.fold(Self::IDENTITY, Self::mul)
1213 }
1214}
1215
1216impl<'a> Product<&'a Self> for Mat3A {
1217 fn product<I>(iter: I) -> Self
1218 where
1219 I: Iterator<Item = &'a Self>,
1220 {
1221 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1222 }
1223}
1224
1225impl PartialEq for Mat3A {
1226 #[inline]
1227 fn eq(&self, rhs: &Self) -> bool {
1228 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1229 }
1230}
1231
1232impl fmt::Debug for Mat3A {
1233 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1234 fmt.debug_struct(stringify!(Mat3A))
1235 .field("x_axis", &self.x_axis)
1236 .field("y_axis", &self.y_axis)
1237 .field("z_axis", &self.z_axis)
1238 .finish()
1239 }
1240}
1241
1242impl fmt::Display for Mat3A {
1243 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1244 if let Some(p) = f.precision() {
1245 write!(
1246 f,
1247 "[{:.*}, {:.*}, {:.*}]",
1248 p, self.x_axis, p, self.y_axis, p, self.z_axis
1249 )
1250 } else {
1251 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1252 }
1253 }
1254}