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}