1use std::ops::Mul;
2
3use crate::math::{Affine2, Mat2, Mat3, Vec2};
4
5#[must_use]
7#[derive(Debug, Default, Clone, Copy)]
8pub struct Transform(Affine2);
9
10impl Transform {
11 pub const IDENTITY: Self = Self::from_affine(Affine2::IDENTITY);
13
14 #[inline]
16 pub const fn from_affine(aff: Affine2) -> Self {
17 Self(aff)
18 }
19
20 #[inline]
22 pub fn from_translation(coords: Vec2) -> Self {
23 Self(Affine2::from_translation(coords))
24 }
25
26 #[inline]
28 pub fn from_scale(scale: Vec2) -> Self {
29 Self(Affine2::from_scale(scale))
30 }
31
32 #[inline]
34 pub fn from_rotation(angle: f32) -> Self {
35 Self(Affine2::from_angle(angle))
36 }
37
38 #[inline]
40 pub fn translate(self, coords: Vec2) -> Self {
41 self * Self::from_translation(coords)
42 }
43
44 #[inline]
46 pub fn scale(self, scale: Vec2) -> Self {
47 self * Self::from_scale(scale)
48 }
49
50 #[inline]
52 pub fn rotate(self, angle: f32) -> Self {
53 self * Self::from_rotation(angle)
54 }
55
56 #[must_use]
58 pub const fn to_affine(self) -> Affine2 {
59 self.0
60 }
61
62 #[must_use]
66 #[inline]
67 pub fn transform_point(&self, point: Vec2) -> Vec2 {
68 self.0.transform_point2(point)
69 }
70}
71
72impl Mul for Transform {
73 type Output = Self;
74
75 #[inline]
76 fn mul(self, rhs: Self) -> Self::Output {
77 Self(self.0 * rhs.0)
78 }
79}
80
81impl From<Mat3> for Transform {
82 #[inline]
83 fn from(value: Mat3) -> Self {
84 Self(Affine2::from_mat3(value))
85 }
86}
87
88impl From<Mat2> for Transform {
89 #[inline]
90 fn from(value: Mat2) -> Self {
91 Self(Affine2::from_mat2(value))
92 }
93}
94
95impl From<()> for Transform {
96 #[inline]
97 fn from((): ()) -> Self {
98 Self::IDENTITY
99 }
100}
101
102macro_rules! impl_translation_scale_rotation {
103 ($T:ty, $U:ty, $V:ty) => {
104 impl From<($T, $U, $V)> for Transform {
105 #[inline]
107 fn from((translation, scale, angle): ($T, $U, $V)) -> Self {
108 Self::from_translation(translation.into())
109 .scale(scale.into())
110 .rotate(angle.into())
111 }
112 }
113 };
114}
115
116macro_rules! impl_translation_scale {
117 ($T:ty, $U:ty) => {
118 impl From<($T, $U)> for Transform {
119 #[inline]
121 fn from((translation, scale): ($T, $U)) -> Self {
122 Self::from_translation(translation.into()).scale(scale.into())
123 }
124 }
125
126 impl_translation_scale_rotation!($T, $U, f32);
127 };
128}
129
130macro_rules! impl_translation {
131 ($T:ty) => {
132 impl From<$T> for Transform {
133 #[inline]
135 fn from(value: $T) -> Self {
136 Self::from_translation(value.into())
137 }
138 }
139
140 impl_translation_scale!($T, Vec2);
141 impl_translation_scale!($T, (f32, f32));
142 impl_translation_scale!($T, [f32; 2]);
143 };
144}
145
146impl_translation!(Vec2);
147impl_translation!((f32, f32));
148impl_translation!([f32; 2]);