Skip to main content

glam/f32/sse2/
mat3a.rs

1// Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3#[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/// Creates a 3x3 matrix from three column vectors.
25#[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/// A 3x3 column major matrix.
32///
33/// This 3x3 matrix type features convenience methods for creating and using linear and
34/// affine transformations. If you are primarily dealing with 2D affine transformations the
35/// [`Affine2`](crate::Affine2) type is much faster and more space efficient than
36/// using a 3x3 matrix.
37///
38/// Linear transformations including 3D rotation and scale can be created using methods
39/// such as [`Self::from_diagonal()`], [`Self::from_quat()`], [`Self::from_axis_angle()`],
40/// [`Self::from_rotation_x()`], [`Self::from_rotation_y()`], or
41/// [`Self::from_rotation_z()`].
42///
43/// The resulting matrices can be use to transform 3D vectors using regular vector
44/// multiplication.
45///
46/// Affine transformations including 2D translation, rotation and scale can be created
47/// using methods such as [`Self::from_translation()`], [`Self::from_angle()`],
48/// [`Self::from_scale()`] and [`Self::from_scale_angle_translation()`].
49///
50/// The [`Self::transform_point2()`] and [`Self::transform_vector2()`] convenience methods
51/// are provided for performing affine transforms on 2D vectors and points. These multiply
52/// 2D inputs as 3D vectors with an implicit `z` value of `1` for points and `0` for
53/// vectors respectively. These methods assume that `Self` contains a valid affine
54/// transform.
55///
56/// SIMD vector types are used for storage on supported platforms.
57///
58/// This type is 16 byte aligned.
59#[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    /// A 3x3 matrix with all elements set to `0.0`.
74    pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
75
76    /// A 3x3 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
77    pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
78
79    /// All NAN:s.
80    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    /// Creates a 3x3 matrix from three column vectors.
104    ///
105    /// See also [`Self::from_rows`] when the data is in row major order.
106    #[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    /// Creates a 3x3 matrix from three row vectors.
117    ///
118    /// Matrices are stored in column major order, so the given rows are permuted into
119    /// the matrix layout. Use [`Self::from_cols`] instead when the data is already in
120    /// column major order.
121    #[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    /// Creates a 3x3 matrix from a `[f32; 9]` array stored in column major order.
131    ///
132    /// If the data is in row major order use [`Self::from_rows_array`] instead.
133    #[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    /// Creates a `[f32; 9]` array storing data in column major order.
140    ///
141    /// If you require the data in row major order use [`Self::to_rows_array`] instead.
142    #[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    /// Creates a 3x3 matrix from a `[[f32; 3]; 3]` 3D array stored in column major order.
156    ///
157    /// If the data is in row major order `transpose` the returned matrix.
158    #[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    /// Creates a `[[f32; 3]; 3]` 3D array storing data in column major order.
169    ///
170    /// If you require row major order `transpose` the matrix first.
171    #[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    /// Creates a 3x3 matrix from a `[f32; 9]` array stored in row major order.
182    ///
183    /// Matrices are stored in column major order, so the array is permuted into the
184    /// matrix layout. Use [`Self::from_cols_array`] instead when the data is already in
185    /// column major order.
186    #[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    /// Creates a `[f32; 9]` array storing data in row major order.
193    ///
194    /// Matrices are stored in column major order, so the array is permuted out of the
195    /// column major storage. Use [`Self::to_cols_array`] instead when you want data in
196    /// column major order.
197    #[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    /// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0.
205    #[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    /// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column.
215    #[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    /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
226    /// and `j`th row.
227    ///
228    /// # Panics
229    ///
230    /// Panics if `i` or `j` is greater than 3.
231    #[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    /// Creates a 3D rotation matrix from the given quaternion.
320    ///
321    /// # Panics
322    ///
323    /// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
324    #[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    /// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in
350    /// radians).
351    ///
352    /// # Panics
353    ///
354    /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
355    #[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    /// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in
376    /// radians).
377    #[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    /// Extract Euler angles with the given Euler rotation order.
384    ///
385    /// Note if the input matrix contains scales, shears, or other non-rotation transformations then
386    /// the resulting Euler angles will be ill-defined.
387    ///
388    /// # Panics
389    ///
390    /// Will panic if any input matrix column is not normalized when `glam_assert` is enabled.
391    #[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    /// Creates a 3D rotation matrix from `angle` (in radians) around the x axis.
403    #[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    /// Creates a 3D rotation matrix from `angle` (in radians) around the y axis.
415    #[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    /// Creates a 3D rotation matrix from `angle` (in radians) around the z axis.
427    #[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    /// Creates an affine transformation matrix from the given 2D `translation`.
439    ///
440    /// The resulting matrix can be used to transform 2D points and vectors. See
441    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
442    #[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    /// Creates an affine transformation matrix from the given 2D rotation `angle` (in
453    /// radians).
454    ///
455    /// The resulting matrix can be used to transform 2D points and vectors. See
456    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
457    #[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    /// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in
469    /// radians) and `translation`.
470    ///
471    /// The resulting matrix can be used to transform 2D points and vectors. See
472    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
473    #[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    /// Creates an affine transformation matrix from the given non-uniform 2D `scale`.
485    ///
486    /// The resulting matrix can be used to transform 2D points and vectors. See
487    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
488    ///
489    /// # Panics
490    ///
491    /// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
492    #[inline]
493    #[must_use]
494    pub fn from_scale(scale: Vec2) -> Self {
495        // Do not panic as long as any component is non-zero
496        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    /// Creates an affine transformation matrix from the given 2x2 matrix.
506    ///
507    /// The resulting matrix can be used to transform 2D points and vectors. See
508    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
509    #[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    /// Creates a 3x3 matrix from the first 9 values in `slice`.
515    ///
516    /// See also [`Self::from_rows_slice`] when the slice is in row major order.
517    ///
518    /// # Panics
519    ///
520    /// Panics if `slice` is less than 9 elements long.
521    #[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    /// Writes the columns of `self` to the first 9 elements in `slice`.
531    ///
532    /// # Panics
533    ///
534    /// Panics if `slice` is less than 9 elements long.
535    #[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    /// Creates a 3x3 matrix from the first 9 values in `slice`, stored in row
549    /// major order.
550    ///
551    /// Matrices are stored in column major order, so the slice is permuted into the
552    /// matrix layout. Use [`Self::from_cols_slice`] instead when the slice is already in
553    /// column major order.
554    ///
555    /// # Panics
556    ///
557    /// Panics if `slice` is less than 9 elements long.
558    #[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    /// Returns the matrix column for the given `index`.
568    ///
569    /// # Panics
570    ///
571    /// Panics if `index` is greater than 2.
572    #[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    /// Returns a mutable reference to the matrix column for the given `index`.
584    ///
585    /// # Panics
586    ///
587    /// Panics if `index` is greater than 2.
588    #[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    /// Returns the matrix row for the given `index`.
599    ///
600    /// See also [`Self::set_row`] when you need to change the row.
601    ///
602    /// # Panics
603    ///
604    /// Panics if `index` is greater than 2.
605    #[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    /// Sets the matrix row for the given `index`.
617    ///
618    /// Matrices are stored in column major order, so the row is spread across all
619    /// 3 columns and writing it touches every column. Use [`Self::col_mut`]
620    /// instead when you can work with columns. See also [`Self::row`].
621    ///
622    /// # Panics
623    ///
624    /// Panics if `index` is greater than 2.
625    #[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    /// Returns `true` if, and only if, all elements are finite.
648    /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
649    #[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    /// Returns `true` if any elements are `NaN`.
656    #[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    /// Returns the transpose of `self`.
663    #[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    /// Returns the diagonal of `self`.
679    #[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    /// Returns the determinant of `self`.
686    #[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    /// If `CHECKED` is true then if the determinant is zero this function will return a tuple
693    /// containing a zero matrix and false. If the determinant is non zero a tuple containing the
694    /// inverted matrix and true is returned.
695    ///
696    /// If `CHECKED` is false then the determinant is not checked and if it is zero the resulting
697    /// inverted matrix will be invalid. Will panic if the determinant of `self` is zero when
698    /// `glam_assert` is enabled.
699    ///
700    /// A tuple containing the inverted matrix and a bool is used instead of an option here as
701    /// regular Rust enums put the discriminant first which can result in a lot of padding if the
702    /// matrix is aligned.
703    #[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    /// Returns the inverse of `self`.
725    ///
726    /// If the matrix is not invertible the returned matrix will be invalid.
727    ///
728    /// # Panics
729    ///
730    /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
731    #[inline]
732    #[must_use]
733    pub fn inverse(&self) -> Self {
734        self.inverse_checked::<false>().0
735    }
736
737    /// Returns the inverse of `self` or `None` if the matrix is not invertible.
738    #[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    /// Returns the inverse of `self` or `Mat3A::ZERO` if the matrix is not invertible.
750    #[inline]
751    #[must_use]
752    pub fn inverse_or_zero(&self) -> Self {
753        self.inverse_checked::<true>().0
754    }
755
756    /// Transforms the given 2D vector as a point.
757    ///
758    /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
759    ///
760    /// This method assumes that `self` contains a valid affine transform.
761    ///
762    /// # Panics
763    ///
764    /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
765    #[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    /// Rotates the given 2D vector.
773    ///
774    /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
775    ///
776    /// This method assumes that `self` contains a valid affine transform.
777    ///
778    /// # Panics
779    ///
780    /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
781    #[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    /// Creates a left-handed view matrix using a facing direction and an up direction.
789    ///
790    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
791    ///
792    /// # Panics
793    ///
794    /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
795    #[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    /// Creates a right-handed view matrix using a facing direction and an up direction.
807    ///
808    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
809    ///
810    /// # Panics
811    ///
812    /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
813    #[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    /// Creates a left-handed view matrix using a camera position, a focal point and an up
834    /// direction.
835    ///
836    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
837    ///
838    /// # Panics
839    ///
840    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
841    #[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    /// Creates a right-handed view matrix using a camera position, a focal point and an up
853    /// direction.
854    ///
855    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
856    ///
857    /// # Panics
858    ///
859    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
860    #[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    /// Transforms a 3D vector.
871    #[inline]
872    #[must_use]
873    pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
874        self.mul_vec3a(rhs.into()).into()
875    }
876
877    /// Transforms a [`Vec3A`].
878    #[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    /// Transforms a 3D vector by the transpose of `self`.
888    #[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    /// Transforms a [`Vec3A`] by the transpose of `self`.
895    #[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    /// Multiplies two 3x3 matrices.
906    #[inline]
907    #[must_use]
908    pub fn mul_mat3(&self, rhs: &Self) -> Self {
909        self.mul(rhs)
910    }
911
912    /// Adds two 3x3 matrices.
913    #[inline]
914    #[must_use]
915    pub fn add_mat3(&self, rhs: &Self) -> Self {
916        self.add(rhs)
917    }
918
919    /// Subtracts two 3x3 matrices.
920    #[inline]
921    #[must_use]
922    pub fn sub_mat3(&self, rhs: &Self) -> Self {
923        self.sub(rhs)
924    }
925
926    /// Multiplies a 3x3 matrix by a scalar.
927    #[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    /// Multiply `self` by a scaling vector `scale`.
938    /// This is faster than creating a whole diagonal scaling matrix and then multiplying that.
939    /// This operation is commutative.
940    #[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    /// Divides a 3x3 matrix by a scalar.
951    #[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    /// Returns a matrix containing the reciprocal `1.0/n` of each element of `self`.
963    #[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    /// Returns true if the absolute difference of all elements between `self` and `rhs`
974    /// is less than or equal to `max_abs_diff`.
975    ///
976    /// This can be used to compare if two matrices contain similar elements. It works best
977    /// when comparing with a known value. The `max_abs_diff` that should be used used
978    /// depends on the values being compared against.
979    ///
980    /// For more see
981    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
982    #[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    /// Takes the absolute value of each element in `self`
991    #[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}