revier_glam/f32/
affine2.rs

1// Generated from affine.rs.tera template. Edit the template, not the generated file.
2
3use crate::{Mat2, Mat3, Mat3A, Vec2, Vec3A};
4use core::ops::{Deref, DerefMut, Mul, MulAssign};
5
6/// A 2D affine transform, which can represent translation, rotation, scaling and shear.
7#[derive(Copy, Clone)]
8#[repr(C)]
9pub struct Affine2 {
10    pub matrix2: Mat2,
11    pub translation: Vec2,
12}
13
14impl Affine2 {
15    /// The degenerate zero transform.
16    ///
17    /// This transforms any finite vector and point to zero.
18    /// The zero transform is non-invertible.
19    pub const ZERO: Self = Self {
20        matrix2: Mat2::ZERO,
21        translation: Vec2::ZERO,
22    };
23
24    /// The identity transform.
25    ///
26    /// Multiplying a vector with this returns the same vector.
27    pub const IDENTITY: Self = Self {
28        matrix2: Mat2::IDENTITY,
29        translation: Vec2::ZERO,
30    };
31
32    /// All NAN:s.
33    pub const NAN: Self = Self {
34        matrix2: Mat2::NAN,
35        translation: Vec2::NAN,
36    };
37
38    /// Creates an affine transform from three column vectors.
39    #[inline(always)]
40    pub const fn from_cols(x_axis: Vec2, y_axis: Vec2, z_axis: Vec2) -> Self {
41        Self {
42            matrix2: Mat2::from_cols(x_axis, y_axis),
43            translation: z_axis,
44        }
45    }
46
47    /// Creates an affine transform from a `[f32; 6]` array stored in column major order.
48    #[inline]
49    pub fn from_cols_array(m: &[f32; 6]) -> Self {
50        Self {
51            matrix2: Mat2::from_cols_slice(&m[0..4]),
52            translation: Vec2::from_slice(&m[4..6]),
53        }
54    }
55
56    /// Creates a `[f32; 6]` array storing data in column major order.
57    #[inline]
58    pub fn to_cols_array(&self) -> [f32; 6] {
59        let x = &self.matrix2.x_axis;
60        let y = &self.matrix2.y_axis;
61        let z = &self.translation;
62        [x.x, x.y, y.x, y.y, z.x, z.y]
63    }
64
65    /// Creates an affine transform from a `[[f32; 2]; 3]`
66    /// 2D array stored in column major order.
67    /// If your data is in row major order you will need to `transpose` the returned
68    /// matrix.
69    #[inline]
70    pub fn from_cols_array_2d(m: &[[f32; 2]; 3]) -> Self {
71        Self {
72            matrix2: Mat2::from_cols(m[0].into(), m[1].into()),
73            translation: m[2].into(),
74        }
75    }
76
77    /// Creates a `[[f32; 2]; 3]` 2D array storing data in
78    /// column major order.
79    /// If you require data in row major order `transpose` the matrix first.
80    #[inline]
81    pub fn to_cols_array_2d(&self) -> [[f32; 2]; 3] {
82        [
83            self.matrix2.x_axis.into(),
84            self.matrix2.y_axis.into(),
85            self.translation.into(),
86        ]
87    }
88
89    /// Creates an affine transform from the first 6 values in `slice`.
90    ///
91    /// # Panics
92    ///
93    /// Panics if `slice` is less than 6 elements long.
94    #[inline]
95    pub fn from_cols_slice(slice: &[f32]) -> Self {
96        Self {
97            matrix2: Mat2::from_cols_slice(&slice[0..4]),
98            translation: Vec2::from_slice(&slice[4..6]),
99        }
100    }
101
102    /// Writes the columns of `self` to the first 6 elements in `slice`.
103    ///
104    /// # Panics
105    ///
106    /// Panics if `slice` is less than 6 elements long.
107    #[inline]
108    pub fn write_cols_to_slice(self, slice: &mut [f32]) {
109        self.matrix2.write_cols_to_slice(&mut slice[0..4]);
110        self.translation.write_to_slice(&mut slice[4..6]);
111    }
112
113    /// Creates an affine transform that changes scale.
114    /// Note that if any scale is zero the transform will be non-invertible.
115    #[inline]
116    pub fn from_scale(scale: Vec2) -> Self {
117        Self {
118            matrix2: Mat2::from_diagonal(scale),
119            translation: Vec2::ZERO,
120        }
121    }
122
123    /// Creates an affine transform from the given rotation `angle`.
124    #[inline]
125    pub fn from_angle(angle: f32) -> Self {
126        Self {
127            matrix2: Mat2::from_angle(angle),
128            translation: Vec2::ZERO,
129        }
130    }
131
132    /// Creates an affine transformation from the given 2D `translation`.
133    #[inline]
134    pub fn from_translation(translation: Vec2) -> Self {
135        Self {
136            matrix2: Mat2::IDENTITY,
137            translation,
138        }
139    }
140
141    /// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation)
142    #[inline]
143    pub fn from_mat2(matrix2: Mat2) -> Self {
144        Self {
145            matrix2,
146            translation: Vec2::ZERO,
147        }
148    }
149
150    /// Creates an affine transform from a 2x2 matrix (expressing scale, shear and rotation) and a
151    /// translation vector.
152    ///
153    /// Equivalent to
154    /// `Affine2::from_translation(translation) * Affine2::from_mat2(mat2)`
155    #[inline]
156    pub fn from_mat2_translation(matrix2: Mat2, translation: Vec2) -> Self {
157        Self {
158            matrix2,
159            translation,
160        }
161    }
162
163    /// Creates an affine transform from the given 2D `scale`, rotation `angle` (in radians) and
164    /// `translation`.
165    ///
166    /// Equivalent to `Affine2::from_translation(translation) *
167    /// Affine2::from_angle(angle) * Affine2::from_scale(scale)`
168    #[inline]
169    pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
170        let rotation = Mat2::from_angle(angle);
171        Self {
172            matrix2: Mat2::from_cols(rotation.x_axis * scale.x, rotation.y_axis * scale.y),
173            translation,
174        }
175    }
176
177    /// Creates an affine transform from the given 2D rotation `angle` (in radians) and
178    /// `translation`.
179    ///
180    /// Equivalent to `Affine2::from_translation(translation) * Affine2::from_angle(angle)`
181    #[inline]
182    pub fn from_angle_translation(angle: f32, translation: Vec2) -> Self {
183        Self {
184            matrix2: Mat2::from_angle(angle),
185            translation,
186        }
187    }
188
189    /// The given `Mat3` must be an affine transform,
190    #[inline]
191    pub fn from_mat3(m: Mat3) -> Self {
192        use crate::swizzles::Vec3Swizzles;
193        Self {
194            matrix2: Mat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
195            translation: m.z_axis.xy(),
196        }
197    }
198
199    /// The given [`Mat3A`] must be an affine transform,
200    #[inline]
201    pub fn from_mat3a(m: Mat3A) -> Self {
202        use crate::swizzles::Vec3Swizzles;
203        Self {
204            matrix2: Mat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
205            translation: m.z_axis.xy(),
206        }
207    }
208
209    /// Extracts `scale`, `angle` and `translation` from `self`.
210    ///
211    /// The transform is expected to be non-degenerate and without shearing, or the output
212    /// will be invalid.
213    ///
214    /// # Panics
215    ///
216    /// Will panic if the determinant `self.matrix2` is zero or if the resulting scale
217    /// vector contains any zero elements when `glam_assert` is enabled.
218    #[inline]
219    pub fn to_scale_angle_translation(self) -> (Vec2, f32, Vec2) {
220        use crate::f32::math;
221        let det = self.matrix2.determinant();
222        glam_assert!(det != 0.0);
223
224        let scale = Vec2::new(
225            self.matrix2.x_axis.length() * math::signum(det),
226            self.matrix2.y_axis.length(),
227        );
228
229        glam_assert!(scale.cmpne(Vec2::ZERO).all());
230
231        let angle = math::atan2(-self.matrix2.y_axis.x, self.matrix2.y_axis.y);
232
233        (scale, angle, self.translation)
234    }
235
236    /// Transforms the given 2D point, applying shear, scale, rotation and translation.
237    #[inline]
238    pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
239        self.matrix2 * rhs + self.translation
240    }
241
242    /// Transforms the given 2D vector, applying shear, scale and rotation (but NOT
243    /// translation).
244    ///
245    /// To also apply translation, use [`Self::transform_point2()`] instead.
246    #[inline]
247    pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
248        self.matrix2 * rhs
249    }
250
251    /// Returns `true` if, and only if, all elements are finite.
252    ///
253    /// If any element is either `NaN`, positive or negative infinity, this will return
254    /// `false`.
255    #[inline]
256    pub fn is_finite(&self) -> bool {
257        self.matrix2.is_finite() && self.translation.is_finite()
258    }
259
260    /// Returns `true` if any elements are `NaN`.
261    #[inline]
262    pub fn is_nan(&self) -> bool {
263        self.matrix2.is_nan() || self.translation.is_nan()
264    }
265
266    /// Returns true if the absolute difference of all elements between `self` and `rhs`
267    /// is less than or equal to `max_abs_diff`.
268    ///
269    /// This can be used to compare if two 3x4 matrices contain similar elements. It works
270    /// best when comparing with a known value. The `max_abs_diff` that should be used used
271    /// depends on the values being compared against.
272    ///
273    /// For more see
274    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
275    #[inline]
276    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
277        self.matrix2.abs_diff_eq(rhs.matrix2, max_abs_diff)
278            && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
279    }
280
281    /// Return the inverse of this transform.
282    ///
283    /// Note that if the transform is not invertible the result will be invalid.
284    #[must_use]
285    #[inline]
286    pub fn inverse(&self) -> Self {
287        let matrix2 = self.matrix2.inverse();
288        // transform negative translation by the matrix inverse:
289        let translation = -(matrix2 * self.translation);
290
291        Self {
292            matrix2,
293            translation,
294        }
295    }
296}
297
298impl Default for Affine2 {
299    #[inline(always)]
300    fn default() -> Self {
301        Self::IDENTITY
302    }
303}
304
305impl Deref for Affine2 {
306    type Target = crate::deref::Cols3<Vec2>;
307    #[inline(always)]
308    fn deref(&self) -> &Self::Target {
309        unsafe { &*(self as *const Self as *const Self::Target) }
310    }
311}
312
313impl DerefMut for Affine2 {
314    #[inline(always)]
315    fn deref_mut(&mut self) -> &mut Self::Target {
316        unsafe { &mut *(self as *mut Self as *mut Self::Target) }
317    }
318}
319
320impl PartialEq for Affine2 {
321    #[inline]
322    fn eq(&self, rhs: &Self) -> bool {
323        self.matrix2.eq(&rhs.matrix2) && self.translation.eq(&rhs.translation)
324    }
325}
326
327#[cfg(not(target_arch = "spirv"))]
328impl core::fmt::Debug for Affine2 {
329    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
330        fmt.debug_struct(stringify!(Affine2))
331            .field("matrix2", &self.matrix2)
332            .field("translation", &self.translation)
333            .finish()
334    }
335}
336
337#[cfg(not(target_arch = "spirv"))]
338impl core::fmt::Display for Affine2 {
339    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
340        write!(
341            f,
342            "[{}, {}, {}]",
343            self.matrix2.x_axis, self.matrix2.y_axis, self.translation
344        )
345    }
346}
347
348impl<'a> core::iter::Product<&'a Self> for Affine2 {
349    fn product<I>(iter: I) -> Self
350    where
351        I: Iterator<Item = &'a Self>,
352    {
353        iter.fold(Self::IDENTITY, |a, &b| a * b)
354    }
355}
356
357impl Mul for Affine2 {
358    type Output = Affine2;
359
360    #[inline]
361    fn mul(self, rhs: Affine2) -> Self::Output {
362        Self {
363            matrix2: self.matrix2 * rhs.matrix2,
364            translation: self.matrix2 * rhs.translation + self.translation,
365        }
366    }
367}
368
369impl MulAssign for Affine2 {
370    #[inline]
371    fn mul_assign(&mut self, rhs: Affine2) {
372        *self = self.mul(rhs);
373    }
374}
375
376impl From<Affine2> for Mat3 {
377    #[inline]
378    fn from(m: Affine2) -> Mat3 {
379        Self::from_cols(
380            m.matrix2.x_axis.extend(0.0),
381            m.matrix2.y_axis.extend(0.0),
382            m.translation.extend(1.0),
383        )
384    }
385}
386
387impl Mul<Mat3> for Affine2 {
388    type Output = Mat3;
389
390    #[inline]
391    fn mul(self, rhs: Mat3) -> Self::Output {
392        Mat3::from(self) * rhs
393    }
394}
395
396impl Mul<Affine2> for Mat3 {
397    type Output = Mat3;
398
399    #[inline]
400    fn mul(self, rhs: Affine2) -> Self::Output {
401        self * Mat3::from(rhs)
402    }
403}
404
405impl From<Affine2> for Mat3A {
406    #[inline]
407    fn from(m: Affine2) -> Mat3A {
408        Self::from_cols(
409            Vec3A::from((m.matrix2.x_axis, 0.0)),
410            Vec3A::from((m.matrix2.y_axis, 0.0)),
411            Vec3A::from((m.translation, 1.0)),
412        )
413    }
414}
415
416impl Mul<Mat3A> for Affine2 {
417    type Output = Mat3A;
418
419    #[inline]
420    fn mul(self, rhs: Mat3A) -> Self::Output {
421        Mat3A::from(self) * rhs
422    }
423}
424
425impl Mul<Affine2> for Mat3A {
426    type Output = Mat3A;
427
428    #[inline]
429    fn mul(self, rhs: Affine2) -> Self::Output {
430        self * Mat3A::from(rhs)
431    }
432}