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