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 determinant of `self`.
502    #[inline]
503    #[must_use]
504    pub fn determinant(&self) -> f32 {
505        self.z_axis.dot(self.x_axis.cross(self.y_axis))
506    }
507
508    /// Returns the inverse of `self`.
509    ///
510    /// If the matrix is not invertible the returned matrix will be invalid.
511    ///
512    /// # Panics
513    ///
514    /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
515    #[inline]
516    #[must_use]
517    pub fn inverse(&self) -> Self {
518        let tmp0 = self.y_axis.cross(self.z_axis);
519        let tmp1 = self.z_axis.cross(self.x_axis);
520        let tmp2 = self.x_axis.cross(self.y_axis);
521        let det = self.z_axis.dot(tmp2);
522        glam_assert!(det != 0.0);
523        let inv_det = Vec3::splat(det.recip());
524        Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
525    }
526
527    /// Transforms the given 2D vector as a point.
528    ///
529    /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
530    ///
531    /// This method assumes that `self` contains a valid affine transform.
532    ///
533    /// # Panics
534    ///
535    /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
536    #[inline]
537    #[must_use]
538    pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
539        glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
540        Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
541    }
542
543    /// Rotates the given 2D vector.
544    ///
545    /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
546    ///
547    /// This method assumes that `self` contains a valid affine transform.
548    ///
549    /// # Panics
550    ///
551    /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
552    #[inline]
553    #[must_use]
554    pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
555        glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
556        Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
557    }
558
559    /// Creates a left-handed view matrix using a facing direction and an up direction.
560    ///
561    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
562    ///
563    /// # Panics
564    ///
565    /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
566    #[inline]
567    #[must_use]
568    pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
569        Self::look_to_rh(-dir, up)
570    }
571
572    /// Creates a right-handed view matrix using a facing direction and an up direction.
573    ///
574    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
575    ///
576    /// # Panics
577    ///
578    /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
579    #[inline]
580    #[must_use]
581    pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
582        glam_assert!(dir.is_normalized());
583        glam_assert!(up.is_normalized());
584        let f = dir;
585        let s = f.cross(up).normalize();
586        let u = s.cross(f);
587
588        Self::from_cols(
589            Vec3::new(s.x, u.x, -f.x),
590            Vec3::new(s.y, u.y, -f.y),
591            Vec3::new(s.z, u.z, -f.z),
592        )
593    }
594
595    /// Creates a left-handed view matrix using a camera position, a focal point and an up
596    /// direction.
597    ///
598    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
599    ///
600    /// # Panics
601    ///
602    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
603    #[inline]
604    #[must_use]
605    pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
606        Self::look_to_lh(center.sub(eye).normalize(), up)
607    }
608
609    /// Creates a right-handed view matrix using a camera position, a focal point and an up
610    /// direction.
611    ///
612    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
613    ///
614    /// # Panics
615    ///
616    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
617    #[inline]
618    pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
619        Self::look_to_rh(center.sub(eye).normalize(), up)
620    }
621
622    /// Transforms a 3D vector.
623    #[inline]
624    #[must_use]
625    pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
626        let mut res = self.x_axis.mul(rhs.x);
627        res = res.add(self.y_axis.mul(rhs.y));
628        res = res.add(self.z_axis.mul(rhs.z));
629        res
630    }
631
632    /// Transforms a [`Vec3A`].
633    #[inline]
634    #[must_use]
635    pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
636        self.mul_vec3(rhs.into()).into()
637    }
638
639    /// Multiplies two 3x3 matrices.
640    #[inline]
641    #[must_use]
642    pub fn mul_mat3(&self, rhs: &Self) -> Self {
643        self.mul(rhs)
644    }
645
646    /// Adds two 3x3 matrices.
647    #[inline]
648    #[must_use]
649    pub fn add_mat3(&self, rhs: &Self) -> Self {
650        self.add(rhs)
651    }
652
653    /// Subtracts two 3x3 matrices.
654    #[inline]
655    #[must_use]
656    pub fn sub_mat3(&self, rhs: &Self) -> Self {
657        self.sub(rhs)
658    }
659
660    /// Multiplies a 3x3 matrix by a scalar.
661    #[inline]
662    #[must_use]
663    pub fn mul_scalar(&self, rhs: f32) -> Self {
664        Self::from_cols(
665            self.x_axis.mul(rhs),
666            self.y_axis.mul(rhs),
667            self.z_axis.mul(rhs),
668        )
669    }
670
671    /// Divides a 3x3 matrix by a scalar.
672    #[inline]
673    #[must_use]
674    pub fn div_scalar(&self, rhs: f32) -> Self {
675        let rhs = Vec3::splat(rhs);
676        Self::from_cols(
677            self.x_axis.div(rhs),
678            self.y_axis.div(rhs),
679            self.z_axis.div(rhs),
680        )
681    }
682
683    /// Returns true if the absolute difference of all elements between `self` and `rhs`
684    /// is less than or equal to `max_abs_diff`.
685    ///
686    /// This can be used to compare if two matrices contain similar elements. It works best
687    /// when comparing with a known value. The `max_abs_diff` that should be used used
688    /// depends on the values being compared against.
689    ///
690    /// For more see
691    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
692    #[inline]
693    #[must_use]
694    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
695        self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
696            && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
697            && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
698    }
699
700    /// Takes the absolute value of each element in `self`
701    #[inline]
702    #[must_use]
703    pub fn abs(&self) -> Self {
704        Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
705    }
706
707    #[inline]
708    pub fn as_dmat3(&self) -> DMat3 {
709        DMat3::from_cols(
710            self.x_axis.as_dvec3(),
711            self.y_axis.as_dvec3(),
712            self.z_axis.as_dvec3(),
713        )
714    }
715}
716
717impl Default for Mat3 {
718    #[inline]
719    fn default() -> Self {
720        Self::IDENTITY
721    }
722}
723
724impl Add for Mat3 {
725    type Output = Self;
726    #[inline]
727    fn add(self, rhs: Self) -> Self {
728        Self::from_cols(
729            self.x_axis.add(rhs.x_axis),
730            self.y_axis.add(rhs.y_axis),
731            self.z_axis.add(rhs.z_axis),
732        )
733    }
734}
735
736impl Add<&Self> for Mat3 {
737    type Output = Self;
738    #[inline]
739    fn add(self, rhs: &Self) -> Self {
740        self.add(*rhs)
741    }
742}
743
744impl Add<&Mat3> for &Mat3 {
745    type Output = Mat3;
746    #[inline]
747    fn add(self, rhs: &Mat3) -> Mat3 {
748        (*self).add(*rhs)
749    }
750}
751
752impl Add<Mat3> for &Mat3 {
753    type Output = Mat3;
754    #[inline]
755    fn add(self, rhs: Mat3) -> Mat3 {
756        (*self).add(rhs)
757    }
758}
759
760impl AddAssign for Mat3 {
761    #[inline]
762    fn add_assign(&mut self, rhs: Self) {
763        *self = self.add(rhs);
764    }
765}
766
767impl AddAssign<&Self> for Mat3 {
768    #[inline]
769    fn add_assign(&mut self, rhs: &Self) {
770        self.add_assign(*rhs);
771    }
772}
773
774impl Sub for Mat3 {
775    type Output = Self;
776    #[inline]
777    fn sub(self, rhs: Self) -> Self {
778        Self::from_cols(
779            self.x_axis.sub(rhs.x_axis),
780            self.y_axis.sub(rhs.y_axis),
781            self.z_axis.sub(rhs.z_axis),
782        )
783    }
784}
785
786impl Sub<&Self> for Mat3 {
787    type Output = Self;
788    #[inline]
789    fn sub(self, rhs: &Self) -> Self {
790        self.sub(*rhs)
791    }
792}
793
794impl Sub<&Mat3> for &Mat3 {
795    type Output = Mat3;
796    #[inline]
797    fn sub(self, rhs: &Mat3) -> Mat3 {
798        (*self).sub(*rhs)
799    }
800}
801
802impl Sub<Mat3> for &Mat3 {
803    type Output = Mat3;
804    #[inline]
805    fn sub(self, rhs: Mat3) -> Mat3 {
806        (*self).sub(rhs)
807    }
808}
809
810impl SubAssign for Mat3 {
811    #[inline]
812    fn sub_assign(&mut self, rhs: Self) {
813        *self = self.sub(rhs);
814    }
815}
816
817impl SubAssign<&Self> for Mat3 {
818    #[inline]
819    fn sub_assign(&mut self, rhs: &Self) {
820        self.sub_assign(*rhs);
821    }
822}
823
824impl Neg for Mat3 {
825    type Output = Self;
826    #[inline]
827    fn neg(self) -> Self::Output {
828        Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
829    }
830}
831
832impl Neg for &Mat3 {
833    type Output = Mat3;
834    #[inline]
835    fn neg(self) -> Mat3 {
836        (*self).neg()
837    }
838}
839
840impl Mul for Mat3 {
841    type Output = Self;
842    #[inline]
843    fn mul(self, rhs: Self) -> Self {
844        Self::from_cols(
845            self.mul(rhs.x_axis),
846            self.mul(rhs.y_axis),
847            self.mul(rhs.z_axis),
848        )
849    }
850}
851
852impl Mul<&Self> for Mat3 {
853    type Output = Self;
854    #[inline]
855    fn mul(self, rhs: &Self) -> Self {
856        self.mul(*rhs)
857    }
858}
859
860impl Mul<&Mat3> for &Mat3 {
861    type Output = Mat3;
862    #[inline]
863    fn mul(self, rhs: &Mat3) -> Mat3 {
864        (*self).mul(*rhs)
865    }
866}
867
868impl Mul<Mat3> for &Mat3 {
869    type Output = Mat3;
870    #[inline]
871    fn mul(self, rhs: Mat3) -> Mat3 {
872        (*self).mul(rhs)
873    }
874}
875
876impl MulAssign for Mat3 {
877    #[inline]
878    fn mul_assign(&mut self, rhs: Self) {
879        *self = self.mul(rhs);
880    }
881}
882
883impl MulAssign<&Self> for Mat3 {
884    #[inline]
885    fn mul_assign(&mut self, rhs: &Self) {
886        self.mul_assign(*rhs);
887    }
888}
889
890impl Mul<Vec3> for Mat3 {
891    type Output = Vec3;
892    #[inline]
893    fn mul(self, rhs: Vec3) -> Self::Output {
894        self.mul_vec3(rhs)
895    }
896}
897
898impl Mul<&Vec3> for Mat3 {
899    type Output = Vec3;
900    #[inline]
901    fn mul(self, rhs: &Vec3) -> Vec3 {
902        self.mul(*rhs)
903    }
904}
905
906impl Mul<&Vec3> for &Mat3 {
907    type Output = Vec3;
908    #[inline]
909    fn mul(self, rhs: &Vec3) -> Vec3 {
910        (*self).mul(*rhs)
911    }
912}
913
914impl Mul<Vec3> for &Mat3 {
915    type Output = Vec3;
916    #[inline]
917    fn mul(self, rhs: Vec3) -> Vec3 {
918        (*self).mul(rhs)
919    }
920}
921
922impl Mul<Mat3> for f32 {
923    type Output = Mat3;
924    #[inline]
925    fn mul(self, rhs: Mat3) -> Self::Output {
926        rhs.mul_scalar(self)
927    }
928}
929
930impl Mul<&Mat3> for f32 {
931    type Output = Mat3;
932    #[inline]
933    fn mul(self, rhs: &Mat3) -> Mat3 {
934        self.mul(*rhs)
935    }
936}
937
938impl Mul<&Mat3> for &f32 {
939    type Output = Mat3;
940    #[inline]
941    fn mul(self, rhs: &Mat3) -> Mat3 {
942        (*self).mul(*rhs)
943    }
944}
945
946impl Mul<Mat3> for &f32 {
947    type Output = Mat3;
948    #[inline]
949    fn mul(self, rhs: Mat3) -> Mat3 {
950        (*self).mul(rhs)
951    }
952}
953
954impl Mul<f32> for Mat3 {
955    type Output = Self;
956    #[inline]
957    fn mul(self, rhs: f32) -> Self {
958        self.mul_scalar(rhs)
959    }
960}
961
962impl Mul<&f32> for Mat3 {
963    type Output = Self;
964    #[inline]
965    fn mul(self, rhs: &f32) -> Self {
966        self.mul(*rhs)
967    }
968}
969
970impl Mul<&f32> for &Mat3 {
971    type Output = Mat3;
972    #[inline]
973    fn mul(self, rhs: &f32) -> Mat3 {
974        (*self).mul(*rhs)
975    }
976}
977
978impl Mul<f32> for &Mat3 {
979    type Output = Mat3;
980    #[inline]
981    fn mul(self, rhs: f32) -> Mat3 {
982        (*self).mul(rhs)
983    }
984}
985
986impl MulAssign<f32> for Mat3 {
987    #[inline]
988    fn mul_assign(&mut self, rhs: f32) {
989        *self = self.mul(rhs);
990    }
991}
992
993impl MulAssign<&f32> for Mat3 {
994    #[inline]
995    fn mul_assign(&mut self, rhs: &f32) {
996        self.mul_assign(*rhs);
997    }
998}
999
1000impl Div<Mat3> for f32 {
1001    type Output = Mat3;
1002    #[inline]
1003    fn div(self, rhs: Mat3) -> Self::Output {
1004        rhs.div_scalar(self)
1005    }
1006}
1007
1008impl Div<&Mat3> for f32 {
1009    type Output = Mat3;
1010    #[inline]
1011    fn div(self, rhs: &Mat3) -> Mat3 {
1012        self.div(*rhs)
1013    }
1014}
1015
1016impl Div<&Mat3> for &f32 {
1017    type Output = Mat3;
1018    #[inline]
1019    fn div(self, rhs: &Mat3) -> Mat3 {
1020        (*self).div(*rhs)
1021    }
1022}
1023
1024impl Div<Mat3> for &f32 {
1025    type Output = Mat3;
1026    #[inline]
1027    fn div(self, rhs: Mat3) -> Mat3 {
1028        (*self).div(rhs)
1029    }
1030}
1031
1032impl Div<f32> for Mat3 {
1033    type Output = Self;
1034    #[inline]
1035    fn div(self, rhs: f32) -> Self {
1036        self.div_scalar(rhs)
1037    }
1038}
1039
1040impl Div<&f32> for Mat3 {
1041    type Output = Self;
1042    #[inline]
1043    fn div(self, rhs: &f32) -> Self {
1044        self.div(*rhs)
1045    }
1046}
1047
1048impl Div<&f32> for &Mat3 {
1049    type Output = Mat3;
1050    #[inline]
1051    fn div(self, rhs: &f32) -> Mat3 {
1052        (*self).div(*rhs)
1053    }
1054}
1055
1056impl Div<f32> for &Mat3 {
1057    type Output = Mat3;
1058    #[inline]
1059    fn div(self, rhs: f32) -> Mat3 {
1060        (*self).div(rhs)
1061    }
1062}
1063
1064impl DivAssign<f32> for Mat3 {
1065    #[inline]
1066    fn div_assign(&mut self, rhs: f32) {
1067        *self = self.div(rhs);
1068    }
1069}
1070
1071impl DivAssign<&f32> for Mat3 {
1072    #[inline]
1073    fn div_assign(&mut self, rhs: &f32) {
1074        self.div_assign(*rhs);
1075    }
1076}
1077
1078impl Mul<Vec3A> for Mat3 {
1079    type Output = Vec3A;
1080    #[inline]
1081    fn mul(self, rhs: Vec3A) -> Vec3A {
1082        self.mul_vec3a(rhs)
1083    }
1084}
1085
1086impl Mul<&Vec3A> for Mat3 {
1087    type Output = Vec3A;
1088    #[inline]
1089    fn mul(self, rhs: &Vec3A) -> Vec3A {
1090        self.mul(*rhs)
1091    }
1092}
1093
1094impl Mul<&Vec3A> for &Mat3 {
1095    type Output = Vec3A;
1096    #[inline]
1097    fn mul(self, rhs: &Vec3A) -> Vec3A {
1098        (*self).mul(*rhs)
1099    }
1100}
1101
1102impl Mul<Vec3A> for &Mat3 {
1103    type Output = Vec3A;
1104    #[inline]
1105    fn mul(self, rhs: Vec3A) -> Vec3A {
1106        (*self).mul(rhs)
1107    }
1108}
1109
1110impl From<Mat3A> for Mat3 {
1111    #[inline]
1112    fn from(m: Mat3A) -> Self {
1113        Self {
1114            x_axis: m.x_axis.into(),
1115            y_axis: m.y_axis.into(),
1116            z_axis: m.z_axis.into(),
1117        }
1118    }
1119}
1120
1121impl Sum<Self> for Mat3 {
1122    fn sum<I>(iter: I) -> Self
1123    where
1124        I: Iterator<Item = Self>,
1125    {
1126        iter.fold(Self::ZERO, Self::add)
1127    }
1128}
1129
1130impl<'a> Sum<&'a Self> for Mat3 {
1131    fn sum<I>(iter: I) -> Self
1132    where
1133        I: Iterator<Item = &'a Self>,
1134    {
1135        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1136    }
1137}
1138
1139impl Product for Mat3 {
1140    fn product<I>(iter: I) -> Self
1141    where
1142        I: Iterator<Item = Self>,
1143    {
1144        iter.fold(Self::IDENTITY, Self::mul)
1145    }
1146}
1147
1148impl<'a> Product<&'a Self> for Mat3 {
1149    fn product<I>(iter: I) -> Self
1150    where
1151        I: Iterator<Item = &'a Self>,
1152    {
1153        iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1154    }
1155}
1156
1157impl PartialEq for Mat3 {
1158    #[inline]
1159    fn eq(&self, rhs: &Self) -> bool {
1160        self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1161    }
1162}
1163
1164impl AsRef<[f32; 9]> for Mat3 {
1165    #[inline]
1166    fn as_ref(&self) -> &[f32; 9] {
1167        unsafe { &*(self as *const Self as *const [f32; 9]) }
1168    }
1169}
1170
1171impl AsMut<[f32; 9]> for Mat3 {
1172    #[inline]
1173    fn as_mut(&mut self) -> &mut [f32; 9] {
1174        unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
1175    }
1176}
1177
1178impl fmt::Debug for Mat3 {
1179    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1180        fmt.debug_struct(stringify!(Mat3))
1181            .field("x_axis", &self.x_axis)
1182            .field("y_axis", &self.y_axis)
1183            .field("z_axis", &self.z_axis)
1184            .finish()
1185    }
1186}
1187
1188impl fmt::Display for Mat3 {
1189    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1190        if let Some(p) = f.precision() {
1191            write!(
1192                f,
1193                "[{:.*}, {:.*}, {:.*}]",
1194                p, self.x_axis, p, self.y_axis, p, self.z_axis
1195            )
1196        } else {
1197            write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1198        }
1199    }
1200}