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