1 use mint::IntoMint;
2 
3 use crate::{
4     DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4, I16Vec2, I16Vec3, I16Vec4, I64Vec2, I64Vec3,
5     I64Vec4, IVec2, IVec3, IVec4, Mat2, Mat3, Mat3A, Mat4, Quat, U16Vec2, U16Vec3, U16Vec4,
6     U64Vec2, U64Vec3, U64Vec4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec3A, Vec4,
7 };
8 
9 macro_rules! impl_vec_types {
10     ($t:ty, $vec2:ty, $vec3:ty, $vec4:ty) => {
11         impl From<mint::Point2<$t>> for $vec2 {
12             fn from(v: mint::Point2<$t>) -> Self {
13                 Self::new(v.x, v.y)
14             }
15         }
16 
17         impl From<$vec2> for mint::Point2<$t> {
18             fn from(v: $vec2) -> Self {
19                 Self { x: v.x, y: v.y }
20             }
21         }
22 
23         impl From<mint::Vector2<$t>> for $vec2 {
24             fn from(v: mint::Vector2<$t>) -> Self {
25                 Self::new(v.x, v.y)
26             }
27         }
28 
29         impl From<$vec2> for mint::Vector2<$t> {
30             fn from(v: $vec2) -> Self {
31                 Self { x: v.x, y: v.y }
32             }
33         }
34 
35         impl IntoMint for $vec2 {
36             type MintType = mint::Vector2<$t>;
37         }
38 
39         impl From<mint::Point3<$t>> for $vec3 {
40             fn from(v: mint::Point3<$t>) -> Self {
41                 Self::new(v.x, v.y, v.z)
42             }
43         }
44 
45         impl From<$vec3> for mint::Point3<$t> {
46             fn from(v: $vec3) -> Self {
47                 Self {
48                     x: v.x,
49                     y: v.y,
50                     z: v.z,
51                 }
52             }
53         }
54 
55         impl From<mint::Vector3<$t>> for $vec3 {
56             fn from(v: mint::Vector3<$t>) -> Self {
57                 Self::new(v.x, v.y, v.z)
58             }
59         }
60 
61         impl From<$vec3> for mint::Vector3<$t> {
62             fn from(v: $vec3) -> Self {
63                 Self {
64                     x: v.x,
65                     y: v.y,
66                     z: v.z,
67                 }
68             }
69         }
70 
71         impl IntoMint for $vec3 {
72             type MintType = mint::Vector3<$t>;
73         }
74 
75         impl From<mint::Vector4<$t>> for $vec4 {
76             fn from(v: mint::Vector4<$t>) -> Self {
77                 Self::new(v.x, v.y, v.z, v.w)
78             }
79         }
80 
81         impl From<$vec4> for mint::Vector4<$t> {
82             fn from(v: $vec4) -> Self {
83                 Self {
84                     x: v.x,
85                     y: v.y,
86                     z: v.z,
87                     w: v.w,
88                 }
89             }
90         }
91 
92         impl IntoMint for $vec4 {
93             type MintType = mint::Vector4<$t>;
94         }
95     };
96 }
97 
98 macro_rules! impl_float_types {
99     ($t:ty, $mat2:ty, $mat3:ty, $mat4:ty, $quat:ty, $vec2:ty, $vec3:ty, $vec4:ty) => {
100         impl_vec_types!($t, $vec2, $vec3, $vec4);
101 
102         impl From<mint::Quaternion<$t>> for $quat {
103             fn from(q: mint::Quaternion<$t>) -> Self {
104                 Self::from_xyzw(q.v.x, q.v.y, q.v.z, q.s)
105             }
106         }
107 
108         impl From<$quat> for mint::Quaternion<$t> {
109             fn from(q: $quat) -> Self {
110                 Self {
111                     s: q.w,
112                     v: mint::Vector3 {
113                         x: q.x,
114                         y: q.y,
115                         z: q.z,
116                     },
117                 }
118             }
119         }
120 
121         impl IntoMint for $quat {
122             type MintType = mint::Quaternion<$t>;
123         }
124 
125         impl From<mint::RowMatrix2<$t>> for $mat2 {
126             fn from(m: mint::RowMatrix2<$t>) -> Self {
127                 Self::from_cols(m.x.into(), m.y.into()).transpose()
128             }
129         }
130 
131         impl From<$mat2> for mint::RowMatrix2<$t> {
132             fn from(m: $mat2) -> Self {
133                 let mt = m.transpose();
134                 Self {
135                     x: mt.x_axis.into(),
136                     y: mt.y_axis.into(),
137                 }
138             }
139         }
140 
141         impl From<mint::ColumnMatrix2<$t>> for $mat2 {
142             fn from(m: mint::ColumnMatrix2<$t>) -> Self {
143                 Self::from_cols(m.x.into(), m.y.into())
144             }
145         }
146 
147         impl From<$mat2> for mint::ColumnMatrix2<$t> {
148             fn from(m: $mat2) -> Self {
149                 Self {
150                     x: m.x_axis.into(),
151                     y: m.y_axis.into(),
152                 }
153             }
154         }
155 
156         impl IntoMint for $mat2 {
157             type MintType = mint::ColumnMatrix2<$t>;
158         }
159 
160         impl From<mint::RowMatrix3<$t>> for $mat3 {
161             fn from(m: mint::RowMatrix3<$t>) -> Self {
162                 Self::from_cols(m.x.into(), m.y.into(), m.z.into()).transpose()
163             }
164         }
165 
166         impl From<$mat3> for mint::RowMatrix3<$t> {
167             fn from(m: $mat3) -> Self {
168                 let mt = m.transpose();
169                 Self {
170                     x: mt.x_axis.into(),
171                     y: mt.y_axis.into(),
172                     z: mt.z_axis.into(),
173                 }
174             }
175         }
176 
177         impl From<mint::ColumnMatrix3<$t>> for $mat3 {
178             fn from(m: mint::ColumnMatrix3<$t>) -> Self {
179                 Self::from_cols(m.x.into(), m.y.into(), m.z.into())
180             }
181         }
182 
183         impl From<$mat3> for mint::ColumnMatrix3<$t> {
184             fn from(m: $mat3) -> Self {
185                 Self {
186                     x: m.x_axis.into(),
187                     y: m.y_axis.into(),
188                     z: m.z_axis.into(),
189                 }
190             }
191         }
192 
193         impl IntoMint for $mat3 {
194             type MintType = mint::ColumnMatrix3<$t>;
195         }
196 
197         impl From<mint::RowMatrix4<$t>> for $mat4 {
198             fn from(m: mint::RowMatrix4<$t>) -> Self {
199                 Self::from_cols(m.x.into(), m.y.into(), m.z.into(), m.w.into()).transpose()
200             }
201         }
202 
203         impl From<$mat4> for mint::RowMatrix4<$t> {
204             fn from(m: $mat4) -> Self {
205                 let mt = m.transpose();
206                 Self {
207                     x: mt.x_axis.into(),
208                     y: mt.y_axis.into(),
209                     z: mt.z_axis.into(),
210                     w: mt.w_axis.into(),
211                 }
212             }
213         }
214 
215         impl From<mint::ColumnMatrix4<$t>> for $mat4 {
216             fn from(m: mint::ColumnMatrix4<$t>) -> Self {
217                 Self::from_cols(m.x.into(), m.y.into(), m.z.into(), m.w.into())
218             }
219         }
220 
221         impl From<$mat4> for mint::ColumnMatrix4<$t> {
222             fn from(m: $mat4) -> Self {
223                 Self {
224                     x: m.x_axis.into(),
225                     y: m.y_axis.into(),
226                     z: m.z_axis.into(),
227                     w: m.w_axis.into(),
228                 }
229             }
230         }
231 
232         impl IntoMint for $mat4 {
233             type MintType = mint::ColumnMatrix4<$t>;
234         }
235     };
236 }
237 
238 impl From<mint::Point3<f32>> for Vec3A {
from(v: mint::Point3<f32>) -> Self239     fn from(v: mint::Point3<f32>) -> Self {
240         Self::new(v.x, v.y, v.z)
241     }
242 }
243 
244 impl From<Vec3A> for mint::Point3<f32> {
from(v: Vec3A) -> Self245     fn from(v: Vec3A) -> Self {
246         Self {
247             x: v.x,
248             y: v.y,
249             z: v.z,
250         }
251     }
252 }
253 
254 impl From<mint::Vector3<f32>> for Vec3A {
from(v: mint::Vector3<f32>) -> Self255     fn from(v: mint::Vector3<f32>) -> Self {
256         Self::new(v.x, v.y, v.z)
257     }
258 }
259 
260 impl From<Vec3A> for mint::Vector3<f32> {
from(v: Vec3A) -> Self261     fn from(v: Vec3A) -> Self {
262         Self {
263             x: v.x,
264             y: v.y,
265             z: v.z,
266         }
267     }
268 }
269 
270 impl IntoMint for Vec3A {
271     type MintType = mint::Vector3<f32>;
272 }
273 
274 impl From<mint::RowMatrix3<f32>> for Mat3A {
from(m: mint::RowMatrix3<f32>) -> Self275     fn from(m: mint::RowMatrix3<f32>) -> Self {
276         Self::from_cols(m.x.into(), m.y.into(), m.z.into()).transpose()
277     }
278 }
279 
280 impl From<Mat3A> for mint::RowMatrix3<f32> {
from(m: Mat3A) -> Self281     fn from(m: Mat3A) -> Self {
282         let mt = m.transpose();
283         Self {
284             x: mt.x_axis.into(),
285             y: mt.y_axis.into(),
286             z: mt.z_axis.into(),
287         }
288     }
289 }
290 
291 impl From<mint::ColumnMatrix3<f32>> for Mat3A {
from(m: mint::ColumnMatrix3<f32>) -> Self292     fn from(m: mint::ColumnMatrix3<f32>) -> Self {
293         Self::from_cols(m.x.into(), m.y.into(), m.z.into())
294     }
295 }
296 
297 impl From<Mat3A> for mint::ColumnMatrix3<f32> {
from(m: Mat3A) -> Self298     fn from(m: Mat3A) -> Self {
299         Self {
300             x: m.x_axis.into(),
301             y: m.y_axis.into(),
302             z: m.z_axis.into(),
303         }
304     }
305 }
306 
307 impl IntoMint for Mat3A {
308     type MintType = mint::ColumnMatrix3<f32>;
309 }
310 
311 impl_float_types!(f32, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec4);
312 impl_float_types!(f64, DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4);
313 impl_vec_types!(i16, I16Vec2, I16Vec3, I16Vec4);
314 impl_vec_types!(u16, U16Vec2, U16Vec3, U16Vec4);
315 impl_vec_types!(i32, IVec2, IVec3, IVec4);
316 impl_vec_types!(u32, UVec2, UVec3, UVec4);
317 impl_vec_types!(i64, I64Vec2, I64Vec3, I64Vec4);
318 impl_vec_types!(u64, U64Vec2, U64Vec3, U64Vec4);
319 
320 #[cfg(test)]
321 mod test {
322     macro_rules! impl_vec_tests {
323         ($t:ty, $vec2:ident, $vec3:ident, $vec4:ident) => {
324             use crate::{$vec2, $vec3, $vec4};
325             use mint;
326 
327             #[test]
328             fn test_point2() {
329                 let m = mint::Point2 {
330                     x: 1 as $t,
331                     y: 2 as $t,
332                 };
333                 let g = $vec2::from(m);
334                 assert_eq!(g, $vec2::new(1 as $t, 2 as $t));
335                 assert_eq!(m, g.into());
336             }
337 
338             #[test]
339             fn test_point3() {
340                 let m = mint::Point3 {
341                     x: 1 as $t,
342                     y: 2 as $t,
343                     z: 3 as $t,
344                 };
345                 let g = $vec3::from(m);
346                 assert_eq!(g, $vec3::new(1 as $t, 2 as $t, 3 as $t));
347                 assert_eq!(m, g.into());
348             }
349 
350             #[test]
351             fn test_vector2() {
352                 let m = mint::Vector2 {
353                     x: 1 as $t,
354                     y: 2 as $t,
355                 };
356                 let g = $vec2::from(m);
357                 assert_eq!(g, $vec2::new(1 as $t, 2 as $t));
358                 assert_eq!(m, g.into());
359             }
360 
361             #[test]
362             fn test_vector3() {
363                 let m = mint::Vector3 {
364                     x: 1 as $t,
365                     y: 2 as $t,
366                     z: 3 as $t,
367                 };
368                 let g = $vec3::from(m);
369                 assert_eq!(g, $vec3::new(1 as $t, 2 as $t, 3 as $t));
370                 assert_eq!(m, g.into());
371             }
372 
373             #[test]
374             fn test_vector4() {
375                 let m = mint::Vector4 {
376                     x: 1 as $t,
377                     y: 2 as $t,
378                     z: 3 as $t,
379                     w: 4 as $t,
380                 };
381                 let g = $vec4::from(m);
382                 assert_eq!(g, $vec4::new(1 as $t, 2 as $t, 3 as $t, 4 as $t));
383                 assert_eq!(m, g.into());
384             }
385         };
386     }
387 
388     macro_rules! impl_float_tests {
389         ($t:ty, $mat2:ident, $mat3:ident, $mat4:ident, $quat:ident, $vec2:ident, $vec3:ident, $vec4:ident) => {
390             impl_vec_tests!($t, $vec2, $vec3, $vec4);
391 
392             use crate::{$mat2, $mat3, $mat4, $quat};
393 
394             #[test]
395             fn test_quaternion() {
396                 let m = mint::Quaternion {
397                     v: mint::Vector3 {
398                         x: 1.0,
399                         y: 2.0,
400                         z: 3.0,
401                     },
402                     s: 4.0,
403                 };
404                 let g = $quat::from(m);
405                 assert_eq!(g, $quat::from_xyzw(1.0, 2.0, 3.0, 4.0));
406                 assert_eq!(m, g.into());
407             }
408 
409             #[test]
410             fn test_matrix2() {
411                 let g = $mat2::from_cols_array_2d(&[[1.0, 2.0], [3.0, 4.0]]);
412                 let m = mint::ColumnMatrix2::from(g);
413                 assert_eq!(g, $mat2::from(m));
414                 let mt = mint::RowMatrix2::from(g);
415                 assert_eq!(mt, mint::RowMatrix2::from([[1.0, 3.0], [2.0, 4.0]]));
416                 assert_eq!(g, $mat2::from(mt));
417             }
418 
419             #[test]
420             fn test_matrix3() {
421                 let g =
422                     $mat3::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]);
423                 let m = mint::ColumnMatrix3::from(g);
424                 assert_eq!(g, $mat3::from(m));
425                 let mt = mint::RowMatrix3::from(g);
426                 assert_eq!(
427                     mt,
428                     mint::RowMatrix3::from([[1.0, 4.0, 7.0], [2.0, 5.0, 8.0], [3.0, 6.0, 9.0]])
429                 );
430                 assert_eq!(g, $mat3::from(mt));
431             }
432 
433             #[test]
434             fn test_matrix4() {
435                 let g = $mat4::from_cols_array_2d(&[
436                     [1.0, 2.0, 3.0, 4.0],
437                     [5.0, 6.0, 7.0, 8.0],
438                     [9.0, 10.0, 11.0, 12.0],
439                     [13.0, 14.0, 15.0, 16.0],
440                 ]);
441                 let m = mint::ColumnMatrix4::from(g);
442                 assert_eq!(g, $mat4::from(m));
443                 let mt = mint::RowMatrix4::from(g);
444                 assert_eq!(
445                     mt,
446                     mint::RowMatrix4::from([
447                         [1.0, 5.0, 9.0, 13.0],
448                         [2.0, 6.0, 10.0, 14.0],
449                         [3.0, 7.0, 11.0, 15.0],
450                         [4.0, 8.0, 12.0, 16.0]
451                     ])
452                 );
453                 assert_eq!(g, $mat4::from(mt));
454             }
455         };
456     }
457 
458     mod f32 {
459         impl_float_tests!(f32, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec4);
460 
461         #[test]
test_point3a()462         fn test_point3a() {
463             use crate::Vec3A;
464             let m = mint::Point3 {
465                 x: 1.0,
466                 y: 2.0,
467                 z: 3.0,
468             };
469             let g = Vec3A::from(m);
470             assert_eq!(g, Vec3A::new(1.0, 2.0, 3.0));
471             assert_eq!(m, g.into());
472         }
473 
474         #[test]
test_vector3a()475         fn test_vector3a() {
476             use crate::Vec3A;
477             let m = mint::Vector3 {
478                 x: 1.0,
479                 y: 2.0,
480                 z: 3.0,
481             };
482             let g = Vec3A::from(m);
483             assert_eq!(g, Vec3A::new(1.0, 2.0, 3.0));
484             assert_eq!(m, g.into());
485         }
486 
487         #[test]
test_mat3a_col_major()488         fn test_mat3a_col_major() {
489             use crate::Mat3A;
490             let m = mint::ColumnMatrix3 {
491                 x: [0.0, 1.0, 2.0].into(),
492                 y: [3.0, 4.0, 5.0].into(),
493                 z: [6.0, 7.0, 8.0].into(),
494             };
495             let expected = Mat3A::from_cols(
496                 [0.0, 1.0, 2.0].into(),
497                 [3.0, 4.0, 5.0].into(),
498                 [6.0, 7.0, 8.0].into(),
499             );
500             assert_eq!(expected, m.into());
501             assert_eq!(m, expected.into());
502         }
503 
504         #[test]
test_mat3a_row_major()505         fn test_mat3a_row_major() {
506             use crate::Mat3A;
507             let m = mint::RowMatrix3 {
508                 x: [0.0, 1.0, 2.0].into(),
509                 y: [3.0, 4.0, 5.0].into(),
510                 z: [6.0, 7.0, 8.0].into(),
511             };
512             let expected = Mat3A::from_cols(
513                 [0.0, 3.0, 6.0].into(),
514                 [1.0, 4.0, 7.0].into(),
515                 [2.0, 5.0, 8.0].into(),
516             );
517             assert_eq!(expected, m.into());
518             assert_eq!(m, expected.into());
519         }
520     }
521 
522     mod f64 {
523         impl_float_tests!(f64, DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4);
524     }
525 
526     mod i32 {
527         impl_vec_tests!(i32, IVec2, IVec3, IVec4);
528     }
529 
530     mod u32 {
531         impl_vec_tests!(u32, UVec2, UVec3, UVec4);
532     }
533 }
534