Skip to main content

glam/f64/
dmat3.rs

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