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-08")]
22use zerocopy_derive_08::*;
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)]
60#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
61#[cfg_attr(
62 feature = "zerocopy-08",
63 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
64)]
65#[repr(C)]
66pub struct Mat3A {
67 pub x_axis: Vec3A,
68 pub y_axis: Vec3A,
69 pub z_axis: Vec3A,
70}
71
72impl Mat3A {
73 pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
75
76 pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
78
79 pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::NAN);
81
82 #[allow(clippy::too_many_arguments)]
83 #[inline(always)]
84 #[must_use]
85 const fn new(
86 m00: f32,
87 m01: f32,
88 m02: f32,
89 m10: f32,
90 m11: f32,
91 m12: f32,
92 m20: f32,
93 m21: f32,
94 m22: f32,
95 ) -> Self {
96 Self {
97 x_axis: Vec3A::new(m00, m01, m02),
98 y_axis: Vec3A::new(m10, m11, m12),
99 z_axis: Vec3A::new(m20, m21, m22),
100 }
101 }
102
103 #[inline(always)]
107 #[must_use]
108 pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self {
109 Self {
110 x_axis,
111 y_axis,
112 z_axis,
113 }
114 }
115
116 #[inline(always)]
122 #[must_use]
123 pub const fn from_rows(row0: Vec3A, row1: Vec3A, row2: Vec3A) -> Self {
124 let [m00, m01, m02] = row0.to_array();
125 let [m10, m11, m12] = row1.to_array();
126 let [m20, m21, m22] = row2.to_array();
127 Self::new(m00, m10, m20, m01, m11, m21, m02, m12, m22)
128 }
129
130 #[inline]
134 #[must_use]
135 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
136 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
137 }
138
139 #[inline]
143 #[must_use]
144 pub const fn to_cols_array(&self) -> [f32; 9] {
145 let [x_axis_x, x_axis_y, x_axis_z] = self.x_axis.to_array();
146 let [y_axis_x, y_axis_y, y_axis_z] = self.y_axis.to_array();
147 let [z_axis_x, z_axis_y, z_axis_z] = self.z_axis.to_array();
148
149 [
150 x_axis_x, x_axis_y, x_axis_z, y_axis_x, y_axis_y, y_axis_z, z_axis_x, z_axis_y,
151 z_axis_z,
152 ]
153 }
154
155 #[inline]
159 #[must_use]
160 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
161 Self::from_cols(
162 Vec3A::from_array(m[0]),
163 Vec3A::from_array(m[1]),
164 Vec3A::from_array(m[2]),
165 )
166 }
167
168 #[inline]
172 #[must_use]
173 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
174 [
175 self.x_axis.to_array(),
176 self.y_axis.to_array(),
177 self.z_axis.to_array(),
178 ]
179 }
180
181 #[inline]
187 #[must_use]
188 pub const fn from_rows_array(m: &[f32; 9]) -> Self {
189 Self::new(m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8])
190 }
191
192 #[inline]
198 #[must_use]
199 pub const fn to_rows_array(&self) -> [f32; 9] {
200 let m = self.to_cols_array();
201 [m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8]]
202 }
203
204 #[doc(alias = "scale")]
206 #[inline]
207 #[must_use]
208 pub const fn from_diagonal(diagonal: Vec3) -> Self {
209 Self::new(
210 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
211 )
212 }
213
214 #[inline]
216 #[must_use]
217 pub fn from_mat4(m: Mat4) -> Self {
218 Self::from_cols(
219 Vec3A::from_vec4(m.x_axis),
220 Vec3A::from_vec4(m.y_axis),
221 Vec3A::from_vec4(m.z_axis),
222 )
223 }
224
225 #[inline]
232 #[must_use]
233 pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
234 match (i, j) {
235 (0, 0) => Self::from_cols(
236 Vec3A::from_vec4(m.y_axis.yzww()),
237 Vec3A::from_vec4(m.z_axis.yzww()),
238 Vec3A::from_vec4(m.w_axis.yzww()),
239 ),
240 (0, 1) => Self::from_cols(
241 Vec3A::from_vec4(m.y_axis.xzww()),
242 Vec3A::from_vec4(m.z_axis.xzww()),
243 Vec3A::from_vec4(m.w_axis.xzww()),
244 ),
245 (0, 2) => Self::from_cols(
246 Vec3A::from_vec4(m.y_axis.xyww()),
247 Vec3A::from_vec4(m.z_axis.xyww()),
248 Vec3A::from_vec4(m.w_axis.xyww()),
249 ),
250 (0, 3) => Self::from_cols(
251 Vec3A::from_vec4(m.y_axis.xyzw()),
252 Vec3A::from_vec4(m.z_axis.xyzw()),
253 Vec3A::from_vec4(m.w_axis.xyzw()),
254 ),
255 (1, 0) => Self::from_cols(
256 Vec3A::from_vec4(m.x_axis.yzww()),
257 Vec3A::from_vec4(m.z_axis.yzww()),
258 Vec3A::from_vec4(m.w_axis.yzww()),
259 ),
260 (1, 1) => Self::from_cols(
261 Vec3A::from_vec4(m.x_axis.xzww()),
262 Vec3A::from_vec4(m.z_axis.xzww()),
263 Vec3A::from_vec4(m.w_axis.xzww()),
264 ),
265 (1, 2) => Self::from_cols(
266 Vec3A::from_vec4(m.x_axis.xyww()),
267 Vec3A::from_vec4(m.z_axis.xyww()),
268 Vec3A::from_vec4(m.w_axis.xyww()),
269 ),
270 (1, 3) => Self::from_cols(
271 Vec3A::from_vec4(m.x_axis.xyzw()),
272 Vec3A::from_vec4(m.z_axis.xyzw()),
273 Vec3A::from_vec4(m.w_axis.xyzw()),
274 ),
275 (2, 0) => Self::from_cols(
276 Vec3A::from_vec4(m.x_axis.yzww()),
277 Vec3A::from_vec4(m.y_axis.yzww()),
278 Vec3A::from_vec4(m.w_axis.yzww()),
279 ),
280 (2, 1) => Self::from_cols(
281 Vec3A::from_vec4(m.x_axis.xzww()),
282 Vec3A::from_vec4(m.y_axis.xzww()),
283 Vec3A::from_vec4(m.w_axis.xzww()),
284 ),
285 (2, 2) => Self::from_cols(
286 Vec3A::from_vec4(m.x_axis.xyww()),
287 Vec3A::from_vec4(m.y_axis.xyww()),
288 Vec3A::from_vec4(m.w_axis.xyww()),
289 ),
290 (2, 3) => Self::from_cols(
291 Vec3A::from_vec4(m.x_axis.xyzw()),
292 Vec3A::from_vec4(m.y_axis.xyzw()),
293 Vec3A::from_vec4(m.w_axis.xyzw()),
294 ),
295 (3, 0) => Self::from_cols(
296 Vec3A::from_vec4(m.x_axis.yzww()),
297 Vec3A::from_vec4(m.y_axis.yzww()),
298 Vec3A::from_vec4(m.z_axis.yzww()),
299 ),
300 (3, 1) => Self::from_cols(
301 Vec3A::from_vec4(m.x_axis.xzww()),
302 Vec3A::from_vec4(m.y_axis.xzww()),
303 Vec3A::from_vec4(m.z_axis.xzww()),
304 ),
305 (3, 2) => Self::from_cols(
306 Vec3A::from_vec4(m.x_axis.xyww()),
307 Vec3A::from_vec4(m.y_axis.xyww()),
308 Vec3A::from_vec4(m.z_axis.xyww()),
309 ),
310 (3, 3) => Self::from_cols(
311 Vec3A::from_vec4(m.x_axis.xyzw()),
312 Vec3A::from_vec4(m.y_axis.xyzw()),
313 Vec3A::from_vec4(m.z_axis.xyzw()),
314 ),
315 _ => panic!("index out of bounds"),
316 }
317 }
318
319 #[inline]
325 #[must_use]
326 pub fn from_quat(rotation: Quat) -> Self {
327 glam_assert!(rotation.is_normalized());
328
329 let x2 = rotation.x + rotation.x;
330 let y2 = rotation.y + rotation.y;
331 let z2 = rotation.z + rotation.z;
332 let xx = rotation.x * x2;
333 let xy = rotation.x * y2;
334 let xz = rotation.x * z2;
335 let yy = rotation.y * y2;
336 let yz = rotation.y * z2;
337 let zz = rotation.z * z2;
338 let wx = rotation.w * x2;
339 let wy = rotation.w * y2;
340 let wz = rotation.w * z2;
341
342 Self::from_cols(
343 Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
344 Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
345 Vec3A::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
346 )
347 }
348
349 #[inline]
356 #[must_use]
357 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
358 glam_assert!(axis.is_normalized());
359
360 let (sin, cos) = math::sin_cos(angle);
361 let (xsin, ysin, zsin) = axis.mul(sin).into();
362 let (x, y, z) = axis.into();
363 let (x2, y2, z2) = axis.mul(axis).into();
364 let omc = 1.0 - cos;
365 let xyomc = x * y * omc;
366 let xzomc = x * z * omc;
367 let yzomc = y * z * omc;
368 Self::from_cols(
369 Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
370 Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
371 Vec3A::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
372 )
373 }
374
375 #[inline]
378 #[must_use]
379 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
380 Self::from_euler_angles(order, a, b, c)
381 }
382
383 #[inline]
392 #[must_use]
393 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
394 glam_assert!(
395 self.x_axis.is_normalized()
396 && self.y_axis.is_normalized()
397 && self.z_axis.is_normalized()
398 );
399 self.to_euler_angles(order)
400 }
401
402 #[inline]
404 #[must_use]
405 pub fn from_rotation_x(angle: f32) -> Self {
406 let (sina, cosa) = math::sin_cos(angle);
407 Self::from_cols(
408 Vec3A::X,
409 Vec3A::new(0.0, cosa, sina),
410 Vec3A::new(0.0, -sina, cosa),
411 )
412 }
413
414 #[inline]
416 #[must_use]
417 pub fn from_rotation_y(angle: f32) -> Self {
418 let (sina, cosa) = math::sin_cos(angle);
419 Self::from_cols(
420 Vec3A::new(cosa, 0.0, -sina),
421 Vec3A::Y,
422 Vec3A::new(sina, 0.0, cosa),
423 )
424 }
425
426 #[inline]
428 #[must_use]
429 pub fn from_rotation_z(angle: f32) -> Self {
430 let (sina, cosa) = math::sin_cos(angle);
431 Self::from_cols(
432 Vec3A::new(cosa, sina, 0.0),
433 Vec3A::new(-sina, cosa, 0.0),
434 Vec3A::Z,
435 )
436 }
437
438 #[inline]
443 #[must_use]
444 pub fn from_translation(translation: Vec2) -> Self {
445 Self::from_cols(
446 Vec3A::X,
447 Vec3A::Y,
448 Vec3A::new(translation.x, translation.y, 1.0),
449 )
450 }
451
452 #[inline]
458 #[must_use]
459 pub fn from_angle(angle: f32) -> Self {
460 let (sin, cos) = math::sin_cos(angle);
461 Self::from_cols(
462 Vec3A::new(cos, sin, 0.0),
463 Vec3A::new(-sin, cos, 0.0),
464 Vec3A::Z,
465 )
466 }
467
468 #[inline]
474 #[must_use]
475 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
476 let (sin, cos) = math::sin_cos(angle);
477 Self::from_cols(
478 Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
479 Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
480 Vec3A::new(translation.x, translation.y, 1.0),
481 )
482 }
483
484 #[inline]
493 #[must_use]
494 pub fn from_scale(scale: Vec2) -> Self {
495 glam_assert!(scale.cmpne(Vec2::ZERO).any());
497
498 Self::from_cols(
499 Vec3A::new(scale.x, 0.0, 0.0),
500 Vec3A::new(0.0, scale.y, 0.0),
501 Vec3A::Z,
502 )
503 }
504
505 #[inline]
510 pub fn from_mat2(m: Mat2) -> Self {
511 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
512 }
513
514 #[inline]
522 #[must_use]
523 pub const fn from_cols_slice(slice: &[f32]) -> Self {
524 Self::new(
525 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
526 slice[8],
527 )
528 }
529
530 #[inline]
536 pub fn write_cols_to_slice(&self, slice: &mut [f32]) {
537 slice[0] = self.x_axis.x;
538 slice[1] = self.x_axis.y;
539 slice[2] = self.x_axis.z;
540 slice[3] = self.y_axis.x;
541 slice[4] = self.y_axis.y;
542 slice[5] = self.y_axis.z;
543 slice[6] = self.z_axis.x;
544 slice[7] = self.z_axis.y;
545 slice[8] = self.z_axis.z;
546 }
547
548 #[inline]
559 #[must_use]
560 pub const fn from_rows_slice(slice: &[f32]) -> Self {
561 Self::new(
562 slice[0], slice[3], slice[6], slice[1], slice[4], slice[7], slice[2], slice[5],
563 slice[8],
564 )
565 }
566
567 #[inline]
573 #[must_use]
574 pub fn col(&self, index: usize) -> Vec3A {
575 match index {
576 0 => self.x_axis,
577 1 => self.y_axis,
578 2 => self.z_axis,
579 _ => panic!("index out of bounds"),
580 }
581 }
582
583 #[inline]
589 pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
590 match index {
591 0 => &mut self.x_axis,
592 1 => &mut self.y_axis,
593 2 => &mut self.z_axis,
594 _ => panic!("index out of bounds"),
595 }
596 }
597
598 #[inline]
606 #[must_use]
607 pub fn row(&self, index: usize) -> Vec3A {
608 match index {
609 0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
610 1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
611 2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
612 _ => panic!("index out of bounds"),
613 }
614 }
615
616 #[inline]
626 pub fn set_row(&mut self, index: usize, row: Vec3A) {
627 match index {
628 0 => {
629 self.x_axis.x = row.x;
630 self.y_axis.x = row.y;
631 self.z_axis.x = row.z;
632 }
633 1 => {
634 self.x_axis.y = row.x;
635 self.y_axis.y = row.y;
636 self.z_axis.y = row.z;
637 }
638 2 => {
639 self.x_axis.z = row.x;
640 self.y_axis.z = row.y;
641 self.z_axis.z = row.z;
642 }
643 _ => panic!("index out of bounds"),
644 }
645 }
646
647 #[inline]
650 #[must_use]
651 pub fn is_finite(&self) -> bool {
652 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
653 }
654
655 #[inline]
657 #[must_use]
658 pub fn is_nan(&self) -> bool {
659 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
660 }
661
662 #[inline]
664 #[must_use]
665 pub fn transpose(&self) -> Self {
666 unsafe {
667 let tmp0 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b01_00_01_00);
668 let tmp1 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b11_10_11_10);
669
670 Self {
671 x_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b00_00_10_00)),
672 y_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b01_01_11_01)),
673 z_axis: Vec3A(_mm_shuffle_ps(tmp1, self.z_axis.0, 0b10_10_10_00)),
674 }
675 }
676 }
677
678 #[inline]
680 #[must_use]
681 pub fn diagonal(&self) -> Vec3A {
682 Vec3A::new(self.x_axis.x, self.y_axis.y, self.z_axis.z)
683 }
684
685 #[inline]
687 #[must_use]
688 pub fn determinant(&self) -> f32 {
689 self.x_axis.dot(self.y_axis.cross(self.z_axis))
690 }
691
692 #[inline(always)]
704 #[must_use]
705 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
706 let tmp0 = self.y_axis.cross(self.z_axis);
707 let det = self.x_axis.dot(tmp0);
708 if CHECKED {
709 if det == 0.0 {
710 return (Self::ZERO, false);
711 }
712 } else {
713 glam_assert!(det != 0.0);
714 }
715 let tmp1 = self.z_axis.cross(self.x_axis);
716 let tmp2 = self.x_axis.cross(self.y_axis);
717 let inv_det = Vec3A::splat(1.0 / det);
718 (
719 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose(),
720 true,
721 )
722 }
723
724 #[inline]
732 #[must_use]
733 pub fn inverse(&self) -> Self {
734 self.inverse_checked::<false>().0
735 }
736
737 #[inline]
739 #[must_use]
740 pub fn try_inverse(&self) -> Option<Self> {
741 let (m, is_valid) = self.inverse_checked::<true>();
742 if is_valid {
743 Some(m)
744 } else {
745 None
746 }
747 }
748
749 #[inline]
751 #[must_use]
752 pub fn inverse_or_zero(&self) -> Self {
753 self.inverse_checked::<true>().0
754 }
755
756 #[inline]
766 #[must_use]
767 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
768 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
769 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
770 }
771
772 #[inline]
782 #[must_use]
783 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
784 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
785 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
786 }
787
788 #[deprecated(
796 since = "0.33.1",
797 note = "use the `glam::camera::lh::view::look_to_mat3` function instead"
798 )]
799 #[inline]
800 #[must_use]
801 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
802 #[allow(deprecated)]
803 Self::look_to_rh(-dir, up)
804 }
805
806 #[deprecated(
814 since = "0.33.1",
815 note = "use the `glam::camera::rh::view::look_to_mat3` function instead"
816 )]
817 #[inline]
818 #[must_use]
819 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
820 glam_assert!(dir.is_normalized());
821 glam_assert!(up.is_normalized());
822 let f = dir;
823 let s = f.cross(up).normalize();
824 let u = s.cross(f);
825
826 Self::from_cols(
827 Vec3A::new(s.x, u.x, -f.x),
828 Vec3A::new(s.y, u.y, -f.y),
829 Vec3A::new(s.z, u.z, -f.z),
830 )
831 }
832
833 #[deprecated(
842 since = "0.33.1",
843 note = "use the `glam::camera::lh::view::look_at_mat3` function instead"
844 )]
845 #[inline]
846 #[must_use]
847 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
848 #[allow(deprecated)]
849 Self::look_to_lh(center.sub(eye).normalize(), up)
850 }
851
852 #[deprecated(
861 since = "0.33.1",
862 note = "use the `glam::camera::rh::view::look_at_mat3` function instead"
863 )]
864 #[inline]
865 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
866 #[allow(deprecated)]
867 Self::look_to_rh(center.sub(eye).normalize(), up)
868 }
869
870 #[inline]
872 #[must_use]
873 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
874 self.mul_vec3a(rhs.into()).into()
875 }
876
877 #[inline]
879 #[must_use]
880 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
881 let mut res = self.x_axis.mul(rhs.xxx());
882 res = res.add(self.y_axis.mul(rhs.yyy()));
883 res = res.add(self.z_axis.mul(rhs.zzz()));
884 res
885 }
886
887 #[inline]
889 #[must_use]
890 pub fn mul_transpose_vec3(&self, rhs: Vec3) -> Vec3 {
891 self.mul_transpose_vec3a(rhs.into()).into()
892 }
893
894 #[inline]
896 #[must_use]
897 pub fn mul_transpose_vec3a(&self, rhs: Vec3A) -> Vec3A {
898 Vec3A::new(
899 self.x_axis.dot(rhs),
900 self.y_axis.dot(rhs),
901 self.z_axis.dot(rhs),
902 )
903 }
904
905 #[inline]
907 #[must_use]
908 pub fn mul_mat3(&self, rhs: &Self) -> Self {
909 self.mul(rhs)
910 }
911
912 #[inline]
914 #[must_use]
915 pub fn add_mat3(&self, rhs: &Self) -> Self {
916 self.add(rhs)
917 }
918
919 #[inline]
921 #[must_use]
922 pub fn sub_mat3(&self, rhs: &Self) -> Self {
923 self.sub(rhs)
924 }
925
926 #[inline]
928 #[must_use]
929 pub fn mul_scalar(&self, rhs: f32) -> Self {
930 Self::from_cols(
931 self.x_axis.mul(rhs),
932 self.y_axis.mul(rhs),
933 self.z_axis.mul(rhs),
934 )
935 }
936
937 #[inline]
941 #[must_use]
942 pub fn mul_diagonal_scale(&self, scale: Vec3) -> Self {
943 Self::from_cols(
944 self.x_axis * scale.x,
945 self.y_axis * scale.y,
946 self.z_axis * scale.z,
947 )
948 }
949
950 #[inline]
952 #[must_use]
953 pub fn div_scalar(&self, rhs: f32) -> Self {
954 let rhs = Vec3A::splat(rhs);
955 Self::from_cols(
956 self.x_axis.div(rhs),
957 self.y_axis.div(rhs),
958 self.z_axis.div(rhs),
959 )
960 }
961
962 #[inline]
964 #[must_use]
965 pub fn recip(&self) -> Self {
966 Self::from_cols(
967 self.x_axis.recip(),
968 self.y_axis.recip(),
969 self.z_axis.recip(),
970 )
971 }
972
973 #[inline]
983 #[must_use]
984 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
985 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
986 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
987 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
988 }
989
990 #[inline]
992 #[must_use]
993 pub fn abs(&self) -> Self {
994 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
995 }
996
997 #[cfg(feature = "f64")]
998 #[inline]
999 #[must_use]
1000 pub fn as_dmat3(&self) -> DMat3 {
1001 DMat3::from_cols(
1002 self.x_axis.as_dvec3(),
1003 self.y_axis.as_dvec3(),
1004 self.z_axis.as_dvec3(),
1005 )
1006 }
1007}
1008
1009impl Default for Mat3A {
1010 #[inline]
1011 fn default() -> Self {
1012 Self::IDENTITY
1013 }
1014}
1015
1016impl Add for Mat3A {
1017 type Output = Self;
1018 #[inline]
1019 fn add(self, rhs: Self) -> Self {
1020 Self::from_cols(
1021 self.x_axis.add(rhs.x_axis),
1022 self.y_axis.add(rhs.y_axis),
1023 self.z_axis.add(rhs.z_axis),
1024 )
1025 }
1026}
1027
1028impl Add<&Self> for Mat3A {
1029 type Output = Self;
1030 #[inline]
1031 fn add(self, rhs: &Self) -> Self {
1032 self.add(*rhs)
1033 }
1034}
1035
1036impl Add<&Mat3A> for &Mat3A {
1037 type Output = Mat3A;
1038 #[inline]
1039 fn add(self, rhs: &Mat3A) -> Mat3A {
1040 (*self).add(*rhs)
1041 }
1042}
1043
1044impl Add<Mat3A> for &Mat3A {
1045 type Output = Mat3A;
1046 #[inline]
1047 fn add(self, rhs: Mat3A) -> Mat3A {
1048 (*self).add(rhs)
1049 }
1050}
1051
1052impl AddAssign for Mat3A {
1053 #[inline]
1054 fn add_assign(&mut self, rhs: Self) {
1055 *self = self.add(rhs);
1056 }
1057}
1058
1059impl AddAssign<&Self> for Mat3A {
1060 #[inline]
1061 fn add_assign(&mut self, rhs: &Self) {
1062 self.add_assign(*rhs);
1063 }
1064}
1065
1066impl Sub for Mat3A {
1067 type Output = Self;
1068 #[inline]
1069 fn sub(self, rhs: Self) -> Self {
1070 Self::from_cols(
1071 self.x_axis.sub(rhs.x_axis),
1072 self.y_axis.sub(rhs.y_axis),
1073 self.z_axis.sub(rhs.z_axis),
1074 )
1075 }
1076}
1077
1078impl Sub<&Self> for Mat3A {
1079 type Output = Self;
1080 #[inline]
1081 fn sub(self, rhs: &Self) -> Self {
1082 self.sub(*rhs)
1083 }
1084}
1085
1086impl Sub<&Mat3A> for &Mat3A {
1087 type Output = Mat3A;
1088 #[inline]
1089 fn sub(self, rhs: &Mat3A) -> Mat3A {
1090 (*self).sub(*rhs)
1091 }
1092}
1093
1094impl Sub<Mat3A> for &Mat3A {
1095 type Output = Mat3A;
1096 #[inline]
1097 fn sub(self, rhs: Mat3A) -> Mat3A {
1098 (*self).sub(rhs)
1099 }
1100}
1101
1102impl SubAssign for Mat3A {
1103 #[inline]
1104 fn sub_assign(&mut self, rhs: Self) {
1105 *self = self.sub(rhs);
1106 }
1107}
1108
1109impl SubAssign<&Self> for Mat3A {
1110 #[inline]
1111 fn sub_assign(&mut self, rhs: &Self) {
1112 self.sub_assign(*rhs);
1113 }
1114}
1115
1116impl Neg for Mat3A {
1117 type Output = Self;
1118 #[inline]
1119 fn neg(self) -> Self::Output {
1120 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
1121 }
1122}
1123
1124impl Neg for &Mat3A {
1125 type Output = Mat3A;
1126 #[inline]
1127 fn neg(self) -> Mat3A {
1128 (*self).neg()
1129 }
1130}
1131
1132impl Mul for Mat3A {
1133 type Output = Self;
1134 #[inline]
1135 fn mul(self, rhs: Self) -> Self {
1136 Self::from_cols(
1137 self.mul(rhs.x_axis),
1138 self.mul(rhs.y_axis),
1139 self.mul(rhs.z_axis),
1140 )
1141 }
1142}
1143
1144impl Mul<&Self> for Mat3A {
1145 type Output = Self;
1146 #[inline]
1147 fn mul(self, rhs: &Self) -> Self {
1148 self.mul(*rhs)
1149 }
1150}
1151
1152impl Mul<&Mat3A> for &Mat3A {
1153 type Output = Mat3A;
1154 #[inline]
1155 fn mul(self, rhs: &Mat3A) -> Mat3A {
1156 (*self).mul(*rhs)
1157 }
1158}
1159
1160impl Mul<Mat3A> for &Mat3A {
1161 type Output = Mat3A;
1162 #[inline]
1163 fn mul(self, rhs: Mat3A) -> Mat3A {
1164 (*self).mul(rhs)
1165 }
1166}
1167
1168impl MulAssign for Mat3A {
1169 #[inline]
1170 fn mul_assign(&mut self, rhs: Self) {
1171 *self = self.mul(rhs);
1172 }
1173}
1174
1175impl MulAssign<&Self> for Mat3A {
1176 #[inline]
1177 fn mul_assign(&mut self, rhs: &Self) {
1178 self.mul_assign(*rhs);
1179 }
1180}
1181
1182impl Mul<Vec3A> for Mat3A {
1183 type Output = Vec3A;
1184 #[inline]
1185 fn mul(self, rhs: Vec3A) -> Self::Output {
1186 self.mul_vec3a(rhs)
1187 }
1188}
1189
1190impl Mul<&Vec3A> for Mat3A {
1191 type Output = Vec3A;
1192 #[inline]
1193 fn mul(self, rhs: &Vec3A) -> Vec3A {
1194 self.mul(*rhs)
1195 }
1196}
1197
1198impl Mul<&Vec3A> for &Mat3A {
1199 type Output = Vec3A;
1200 #[inline]
1201 fn mul(self, rhs: &Vec3A) -> Vec3A {
1202 (*self).mul(*rhs)
1203 }
1204}
1205
1206impl Mul<Vec3A> for &Mat3A {
1207 type Output = Vec3A;
1208 #[inline]
1209 fn mul(self, rhs: Vec3A) -> Vec3A {
1210 (*self).mul(rhs)
1211 }
1212}
1213
1214impl Mul<Mat3A> for f32 {
1215 type Output = Mat3A;
1216 #[inline]
1217 fn mul(self, rhs: Mat3A) -> Self::Output {
1218 rhs.mul_scalar(self)
1219 }
1220}
1221
1222impl Mul<&Mat3A> for f32 {
1223 type Output = Mat3A;
1224 #[inline]
1225 fn mul(self, rhs: &Mat3A) -> Mat3A {
1226 self.mul(*rhs)
1227 }
1228}
1229
1230impl Mul<&Mat3A> for &f32 {
1231 type Output = Mat3A;
1232 #[inline]
1233 fn mul(self, rhs: &Mat3A) -> Mat3A {
1234 (*self).mul(*rhs)
1235 }
1236}
1237
1238impl Mul<Mat3A> for &f32 {
1239 type Output = Mat3A;
1240 #[inline]
1241 fn mul(self, rhs: Mat3A) -> Mat3A {
1242 (*self).mul(rhs)
1243 }
1244}
1245
1246impl Mul<f32> for Mat3A {
1247 type Output = Self;
1248 #[inline]
1249 fn mul(self, rhs: f32) -> Self {
1250 self.mul_scalar(rhs)
1251 }
1252}
1253
1254impl Mul<&f32> for Mat3A {
1255 type Output = Self;
1256 #[inline]
1257 fn mul(self, rhs: &f32) -> Self {
1258 self.mul(*rhs)
1259 }
1260}
1261
1262impl Mul<&f32> for &Mat3A {
1263 type Output = Mat3A;
1264 #[inline]
1265 fn mul(self, rhs: &f32) -> Mat3A {
1266 (*self).mul(*rhs)
1267 }
1268}
1269
1270impl Mul<f32> for &Mat3A {
1271 type Output = Mat3A;
1272 #[inline]
1273 fn mul(self, rhs: f32) -> Mat3A {
1274 (*self).mul(rhs)
1275 }
1276}
1277
1278impl MulAssign<f32> for Mat3A {
1279 #[inline]
1280 fn mul_assign(&mut self, rhs: f32) {
1281 *self = self.mul(rhs);
1282 }
1283}
1284
1285impl MulAssign<&f32> for Mat3A {
1286 #[inline]
1287 fn mul_assign(&mut self, rhs: &f32) {
1288 self.mul_assign(*rhs);
1289 }
1290}
1291
1292impl Div<Mat3A> for f32 {
1293 type Output = Mat3A;
1294 #[inline]
1295 fn div(self, rhs: Mat3A) -> Self::Output {
1296 Mat3A::from_cols(
1297 self.div(rhs.x_axis),
1298 self.div(rhs.y_axis),
1299 self.div(rhs.z_axis),
1300 )
1301 }
1302}
1303
1304impl Div<&Mat3A> for f32 {
1305 type Output = Mat3A;
1306 #[inline]
1307 fn div(self, rhs: &Mat3A) -> Mat3A {
1308 self.div(*rhs)
1309 }
1310}
1311
1312impl Div<&Mat3A> for &f32 {
1313 type Output = Mat3A;
1314 #[inline]
1315 fn div(self, rhs: &Mat3A) -> Mat3A {
1316 (*self).div(*rhs)
1317 }
1318}
1319
1320impl Div<Mat3A> for &f32 {
1321 type Output = Mat3A;
1322 #[inline]
1323 fn div(self, rhs: Mat3A) -> Mat3A {
1324 (*self).div(rhs)
1325 }
1326}
1327
1328impl Div<f32> for Mat3A {
1329 type Output = Self;
1330 #[inline]
1331 fn div(self, rhs: f32) -> Self {
1332 self.div_scalar(rhs)
1333 }
1334}
1335
1336impl Div<&f32> for Mat3A {
1337 type Output = Self;
1338 #[inline]
1339 fn div(self, rhs: &f32) -> Self {
1340 self.div(*rhs)
1341 }
1342}
1343
1344impl Div<&f32> for &Mat3A {
1345 type Output = Mat3A;
1346 #[inline]
1347 fn div(self, rhs: &f32) -> Mat3A {
1348 (*self).div(*rhs)
1349 }
1350}
1351
1352impl Div<f32> for &Mat3A {
1353 type Output = Mat3A;
1354 #[inline]
1355 fn div(self, rhs: f32) -> Mat3A {
1356 (*self).div(rhs)
1357 }
1358}
1359
1360impl DivAssign<f32> for Mat3A {
1361 #[inline]
1362 fn div_assign(&mut self, rhs: f32) {
1363 *self = self.div(rhs);
1364 }
1365}
1366
1367impl DivAssign<&f32> for Mat3A {
1368 #[inline]
1369 fn div_assign(&mut self, rhs: &f32) {
1370 self.div_assign(*rhs);
1371 }
1372}
1373
1374impl Mul<Vec3> for Mat3A {
1375 type Output = Vec3;
1376 #[inline]
1377 fn mul(self, rhs: Vec3) -> Vec3 {
1378 self.mul_vec3a(rhs.into()).into()
1379 }
1380}
1381
1382impl Mul<&Vec3> for Mat3A {
1383 type Output = Vec3;
1384 #[inline]
1385 fn mul(self, rhs: &Vec3) -> Vec3 {
1386 self.mul(*rhs)
1387 }
1388}
1389
1390impl Mul<&Vec3> for &Mat3A {
1391 type Output = Vec3;
1392 #[inline]
1393 fn mul(self, rhs: &Vec3) -> Vec3 {
1394 (*self).mul(*rhs)
1395 }
1396}
1397
1398impl Mul<Vec3> for &Mat3A {
1399 type Output = Vec3;
1400 #[inline]
1401 fn mul(self, rhs: Vec3) -> Vec3 {
1402 (*self).mul(rhs)
1403 }
1404}
1405
1406impl From<Mat3> for Mat3A {
1407 #[inline]
1408 fn from(m: Mat3) -> Self {
1409 Self {
1410 x_axis: m.x_axis.into(),
1411 y_axis: m.y_axis.into(),
1412 z_axis: m.z_axis.into(),
1413 }
1414 }
1415}
1416
1417impl Sum<Self> for Mat3A {
1418 fn sum<I>(iter: I) -> Self
1419 where
1420 I: Iterator<Item = Self>,
1421 {
1422 iter.fold(Self::ZERO, Self::add)
1423 }
1424}
1425
1426impl<'a> Sum<&'a Self> for Mat3A {
1427 fn sum<I>(iter: I) -> Self
1428 where
1429 I: Iterator<Item = &'a Self>,
1430 {
1431 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1432 }
1433}
1434
1435impl Product for Mat3A {
1436 fn product<I>(iter: I) -> Self
1437 where
1438 I: Iterator<Item = Self>,
1439 {
1440 iter.fold(Self::IDENTITY, Self::mul)
1441 }
1442}
1443
1444impl<'a> Product<&'a Self> for Mat3A {
1445 fn product<I>(iter: I) -> Self
1446 where
1447 I: Iterator<Item = &'a Self>,
1448 {
1449 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1450 }
1451}
1452
1453impl PartialEq for Mat3A {
1454 #[inline]
1455 fn eq(&self, rhs: &Self) -> bool {
1456 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1457 }
1458}
1459
1460impl fmt::Debug for Mat3A {
1461 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1462 fmt.debug_struct(stringify!(Mat3A))
1463 .field("x_axis", &self.x_axis)
1464 .field("y_axis", &self.y_axis)
1465 .field("z_axis", &self.z_axis)
1466 .finish()
1467 }
1468}
1469
1470impl fmt::Display for Mat3A {
1471 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1472 if let Some(p) = f.precision() {
1473 write!(
1474 f,
1475 "[{:.*}, {:.*}, {:.*}]",
1476 p, self.x_axis, p, self.y_axis, p, self.z_axis
1477 )
1478 } else {
1479 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1480 }
1481 }
1482}