glam/f32/neon/
mat3a.rs

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