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#[repr(C)]
51pub struct Mat3A {
52 pub x_axis: Vec3A,
53 pub y_axis: Vec3A,
54 pub z_axis: Vec3A,
55}
56
57impl Mat3A {
58 pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
60
61 pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
63
64 pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::NAN);
66
67 #[allow(clippy::too_many_arguments)]
68 #[inline(always)]
69 #[must_use]
70 const fn new(
71 m00: f32,
72 m01: f32,
73 m02: f32,
74 m10: f32,
75 m11: f32,
76 m12: f32,
77 m20: f32,
78 m21: f32,
79 m22: f32,
80 ) -> Self {
81 Self {
82 x_axis: Vec3A::new(m00, m01, m02),
83 y_axis: Vec3A::new(m10, m11, m12),
84 z_axis: Vec3A::new(m20, m21, m22),
85 }
86 }
87
88 #[inline(always)]
90 #[must_use]
91 pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self {
92 Self {
93 x_axis,
94 y_axis,
95 z_axis,
96 }
97 }
98
99 #[inline]
103 #[must_use]
104 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
105 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
106 }
107
108 #[inline]
111 #[must_use]
112 pub const fn to_cols_array(&self) -> [f32; 9] {
113 let [x_axis_x, x_axis_y, x_axis_z] = self.x_axis.to_array();
114 let [y_axis_x, y_axis_y, y_axis_z] = self.y_axis.to_array();
115 let [z_axis_x, z_axis_y, z_axis_z] = self.z_axis.to_array();
116
117 [
118 x_axis_x, x_axis_y, x_axis_z, y_axis_x, y_axis_y, y_axis_z, z_axis_x, z_axis_y,
119 z_axis_z,
120 ]
121 }
122
123 #[inline]
127 #[must_use]
128 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
129 Self::from_cols(
130 Vec3A::from_array(m[0]),
131 Vec3A::from_array(m[1]),
132 Vec3A::from_array(m[2]),
133 )
134 }
135
136 #[inline]
139 #[must_use]
140 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
141 [
142 self.x_axis.to_array(),
143 self.y_axis.to_array(),
144 self.z_axis.to_array(),
145 ]
146 }
147
148 #[doc(alias = "scale")]
150 #[inline]
151 #[must_use]
152 pub const fn from_diagonal(diagonal: Vec3) -> Self {
153 Self::new(
154 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
155 )
156 }
157
158 #[inline]
160 #[must_use]
161 pub fn from_mat4(m: Mat4) -> Self {
162 Self::from_cols(
163 Vec3A::from_vec4(m.x_axis),
164 Vec3A::from_vec4(m.y_axis),
165 Vec3A::from_vec4(m.z_axis),
166 )
167 }
168
169 #[inline]
176 #[must_use]
177 pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
178 match (i, j) {
179 (0, 0) => Self::from_cols(
180 Vec3A::from_vec4(m.y_axis.yzww()),
181 Vec3A::from_vec4(m.z_axis.yzww()),
182 Vec3A::from_vec4(m.w_axis.yzww()),
183 ),
184 (0, 1) => Self::from_cols(
185 Vec3A::from_vec4(m.y_axis.xzww()),
186 Vec3A::from_vec4(m.z_axis.xzww()),
187 Vec3A::from_vec4(m.w_axis.xzww()),
188 ),
189 (0, 2) => Self::from_cols(
190 Vec3A::from_vec4(m.y_axis.xyww()),
191 Vec3A::from_vec4(m.z_axis.xyww()),
192 Vec3A::from_vec4(m.w_axis.xyww()),
193 ),
194 (0, 3) => Self::from_cols(
195 Vec3A::from_vec4(m.y_axis.xyzw()),
196 Vec3A::from_vec4(m.z_axis.xyzw()),
197 Vec3A::from_vec4(m.w_axis.xyzw()),
198 ),
199 (1, 0) => Self::from_cols(
200 Vec3A::from_vec4(m.x_axis.yzww()),
201 Vec3A::from_vec4(m.z_axis.yzww()),
202 Vec3A::from_vec4(m.w_axis.yzww()),
203 ),
204 (1, 1) => Self::from_cols(
205 Vec3A::from_vec4(m.x_axis.xzww()),
206 Vec3A::from_vec4(m.z_axis.xzww()),
207 Vec3A::from_vec4(m.w_axis.xzww()),
208 ),
209 (1, 2) => Self::from_cols(
210 Vec3A::from_vec4(m.x_axis.xyww()),
211 Vec3A::from_vec4(m.z_axis.xyww()),
212 Vec3A::from_vec4(m.w_axis.xyww()),
213 ),
214 (1, 3) => Self::from_cols(
215 Vec3A::from_vec4(m.x_axis.xyzw()),
216 Vec3A::from_vec4(m.z_axis.xyzw()),
217 Vec3A::from_vec4(m.w_axis.xyzw()),
218 ),
219 (2, 0) => Self::from_cols(
220 Vec3A::from_vec4(m.x_axis.yzww()),
221 Vec3A::from_vec4(m.y_axis.yzww()),
222 Vec3A::from_vec4(m.w_axis.yzww()),
223 ),
224 (2, 1) => Self::from_cols(
225 Vec3A::from_vec4(m.x_axis.xzww()),
226 Vec3A::from_vec4(m.y_axis.xzww()),
227 Vec3A::from_vec4(m.w_axis.xzww()),
228 ),
229 (2, 2) => Self::from_cols(
230 Vec3A::from_vec4(m.x_axis.xyww()),
231 Vec3A::from_vec4(m.y_axis.xyww()),
232 Vec3A::from_vec4(m.w_axis.xyww()),
233 ),
234 (2, 3) => Self::from_cols(
235 Vec3A::from_vec4(m.x_axis.xyzw()),
236 Vec3A::from_vec4(m.y_axis.xyzw()),
237 Vec3A::from_vec4(m.w_axis.xyzw()),
238 ),
239 (3, 0) => Self::from_cols(
240 Vec3A::from_vec4(m.x_axis.yzww()),
241 Vec3A::from_vec4(m.y_axis.yzww()),
242 Vec3A::from_vec4(m.z_axis.yzww()),
243 ),
244 (3, 1) => Self::from_cols(
245 Vec3A::from_vec4(m.x_axis.xzww()),
246 Vec3A::from_vec4(m.y_axis.xzww()),
247 Vec3A::from_vec4(m.z_axis.xzww()),
248 ),
249 (3, 2) => Self::from_cols(
250 Vec3A::from_vec4(m.x_axis.xyww()),
251 Vec3A::from_vec4(m.y_axis.xyww()),
252 Vec3A::from_vec4(m.z_axis.xyww()),
253 ),
254 (3, 3) => Self::from_cols(
255 Vec3A::from_vec4(m.x_axis.xyzw()),
256 Vec3A::from_vec4(m.y_axis.xyzw()),
257 Vec3A::from_vec4(m.z_axis.xyzw()),
258 ),
259 _ => panic!("index out of bounds"),
260 }
261 }
262
263 #[inline]
269 #[must_use]
270 pub fn from_quat(rotation: Quat) -> Self {
271 glam_assert!(rotation.is_normalized());
272
273 let x2 = rotation.x + rotation.x;
274 let y2 = rotation.y + rotation.y;
275 let z2 = rotation.z + rotation.z;
276 let xx = rotation.x * x2;
277 let xy = rotation.x * y2;
278 let xz = rotation.x * z2;
279 let yy = rotation.y * y2;
280 let yz = rotation.y * z2;
281 let zz = rotation.z * z2;
282 let wx = rotation.w * x2;
283 let wy = rotation.w * y2;
284 let wz = rotation.w * z2;
285
286 Self::from_cols(
287 Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
288 Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
289 Vec3A::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
290 )
291 }
292
293 #[inline]
300 #[must_use]
301 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
302 glam_assert!(axis.is_normalized());
303
304 let (sin, cos) = math::sin_cos(angle);
305 let (xsin, ysin, zsin) = axis.mul(sin).into();
306 let (x, y, z) = axis.into();
307 let (x2, y2, z2) = axis.mul(axis).into();
308 let omc = 1.0 - cos;
309 let xyomc = x * y * omc;
310 let xzomc = x * z * omc;
311 let yzomc = y * z * omc;
312 Self::from_cols(
313 Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
314 Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
315 Vec3A::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
316 )
317 }
318
319 #[inline]
322 #[must_use]
323 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
324 Self::from_euler_angles(order, a, b, c)
325 }
326
327 #[inline]
336 #[must_use]
337 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
338 glam_assert!(
339 self.x_axis.is_normalized()
340 && self.y_axis.is_normalized()
341 && self.z_axis.is_normalized()
342 );
343 self.to_euler_angles(order)
344 }
345
346 #[inline]
348 #[must_use]
349 pub fn from_rotation_x(angle: f32) -> Self {
350 let (sina, cosa) = math::sin_cos(angle);
351 Self::from_cols(
352 Vec3A::X,
353 Vec3A::new(0.0, cosa, sina),
354 Vec3A::new(0.0, -sina, cosa),
355 )
356 }
357
358 #[inline]
360 #[must_use]
361 pub fn from_rotation_y(angle: f32) -> Self {
362 let (sina, cosa) = math::sin_cos(angle);
363 Self::from_cols(
364 Vec3A::new(cosa, 0.0, -sina),
365 Vec3A::Y,
366 Vec3A::new(sina, 0.0, cosa),
367 )
368 }
369
370 #[inline]
372 #[must_use]
373 pub fn from_rotation_z(angle: f32) -> Self {
374 let (sina, cosa) = math::sin_cos(angle);
375 Self::from_cols(
376 Vec3A::new(cosa, sina, 0.0),
377 Vec3A::new(-sina, cosa, 0.0),
378 Vec3A::Z,
379 )
380 }
381
382 #[inline]
387 #[must_use]
388 pub fn from_translation(translation: Vec2) -> Self {
389 Self::from_cols(
390 Vec3A::X,
391 Vec3A::Y,
392 Vec3A::new(translation.x, translation.y, 1.0),
393 )
394 }
395
396 #[inline]
402 #[must_use]
403 pub fn from_angle(angle: f32) -> Self {
404 let (sin, cos) = math::sin_cos(angle);
405 Self::from_cols(
406 Vec3A::new(cos, sin, 0.0),
407 Vec3A::new(-sin, cos, 0.0),
408 Vec3A::Z,
409 )
410 }
411
412 #[inline]
418 #[must_use]
419 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
420 let (sin, cos) = math::sin_cos(angle);
421 Self::from_cols(
422 Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
423 Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
424 Vec3A::new(translation.x, translation.y, 1.0),
425 )
426 }
427
428 #[inline]
437 #[must_use]
438 pub fn from_scale(scale: Vec2) -> Self {
439 glam_assert!(scale.cmpne(Vec2::ZERO).any());
441
442 Self::from_cols(
443 Vec3A::new(scale.x, 0.0, 0.0),
444 Vec3A::new(0.0, scale.y, 0.0),
445 Vec3A::Z,
446 )
447 }
448
449 #[inline]
454 pub fn from_mat2(m: Mat2) -> Self {
455 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
456 }
457
458 #[inline]
464 #[must_use]
465 pub const fn from_cols_slice(slice: &[f32]) -> Self {
466 Self::new(
467 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
468 slice[8],
469 )
470 }
471
472 #[inline]
478 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
479 slice[0] = self.x_axis.x;
480 slice[1] = self.x_axis.y;
481 slice[2] = self.x_axis.z;
482 slice[3] = self.y_axis.x;
483 slice[4] = self.y_axis.y;
484 slice[5] = self.y_axis.z;
485 slice[6] = self.z_axis.x;
486 slice[7] = self.z_axis.y;
487 slice[8] = self.z_axis.z;
488 }
489
490 #[inline]
496 #[must_use]
497 pub fn col(&self, index: usize) -> Vec3A {
498 match index {
499 0 => self.x_axis,
500 1 => self.y_axis,
501 2 => self.z_axis,
502 _ => panic!("index out of bounds"),
503 }
504 }
505
506 #[inline]
512 pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
513 match index {
514 0 => &mut self.x_axis,
515 1 => &mut self.y_axis,
516 2 => &mut self.z_axis,
517 _ => panic!("index out of bounds"),
518 }
519 }
520
521 #[inline]
527 #[must_use]
528 pub fn row(&self, index: usize) -> Vec3A {
529 match index {
530 0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
531 1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
532 2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
533 _ => panic!("index out of bounds"),
534 }
535 }
536
537 #[inline]
540 #[must_use]
541 pub fn is_finite(&self) -> bool {
542 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
543 }
544
545 #[inline]
547 #[must_use]
548 pub fn is_nan(&self) -> bool {
549 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
550 }
551
552 #[inline]
554 #[must_use]
555 pub fn transpose(&self) -> Self {
556 unsafe {
557 let tmp0 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b01_00_01_00);
558 let tmp1 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b11_10_11_10);
559
560 Self {
561 x_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b00_00_10_00)),
562 y_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b01_01_11_01)),
563 z_axis: Vec3A(_mm_shuffle_ps(tmp1, self.z_axis.0, 0b10_10_10_00)),
564 }
565 }
566 }
567
568 #[inline]
570 #[must_use]
571 pub fn determinant(&self) -> f32 {
572 self.z_axis.dot(self.x_axis.cross(self.y_axis))
573 }
574
575 #[inline]
583 #[must_use]
584 pub fn inverse(&self) -> Self {
585 let tmp0 = self.y_axis.cross(self.z_axis);
586 let tmp1 = self.z_axis.cross(self.x_axis);
587 let tmp2 = self.x_axis.cross(self.y_axis);
588 let det = self.z_axis.dot(tmp2);
589 glam_assert!(det != 0.0);
590 let inv_det = Vec3A::splat(det.recip());
591 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
592 }
593
594 #[inline]
604 #[must_use]
605 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
606 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
607 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
608 }
609
610 #[inline]
620 #[must_use]
621 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
622 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
623 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
624 }
625
626 #[inline]
634 #[must_use]
635 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
636 Self::look_to_rh(-dir, up)
637 }
638
639 #[inline]
647 #[must_use]
648 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
649 glam_assert!(dir.is_normalized());
650 glam_assert!(up.is_normalized());
651 let f = dir;
652 let s = f.cross(up).normalize();
653 let u = s.cross(f);
654
655 Self::from_cols(
656 Vec3A::new(s.x, u.x, -f.x),
657 Vec3A::new(s.y, u.y, -f.y),
658 Vec3A::new(s.z, u.z, -f.z),
659 )
660 }
661
662 #[inline]
671 #[must_use]
672 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
673 Self::look_to_lh(center.sub(eye).normalize(), up)
674 }
675
676 #[inline]
685 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
686 Self::look_to_rh(center.sub(eye).normalize(), up)
687 }
688
689 #[inline]
691 #[must_use]
692 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
693 self.mul_vec3a(rhs.into()).into()
694 }
695
696 #[inline]
698 #[must_use]
699 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
700 let mut res = self.x_axis.mul(rhs.xxx());
701 res = res.add(self.y_axis.mul(rhs.yyy()));
702 res = res.add(self.z_axis.mul(rhs.zzz()));
703 res
704 }
705
706 #[inline]
708 #[must_use]
709 pub fn mul_mat3(&self, rhs: &Self) -> Self {
710 Self::from_cols(
711 self.mul(rhs.x_axis),
712 self.mul(rhs.y_axis),
713 self.mul(rhs.z_axis),
714 )
715 }
716
717 #[inline]
719 #[must_use]
720 pub fn add_mat3(&self, rhs: &Self) -> Self {
721 Self::from_cols(
722 self.x_axis.add(rhs.x_axis),
723 self.y_axis.add(rhs.y_axis),
724 self.z_axis.add(rhs.z_axis),
725 )
726 }
727
728 #[inline]
730 #[must_use]
731 pub fn sub_mat3(&self, rhs: &Self) -> Self {
732 Self::from_cols(
733 self.x_axis.sub(rhs.x_axis),
734 self.y_axis.sub(rhs.y_axis),
735 self.z_axis.sub(rhs.z_axis),
736 )
737 }
738
739 #[inline]
741 #[must_use]
742 pub fn mul_scalar(&self, rhs: f32) -> Self {
743 Self::from_cols(
744 self.x_axis.mul(rhs),
745 self.y_axis.mul(rhs),
746 self.z_axis.mul(rhs),
747 )
748 }
749
750 #[inline]
752 #[must_use]
753 pub fn div_scalar(&self, rhs: f32) -> Self {
754 let rhs = Vec3A::splat(rhs);
755 Self::from_cols(
756 self.x_axis.div(rhs),
757 self.y_axis.div(rhs),
758 self.z_axis.div(rhs),
759 )
760 }
761
762 #[inline]
772 #[must_use]
773 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
774 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
775 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
776 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
777 }
778
779 #[inline]
781 #[must_use]
782 pub fn abs(&self) -> Self {
783 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
784 }
785
786 #[inline]
787 pub fn as_dmat3(&self) -> DMat3 {
788 DMat3::from_cols(
789 self.x_axis.as_dvec3(),
790 self.y_axis.as_dvec3(),
791 self.z_axis.as_dvec3(),
792 )
793 }
794}
795
796impl Default for Mat3A {
797 #[inline]
798 fn default() -> Self {
799 Self::IDENTITY
800 }
801}
802
803impl Add<Mat3A> for Mat3A {
804 type Output = Self;
805 #[inline]
806 fn add(self, rhs: Self) -> Self::Output {
807 self.add_mat3(&rhs)
808 }
809}
810
811impl AddAssign<Mat3A> for Mat3A {
812 #[inline]
813 fn add_assign(&mut self, rhs: Self) {
814 *self = self.add_mat3(&rhs);
815 }
816}
817
818impl Sub<Mat3A> for Mat3A {
819 type Output = Self;
820 #[inline]
821 fn sub(self, rhs: Self) -> Self::Output {
822 self.sub_mat3(&rhs)
823 }
824}
825
826impl SubAssign<Mat3A> for Mat3A {
827 #[inline]
828 fn sub_assign(&mut self, rhs: Self) {
829 *self = self.sub_mat3(&rhs);
830 }
831}
832
833impl Neg for Mat3A {
834 type Output = Self;
835 #[inline]
836 fn neg(self) -> Self::Output {
837 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
838 }
839}
840
841impl Mul<Mat3A> for Mat3A {
842 type Output = Self;
843 #[inline]
844 fn mul(self, rhs: Self) -> Self::Output {
845 self.mul_mat3(&rhs)
846 }
847}
848
849impl MulAssign<Mat3A> for Mat3A {
850 #[inline]
851 fn mul_assign(&mut self, rhs: Self) {
852 *self = self.mul_mat3(&rhs);
853 }
854}
855
856impl Mul<Vec3A> for Mat3A {
857 type Output = Vec3A;
858 #[inline]
859 fn mul(self, rhs: Vec3A) -> Self::Output {
860 self.mul_vec3a(rhs)
861 }
862}
863
864impl Mul<Mat3A> for f32 {
865 type Output = Mat3A;
866 #[inline]
867 fn mul(self, rhs: Mat3A) -> Self::Output {
868 rhs.mul_scalar(self)
869 }
870}
871
872impl Mul<f32> for Mat3A {
873 type Output = Self;
874 #[inline]
875 fn mul(self, rhs: f32) -> Self::Output {
876 self.mul_scalar(rhs)
877 }
878}
879
880impl MulAssign<f32> for Mat3A {
881 #[inline]
882 fn mul_assign(&mut self, rhs: f32) {
883 *self = self.mul_scalar(rhs);
884 }
885}
886
887impl Div<Mat3A> for f32 {
888 type Output = Mat3A;
889 #[inline]
890 fn div(self, rhs: Mat3A) -> Self::Output {
891 rhs.div_scalar(self)
892 }
893}
894
895impl Div<f32> for Mat3A {
896 type Output = Self;
897 #[inline]
898 fn div(self, rhs: f32) -> Self::Output {
899 self.div_scalar(rhs)
900 }
901}
902
903impl DivAssign<f32> for Mat3A {
904 #[inline]
905 fn div_assign(&mut self, rhs: f32) {
906 *self = self.div_scalar(rhs);
907 }
908}
909
910impl Mul<Vec3> for Mat3A {
911 type Output = Vec3;
912 #[inline]
913 fn mul(self, rhs: Vec3) -> Vec3 {
914 self.mul_vec3a(rhs.into()).into()
915 }
916}
917
918impl From<Mat3> for Mat3A {
919 #[inline]
920 fn from(m: Mat3) -> Self {
921 Self {
922 x_axis: m.x_axis.into(),
923 y_axis: m.y_axis.into(),
924 z_axis: m.z_axis.into(),
925 }
926 }
927}
928
929impl Sum<Self> for Mat3A {
930 fn sum<I>(iter: I) -> Self
931 where
932 I: Iterator<Item = Self>,
933 {
934 iter.fold(Self::ZERO, Self::add)
935 }
936}
937
938impl<'a> Sum<&'a Self> for Mat3A {
939 fn sum<I>(iter: I) -> Self
940 where
941 I: Iterator<Item = &'a Self>,
942 {
943 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
944 }
945}
946
947impl Product for Mat3A {
948 fn product<I>(iter: I) -> Self
949 where
950 I: Iterator<Item = Self>,
951 {
952 iter.fold(Self::IDENTITY, Self::mul)
953 }
954}
955
956impl<'a> Product<&'a Self> for Mat3A {
957 fn product<I>(iter: I) -> Self
958 where
959 I: Iterator<Item = &'a Self>,
960 {
961 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
962 }
963}
964
965impl PartialEq for Mat3A {
966 #[inline]
967 fn eq(&self, rhs: &Self) -> bool {
968 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
969 }
970}
971
972impl fmt::Debug for Mat3A {
973 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
974 fmt.debug_struct(stringify!(Mat3A))
975 .field("x_axis", &self.x_axis)
976 .field("y_axis", &self.y_axis)
977 .field("z_axis", &self.z_axis)
978 .finish()
979 }
980}
981
982impl fmt::Display for Mat3A {
983 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
984 if let Some(p) = f.precision() {
985 write!(
986 f,
987 "[{:.*}, {:.*}, {:.*}]",
988 p, self.x_axis, p, self.y_axis, p, self.z_axis
989 )
990 } else {
991 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
992 }
993 }
994}