Skip to main content

glam/f32/
mat3.rs

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