Skip to main content

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