1use crate::{Mat2, Mat3, Mat3A, Vec2, Vec3A};
4use core::ops::{Deref, DerefMut, Mul, MulAssign};
5
6#[derive(Copy, Clone)]
8#[repr(C)]
9pub struct Affine2 {
10 pub matrix2: Mat2,
11 pub translation: Vec2,
12}
13
14impl Affine2 {
15 pub const ZERO: Self = Self {
20 matrix2: Mat2::ZERO,
21 translation: Vec2::ZERO,
22 };
23
24 pub const IDENTITY: Self = Self {
28 matrix2: Mat2::IDENTITY,
29 translation: Vec2::ZERO,
30 };
31
32 pub const NAN: Self = Self {
34 matrix2: Mat2::NAN,
35 translation: Vec2::NAN,
36 };
37
38 #[inline(always)]
40 #[must_use]
41 pub const fn from_cols(x_axis: Vec2, y_axis: Vec2, z_axis: Vec2) -> Self {
42 Self {
43 matrix2: Mat2::from_cols(x_axis, y_axis),
44 translation: z_axis,
45 }
46 }
47
48 #[inline]
50 #[must_use]
51 pub fn from_cols_array(m: &[f32; 6]) -> Self {
52 Self {
53 matrix2: Mat2::from_cols_slice(&m[0..4]),
54 translation: Vec2::from_slice(&m[4..6]),
55 }
56 }
57
58 #[inline]
60 #[must_use]
61 pub fn to_cols_array(&self) -> [f32; 6] {
62 let x = &self.matrix2.x_axis;
63 let y = &self.matrix2.y_axis;
64 let z = &self.translation;
65 [x.x, x.y, y.x, y.y, z.x, z.y]
66 }
67
68 #[inline]
73 #[must_use]
74 pub fn from_cols_array_2d(m: &[[f32; 2]; 3]) -> Self {
75 Self {
76 matrix2: Mat2::from_cols(m[0].into(), m[1].into()),
77 translation: m[2].into(),
78 }
79 }
80
81 #[inline]
85 #[must_use]
86 pub fn to_cols_array_2d(&self) -> [[f32; 2]; 3] {
87 [
88 self.matrix2.x_axis.into(),
89 self.matrix2.y_axis.into(),
90 self.translation.into(),
91 ]
92 }
93
94 #[inline]
100 #[must_use]
101 pub fn from_cols_slice(slice: &[f32]) -> Self {
102 Self {
103 matrix2: Mat2::from_cols_slice(&slice[0..4]),
104 translation: Vec2::from_slice(&slice[4..6]),
105 }
106 }
107
108 #[inline]
114 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
115 self.matrix2.write_cols_to_slice(&mut slice[0..4]);
116 self.translation.write_to_slice(&mut slice[4..6]);
117 }
118
119 #[inline]
122 #[must_use]
123 pub fn from_scale(scale: Vec2) -> Self {
124 Self {
125 matrix2: Mat2::from_diagonal(scale),
126 translation: Vec2::ZERO,
127 }
128 }
129
130 #[inline]
132 #[must_use]
133 pub fn from_angle(angle: f32) -> Self {
134 Self {
135 matrix2: Mat2::from_angle(angle),
136 translation: Vec2::ZERO,
137 }
138 }
139
140 #[inline]
142 #[must_use]
143 pub fn from_translation(translation: Vec2) -> Self {
144 Self {
145 matrix2: Mat2::IDENTITY,
146 translation,
147 }
148 }
149
150 #[inline]
152 #[must_use]
153 pub fn from_mat2(matrix2: Mat2) -> Self {
154 Self {
155 matrix2,
156 translation: Vec2::ZERO,
157 }
158 }
159
160 #[inline]
166 #[must_use]
167 pub fn from_mat2_translation(matrix2: Mat2, translation: Vec2) -> Self {
168 Self {
169 matrix2,
170 translation,
171 }
172 }
173
174 #[inline]
180 #[must_use]
181 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
182 let rotation = Mat2::from_angle(angle);
183 Self {
184 matrix2: Mat2::from_cols(rotation.x_axis * scale.x, rotation.y_axis * scale.y),
185 translation,
186 }
187 }
188
189 #[inline]
194 #[must_use]
195 pub fn from_angle_translation(angle: f32, translation: Vec2) -> Self {
196 Self {
197 matrix2: Mat2::from_angle(angle),
198 translation,
199 }
200 }
201
202 #[inline]
204 #[must_use]
205 pub fn from_mat3(m: Mat3) -> Self {
206 use crate::swizzles::Vec3Swizzles;
207 Self {
208 matrix2: Mat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
209 translation: m.z_axis.xy(),
210 }
211 }
212
213 #[inline]
215 #[must_use]
216 pub fn from_mat3a(m: Mat3A) -> Self {
217 use crate::swizzles::Vec3Swizzles;
218 Self {
219 matrix2: Mat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
220 translation: m.z_axis.xy(),
221 }
222 }
223
224 #[inline]
234 #[must_use]
235 pub fn to_scale_angle_translation(self) -> (Vec2, f32, Vec2) {
236 use crate::f32::math;
237 let det = self.matrix2.determinant();
238 glam_assert!(det != 0.0);
239
240 let scale = Vec2::new(
241 self.matrix2.x_axis.length() * math::signum(det),
242 self.matrix2.y_axis.length(),
243 );
244
245 glam_assert!(scale.cmpne(Vec2::ZERO).all());
246
247 let angle = math::atan2(-self.matrix2.y_axis.x, self.matrix2.y_axis.y);
248
249 (scale, angle, self.translation)
250 }
251
252 #[inline]
254 #[must_use]
255 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
256 self.matrix2 * rhs + self.translation
257 }
258
259 #[inline]
264 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
265 self.matrix2 * rhs
266 }
267
268 #[inline]
273 #[must_use]
274 pub fn is_finite(&self) -> bool {
275 self.matrix2.is_finite() && self.translation.is_finite()
276 }
277
278 #[inline]
280 #[must_use]
281 pub fn is_nan(&self) -> bool {
282 self.matrix2.is_nan() || self.translation.is_nan()
283 }
284
285 #[inline]
295 #[must_use]
296 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
297 self.matrix2.abs_diff_eq(rhs.matrix2, max_abs_diff)
298 && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
299 }
300
301 #[inline]
305 #[must_use]
306 pub fn inverse(&self) -> Self {
307 let matrix2 = self.matrix2.inverse();
308 let translation = -(matrix2 * self.translation);
310
311 Self {
312 matrix2,
313 translation,
314 }
315 }
316}
317
318impl Default for Affine2 {
319 #[inline(always)]
320 fn default() -> Self {
321 Self::IDENTITY
322 }
323}
324
325impl Deref for Affine2 {
326 type Target = crate::deref::Cols3<Vec2>;
327 #[inline(always)]
328 fn deref(&self) -> &Self::Target {
329 unsafe { &*(self as *const Self as *const Self::Target) }
330 }
331}
332
333impl DerefMut for Affine2 {
334 #[inline(always)]
335 fn deref_mut(&mut self) -> &mut Self::Target {
336 unsafe { &mut *(self as *mut Self as *mut Self::Target) }
337 }
338}
339
340impl PartialEq for Affine2 {
341 #[inline]
342 fn eq(&self, rhs: &Self) -> bool {
343 self.matrix2.eq(&rhs.matrix2) && self.translation.eq(&rhs.translation)
344 }
345}
346
347#[cfg(not(target_arch = "spirv"))]
348impl core::fmt::Debug for Affine2 {
349 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
350 fmt.debug_struct(stringify!(Affine2))
351 .field("matrix2", &self.matrix2)
352 .field("translation", &self.translation)
353 .finish()
354 }
355}
356
357#[cfg(not(target_arch = "spirv"))]
358impl core::fmt::Display for Affine2 {
359 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
360 write!(
361 f,
362 "[{}, {}, {}]",
363 self.matrix2.x_axis, self.matrix2.y_axis, self.translation
364 )
365 }
366}
367
368impl<'a> core::iter::Product<&'a Self> for Affine2 {
369 fn product<I>(iter: I) -> Self
370 where
371 I: Iterator<Item = &'a Self>,
372 {
373 iter.fold(Self::IDENTITY, |a, &b| a * b)
374 }
375}
376
377impl Mul for Affine2 {
378 type Output = Affine2;
379
380 #[inline]
381 fn mul(self, rhs: Affine2) -> Self::Output {
382 Self {
383 matrix2: self.matrix2 * rhs.matrix2,
384 translation: self.matrix2 * rhs.translation + self.translation,
385 }
386 }
387}
388
389impl MulAssign for Affine2 {
390 #[inline]
391 fn mul_assign(&mut self, rhs: Affine2) {
392 *self = self.mul(rhs);
393 }
394}
395
396impl From<Affine2> for Mat3 {
397 #[inline]
398 fn from(m: Affine2) -> Mat3 {
399 Self::from_cols(
400 m.matrix2.x_axis.extend(0.0),
401 m.matrix2.y_axis.extend(0.0),
402 m.translation.extend(1.0),
403 )
404 }
405}
406
407impl Mul<Mat3> for Affine2 {
408 type Output = Mat3;
409
410 #[inline]
411 fn mul(self, rhs: Mat3) -> Self::Output {
412 Mat3::from(self) * rhs
413 }
414}
415
416impl Mul<Affine2> for Mat3 {
417 type Output = Mat3;
418
419 #[inline]
420 fn mul(self, rhs: Affine2) -> Self::Output {
421 self * Mat3::from(rhs)
422 }
423}
424
425impl From<Affine2> for Mat3A {
426 #[inline]
427 fn from(m: Affine2) -> Mat3A {
428 Self::from_cols(
429 Vec3A::from((m.matrix2.x_axis, 0.0)),
430 Vec3A::from((m.matrix2.y_axis, 0.0)),
431 Vec3A::from((m.translation, 1.0)),
432 )
433 }
434}
435
436impl Mul<Mat3A> for Affine2 {
437 type Output = Mat3A;
438
439 #[inline]
440 fn mul(self, rhs: Mat3A) -> Self::Output {
441 Mat3A::from(self) * rhs
442 }
443}
444
445impl Mul<Affine2> for Mat3A {
446 type Output = Mat3A;
447
448 #[inline]
449 fn mul(self, rhs: Affine2) -> Self::Output {
450 self * Mat3A::from(rhs)
451 }
452}