glam/f32/neon/
mat3a.rs

1// Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3use 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
13use core::arch::aarch64::*;
14
15#[cfg(feature = "zerocopy")]
16use zerocopy_derive::*;
17
18/// Creates a 3x3 matrix from three column vectors.
19#[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/// A 3x3 column major matrix.
26///
27/// This 3x3 matrix type features convenience methods for creating and using linear and
28/// affine transformations. If you are primarily dealing with 2D affine transformations the
29/// [`Affine2`](crate::Affine2) type is much faster and more space efficient than
30/// using a 3x3 matrix.
31///
32/// Linear transformations including 3D rotation and scale can be created using methods
33/// such as [`Self::from_diagonal()`], [`Self::from_quat()`], [`Self::from_axis_angle()`],
34/// [`Self::from_rotation_x()`], [`Self::from_rotation_y()`], or
35/// [`Self::from_rotation_z()`].
36///
37/// The resulting matrices can be use to transform 3D vectors using regular vector
38/// multiplication.
39///
40/// Affine transformations including 2D translation, rotation and scale can be created
41/// using methods such as [`Self::from_translation()`], [`Self::from_angle()`],
42/// [`Self::from_scale()`] and [`Self::from_scale_angle_translation()`].
43///
44/// The [`Self::transform_point2()`] and [`Self::transform_vector2()`] convenience methods
45/// are provided for performing affine transforms on 2D vectors and points. These multiply
46/// 2D inputs as 3D vectors with an implicit `z` value of `1` for points and `0` for
47/// vectors respectively. These methods assume that `Self` contains a valid affine
48/// transform.
49#[derive(Clone, Copy)]
50#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
51#[cfg_attr(
52    feature = "zerocopy",
53    derive(FromBytes, Immutable, IntoBytes, KnownLayout)
54)]
55#[repr(C)]
56pub struct Mat3A {
57    pub x_axis: Vec3A,
58    pub y_axis: Vec3A,
59    pub z_axis: Vec3A,
60}
61
62impl Mat3A {
63    /// A 3x3 matrix with all elements set to `0.0`.
64    pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
65
66    /// A 3x3 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
67    pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
68
69    /// All NAN:s.
70    pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::NAN);
71
72    #[allow(clippy::too_many_arguments)]
73    #[inline(always)]
74    #[must_use]
75    const fn new(
76        m00: f32,
77        m01: f32,
78        m02: f32,
79        m10: f32,
80        m11: f32,
81        m12: f32,
82        m20: f32,
83        m21: f32,
84        m22: f32,
85    ) -> Self {
86        Self {
87            x_axis: Vec3A::new(m00, m01, m02),
88            y_axis: Vec3A::new(m10, m11, m12),
89            z_axis: Vec3A::new(m20, m21, m22),
90        }
91    }
92
93    /// Creates a 3x3 matrix from three column vectors.
94    #[inline(always)]
95    #[must_use]
96    pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self {
97        Self {
98            x_axis,
99            y_axis,
100            z_axis,
101        }
102    }
103
104    /// Creates a 3x3 matrix from a `[f32; 9]` array stored in column major order.
105    /// If your data is stored in row major you will need to `transpose` the returned
106    /// matrix.
107    #[inline]
108    #[must_use]
109    pub const fn from_cols_array(m: &[f32; 9]) -> Self {
110        Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
111    }
112
113    /// Creates a `[f32; 9]` array storing data in column major order.
114    /// If you require data in row major order `transpose` the matrix first.
115    #[inline]
116    #[must_use]
117    pub const fn to_cols_array(&self) -> [f32; 9] {
118        let [x_axis_x, x_axis_y, x_axis_z] = self.x_axis.to_array();
119        let [y_axis_x, y_axis_y, y_axis_z] = self.y_axis.to_array();
120        let [z_axis_x, z_axis_y, z_axis_z] = self.z_axis.to_array();
121
122        [
123            x_axis_x, x_axis_y, x_axis_z, y_axis_x, y_axis_y, y_axis_z, z_axis_x, z_axis_y,
124            z_axis_z,
125        ]
126    }
127
128    /// Creates a 3x3 matrix from a `[[f32; 3]; 3]` 3D array stored in column major order.
129    /// If your data is in row major order you will need to `transpose` the returned
130    /// matrix.
131    #[inline]
132    #[must_use]
133    pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
134        Self::from_cols(
135            Vec3A::from_array(m[0]),
136            Vec3A::from_array(m[1]),
137            Vec3A::from_array(m[2]),
138        )
139    }
140
141    /// Creates a `[[f32; 3]; 3]` 3D array storing data in column major order.
142    /// If you require data in row major order `transpose` the matrix first.
143    #[inline]
144    #[must_use]
145    pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
146        [
147            self.x_axis.to_array(),
148            self.y_axis.to_array(),
149            self.z_axis.to_array(),
150        ]
151    }
152
153    /// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0.
154    #[doc(alias = "scale")]
155    #[inline]
156    #[must_use]
157    pub const fn from_diagonal(diagonal: Vec3) -> Self {
158        Self::new(
159            diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
160        )
161    }
162
163    /// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column.
164    #[inline]
165    #[must_use]
166    pub fn from_mat4(m: Mat4) -> Self {
167        Self::from_cols(
168            Vec3A::from_vec4(m.x_axis),
169            Vec3A::from_vec4(m.y_axis),
170            Vec3A::from_vec4(m.z_axis),
171        )
172    }
173
174    /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
175    /// and `j`th row.
176    ///
177    /// # Panics
178    ///
179    /// Panics if `i` or `j` is greater than 3.
180    #[inline]
181    #[must_use]
182    pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
183        match (i, j) {
184            (0, 0) => Self::from_cols(
185                Vec3A::from_vec4(m.y_axis.yzww()),
186                Vec3A::from_vec4(m.z_axis.yzww()),
187                Vec3A::from_vec4(m.w_axis.yzww()),
188            ),
189            (0, 1) => Self::from_cols(
190                Vec3A::from_vec4(m.y_axis.xzww()),
191                Vec3A::from_vec4(m.z_axis.xzww()),
192                Vec3A::from_vec4(m.w_axis.xzww()),
193            ),
194            (0, 2) => Self::from_cols(
195                Vec3A::from_vec4(m.y_axis.xyww()),
196                Vec3A::from_vec4(m.z_axis.xyww()),
197                Vec3A::from_vec4(m.w_axis.xyww()),
198            ),
199            (0, 3) => Self::from_cols(
200                Vec3A::from_vec4(m.y_axis.xyzw()),
201                Vec3A::from_vec4(m.z_axis.xyzw()),
202                Vec3A::from_vec4(m.w_axis.xyzw()),
203            ),
204            (1, 0) => Self::from_cols(
205                Vec3A::from_vec4(m.x_axis.yzww()),
206                Vec3A::from_vec4(m.z_axis.yzww()),
207                Vec3A::from_vec4(m.w_axis.yzww()),
208            ),
209            (1, 1) => Self::from_cols(
210                Vec3A::from_vec4(m.x_axis.xzww()),
211                Vec3A::from_vec4(m.z_axis.xzww()),
212                Vec3A::from_vec4(m.w_axis.xzww()),
213            ),
214            (1, 2) => Self::from_cols(
215                Vec3A::from_vec4(m.x_axis.xyww()),
216                Vec3A::from_vec4(m.z_axis.xyww()),
217                Vec3A::from_vec4(m.w_axis.xyww()),
218            ),
219            (1, 3) => Self::from_cols(
220                Vec3A::from_vec4(m.x_axis.xyzw()),
221                Vec3A::from_vec4(m.z_axis.xyzw()),
222                Vec3A::from_vec4(m.w_axis.xyzw()),
223            ),
224            (2, 0) => Self::from_cols(
225                Vec3A::from_vec4(m.x_axis.yzww()),
226                Vec3A::from_vec4(m.y_axis.yzww()),
227                Vec3A::from_vec4(m.w_axis.yzww()),
228            ),
229            (2, 1) => Self::from_cols(
230                Vec3A::from_vec4(m.x_axis.xzww()),
231                Vec3A::from_vec4(m.y_axis.xzww()),
232                Vec3A::from_vec4(m.w_axis.xzww()),
233            ),
234            (2, 2) => Self::from_cols(
235                Vec3A::from_vec4(m.x_axis.xyww()),
236                Vec3A::from_vec4(m.y_axis.xyww()),
237                Vec3A::from_vec4(m.w_axis.xyww()),
238            ),
239            (2, 3) => Self::from_cols(
240                Vec3A::from_vec4(m.x_axis.xyzw()),
241                Vec3A::from_vec4(m.y_axis.xyzw()),
242                Vec3A::from_vec4(m.w_axis.xyzw()),
243            ),
244            (3, 0) => Self::from_cols(
245                Vec3A::from_vec4(m.x_axis.yzww()),
246                Vec3A::from_vec4(m.y_axis.yzww()),
247                Vec3A::from_vec4(m.z_axis.yzww()),
248            ),
249            (3, 1) => Self::from_cols(
250                Vec3A::from_vec4(m.x_axis.xzww()),
251                Vec3A::from_vec4(m.y_axis.xzww()),
252                Vec3A::from_vec4(m.z_axis.xzww()),
253            ),
254            (3, 2) => Self::from_cols(
255                Vec3A::from_vec4(m.x_axis.xyww()),
256                Vec3A::from_vec4(m.y_axis.xyww()),
257                Vec3A::from_vec4(m.z_axis.xyww()),
258            ),
259            (3, 3) => Self::from_cols(
260                Vec3A::from_vec4(m.x_axis.xyzw()),
261                Vec3A::from_vec4(m.y_axis.xyzw()),
262                Vec3A::from_vec4(m.z_axis.xyzw()),
263            ),
264            _ => panic!("index out of bounds"),
265        }
266    }
267
268    /// Creates a 3D rotation matrix from the given quaternion.
269    ///
270    /// # Panics
271    ///
272    /// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
273    #[inline]
274    #[must_use]
275    pub fn from_quat(rotation: Quat) -> Self {
276        glam_assert!(rotation.is_normalized());
277
278        let x2 = rotation.x + rotation.x;
279        let y2 = rotation.y + rotation.y;
280        let z2 = rotation.z + rotation.z;
281        let xx = rotation.x * x2;
282        let xy = rotation.x * y2;
283        let xz = rotation.x * z2;
284        let yy = rotation.y * y2;
285        let yz = rotation.y * z2;
286        let zz = rotation.z * z2;
287        let wx = rotation.w * x2;
288        let wy = rotation.w * y2;
289        let wz = rotation.w * z2;
290
291        Self::from_cols(
292            Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
293            Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
294            Vec3A::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
295        )
296    }
297
298    /// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in
299    /// radians).
300    ///
301    /// # Panics
302    ///
303    /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
304    #[inline]
305    #[must_use]
306    pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
307        glam_assert!(axis.is_normalized());
308
309        let (sin, cos) = math::sin_cos(angle);
310        let (xsin, ysin, zsin) = axis.mul(sin).into();
311        let (x, y, z) = axis.into();
312        let (x2, y2, z2) = axis.mul(axis).into();
313        let omc = 1.0 - cos;
314        let xyomc = x * y * omc;
315        let xzomc = x * z * omc;
316        let yzomc = y * z * omc;
317        Self::from_cols(
318            Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
319            Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
320            Vec3A::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
321        )
322    }
323
324    /// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in
325    /// radians).
326    #[inline]
327    #[must_use]
328    pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
329        Self::from_euler_angles(order, a, b, c)
330    }
331
332    /// Extract Euler angles with the given Euler rotation order.
333    ///
334    /// Note if the input matrix contains scales, shears, or other non-rotation transformations then
335    /// the resulting Euler angles will be ill-defined.
336    ///
337    /// # Panics
338    ///
339    /// Will panic if any input matrix column is not normalized when `glam_assert` is enabled.
340    #[inline]
341    #[must_use]
342    pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
343        glam_assert!(
344            self.x_axis.is_normalized()
345                && self.y_axis.is_normalized()
346                && self.z_axis.is_normalized()
347        );
348        self.to_euler_angles(order)
349    }
350
351    /// Creates a 3D rotation matrix from `angle` (in radians) around the x axis.
352    #[inline]
353    #[must_use]
354    pub fn from_rotation_x(angle: f32) -> Self {
355        let (sina, cosa) = math::sin_cos(angle);
356        Self::from_cols(
357            Vec3A::X,
358            Vec3A::new(0.0, cosa, sina),
359            Vec3A::new(0.0, -sina, cosa),
360        )
361    }
362
363    /// Creates a 3D rotation matrix from `angle` (in radians) around the y axis.
364    #[inline]
365    #[must_use]
366    pub fn from_rotation_y(angle: f32) -> Self {
367        let (sina, cosa) = math::sin_cos(angle);
368        Self::from_cols(
369            Vec3A::new(cosa, 0.0, -sina),
370            Vec3A::Y,
371            Vec3A::new(sina, 0.0, cosa),
372        )
373    }
374
375    /// Creates a 3D rotation matrix from `angle` (in radians) around the z axis.
376    #[inline]
377    #[must_use]
378    pub fn from_rotation_z(angle: f32) -> Self {
379        let (sina, cosa) = math::sin_cos(angle);
380        Self::from_cols(
381            Vec3A::new(cosa, sina, 0.0),
382            Vec3A::new(-sina, cosa, 0.0),
383            Vec3A::Z,
384        )
385    }
386
387    /// Creates an affine transformation matrix from the given 2D `translation`.
388    ///
389    /// The resulting matrix can be used to transform 2D points and vectors. See
390    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
391    #[inline]
392    #[must_use]
393    pub fn from_translation(translation: Vec2) -> Self {
394        Self::from_cols(
395            Vec3A::X,
396            Vec3A::Y,
397            Vec3A::new(translation.x, translation.y, 1.0),
398        )
399    }
400
401    /// Creates an affine transformation matrix from the given 2D rotation `angle` (in
402    /// radians).
403    ///
404    /// The resulting matrix can be used to transform 2D points and vectors. See
405    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
406    #[inline]
407    #[must_use]
408    pub fn from_angle(angle: f32) -> Self {
409        let (sin, cos) = math::sin_cos(angle);
410        Self::from_cols(
411            Vec3A::new(cos, sin, 0.0),
412            Vec3A::new(-sin, cos, 0.0),
413            Vec3A::Z,
414        )
415    }
416
417    /// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in
418    /// radians) and `translation`.
419    ///
420    /// The resulting matrix can be used to transform 2D points and vectors. See
421    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
422    #[inline]
423    #[must_use]
424    pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
425        let (sin, cos) = math::sin_cos(angle);
426        Self::from_cols(
427            Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
428            Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
429            Vec3A::new(translation.x, translation.y, 1.0),
430        )
431    }
432
433    /// Creates an affine transformation matrix from the given non-uniform 2D `scale`.
434    ///
435    /// The resulting matrix can be used to transform 2D points and vectors. See
436    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
437    ///
438    /// # Panics
439    ///
440    /// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
441    #[inline]
442    #[must_use]
443    pub fn from_scale(scale: Vec2) -> Self {
444        // Do not panic as long as any component is non-zero
445        glam_assert!(scale.cmpne(Vec2::ZERO).any());
446
447        Self::from_cols(
448            Vec3A::new(scale.x, 0.0, 0.0),
449            Vec3A::new(0.0, scale.y, 0.0),
450            Vec3A::Z,
451        )
452    }
453
454    /// Creates an affine transformation matrix from the given 2x2 matrix.
455    ///
456    /// The resulting matrix can be used to transform 2D points and vectors. See
457    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
458    #[inline]
459    pub fn from_mat2(m: Mat2) -> Self {
460        Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
461    }
462
463    /// Creates a 3x3 matrix from the first 9 values in `slice`.
464    ///
465    /// # Panics
466    ///
467    /// Panics if `slice` is less than 9 elements long.
468    #[inline]
469    #[must_use]
470    pub const fn from_cols_slice(slice: &[f32]) -> Self {
471        Self::new(
472            slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
473            slice[8],
474        )
475    }
476
477    /// Writes the columns of `self` to the first 9 elements in `slice`.
478    ///
479    /// # Panics
480    ///
481    /// Panics if `slice` is less than 9 elements long.
482    #[inline]
483    pub fn write_cols_to_slice(&self, slice: &mut [f32]) {
484        slice[0] = self.x_axis.x;
485        slice[1] = self.x_axis.y;
486        slice[2] = self.x_axis.z;
487        slice[3] = self.y_axis.x;
488        slice[4] = self.y_axis.y;
489        slice[5] = self.y_axis.z;
490        slice[6] = self.z_axis.x;
491        slice[7] = self.z_axis.y;
492        slice[8] = self.z_axis.z;
493    }
494
495    /// Returns the matrix column for the given `index`.
496    ///
497    /// # Panics
498    ///
499    /// Panics if `index` is greater than 2.
500    #[inline]
501    #[must_use]
502    pub fn col(&self, index: usize) -> Vec3A {
503        match index {
504            0 => self.x_axis,
505            1 => self.y_axis,
506            2 => self.z_axis,
507            _ => panic!("index out of bounds"),
508        }
509    }
510
511    /// Returns a mutable reference to the matrix column for the given `index`.
512    ///
513    /// # Panics
514    ///
515    /// Panics if `index` is greater than 2.
516    #[inline]
517    pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
518        match index {
519            0 => &mut self.x_axis,
520            1 => &mut self.y_axis,
521            2 => &mut self.z_axis,
522            _ => panic!("index out of bounds"),
523        }
524    }
525
526    /// Returns the matrix row for the given `index`.
527    ///
528    /// # Panics
529    ///
530    /// Panics if `index` is greater than 2.
531    #[inline]
532    #[must_use]
533    pub fn row(&self, index: usize) -> Vec3A {
534        match index {
535            0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
536            1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
537            2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
538            _ => panic!("index out of bounds"),
539        }
540    }
541
542    /// Returns `true` if, and only if, all elements are finite.
543    /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
544    #[inline]
545    #[must_use]
546    pub fn is_finite(&self) -> bool {
547        self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
548    }
549
550    /// Returns `true` if any elements are `NaN`.
551    #[inline]
552    #[must_use]
553    pub fn is_nan(&self) -> bool {
554        self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
555    }
556
557    /// Returns the transpose of `self`.
558    #[inline]
559    #[must_use]
560    pub fn transpose(&self) -> Self {
561        let x = self.x_axis.0;
562        let y = self.y_axis.0;
563        let z = self.z_axis.0;
564        unsafe {
565            let tmp0 = vreinterpretq_f32_u64(vsetq_lane_u64(
566                vgetq_lane_u64(vreinterpretq_u64_f32(y), 0),
567                vreinterpretq_u64_f32(x),
568                1,
569            ));
570            let tmp1 = vreinterpretq_f32_u64(vzip2q_u64(
571                vreinterpretq_u64_f32(x),
572                vreinterpretq_u64_f32(y),
573            ));
574            Mat3A::from_cols(
575                Vec3A::from(vsetq_lane_f32(vgetq_lane_f32(z, 0), vuzp1q_f32(tmp0, z), 3)),
576                Vec3A::from(vuzp2q_f32(tmp0, vdupq_laneq_f32(z, 1))),
577                Vec3A::from(vsetq_lane_f32(vgetq_lane_f32(z, 2), vuzp1q_f32(tmp1, z), 2)),
578            )
579        }
580    }
581
582    /// Returns the diagonal of `self`.
583    #[inline]
584    #[must_use]
585    pub fn diagonal(&self) -> Vec3A {
586        Vec3A::new(self.x_axis.x, self.y_axis.y, self.z_axis.z)
587    }
588
589    /// Returns the determinant of `self`.
590    #[inline]
591    #[must_use]
592    pub fn determinant(&self) -> f32 {
593        self.z_axis.dot(self.x_axis.cross(self.y_axis))
594    }
595
596    /// If `CHECKED` is true then if the determinant is zero this function will return a tuple
597    /// containing a zero matrix and false. If the determinant is non zero a tuple containing the
598    /// inverted matrix and true is returned.
599    ///
600    /// If `CHECKED` is false then the determinant is not checked and if it is zero the resulting
601    /// inverted matrix will be invalid. Will panic if the determinant of `self` is zero when
602    /// `glam_assert` is enabled.
603    ///
604    /// A tuple containing the inverted matrix and a bool is used instead of an option here as
605    /// regular Rust enums put the discriminant first which can result in a lot of padding if the
606    /// matrix is aligned.
607    #[inline(always)]
608    #[must_use]
609    fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
610        let tmp0 = self.y_axis.cross(self.z_axis);
611        let tmp1 = self.z_axis.cross(self.x_axis);
612        let tmp2 = self.x_axis.cross(self.y_axis);
613        let det = self.z_axis.dot(tmp2);
614        if CHECKED {
615            if det == 0.0 {
616                return (Self::ZERO, false);
617            }
618        } else {
619            glam_assert!(det != 0.0);
620        }
621        let inv_det = Vec3A::splat(det.recip());
622        (
623            Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose(),
624            true,
625        )
626    }
627
628    /// Returns the inverse of `self`.
629    ///
630    /// If the matrix is not invertible the returned matrix will be invalid.
631    ///
632    /// # Panics
633    ///
634    /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
635    #[inline]
636    #[must_use]
637    pub fn inverse(&self) -> Self {
638        self.inverse_checked::<false>().0
639    }
640
641    /// Returns the inverse of `self` or `None` if the matrix is not invertible.
642    #[inline]
643    #[must_use]
644    pub fn try_inverse(&self) -> Option<Self> {
645        let (m, is_valid) = self.inverse_checked::<true>();
646        if is_valid {
647            Some(m)
648        } else {
649            None
650        }
651    }
652
653    /// Returns the inverse of `self` or `Mat3A::ZERO` if the matrix is not invertible.
654    #[inline]
655    #[must_use]
656    pub fn inverse_or_zero(&self) -> Self {
657        self.inverse_checked::<true>().0
658    }
659
660    /// Transforms the given 2D vector as a point.
661    ///
662    /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
663    ///
664    /// This method assumes that `self` contains a valid affine transform.
665    ///
666    /// # Panics
667    ///
668    /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
669    #[inline]
670    #[must_use]
671    pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
672        glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
673        Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
674    }
675
676    /// Rotates the given 2D vector.
677    ///
678    /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
679    ///
680    /// This method assumes that `self` contains a valid affine transform.
681    ///
682    /// # Panics
683    ///
684    /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
685    #[inline]
686    #[must_use]
687    pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
688        glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
689        Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
690    }
691
692    /// Creates a left-handed view matrix using a facing direction and an up direction.
693    ///
694    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
695    ///
696    /// # Panics
697    ///
698    /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
699    #[inline]
700    #[must_use]
701    pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
702        Self::look_to_rh(-dir, up)
703    }
704
705    /// Creates a right-handed view matrix using a facing direction and an up direction.
706    ///
707    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
708    ///
709    /// # Panics
710    ///
711    /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
712    #[inline]
713    #[must_use]
714    pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
715        glam_assert!(dir.is_normalized());
716        glam_assert!(up.is_normalized());
717        let f = dir;
718        let s = f.cross(up).normalize();
719        let u = s.cross(f);
720
721        Self::from_cols(
722            Vec3A::new(s.x, u.x, -f.x),
723            Vec3A::new(s.y, u.y, -f.y),
724            Vec3A::new(s.z, u.z, -f.z),
725        )
726    }
727
728    /// Creates a left-handed view matrix using a camera position, a focal point and an up
729    /// direction.
730    ///
731    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
732    ///
733    /// # Panics
734    ///
735    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
736    #[inline]
737    #[must_use]
738    pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
739        Self::look_to_lh(center.sub(eye).normalize(), up)
740    }
741
742    /// Creates a right-handed view matrix using a camera position, a focal point and an up
743    /// direction.
744    ///
745    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
746    ///
747    /// # Panics
748    ///
749    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
750    #[inline]
751    pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
752        Self::look_to_rh(center.sub(eye).normalize(), up)
753    }
754
755    /// Transforms a 3D vector.
756    #[inline]
757    #[must_use]
758    pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
759        self.mul_vec3a(rhs.into()).into()
760    }
761
762    /// Transforms a [`Vec3A`].
763    #[inline]
764    #[must_use]
765    pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
766        let mut res = self.x_axis.mul(rhs.xxx());
767        res = res.add(self.y_axis.mul(rhs.yyy()));
768        res = res.add(self.z_axis.mul(rhs.zzz()));
769        res
770    }
771
772    /// Transforms a 3D vector by the transpose of `self`.
773    #[inline]
774    #[must_use]
775    pub fn mul_transpose_vec3(&self, rhs: Vec3) -> Vec3 {
776        self.mul_transpose_vec3a(rhs.into()).into()
777    }
778
779    /// Transforms a [`Vec3A`] by the transpose of `self`.
780    #[inline]
781    #[must_use]
782    pub fn mul_transpose_vec3a(&self, rhs: Vec3A) -> Vec3A {
783        Vec3A::new(
784            self.x_axis.dot(rhs),
785            self.y_axis.dot(rhs),
786            self.z_axis.dot(rhs),
787        )
788    }
789
790    /// Multiplies two 3x3 matrices.
791    #[inline]
792    #[must_use]
793    pub fn mul_mat3(&self, rhs: &Self) -> Self {
794        self.mul(rhs)
795    }
796
797    /// Adds two 3x3 matrices.
798    #[inline]
799    #[must_use]
800    pub fn add_mat3(&self, rhs: &Self) -> Self {
801        self.add(rhs)
802    }
803
804    /// Subtracts two 3x3 matrices.
805    #[inline]
806    #[must_use]
807    pub fn sub_mat3(&self, rhs: &Self) -> Self {
808        self.sub(rhs)
809    }
810
811    /// Multiplies a 3x3 matrix by a scalar.
812    #[inline]
813    #[must_use]
814    pub fn mul_scalar(&self, rhs: f32) -> Self {
815        Self::from_cols(
816            self.x_axis.mul(rhs),
817            self.y_axis.mul(rhs),
818            self.z_axis.mul(rhs),
819        )
820    }
821
822    /// Multiply `self` by a scaling vector `scale`.
823    /// This is faster than creating a whole diagonal scaling matrix and then multiplying that.
824    /// This operation is commutative.
825    #[inline]
826    #[must_use]
827    pub fn mul_diagonal_scale(&self, scale: Vec3) -> Self {
828        Self::from_cols(
829            self.x_axis * scale.x,
830            self.y_axis * scale.y,
831            self.z_axis * scale.z,
832        )
833    }
834
835    /// Divides a 3x3 matrix by a scalar.
836    #[inline]
837    #[must_use]
838    pub fn div_scalar(&self, rhs: f32) -> Self {
839        let rhs = Vec3A::splat(rhs);
840        Self::from_cols(
841            self.x_axis.div(rhs),
842            self.y_axis.div(rhs),
843            self.z_axis.div(rhs),
844        )
845    }
846
847    /// Returns true if the absolute difference of all elements between `self` and `rhs`
848    /// is less than or equal to `max_abs_diff`.
849    ///
850    /// This can be used to compare if two matrices contain similar elements. It works best
851    /// when comparing with a known value. The `max_abs_diff` that should be used used
852    /// depends on the values being compared against.
853    ///
854    /// For more see
855    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
856    #[inline]
857    #[must_use]
858    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
859        self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
860            && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
861            && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
862    }
863
864    /// Takes the absolute value of each element in `self`
865    #[inline]
866    #[must_use]
867    pub fn abs(&self) -> Self {
868        Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
869    }
870
871    #[inline]
872    pub fn as_dmat3(&self) -> DMat3 {
873        DMat3::from_cols(
874            self.x_axis.as_dvec3(),
875            self.y_axis.as_dvec3(),
876            self.z_axis.as_dvec3(),
877        )
878    }
879}
880
881impl Default for Mat3A {
882    #[inline]
883    fn default() -> Self {
884        Self::IDENTITY
885    }
886}
887
888impl Add for Mat3A {
889    type Output = Self;
890    #[inline]
891    fn add(self, rhs: Self) -> Self {
892        Self::from_cols(
893            self.x_axis.add(rhs.x_axis),
894            self.y_axis.add(rhs.y_axis),
895            self.z_axis.add(rhs.z_axis),
896        )
897    }
898}
899
900impl Add<&Self> for Mat3A {
901    type Output = Self;
902    #[inline]
903    fn add(self, rhs: &Self) -> Self {
904        self.add(*rhs)
905    }
906}
907
908impl Add<&Mat3A> for &Mat3A {
909    type Output = Mat3A;
910    #[inline]
911    fn add(self, rhs: &Mat3A) -> Mat3A {
912        (*self).add(*rhs)
913    }
914}
915
916impl Add<Mat3A> for &Mat3A {
917    type Output = Mat3A;
918    #[inline]
919    fn add(self, rhs: Mat3A) -> Mat3A {
920        (*self).add(rhs)
921    }
922}
923
924impl AddAssign for Mat3A {
925    #[inline]
926    fn add_assign(&mut self, rhs: Self) {
927        *self = self.add(rhs);
928    }
929}
930
931impl AddAssign<&Self> for Mat3A {
932    #[inline]
933    fn add_assign(&mut self, rhs: &Self) {
934        self.add_assign(*rhs);
935    }
936}
937
938impl Sub for Mat3A {
939    type Output = Self;
940    #[inline]
941    fn sub(self, rhs: Self) -> Self {
942        Self::from_cols(
943            self.x_axis.sub(rhs.x_axis),
944            self.y_axis.sub(rhs.y_axis),
945            self.z_axis.sub(rhs.z_axis),
946        )
947    }
948}
949
950impl Sub<&Self> for Mat3A {
951    type Output = Self;
952    #[inline]
953    fn sub(self, rhs: &Self) -> Self {
954        self.sub(*rhs)
955    }
956}
957
958impl Sub<&Mat3A> for &Mat3A {
959    type Output = Mat3A;
960    #[inline]
961    fn sub(self, rhs: &Mat3A) -> Mat3A {
962        (*self).sub(*rhs)
963    }
964}
965
966impl Sub<Mat3A> for &Mat3A {
967    type Output = Mat3A;
968    #[inline]
969    fn sub(self, rhs: Mat3A) -> Mat3A {
970        (*self).sub(rhs)
971    }
972}
973
974impl SubAssign for Mat3A {
975    #[inline]
976    fn sub_assign(&mut self, rhs: Self) {
977        *self = self.sub(rhs);
978    }
979}
980
981impl SubAssign<&Self> for Mat3A {
982    #[inline]
983    fn sub_assign(&mut self, rhs: &Self) {
984        self.sub_assign(*rhs);
985    }
986}
987
988impl Neg for Mat3A {
989    type Output = Self;
990    #[inline]
991    fn neg(self) -> Self::Output {
992        Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
993    }
994}
995
996impl Neg for &Mat3A {
997    type Output = Mat3A;
998    #[inline]
999    fn neg(self) -> Mat3A {
1000        (*self).neg()
1001    }
1002}
1003
1004impl Mul for Mat3A {
1005    type Output = Self;
1006    #[inline]
1007    fn mul(self, rhs: Self) -> Self {
1008        Self::from_cols(
1009            self.mul(rhs.x_axis),
1010            self.mul(rhs.y_axis),
1011            self.mul(rhs.z_axis),
1012        )
1013    }
1014}
1015
1016impl Mul<&Self> for Mat3A {
1017    type Output = Self;
1018    #[inline]
1019    fn mul(self, rhs: &Self) -> Self {
1020        self.mul(*rhs)
1021    }
1022}
1023
1024impl Mul<&Mat3A> for &Mat3A {
1025    type Output = Mat3A;
1026    #[inline]
1027    fn mul(self, rhs: &Mat3A) -> Mat3A {
1028        (*self).mul(*rhs)
1029    }
1030}
1031
1032impl Mul<Mat3A> for &Mat3A {
1033    type Output = Mat3A;
1034    #[inline]
1035    fn mul(self, rhs: Mat3A) -> Mat3A {
1036        (*self).mul(rhs)
1037    }
1038}
1039
1040impl MulAssign for Mat3A {
1041    #[inline]
1042    fn mul_assign(&mut self, rhs: Self) {
1043        *self = self.mul(rhs);
1044    }
1045}
1046
1047impl MulAssign<&Self> for Mat3A {
1048    #[inline]
1049    fn mul_assign(&mut self, rhs: &Self) {
1050        self.mul_assign(*rhs);
1051    }
1052}
1053
1054impl Mul<Vec3A> for Mat3A {
1055    type Output = Vec3A;
1056    #[inline]
1057    fn mul(self, rhs: Vec3A) -> Self::Output {
1058        self.mul_vec3a(rhs)
1059    }
1060}
1061
1062impl Mul<&Vec3A> for Mat3A {
1063    type Output = Vec3A;
1064    #[inline]
1065    fn mul(self, rhs: &Vec3A) -> Vec3A {
1066        self.mul(*rhs)
1067    }
1068}
1069
1070impl Mul<&Vec3A> for &Mat3A {
1071    type Output = Vec3A;
1072    #[inline]
1073    fn mul(self, rhs: &Vec3A) -> Vec3A {
1074        (*self).mul(*rhs)
1075    }
1076}
1077
1078impl Mul<Vec3A> for &Mat3A {
1079    type Output = Vec3A;
1080    #[inline]
1081    fn mul(self, rhs: Vec3A) -> Vec3A {
1082        (*self).mul(rhs)
1083    }
1084}
1085
1086impl Mul<Mat3A> for f32 {
1087    type Output = Mat3A;
1088    #[inline]
1089    fn mul(self, rhs: Mat3A) -> Self::Output {
1090        rhs.mul_scalar(self)
1091    }
1092}
1093
1094impl Mul<&Mat3A> for f32 {
1095    type Output = Mat3A;
1096    #[inline]
1097    fn mul(self, rhs: &Mat3A) -> Mat3A {
1098        self.mul(*rhs)
1099    }
1100}
1101
1102impl Mul<&Mat3A> for &f32 {
1103    type Output = Mat3A;
1104    #[inline]
1105    fn mul(self, rhs: &Mat3A) -> Mat3A {
1106        (*self).mul(*rhs)
1107    }
1108}
1109
1110impl Mul<Mat3A> for &f32 {
1111    type Output = Mat3A;
1112    #[inline]
1113    fn mul(self, rhs: Mat3A) -> Mat3A {
1114        (*self).mul(rhs)
1115    }
1116}
1117
1118impl Mul<f32> for Mat3A {
1119    type Output = Self;
1120    #[inline]
1121    fn mul(self, rhs: f32) -> Self {
1122        self.mul_scalar(rhs)
1123    }
1124}
1125
1126impl Mul<&f32> for Mat3A {
1127    type Output = Self;
1128    #[inline]
1129    fn mul(self, rhs: &f32) -> Self {
1130        self.mul(*rhs)
1131    }
1132}
1133
1134impl Mul<&f32> for &Mat3A {
1135    type Output = Mat3A;
1136    #[inline]
1137    fn mul(self, rhs: &f32) -> Mat3A {
1138        (*self).mul(*rhs)
1139    }
1140}
1141
1142impl Mul<f32> for &Mat3A {
1143    type Output = Mat3A;
1144    #[inline]
1145    fn mul(self, rhs: f32) -> Mat3A {
1146        (*self).mul(rhs)
1147    }
1148}
1149
1150impl MulAssign<f32> for Mat3A {
1151    #[inline]
1152    fn mul_assign(&mut self, rhs: f32) {
1153        *self = self.mul(rhs);
1154    }
1155}
1156
1157impl MulAssign<&f32> for Mat3A {
1158    #[inline]
1159    fn mul_assign(&mut self, rhs: &f32) {
1160        self.mul_assign(*rhs);
1161    }
1162}
1163
1164impl Div<Mat3A> for f32 {
1165    type Output = Mat3A;
1166    #[inline]
1167    fn div(self, rhs: Mat3A) -> Self::Output {
1168        rhs.div_scalar(self)
1169    }
1170}
1171
1172impl Div<&Mat3A> for f32 {
1173    type Output = Mat3A;
1174    #[inline]
1175    fn div(self, rhs: &Mat3A) -> Mat3A {
1176        self.div(*rhs)
1177    }
1178}
1179
1180impl Div<&Mat3A> for &f32 {
1181    type Output = Mat3A;
1182    #[inline]
1183    fn div(self, rhs: &Mat3A) -> Mat3A {
1184        (*self).div(*rhs)
1185    }
1186}
1187
1188impl Div<Mat3A> for &f32 {
1189    type Output = Mat3A;
1190    #[inline]
1191    fn div(self, rhs: Mat3A) -> Mat3A {
1192        (*self).div(rhs)
1193    }
1194}
1195
1196impl Div<f32> for Mat3A {
1197    type Output = Self;
1198    #[inline]
1199    fn div(self, rhs: f32) -> Self {
1200        self.div_scalar(rhs)
1201    }
1202}
1203
1204impl Div<&f32> for Mat3A {
1205    type Output = Self;
1206    #[inline]
1207    fn div(self, rhs: &f32) -> Self {
1208        self.div(*rhs)
1209    }
1210}
1211
1212impl Div<&f32> for &Mat3A {
1213    type Output = Mat3A;
1214    #[inline]
1215    fn div(self, rhs: &f32) -> Mat3A {
1216        (*self).div(*rhs)
1217    }
1218}
1219
1220impl Div<f32> for &Mat3A {
1221    type Output = Mat3A;
1222    #[inline]
1223    fn div(self, rhs: f32) -> Mat3A {
1224        (*self).div(rhs)
1225    }
1226}
1227
1228impl DivAssign<f32> for Mat3A {
1229    #[inline]
1230    fn div_assign(&mut self, rhs: f32) {
1231        *self = self.div(rhs);
1232    }
1233}
1234
1235impl DivAssign<&f32> for Mat3A {
1236    #[inline]
1237    fn div_assign(&mut self, rhs: &f32) {
1238        self.div_assign(*rhs);
1239    }
1240}
1241
1242impl Mul<Vec3> for Mat3A {
1243    type Output = Vec3;
1244    #[inline]
1245    fn mul(self, rhs: Vec3) -> Vec3 {
1246        self.mul_vec3a(rhs.into()).into()
1247    }
1248}
1249
1250impl Mul<&Vec3> for Mat3A {
1251    type Output = Vec3;
1252    #[inline]
1253    fn mul(self, rhs: &Vec3) -> Vec3 {
1254        self.mul(*rhs)
1255    }
1256}
1257
1258impl Mul<&Vec3> for &Mat3A {
1259    type Output = Vec3;
1260    #[inline]
1261    fn mul(self, rhs: &Vec3) -> Vec3 {
1262        (*self).mul(*rhs)
1263    }
1264}
1265
1266impl Mul<Vec3> for &Mat3A {
1267    type Output = Vec3;
1268    #[inline]
1269    fn mul(self, rhs: Vec3) -> Vec3 {
1270        (*self).mul(rhs)
1271    }
1272}
1273
1274impl From<Mat3> for Mat3A {
1275    #[inline]
1276    fn from(m: Mat3) -> Self {
1277        Self {
1278            x_axis: m.x_axis.into(),
1279            y_axis: m.y_axis.into(),
1280            z_axis: m.z_axis.into(),
1281        }
1282    }
1283}
1284
1285impl Sum<Self> for Mat3A {
1286    fn sum<I>(iter: I) -> Self
1287    where
1288        I: Iterator<Item = Self>,
1289    {
1290        iter.fold(Self::ZERO, Self::add)
1291    }
1292}
1293
1294impl<'a> Sum<&'a Self> for Mat3A {
1295    fn sum<I>(iter: I) -> Self
1296    where
1297        I: Iterator<Item = &'a Self>,
1298    {
1299        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1300    }
1301}
1302
1303impl Product for Mat3A {
1304    fn product<I>(iter: I) -> Self
1305    where
1306        I: Iterator<Item = Self>,
1307    {
1308        iter.fold(Self::IDENTITY, Self::mul)
1309    }
1310}
1311
1312impl<'a> Product<&'a Self> for Mat3A {
1313    fn product<I>(iter: I) -> Self
1314    where
1315        I: Iterator<Item = &'a Self>,
1316    {
1317        iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1318    }
1319}
1320
1321impl PartialEq for Mat3A {
1322    #[inline]
1323    fn eq(&self, rhs: &Self) -> bool {
1324        self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1325    }
1326}
1327
1328impl fmt::Debug for Mat3A {
1329    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1330        fmt.debug_struct(stringify!(Mat3A))
1331            .field("x_axis", &self.x_axis)
1332            .field("y_axis", &self.y_axis)
1333            .field("z_axis", &self.z_axis)
1334            .finish()
1335    }
1336}
1337
1338impl fmt::Display for Mat3A {
1339    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1340        if let Some(p) = f.precision() {
1341            write!(
1342                f,
1343                "[{:.*}, {:.*}, {:.*}]",
1344                p, self.x_axis, p, self.y_axis, p, self.z_axis
1345            )
1346        } else {
1347            write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1348        }
1349    }
1350}