glam/f32/
affine3a.rs

1// Generated from affine.rs.tera template. Edit the template, not the generated file.
2
3use crate::{Mat3, Mat3A, Mat4, Quat, Vec3, Vec3A};
4use core::ops::{Deref, DerefMut, Mul, MulAssign};
5
6/// A 3D affine transform, which can represent translation, rotation, scaling and shear.
7///
8/// This type is 16 byte aligned.
9#[derive(Copy, Clone)]
10#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
11#[repr(C)]
12pub struct Affine3A {
13    pub matrix3: Mat3A,
14    pub translation: Vec3A,
15}
16
17impl Affine3A {
18    /// The degenerate zero transform.
19    ///
20    /// This transforms any finite vector and point to zero.
21    /// The zero transform is non-invertible.
22    pub const ZERO: Self = Self {
23        matrix3: Mat3A::ZERO,
24        translation: Vec3A::ZERO,
25    };
26
27    /// The identity transform.
28    ///
29    /// Multiplying a vector with this returns the same vector.
30    pub const IDENTITY: Self = Self {
31        matrix3: Mat3A::IDENTITY,
32        translation: Vec3A::ZERO,
33    };
34
35    /// All NAN:s.
36    pub const NAN: Self = Self {
37        matrix3: Mat3A::NAN,
38        translation: Vec3A::NAN,
39    };
40
41    /// Creates an affine transform from three column vectors.
42    #[inline(always)]
43    #[must_use]
44    pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A, w_axis: Vec3A) -> Self {
45        Self {
46            matrix3: Mat3A::from_cols(x_axis, y_axis, z_axis),
47            translation: w_axis,
48        }
49    }
50
51    /// Creates an affine transform from a `[f32; 12]` array stored in column major order.
52    #[inline]
53    #[must_use]
54    pub fn from_cols_array(m: &[f32; 12]) -> Self {
55        Self {
56            matrix3: Mat3A::from_cols_array(&[
57                m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8],
58            ]),
59            translation: Vec3A::from_array([m[9], m[10], m[11]]),
60        }
61    }
62
63    /// Creates a `[f32; 12]` array storing data in column major order.
64    #[inline]
65    #[must_use]
66    pub fn to_cols_array(&self) -> [f32; 12] {
67        let x = &self.matrix3.x_axis;
68        let y = &self.matrix3.y_axis;
69        let z = &self.matrix3.z_axis;
70        let w = &self.translation;
71        [x.x, x.y, x.z, y.x, y.y, y.z, z.x, z.y, z.z, w.x, w.y, w.z]
72    }
73
74    /// Creates an affine transform from a `[[f32; 3]; 4]`
75    /// 3D array stored in column major order.
76    /// If your data is in row major order you will need to `transpose` the returned
77    /// matrix.
78    #[inline]
79    #[must_use]
80    pub fn from_cols_array_2d(m: &[[f32; 3]; 4]) -> Self {
81        Self {
82            matrix3: Mat3A::from_cols(m[0].into(), m[1].into(), m[2].into()),
83            translation: m[3].into(),
84        }
85    }
86
87    /// Creates a `[[f32; 3]; 4]` 3D array storing data in
88    /// column major order.
89    /// If you require data in row major order `transpose` the matrix first.
90    #[inline]
91    #[must_use]
92    pub fn to_cols_array_2d(&self) -> [[f32; 3]; 4] {
93        [
94            self.matrix3.x_axis.into(),
95            self.matrix3.y_axis.into(),
96            self.matrix3.z_axis.into(),
97            self.translation.into(),
98        ]
99    }
100
101    /// Creates an affine transform from the first 12 values in `slice`.
102    ///
103    /// # Panics
104    ///
105    /// Panics if `slice` is less than 12 elements long.
106    #[inline]
107    #[must_use]
108    pub fn from_cols_slice(slice: &[f32]) -> Self {
109        Self {
110            matrix3: Mat3A::from_cols_slice(&slice[0..9]),
111            translation: Vec3A::from_slice(&slice[9..12]),
112        }
113    }
114
115    /// Writes the columns of `self` to the first 12 elements in `slice`.
116    ///
117    /// # Panics
118    ///
119    /// Panics if `slice` is less than 12 elements long.
120    #[inline]
121    pub fn write_cols_to_slice(self, slice: &mut [f32]) {
122        self.matrix3.write_cols_to_slice(&mut slice[0..9]);
123        self.translation.write_to_slice(&mut slice[9..12]);
124    }
125
126    /// Creates an affine transform that changes scale.
127    /// Note that if any scale is zero the transform will be non-invertible.
128    #[inline]
129    #[must_use]
130    pub fn from_scale(scale: Vec3) -> Self {
131        Self {
132            matrix3: Mat3A::from_diagonal(scale),
133            translation: Vec3A::ZERO,
134        }
135    }
136    /// Creates an affine transform from the given `rotation` quaternion.
137    #[inline]
138    #[must_use]
139    pub fn from_quat(rotation: Quat) -> Self {
140        Self {
141            matrix3: Mat3A::from_quat(rotation),
142            translation: Vec3A::ZERO,
143        }
144    }
145
146    /// Creates an affine transform containing a 3D rotation around a normalized
147    /// rotation `axis` of `angle` (in radians).
148    #[inline]
149    #[must_use]
150    pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
151        Self {
152            matrix3: Mat3A::from_axis_angle(axis, angle),
153            translation: Vec3A::ZERO,
154        }
155    }
156
157    /// Creates an affine transform containing a 3D rotation around the x axis of
158    /// `angle` (in radians).
159    #[inline]
160    #[must_use]
161    pub fn from_rotation_x(angle: f32) -> Self {
162        Self {
163            matrix3: Mat3A::from_rotation_x(angle),
164            translation: Vec3A::ZERO,
165        }
166    }
167
168    /// Creates an affine transform containing a 3D rotation around the y axis of
169    /// `angle` (in radians).
170    #[inline]
171    #[must_use]
172    pub fn from_rotation_y(angle: f32) -> Self {
173        Self {
174            matrix3: Mat3A::from_rotation_y(angle),
175            translation: Vec3A::ZERO,
176        }
177    }
178
179    /// Creates an affine transform containing a 3D rotation around the z axis of
180    /// `angle` (in radians).
181    #[inline]
182    #[must_use]
183    pub fn from_rotation_z(angle: f32) -> Self {
184        Self {
185            matrix3: Mat3A::from_rotation_z(angle),
186            translation: Vec3A::ZERO,
187        }
188    }
189
190    /// Creates an affine transformation from the given 3D `translation`.
191    #[inline]
192    #[must_use]
193    pub fn from_translation(translation: Vec3) -> Self {
194        #[allow(clippy::useless_conversion)]
195        Self {
196            matrix3: Mat3A::IDENTITY,
197            translation: translation.into(),
198        }
199    }
200
201    /// Creates an affine transform from a 3x3 matrix (expressing scale, shear and
202    /// rotation)
203    #[inline]
204    #[must_use]
205    pub fn from_mat3(mat3: Mat3) -> Self {
206        #[allow(clippy::useless_conversion)]
207        Self {
208            matrix3: mat3.into(),
209            translation: Vec3A::ZERO,
210        }
211    }
212
213    /// Creates an affine transform from a 3x3 matrix (expressing scale, shear and rotation)
214    /// and a translation vector.
215    ///
216    /// Equivalent to `Affine3A::from_translation(translation) * Affine3A::from_mat3(mat3)`
217    #[inline]
218    #[must_use]
219    pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self {
220        #[allow(clippy::useless_conversion)]
221        Self {
222            matrix3: mat3.into(),
223            translation: translation.into(),
224        }
225    }
226
227    /// Creates an affine transform from the given 3D `scale`, `rotation` and
228    /// `translation`.
229    ///
230    /// Equivalent to `Affine3A::from_translation(translation) *
231    /// Affine3A::from_quat(rotation) * Affine3A::from_scale(scale)`
232    #[inline]
233    #[must_use]
234    pub fn from_scale_rotation_translation(scale: Vec3, rotation: Quat, translation: Vec3) -> Self {
235        let rotation = Mat3A::from_quat(rotation);
236        #[allow(clippy::useless_conversion)]
237        Self {
238            matrix3: Mat3A::from_cols(
239                rotation.x_axis * scale.x,
240                rotation.y_axis * scale.y,
241                rotation.z_axis * scale.z,
242            ),
243            translation: translation.into(),
244        }
245    }
246
247    /// Creates an affine transform from the given 3D `rotation` and `translation`.
248    ///
249    /// Equivalent to `Affine3A::from_translation(translation) * Affine3A::from_quat(rotation)`
250    #[inline]
251    #[must_use]
252    pub fn from_rotation_translation(rotation: Quat, translation: Vec3) -> Self {
253        #[allow(clippy::useless_conversion)]
254        Self {
255            matrix3: Mat3A::from_quat(rotation),
256            translation: translation.into(),
257        }
258    }
259
260    /// The given `Mat4` must be an affine transform,
261    /// i.e. contain no perspective transform.
262    #[inline]
263    #[must_use]
264    pub fn from_mat4(m: Mat4) -> Self {
265        Self {
266            matrix3: Mat3A::from_cols(
267                Vec3A::from_vec4(m.x_axis),
268                Vec3A::from_vec4(m.y_axis),
269                Vec3A::from_vec4(m.z_axis),
270            ),
271            translation: Vec3A::from_vec4(m.w_axis),
272        }
273    }
274
275    /// Extracts `scale`, `rotation` and `translation` from `self`.
276    ///
277    /// The transform is expected to be non-degenerate and without shearing, or the output
278    /// will be invalid.
279    ///
280    /// # Panics
281    ///
282    /// Will panic if the determinant `self.matrix3` is zero or if the resulting scale
283    /// vector contains any zero elements when `glam_assert` is enabled.
284    #[inline]
285    #[must_use]
286    pub fn to_scale_rotation_translation(&self) -> (Vec3, Quat, Vec3) {
287        use crate::f32::math;
288        let det = self.matrix3.determinant();
289        glam_assert!(det != 0.0);
290
291        let scale = Vec3::new(
292            self.matrix3.x_axis.length() * math::signum(det),
293            self.matrix3.y_axis.length(),
294            self.matrix3.z_axis.length(),
295        );
296
297        glam_assert!(scale.cmpne(Vec3::ZERO).all());
298
299        let inv_scale = scale.recip();
300
301        #[allow(clippy::useless_conversion)]
302        let rotation = Quat::from_mat3(&Mat3::from_cols(
303            (self.matrix3.x_axis * inv_scale.x).into(),
304            (self.matrix3.y_axis * inv_scale.y).into(),
305            (self.matrix3.z_axis * inv_scale.z).into(),
306        ));
307
308        #[allow(clippy::useless_conversion)]
309        (scale, rotation, self.translation.into())
310    }
311
312    /// Creates a left-handed view transform using a camera position, an up direction, and a facing
313    /// direction.
314    ///
315    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
316    #[inline]
317    #[must_use]
318    pub fn look_to_lh(eye: Vec3, dir: Vec3, up: Vec3) -> Self {
319        Self::look_to_rh(eye, -dir, up)
320    }
321
322    /// Creates a right-handed view transform using a camera position, an up direction, and a facing
323    /// direction.
324    ///
325    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
326    #[inline]
327    #[must_use]
328    pub fn look_to_rh(eye: Vec3, dir: Vec3, up: Vec3) -> Self {
329        let f = dir.normalize();
330        let s = f.cross(up).normalize();
331        let u = s.cross(f);
332
333        Self {
334            matrix3: Mat3A::from_cols(
335                Vec3A::new(s.x, u.x, -f.x),
336                Vec3A::new(s.y, u.y, -f.y),
337                Vec3A::new(s.z, u.z, -f.z),
338            ),
339            translation: Vec3A::new(-eye.dot(s), -eye.dot(u), eye.dot(f)),
340        }
341    }
342
343    /// Creates a left-handed view transform using a camera position, an up direction, and a focal
344    /// point.
345    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
346    ///
347    /// # Panics
348    ///
349    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
350    #[inline]
351    #[must_use]
352    pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
353        glam_assert!(up.is_normalized());
354        Self::look_to_lh(eye, center - eye, up)
355    }
356
357    /// Creates a right-handed view transform using a camera position, an up direction, and a focal
358    /// point.
359    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
360    ///
361    /// # Panics
362    ///
363    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
364    #[inline]
365    #[must_use]
366    pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
367        glam_assert!(up.is_normalized());
368        Self::look_to_rh(eye, center - eye, up)
369    }
370
371    /// Transforms the given 3D points, applying shear, scale, rotation and translation.
372    #[inline]
373    pub fn transform_point3(&self, rhs: Vec3) -> Vec3 {
374        #[allow(clippy::useless_conversion)]
375        ((self.matrix3.x_axis * rhs.x)
376            + (self.matrix3.y_axis * rhs.y)
377            + (self.matrix3.z_axis * rhs.z)
378            + self.translation)
379            .into()
380    }
381
382    /// Transforms the given 3D vector, applying shear, scale and rotation (but NOT
383    /// translation).
384    ///
385    /// To also apply translation, use [`Self::transform_point3()`] instead.
386    #[inline]
387    #[must_use]
388    pub fn transform_vector3(&self, rhs: Vec3) -> Vec3 {
389        #[allow(clippy::useless_conversion)]
390        ((self.matrix3.x_axis * rhs.x)
391            + (self.matrix3.y_axis * rhs.y)
392            + (self.matrix3.z_axis * rhs.z))
393            .into()
394    }
395
396    /// Transforms the given [`Vec3A`], applying shear, scale, rotation and translation.
397    #[inline]
398    #[must_use]
399    pub fn transform_point3a(&self, rhs: Vec3A) -> Vec3A {
400        self.matrix3 * rhs + self.translation
401    }
402
403    /// Transforms the given [`Vec3A`], applying shear, scale and rotation (but NOT
404    /// translation).
405    ///
406    /// To also apply translation, use [`Self::transform_point3a()`] instead.
407    #[inline]
408    #[must_use]
409    pub fn transform_vector3a(&self, rhs: Vec3A) -> Vec3A {
410        self.matrix3 * rhs
411    }
412
413    /// Returns `true` if, and only if, all elements are finite.
414    ///
415    /// If any element is either `NaN`, positive or negative infinity, this will return
416    /// `false`.
417    #[inline]
418    #[must_use]
419    pub fn is_finite(&self) -> bool {
420        self.matrix3.is_finite() && self.translation.is_finite()
421    }
422
423    /// Returns `true` if any elements are `NaN`.
424    #[inline]
425    #[must_use]
426    pub fn is_nan(&self) -> bool {
427        self.matrix3.is_nan() || self.translation.is_nan()
428    }
429
430    /// Returns true if the absolute difference of all elements between `self` and `rhs`
431    /// is less than or equal to `max_abs_diff`.
432    ///
433    /// This can be used to compare if two 3x4 matrices contain similar elements. It works
434    /// best when comparing with a known value. The `max_abs_diff` that should be used used
435    /// depends on the values being compared against.
436    ///
437    /// For more see
438    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
439    #[inline]
440    #[must_use]
441    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
442        self.matrix3.abs_diff_eq(rhs.matrix3, max_abs_diff)
443            && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
444    }
445
446    /// Return the inverse of this transform.
447    ///
448    /// Note that if the transform is not invertible the result will be invalid.
449    #[inline]
450    #[must_use]
451    pub fn inverse(&self) -> Self {
452        let matrix3 = self.matrix3.inverse();
453        // transform negative translation by the matrix inverse:
454        let translation = -(matrix3 * self.translation);
455
456        Self {
457            matrix3,
458            translation,
459        }
460    }
461
462    /// Casts all elements of `self` to `f64`.
463    #[inline]
464    #[must_use]
465    pub fn as_daffine3(&self) -> crate::DAffine3 {
466        crate::DAffine3::from_mat3_translation(self.matrix3.as_dmat3(), self.translation.as_dvec3())
467    }
468}
469
470impl Default for Affine3A {
471    #[inline(always)]
472    fn default() -> Self {
473        Self::IDENTITY
474    }
475}
476
477impl Deref for Affine3A {
478    type Target = crate::deref::Cols4<Vec3A>;
479    #[inline(always)]
480    fn deref(&self) -> &Self::Target {
481        unsafe { &*(self as *const Self as *const Self::Target) }
482    }
483}
484
485impl DerefMut for Affine3A {
486    #[inline(always)]
487    fn deref_mut(&mut self) -> &mut Self::Target {
488        unsafe { &mut *(self as *mut Self as *mut Self::Target) }
489    }
490}
491
492impl PartialEq for Affine3A {
493    #[inline]
494    fn eq(&self, rhs: &Self) -> bool {
495        self.matrix3.eq(&rhs.matrix3) && self.translation.eq(&rhs.translation)
496    }
497}
498
499impl core::fmt::Debug for Affine3A {
500    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
501        fmt.debug_struct(stringify!(Affine3A))
502            .field("matrix3", &self.matrix3)
503            .field("translation", &self.translation)
504            .finish()
505    }
506}
507
508impl core::fmt::Display for Affine3A {
509    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
510        if let Some(p) = f.precision() {
511            write!(
512                f,
513                "[{:.*}, {:.*}, {:.*}, {:.*}]",
514                p,
515                self.matrix3.x_axis,
516                p,
517                self.matrix3.y_axis,
518                p,
519                self.matrix3.z_axis,
520                p,
521                self.translation
522            )
523        } else {
524            write!(
525                f,
526                "[{}, {}, {}, {}]",
527                self.matrix3.x_axis, self.matrix3.y_axis, self.matrix3.z_axis, self.translation
528            )
529        }
530    }
531}
532
533impl<'a> core::iter::Product<&'a Self> for Affine3A {
534    fn product<I>(iter: I) -> Self
535    where
536        I: Iterator<Item = &'a Self>,
537    {
538        iter.fold(Self::IDENTITY, |a, &b| a * b)
539    }
540}
541
542impl Mul for Affine3A {
543    type Output = Self;
544
545    #[inline]
546    fn mul(self, rhs: Self) -> Self {
547        Self {
548            matrix3: self.matrix3 * rhs.matrix3,
549            translation: self.matrix3 * rhs.translation + self.translation,
550        }
551    }
552}
553
554impl Mul<&Self> for Affine3A {
555    type Output = Self;
556    #[inline]
557    fn mul(self, rhs: &Self) -> Self {
558        self.mul(*rhs)
559    }
560}
561
562impl Mul<&Affine3A> for &Affine3A {
563    type Output = Affine3A;
564    #[inline]
565    fn mul(self, rhs: &Affine3A) -> Affine3A {
566        (*self).mul(*rhs)
567    }
568}
569
570impl Mul<Affine3A> for &Affine3A {
571    type Output = Affine3A;
572    #[inline]
573    fn mul(self, rhs: Affine3A) -> Affine3A {
574        (*self).mul(rhs)
575    }
576}
577
578impl MulAssign for Affine3A {
579    #[inline]
580    fn mul_assign(&mut self, rhs: Self) {
581        *self = self.mul(rhs);
582    }
583}
584
585impl MulAssign<&Self> for Affine3A {
586    #[inline]
587    fn mul_assign(&mut self, rhs: &Self) {
588        self.mul_assign(*rhs);
589    }
590}
591
592impl Mul<Mat4> for Affine3A {
593    type Output = Mat4;
594
595    #[inline]
596    fn mul(self, rhs: Mat4) -> Self::Output {
597        Mat4::from(self) * rhs
598    }
599}
600
601impl Mul<&Mat4> for Affine3A {
602    type Output = Mat4;
603    #[inline]
604    fn mul(self, rhs: &Mat4) -> Mat4 {
605        self.mul(*rhs)
606    }
607}
608
609impl Mul<&Mat4> for &Affine3A {
610    type Output = Mat4;
611    #[inline]
612    fn mul(self, rhs: &Mat4) -> Mat4 {
613        (*self).mul(*rhs)
614    }
615}
616
617impl Mul<Mat4> for &Affine3A {
618    type Output = Mat4;
619    #[inline]
620    fn mul(self, rhs: Mat4) -> Mat4 {
621        (*self).mul(rhs)
622    }
623}
624
625impl Mul<Affine3A> for Mat4 {
626    type Output = Self;
627
628    #[inline]
629    fn mul(self, rhs: Affine3A) -> Self {
630        self * Self::from(rhs)
631    }
632}
633
634impl Mul<&Affine3A> for Mat4 {
635    type Output = Self;
636    #[inline]
637    fn mul(self, rhs: &Affine3A) -> Self {
638        self.mul(*rhs)
639    }
640}
641
642impl Mul<&Affine3A> for &Mat4 {
643    type Output = Mat4;
644    #[inline]
645    fn mul(self, rhs: &Affine3A) -> Mat4 {
646        (*self).mul(*rhs)
647    }
648}
649
650impl Mul<Affine3A> for &Mat4 {
651    type Output = Mat4;
652    #[inline]
653    fn mul(self, rhs: Affine3A) -> Mat4 {
654        (*self).mul(rhs)
655    }
656}
657
658impl MulAssign<Affine3A> for Mat4 {
659    #[inline]
660    fn mul_assign(&mut self, rhs: Affine3A) {
661        *self = self.mul(rhs);
662    }
663}
664
665impl MulAssign<&Affine3A> for Mat4 {
666    #[inline]
667    fn mul_assign(&mut self, rhs: &Affine3A) {
668        self.mul_assign(*rhs);
669    }
670}
671
672impl From<Affine3A> for Mat4 {
673    #[inline]
674    fn from(m: Affine3A) -> Self {
675        Self::from_cols(
676            m.matrix3.x_axis.extend(0.0),
677            m.matrix3.y_axis.extend(0.0),
678            m.matrix3.z_axis.extend(0.0),
679            m.translation.extend(1.0),
680        )
681    }
682}