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