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