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    #[deprecated(
622        since = "0.33.1",
623        note = "use the `glam::camera::lh::view::look_to_mat3` function instead"
624    )]
625    #[inline]
626    #[must_use]
627    pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
628        #[allow(deprecated)]
629        Self::look_to_rh(-dir, up)
630    }
631
632    /// Creates a right-handed view matrix using a facing direction and an up direction.
633    ///
634    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
635    ///
636    /// # Panics
637    ///
638    /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
639    #[deprecated(
640        since = "0.33.1",
641        note = "use the `glam::camera::rh::view::look_to_mat3` function instead"
642    )]
643    #[inline]
644    #[must_use]
645    pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
646        glam_assert!(dir.is_normalized());
647        glam_assert!(up.is_normalized());
648        let f = dir;
649        let s = f.cross(up).normalize();
650        let u = s.cross(f);
651
652        Self::from_cols(
653            Vec3::new(s.x, u.x, -f.x),
654            Vec3::new(s.y, u.y, -f.y),
655            Vec3::new(s.z, u.z, -f.z),
656        )
657    }
658
659    /// Creates a left-handed view matrix using a camera position, a focal point and an up
660    /// direction.
661    ///
662    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
663    ///
664    /// # Panics
665    ///
666    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
667    #[deprecated(
668        since = "0.33.1",
669        note = "use the `glam::camera::lh::view::look_at_mat3` function instead"
670    )]
671    #[inline]
672    #[must_use]
673    pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
674        #[allow(deprecated)]
675        Self::look_to_lh(center.sub(eye).normalize(), up)
676    }
677
678    /// Creates a right-handed view matrix using a camera position, a focal point and an up
679    /// direction.
680    ///
681    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
682    ///
683    /// # Panics
684    ///
685    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
686    #[deprecated(
687        since = "0.33.1",
688        note = "use the `glam::camera::rh::view::look_at_mat3` function instead"
689    )]
690    #[inline]
691    pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
692        #[allow(deprecated)]
693        Self::look_to_rh(center.sub(eye).normalize(), up)
694    }
695
696    /// Transforms a 3D vector.
697    #[inline]
698    #[must_use]
699    pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
700        let mut res = self.x_axis.mul(rhs.x);
701        res = res.add(self.y_axis.mul(rhs.y));
702        res = res.add(self.z_axis.mul(rhs.z));
703        res
704    }
705
706    /// Transforms a [`Vec3A`].
707    #[inline]
708    #[must_use]
709    pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
710        self.mul_vec3(rhs.into()).into()
711    }
712
713    /// Transforms a 3D vector by the transpose of `self`.
714    #[inline]
715    #[must_use]
716    pub fn mul_transpose_vec3(&self, rhs: Vec3) -> Vec3 {
717        Vec3::new(
718            self.x_axis.dot(rhs),
719            self.y_axis.dot(rhs),
720            self.z_axis.dot(rhs),
721        )
722    }
723
724    /// Multiplies two 3x3 matrices.
725    #[inline]
726    #[must_use]
727    pub fn mul_mat3(&self, rhs: &Self) -> Self {
728        self.mul(rhs)
729    }
730
731    /// Adds two 3x3 matrices.
732    #[inline]
733    #[must_use]
734    pub fn add_mat3(&self, rhs: &Self) -> Self {
735        self.add(rhs)
736    }
737
738    /// Subtracts two 3x3 matrices.
739    #[inline]
740    #[must_use]
741    pub fn sub_mat3(&self, rhs: &Self) -> Self {
742        self.sub(rhs)
743    }
744
745    /// Multiplies a 3x3 matrix by a scalar.
746    #[inline]
747    #[must_use]
748    pub fn mul_scalar(&self, rhs: f32) -> Self {
749        Self::from_cols(
750            self.x_axis.mul(rhs),
751            self.y_axis.mul(rhs),
752            self.z_axis.mul(rhs),
753        )
754    }
755
756    /// Multiply `self` by a scaling vector `scale`.
757    /// This is faster than creating a whole diagonal scaling matrix and then multiplying that.
758    /// This operation is commutative.
759    #[inline]
760    #[must_use]
761    pub fn mul_diagonal_scale(&self, scale: Vec3) -> Self {
762        Self::from_cols(
763            self.x_axis * scale.x,
764            self.y_axis * scale.y,
765            self.z_axis * scale.z,
766        )
767    }
768
769    /// Divides a 3x3 matrix by a scalar.
770    #[inline]
771    #[must_use]
772    pub fn div_scalar(&self, rhs: f32) -> Self {
773        let rhs = Vec3::splat(rhs);
774        Self::from_cols(
775            self.x_axis.div(rhs),
776            self.y_axis.div(rhs),
777            self.z_axis.div(rhs),
778        )
779    }
780
781    /// Returns a matrix containing the reciprocal `1.0/n` of each element of `self`.
782    #[inline]
783    #[must_use]
784    pub fn recip(&self) -> Self {
785        Self::from_cols(
786            self.x_axis.recip(),
787            self.y_axis.recip(),
788            self.z_axis.recip(),
789        )
790    }
791
792    /// Returns true if the absolute difference of all elements between `self` and `rhs`
793    /// is less than or equal to `max_abs_diff`.
794    ///
795    /// This can be used to compare if two matrices contain similar elements. It works best
796    /// when comparing with a known value. The `max_abs_diff` that should be used used
797    /// depends on the values being compared against.
798    ///
799    /// For more see
800    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
801    #[inline]
802    #[must_use]
803    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
804        self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
805            && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
806            && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
807    }
808
809    /// Takes the absolute value of each element in `self`
810    #[inline]
811    #[must_use]
812    pub fn abs(&self) -> Self {
813        Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
814    }
815
816    #[cfg(feature = "f64")]
817    #[inline]
818    #[must_use]
819    pub fn as_dmat3(&self) -> DMat3 {
820        DMat3::from_cols(
821            self.x_axis.as_dvec3(),
822            self.y_axis.as_dvec3(),
823            self.z_axis.as_dvec3(),
824        )
825    }
826}
827
828impl Default for Mat3 {
829    #[inline]
830    fn default() -> Self {
831        Self::IDENTITY
832    }
833}
834
835impl Add for Mat3 {
836    type Output = Self;
837    #[inline]
838    fn add(self, rhs: Self) -> Self {
839        Self::from_cols(
840            self.x_axis.add(rhs.x_axis),
841            self.y_axis.add(rhs.y_axis),
842            self.z_axis.add(rhs.z_axis),
843        )
844    }
845}
846
847impl Add<&Self> for Mat3 {
848    type Output = Self;
849    #[inline]
850    fn add(self, rhs: &Self) -> Self {
851        self.add(*rhs)
852    }
853}
854
855impl Add<&Mat3> for &Mat3 {
856    type Output = Mat3;
857    #[inline]
858    fn add(self, rhs: &Mat3) -> Mat3 {
859        (*self).add(*rhs)
860    }
861}
862
863impl Add<Mat3> for &Mat3 {
864    type Output = Mat3;
865    #[inline]
866    fn add(self, rhs: Mat3) -> Mat3 {
867        (*self).add(rhs)
868    }
869}
870
871impl AddAssign for Mat3 {
872    #[inline]
873    fn add_assign(&mut self, rhs: Self) {
874        *self = self.add(rhs);
875    }
876}
877
878impl AddAssign<&Self> for Mat3 {
879    #[inline]
880    fn add_assign(&mut self, rhs: &Self) {
881        self.add_assign(*rhs);
882    }
883}
884
885impl Sub for Mat3 {
886    type Output = Self;
887    #[inline]
888    fn sub(self, rhs: Self) -> Self {
889        Self::from_cols(
890            self.x_axis.sub(rhs.x_axis),
891            self.y_axis.sub(rhs.y_axis),
892            self.z_axis.sub(rhs.z_axis),
893        )
894    }
895}
896
897impl Sub<&Self> for Mat3 {
898    type Output = Self;
899    #[inline]
900    fn sub(self, rhs: &Self) -> Self {
901        self.sub(*rhs)
902    }
903}
904
905impl Sub<&Mat3> for &Mat3 {
906    type Output = Mat3;
907    #[inline]
908    fn sub(self, rhs: &Mat3) -> Mat3 {
909        (*self).sub(*rhs)
910    }
911}
912
913impl Sub<Mat3> for &Mat3 {
914    type Output = Mat3;
915    #[inline]
916    fn sub(self, rhs: Mat3) -> Mat3 {
917        (*self).sub(rhs)
918    }
919}
920
921impl SubAssign for Mat3 {
922    #[inline]
923    fn sub_assign(&mut self, rhs: Self) {
924        *self = self.sub(rhs);
925    }
926}
927
928impl SubAssign<&Self> for Mat3 {
929    #[inline]
930    fn sub_assign(&mut self, rhs: &Self) {
931        self.sub_assign(*rhs);
932    }
933}
934
935impl Neg for Mat3 {
936    type Output = Self;
937    #[inline]
938    fn neg(self) -> Self::Output {
939        Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
940    }
941}
942
943impl Neg for &Mat3 {
944    type Output = Mat3;
945    #[inline]
946    fn neg(self) -> Mat3 {
947        (*self).neg()
948    }
949}
950
951impl Mul for Mat3 {
952    type Output = Self;
953    #[inline]
954    fn mul(self, rhs: Self) -> Self {
955        Self::from_cols(
956            self.mul(rhs.x_axis),
957            self.mul(rhs.y_axis),
958            self.mul(rhs.z_axis),
959        )
960    }
961}
962
963impl Mul<&Self> for Mat3 {
964    type Output = Self;
965    #[inline]
966    fn mul(self, rhs: &Self) -> Self {
967        self.mul(*rhs)
968    }
969}
970
971impl Mul<&Mat3> for &Mat3 {
972    type Output = Mat3;
973    #[inline]
974    fn mul(self, rhs: &Mat3) -> Mat3 {
975        (*self).mul(*rhs)
976    }
977}
978
979impl Mul<Mat3> for &Mat3 {
980    type Output = Mat3;
981    #[inline]
982    fn mul(self, rhs: Mat3) -> Mat3 {
983        (*self).mul(rhs)
984    }
985}
986
987impl MulAssign for Mat3 {
988    #[inline]
989    fn mul_assign(&mut self, rhs: Self) {
990        *self = self.mul(rhs);
991    }
992}
993
994impl MulAssign<&Self> for Mat3 {
995    #[inline]
996    fn mul_assign(&mut self, rhs: &Self) {
997        self.mul_assign(*rhs);
998    }
999}
1000
1001impl Mul<Vec3> for Mat3 {
1002    type Output = Vec3;
1003    #[inline]
1004    fn mul(self, rhs: Vec3) -> Self::Output {
1005        self.mul_vec3(rhs)
1006    }
1007}
1008
1009impl Mul<&Vec3> for Mat3 {
1010    type Output = Vec3;
1011    #[inline]
1012    fn mul(self, rhs: &Vec3) -> Vec3 {
1013        self.mul(*rhs)
1014    }
1015}
1016
1017impl Mul<&Vec3> for &Mat3 {
1018    type Output = Vec3;
1019    #[inline]
1020    fn mul(self, rhs: &Vec3) -> Vec3 {
1021        (*self).mul(*rhs)
1022    }
1023}
1024
1025impl Mul<Vec3> for &Mat3 {
1026    type Output = Vec3;
1027    #[inline]
1028    fn mul(self, rhs: Vec3) -> Vec3 {
1029        (*self).mul(rhs)
1030    }
1031}
1032
1033impl Mul<Mat3> for f32 {
1034    type Output = Mat3;
1035    #[inline]
1036    fn mul(self, rhs: Mat3) -> Self::Output {
1037        rhs.mul_scalar(self)
1038    }
1039}
1040
1041impl Mul<&Mat3> for f32 {
1042    type Output = Mat3;
1043    #[inline]
1044    fn mul(self, rhs: &Mat3) -> Mat3 {
1045        self.mul(*rhs)
1046    }
1047}
1048
1049impl Mul<&Mat3> for &f32 {
1050    type Output = Mat3;
1051    #[inline]
1052    fn mul(self, rhs: &Mat3) -> Mat3 {
1053        (*self).mul(*rhs)
1054    }
1055}
1056
1057impl Mul<Mat3> for &f32 {
1058    type Output = Mat3;
1059    #[inline]
1060    fn mul(self, rhs: Mat3) -> Mat3 {
1061        (*self).mul(rhs)
1062    }
1063}
1064
1065impl Mul<f32> for Mat3 {
1066    type Output = Self;
1067    #[inline]
1068    fn mul(self, rhs: f32) -> Self {
1069        self.mul_scalar(rhs)
1070    }
1071}
1072
1073impl Mul<&f32> for Mat3 {
1074    type Output = Self;
1075    #[inline]
1076    fn mul(self, rhs: &f32) -> Self {
1077        self.mul(*rhs)
1078    }
1079}
1080
1081impl Mul<&f32> for &Mat3 {
1082    type Output = Mat3;
1083    #[inline]
1084    fn mul(self, rhs: &f32) -> Mat3 {
1085        (*self).mul(*rhs)
1086    }
1087}
1088
1089impl Mul<f32> for &Mat3 {
1090    type Output = Mat3;
1091    #[inline]
1092    fn mul(self, rhs: f32) -> Mat3 {
1093        (*self).mul(rhs)
1094    }
1095}
1096
1097impl MulAssign<f32> for Mat3 {
1098    #[inline]
1099    fn mul_assign(&mut self, rhs: f32) {
1100        *self = self.mul(rhs);
1101    }
1102}
1103
1104impl MulAssign<&f32> for Mat3 {
1105    #[inline]
1106    fn mul_assign(&mut self, rhs: &f32) {
1107        self.mul_assign(*rhs);
1108    }
1109}
1110
1111impl Div<Mat3> for f32 {
1112    type Output = Mat3;
1113    #[inline]
1114    fn div(self, rhs: Mat3) -> Self::Output {
1115        Mat3::from_cols(
1116            self.div(rhs.x_axis),
1117            self.div(rhs.y_axis),
1118            self.div(rhs.z_axis),
1119        )
1120    }
1121}
1122
1123impl Div<&Mat3> for f32 {
1124    type Output = Mat3;
1125    #[inline]
1126    fn div(self, rhs: &Mat3) -> Mat3 {
1127        self.div(*rhs)
1128    }
1129}
1130
1131impl Div<&Mat3> for &f32 {
1132    type Output = Mat3;
1133    #[inline]
1134    fn div(self, rhs: &Mat3) -> Mat3 {
1135        (*self).div(*rhs)
1136    }
1137}
1138
1139impl Div<Mat3> for &f32 {
1140    type Output = Mat3;
1141    #[inline]
1142    fn div(self, rhs: Mat3) -> Mat3 {
1143        (*self).div(rhs)
1144    }
1145}
1146
1147impl Div<f32> for Mat3 {
1148    type Output = Self;
1149    #[inline]
1150    fn div(self, rhs: f32) -> Self {
1151        self.div_scalar(rhs)
1152    }
1153}
1154
1155impl Div<&f32> for Mat3 {
1156    type Output = Self;
1157    #[inline]
1158    fn div(self, rhs: &f32) -> Self {
1159        self.div(*rhs)
1160    }
1161}
1162
1163impl Div<&f32> for &Mat3 {
1164    type Output = Mat3;
1165    #[inline]
1166    fn div(self, rhs: &f32) -> Mat3 {
1167        (*self).div(*rhs)
1168    }
1169}
1170
1171impl Div<f32> for &Mat3 {
1172    type Output = Mat3;
1173    #[inline]
1174    fn div(self, rhs: f32) -> Mat3 {
1175        (*self).div(rhs)
1176    }
1177}
1178
1179impl DivAssign<f32> for Mat3 {
1180    #[inline]
1181    fn div_assign(&mut self, rhs: f32) {
1182        *self = self.div(rhs);
1183    }
1184}
1185
1186impl DivAssign<&f32> for Mat3 {
1187    #[inline]
1188    fn div_assign(&mut self, rhs: &f32) {
1189        self.div_assign(*rhs);
1190    }
1191}
1192
1193impl Mul<Vec3A> for Mat3 {
1194    type Output = Vec3A;
1195    #[inline]
1196    fn mul(self, rhs: Vec3A) -> Vec3A {
1197        self.mul_vec3a(rhs)
1198    }
1199}
1200
1201impl Mul<&Vec3A> for Mat3 {
1202    type Output = Vec3A;
1203    #[inline]
1204    fn mul(self, rhs: &Vec3A) -> Vec3A {
1205        self.mul(*rhs)
1206    }
1207}
1208
1209impl Mul<&Vec3A> for &Mat3 {
1210    type Output = Vec3A;
1211    #[inline]
1212    fn mul(self, rhs: &Vec3A) -> Vec3A {
1213        (*self).mul(*rhs)
1214    }
1215}
1216
1217impl Mul<Vec3A> for &Mat3 {
1218    type Output = Vec3A;
1219    #[inline]
1220    fn mul(self, rhs: Vec3A) -> Vec3A {
1221        (*self).mul(rhs)
1222    }
1223}
1224
1225impl From<Mat3A> for Mat3 {
1226    #[inline]
1227    fn from(m: Mat3A) -> Self {
1228        Self {
1229            x_axis: m.x_axis.into(),
1230            y_axis: m.y_axis.into(),
1231            z_axis: m.z_axis.into(),
1232        }
1233    }
1234}
1235
1236impl Sum<Self> for Mat3 {
1237    fn sum<I>(iter: I) -> Self
1238    where
1239        I: Iterator<Item = Self>,
1240    {
1241        iter.fold(Self::ZERO, Self::add)
1242    }
1243}
1244
1245impl<'a> Sum<&'a Self> for Mat3 {
1246    fn sum<I>(iter: I) -> Self
1247    where
1248        I: Iterator<Item = &'a Self>,
1249    {
1250        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1251    }
1252}
1253
1254impl Product for Mat3 {
1255    fn product<I>(iter: I) -> Self
1256    where
1257        I: Iterator<Item = Self>,
1258    {
1259        iter.fold(Self::IDENTITY, Self::mul)
1260    }
1261}
1262
1263impl<'a> Product<&'a Self> for Mat3 {
1264    fn product<I>(iter: I) -> Self
1265    where
1266        I: Iterator<Item = &'a Self>,
1267    {
1268        iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1269    }
1270}
1271
1272impl PartialEq for Mat3 {
1273    #[inline]
1274    fn eq(&self, rhs: &Self) -> bool {
1275        self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1276    }
1277}
1278
1279impl AsRef<[f32; 9]> for Mat3 {
1280    #[inline]
1281    fn as_ref(&self) -> &[f32; 9] {
1282        unsafe { &*(self as *const Self as *const [f32; 9]) }
1283    }
1284}
1285
1286impl AsMut<[f32; 9]> for Mat3 {
1287    #[inline]
1288    fn as_mut(&mut self) -> &mut [f32; 9] {
1289        unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
1290    }
1291}
1292
1293impl fmt::Debug for Mat3 {
1294    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1295        fmt.debug_struct(stringify!(Mat3))
1296            .field("x_axis", &self.x_axis)
1297            .field("y_axis", &self.y_axis)
1298            .field("z_axis", &self.z_axis)
1299            .finish()
1300    }
1301}
1302
1303impl fmt::Display for Mat3 {
1304    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1305        if let Some(p) = f.precision() {
1306            write!(
1307                f,
1308                "[{:.*}, {:.*}, {:.*}]",
1309                p, self.x_axis, p, self.y_axis, p, self.z_axis
1310            )
1311        } else {
1312            write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1313        }
1314    }
1315}