glam/features/
impl_encase.rs

1use crate::{IVec2, IVec3, IVec4, Mat2, Mat3, Mat4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec4};
2use encase::{
3    matrix::{impl_matrix, AsMutMatrixParts, AsRefMatrixParts, FromMatrixParts, MatrixScalar},
4    vector::impl_vector,
5};
6
7impl_vector!(2, Vec2, f32; using AsRef AsMut From);
8impl_vector!(2, UVec2, u32; using AsRef AsMut From);
9impl_vector!(2, IVec2, i32; using AsRef AsMut From);
10
11impl_vector!(3, Vec3, f32; using AsRef AsMut From);
12impl_vector!(3, UVec3, u32; using AsRef AsMut From);
13impl_vector!(3, IVec3, i32; using AsRef AsMut From);
14
15impl_vector!(4, Vec4, f32; using AsRef AsMut From);
16impl_vector!(4, UVec4, u32; using AsRef AsMut From);
17impl_vector!(4, IVec4, i32; using AsRef AsMut From);
18
19macro_rules! impl_matrix_traits {
20    ($c:literal, $r:literal, $type:ty, $el_ty:ty) => {
21        impl AsRefMatrixParts<$el_ty, $c, $r> for $type
22        where
23            Self: AsRef<[$el_ty; $r * $c]>,
24            $el_ty: MatrixScalar,
25        {
26            fn as_ref_parts(&self) -> &[[$el_ty; $r]; $c] {
27                unsafe {
28                    ::core::mem::transmute::<&[$el_ty; $r * $c], &[[$el_ty; $r]; $c]>(self.as_ref())
29                }
30            }
31        }
32
33        impl AsMutMatrixParts<$el_ty, $c, $r> for $type
34        where
35            Self: AsMut<[$el_ty; $r * $c]>,
36            $el_ty: MatrixScalar,
37        {
38            fn as_mut_parts(&mut self) -> &mut [[$el_ty; $r]; $c] {
39                unsafe {
40                    ::core::mem::transmute::<&mut [$el_ty; $r * $c], &mut [[$el_ty; $r]; $c]>(
41                        self.as_mut(),
42                    )
43                }
44            }
45        }
46
47        impl FromMatrixParts<$el_ty, $c, $r> for $type {
48            fn from_parts(parts: [[$el_ty; $r]; $c]) -> Self {
49                Self::from_cols_array_2d(&parts)
50            }
51        }
52    };
53}
54
55impl_matrix_traits!(2, 2, Mat2, f32);
56impl_matrix_traits!(3, 3, Mat3, f32);
57impl_matrix_traits!(4, 4, Mat4, f32);
58
59impl_matrix!(2, 2, Mat2, f32);
60impl_matrix!(3, 3, Mat3, f32);
61impl_matrix!(4, 4, Mat4, f32);
62
63#[cfg(test)]
64macro_rules! impl_vec_test {
65    ($dim:literal, $test:ident, $ty:ty, $value:expr) => {
66        #[test]
67        fn $test() {
68            let v = <$ty>::from_array($value);
69
70            let mut buf = [255u8; $dim * 4];
71            let mut s_buf = StorageBuffer::new(&mut buf);
72
73            s_buf.write(&v).unwrap();
74            for i in 0..$dim {
75                assert_eq!(&s_buf.as_ref()[(i * 4)..][..4], &v[i].to_le_bytes());
76            }
77
78            let mut v_out = <$ty>::ZERO;
79            s_buf.read(&mut v_out).unwrap();
80            assert_eq!(v, v_out);
81
82            assert_eq!(v, s_buf.create().unwrap());
83        }
84    };
85}
86
87#[cfg(test)]
88macro_rules! impl_mat_test {
89    ($dim:literal, $stride:literal, $test:ident, $ty:ty, $value:expr) => {
90        #[test]
91        fn $test() {
92            let m = <$ty>::from_cols_array_2d(&$value);
93
94            let mut buf = [255u8; $dim * $stride * 4];
95            let mut s_buf = StorageBuffer::new(&mut buf);
96
97            s_buf.write(&m).unwrap();
98            for i in 0..$dim {
99                for j in 0..$dim {
100                    let stride = j * $stride * 4;
101                    let offset = i * 4;
102                    assert_eq!(
103                        &s_buf.as_ref()[(stride + offset)..][..4],
104                        &m.col(j)[i].to_le_bytes()
105                    );
106                }
107            }
108
109            let mut m_out = <$ty>::ZERO;
110            s_buf.read(&mut m_out).unwrap();
111            assert_eq!(m, m_out);
112
113            assert_eq!(m, s_buf.create().unwrap());
114        }
115    };
116}
117
118#[cfg(test)]
119mod test {
120    use crate::{IVec2, IVec3, IVec4, Mat2, Mat3, Mat4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec4};
121    use encase::StorageBuffer;
122
123    impl_vec_test!(2, vec2, Vec2, [1.12, 3.04]);
124    impl_vec_test!(2, ivec2, IVec2, [1, 3]);
125    impl_vec_test!(2, uvec2, UVec2, [1, 3]);
126
127    impl_vec_test!(3, vec3, Vec3, [1.12, 3.04, 6.75]);
128    impl_vec_test!(3, ivec3, IVec3, [1, 3, 6]);
129    impl_vec_test!(3, uvec3, UVec3, [1, 3, 6]);
130
131    impl_vec_test!(4, vec4, Vec4, [1.12, 3.04, 6.75, 9.99]);
132    impl_vec_test!(4, ivec4, IVec4, [1, 3, 6, 9]);
133    impl_vec_test!(4, uvec4, UVec4, [1, 3, 6, 9]);
134
135    impl_mat_test!(2, 2, mat2, Mat2, [[1.12, 3.04], [8.65, 2.34]]);
136
137    impl_mat_test!(
138        3,
139        4,
140        mat3,
141        Mat3,
142        [[1.12, 3.04, 6.75], [8.65, 2.34, 94.6], [5.45, 6.34, 89.41]]
143    );
144
145    impl_mat_test!(
146        4,
147        4,
148        mat4,
149        Mat4,
150        [
151            [1.12, 3.04, 6.75, 9.99],
152            [8.65, 2.34, 94.6, 113.3],
153            [5.45, 6.34, 89.41, 185.1],
154            [3.56, 5.43, 77.90, 140.67]
155        ]
156    );
157}