glam/f32/
affine3.rs

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