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