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