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