Skip to main content

glem/
lib.rs

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}