1use glam::f32::Mat4;
2
3
4pub mod prelude {
5 pub use super::Mat;
6}
7
8pub fn build_inverse(a: impl Inverse) -> Mat4 {
9 let mut m = Mat4::IDENTITY;
10 a.apply_inverse(&mut m);
11 m
12}
13
14pub fn build(a: impl Mat) -> Mat4 {
15 let mut m = Mat4::IDENTITY;
16 a.apply(&mut m);
17 m
18}
19
20pub trait Inverse: Mat {
21 fn apply_inverse(&self, a: &mut Mat4);
22}
23
24impl<T: Inverse> Inverse for &T {
25 fn apply_inverse(&self, m: &mut Mat4) {
26 (**self).apply_inverse(m)
27 }
28}
29
30impl Mat for Mat4 {
31 fn apply(&self, m: &mut Mat4) {
32 *m *= *self;
33 }
34}
35
36impl Inverse for Mat4 {
37 fn apply_inverse(&self, a: &mut Mat4) {
38 *a *= self.inverse()
39 }
40}
41
42impl<T: Mat> Mat for &T {
43 fn apply(&self, m: &mut Mat4) {
44 (**self).apply(m)
45 }
46}
47
48pub trait Mat {
49 fn apply(&self, m: &mut Mat4);
50
51 fn chain<K: Mat>(self, other: K) -> Chain<Self, K>
52 where
53 Self: Sized,
54 {
55 Chain { a: self, b: other }
56 }
57}
58
59#[derive(Copy, Clone, Debug)]
60pub struct Chain<A, B> {
61 a: A,
62 b: B,
63}
64impl<A: Inverse, B: Inverse> Inverse for Chain<A, B> {
65 fn apply_inverse(&self, a: &mut Mat4) {
66 self.b.apply_inverse(a);
67 self.a.apply_inverse(a);
68 }
69}
70impl<A: Mat, B: Mat> Mat for Chain<A, B> {
71 fn apply(&self, m: &mut Mat4) {
72 self.a.apply(m);
73 self.b.apply(m);
74 }
75}
76
77#[derive(Copy, Clone, Debug)]
78pub struct Scale {
79 pub tx: f32,
80 pub ty: f32,
81 pub tz: f32,
82}
83
84impl Inverse for Scale {
85 fn apply_inverse(&self, m: &mut Mat4) {
86 scale(1.0 / self.tx, 1.0 / self.ty, 1.0 / self.tz).apply(m)
87 }
88}
89impl Mat for Scale {
90 fn apply(&self, m: &mut Mat4) {
91 *m *= Mat4::from_cols_array(&[
92 self.tx, 0., 0., 0., 0., self.ty, 0., 0., 0., 0., self.tz, 0., 0., 0., 0., 1.0,
93 ])
94 }
95}
96
97#[derive(Copy, Clone, Debug)]
98pub struct XRot {
99 pub angle_rad: f32,
100}
101impl Inverse for XRot {
102 fn apply_inverse(&self, m: &mut Mat4) {
103 rotate_x(-self.angle_rad).apply(m)
104 }
105}
106impl Mat for XRot {
107 fn apply(&self, m: &mut Mat4) {
108 let c = self.angle_rad.cos();
109 let s = self.angle_rad.sin();
110
111 *m *= Mat4::from_cols_array(&[1., 0., 0., 0., 0., c, s, 0., 0., -s, c, 0., 0., 0., 0., 1.])
112 }
113}
114
115#[derive(Copy, Clone, Debug)]
116pub struct YRot {
117 pub angle_rad: f32,
118}
119impl Inverse for YRot {
120 fn apply_inverse(&self, m: &mut Mat4) {
121 rotate_y(-self.angle_rad).apply(m)
122 }
123}
124impl Mat for YRot {
125 fn apply(&self, m: &mut Mat4) {
126 let c = self.angle_rad.cos();
127 let s = self.angle_rad.sin();
128
129 *m *= Mat4::from_cols_array(&[c, 0., -s, 0., 0., 1., 0., 0., s, 0., c, 0., 0., 0., 0., 1.])
130 }
131}
132
133#[derive(Copy, Clone, Debug)]
134pub struct ZRot {
135 pub angle_rad: f32,
136}
137impl Inverse for ZRot {
138 fn apply_inverse(&self, m: &mut Mat4) {
139 rotate_z(-self.angle_rad).apply(m)
140 }
141}
142impl Mat for ZRot {
143 fn apply(&self, m: &mut Mat4) {
144 let c = self.angle_rad.cos();
145 let s = self.angle_rad.sin();
146
147 *m *= Mat4::from_cols_array(&[c, s, 0., 0., -s, c, 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.])
148 }
149}
150
151pub fn rotate_x(angle_rad: f32) -> XRot {
152 XRot { angle_rad }
153}
154pub fn rotate_y(angle_rad: f32) -> YRot {
155 YRot { angle_rad }
156}
157pub fn rotate_z(angle_rad: f32) -> ZRot {
158 ZRot { angle_rad }
159}
160
161pub fn scale(x: f32, y: f32, z: f32) -> Scale {
162 Scale {
163 tx: x,
164 ty: y,
165 tz: z,
166 }
167}
168pub fn translate(tx: f32, ty: f32, tz: f32) -> Translation {
169 Translation { tx, ty, tz }
170}
171
172#[derive(Copy, Clone, Debug)]
173pub struct Translation {
174 tx: f32,
175 ty: f32,
176 tz: f32,
177}
178
179impl Inverse for Translation {
180 fn apply_inverse(&self, m: &mut Mat4) {
181 translate(-self.tx, -self.ty, -self.tz).apply(m)
182 }
183}
184impl Mat for Translation {
185 fn apply(&self, m: &mut Mat4) {
186 let tx = self.tx;
187 let ty = self.ty;
188 let tz = self.tz;
189 *m *= Mat4::from_cols_array(&[
190 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., tx, ty, tz, 1.,
191 ])
192 }
193}
194
195
196#[macro_export]
197macro_rules! combine {
198 ($a:expr)=>{
199 $a
200 };
201 ( $a:expr,$( $x:expr ),* ) => {
202 {
203 use $crate::Mat;
204 let mut a=$a;
205 $(
206 let a=a.chain($x);
207 )*
208
209 a
210 }
211 };
212}