use mint::IntoMint; use crate::{ DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4, I16Vec2, I16Vec3, I16Vec4, I64Vec2, I64Vec3, I64Vec4, IVec2, IVec3, IVec4, Mat2, Mat3, Mat3A, Mat4, Quat, U16Vec2, U16Vec3, U16Vec4, U64Vec2, U64Vec3, U64Vec4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec3A, Vec4, }; macro_rules! impl_vec_types { ($t:ty, $vec2:ty, $vec3:ty, $vec4:ty) => { impl From> for $vec2 { fn from(v: mint::Point2<$t>) -> Self { Self::new(v.x, v.y) } } impl From<$vec2> for mint::Point2<$t> { fn from(v: $vec2) -> Self { Self { x: v.x, y: v.y } } } impl From> for $vec2 { fn from(v: mint::Vector2<$t>) -> Self { Self::new(v.x, v.y) } } impl From<$vec2> for mint::Vector2<$t> { fn from(v: $vec2) -> Self { Self { x: v.x, y: v.y } } } impl IntoMint for $vec2 { type MintType = mint::Vector2<$t>; } impl From> for $vec3 { fn from(v: mint::Point3<$t>) -> Self { Self::new(v.x, v.y, v.z) } } impl From<$vec3> for mint::Point3<$t> { fn from(v: $vec3) -> Self { Self { x: v.x, y: v.y, z: v.z, } } } impl From> for $vec3 { fn from(v: mint::Vector3<$t>) -> Self { Self::new(v.x, v.y, v.z) } } impl From<$vec3> for mint::Vector3<$t> { fn from(v: $vec3) -> Self { Self { x: v.x, y: v.y, z: v.z, } } } impl IntoMint for $vec3 { type MintType = mint::Vector3<$t>; } impl From> for $vec4 { fn from(v: mint::Vector4<$t>) -> Self { Self::new(v.x, v.y, v.z, v.w) } } impl From<$vec4> for mint::Vector4<$t> { fn from(v: $vec4) -> Self { Self { x: v.x, y: v.y, z: v.z, w: v.w, } } } impl IntoMint for $vec4 { type MintType = mint::Vector4<$t>; } }; } macro_rules! impl_float_types { ($t:ty, $mat2:ty, $mat3:ty, $mat4:ty, $quat:ty, $vec2:ty, $vec3:ty, $vec4:ty) => { impl_vec_types!($t, $vec2, $vec3, $vec4); impl From> for $quat { fn from(q: mint::Quaternion<$t>) -> Self { Self::from_xyzw(q.v.x, q.v.y, q.v.z, q.s) } } impl From<$quat> for mint::Quaternion<$t> { fn from(q: $quat) -> Self { Self { s: q.w, v: mint::Vector3 { x: q.x, y: q.y, z: q.z, }, } } } impl IntoMint for $quat { type MintType = mint::Quaternion<$t>; } impl From> for $mat2 { fn from(m: mint::RowMatrix2<$t>) -> Self { Self::from_cols(m.x.into(), m.y.into()).transpose() } } impl From<$mat2> for mint::RowMatrix2<$t> { fn from(m: $mat2) -> Self { let mt = m.transpose(); Self { x: mt.x_axis.into(), y: mt.y_axis.into(), } } } impl From> for $mat2 { fn from(m: mint::ColumnMatrix2<$t>) -> Self { Self::from_cols(m.x.into(), m.y.into()) } } impl From<$mat2> for mint::ColumnMatrix2<$t> { fn from(m: $mat2) -> Self { Self { x: m.x_axis.into(), y: m.y_axis.into(), } } } impl IntoMint for $mat2 { type MintType = mint::ColumnMatrix2<$t>; } impl From> for $mat3 { fn from(m: mint::RowMatrix3<$t>) -> Self { Self::from_cols(m.x.into(), m.y.into(), m.z.into()).transpose() } } impl From<$mat3> for mint::RowMatrix3<$t> { fn from(m: $mat3) -> Self { let mt = m.transpose(); Self { x: mt.x_axis.into(), y: mt.y_axis.into(), z: mt.z_axis.into(), } } } impl From> for $mat3 { fn from(m: mint::ColumnMatrix3<$t>) -> Self { Self::from_cols(m.x.into(), m.y.into(), m.z.into()) } } impl From<$mat3> for mint::ColumnMatrix3<$t> { fn from(m: $mat3) -> Self { Self { x: m.x_axis.into(), y: m.y_axis.into(), z: m.z_axis.into(), } } } impl IntoMint for $mat3 { type MintType = mint::ColumnMatrix3<$t>; } impl From> for $mat4 { fn from(m: mint::RowMatrix4<$t>) -> Self { Self::from_cols(m.x.into(), m.y.into(), m.z.into(), m.w.into()).transpose() } } impl From<$mat4> for mint::RowMatrix4<$t> { fn from(m: $mat4) -> Self { let mt = m.transpose(); Self { x: mt.x_axis.into(), y: mt.y_axis.into(), z: mt.z_axis.into(), w: mt.w_axis.into(), } } } impl From> for $mat4 { fn from(m: mint::ColumnMatrix4<$t>) -> Self { Self::from_cols(m.x.into(), m.y.into(), m.z.into(), m.w.into()) } } impl From<$mat4> for mint::ColumnMatrix4<$t> { fn from(m: $mat4) -> Self { Self { x: m.x_axis.into(), y: m.y_axis.into(), z: m.z_axis.into(), w: m.w_axis.into(), } } } impl IntoMint for $mat4 { type MintType = mint::ColumnMatrix4<$t>; } }; } impl From> for Vec3A { fn from(v: mint::Point3) -> Self { Self::new(v.x, v.y, v.z) } } impl From for mint::Point3 { fn from(v: Vec3A) -> Self { Self { x: v.x, y: v.y, z: v.z, } } } impl From> for Vec3A { fn from(v: mint::Vector3) -> Self { Self::new(v.x, v.y, v.z) } } impl From for mint::Vector3 { fn from(v: Vec3A) -> Self { Self { x: v.x, y: v.y, z: v.z, } } } impl IntoMint for Vec3A { type MintType = mint::Vector3; } impl From> for Mat3A { fn from(m: mint::RowMatrix3) -> Self { Self::from_cols(m.x.into(), m.y.into(), m.z.into()).transpose() } } impl From for mint::RowMatrix3 { fn from(m: Mat3A) -> Self { let mt = m.transpose(); Self { x: mt.x_axis.into(), y: mt.y_axis.into(), z: mt.z_axis.into(), } } } impl From> for Mat3A { fn from(m: mint::ColumnMatrix3) -> Self { Self::from_cols(m.x.into(), m.y.into(), m.z.into()) } } impl From for mint::ColumnMatrix3 { fn from(m: Mat3A) -> Self { Self { x: m.x_axis.into(), y: m.y_axis.into(), z: m.z_axis.into(), } } } impl IntoMint for Mat3A { type MintType = mint::ColumnMatrix3; } impl_float_types!(f32, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec4); impl_float_types!(f64, DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4); impl_vec_types!(i16, I16Vec2, I16Vec3, I16Vec4); impl_vec_types!(u16, U16Vec2, U16Vec3, U16Vec4); impl_vec_types!(i32, IVec2, IVec3, IVec4); impl_vec_types!(u32, UVec2, UVec3, UVec4); impl_vec_types!(i64, I64Vec2, I64Vec3, I64Vec4); impl_vec_types!(u64, U64Vec2, U64Vec3, U64Vec4); #[cfg(test)] mod test { macro_rules! impl_vec_tests { ($t:ty, $vec2:ident, $vec3:ident, $vec4:ident) => { use crate::{$vec2, $vec3, $vec4}; use mint; #[test] fn test_point2() { let m = mint::Point2 { x: 1 as $t, y: 2 as $t, }; let g = $vec2::from(m); assert_eq!(g, $vec2::new(1 as $t, 2 as $t)); assert_eq!(m, g.into()); } #[test] fn test_point3() { let m = mint::Point3 { x: 1 as $t, y: 2 as $t, z: 3 as $t, }; let g = $vec3::from(m); assert_eq!(g, $vec3::new(1 as $t, 2 as $t, 3 as $t)); assert_eq!(m, g.into()); } #[test] fn test_vector2() { let m = mint::Vector2 { x: 1 as $t, y: 2 as $t, }; let g = $vec2::from(m); assert_eq!(g, $vec2::new(1 as $t, 2 as $t)); assert_eq!(m, g.into()); } #[test] fn test_vector3() { let m = mint::Vector3 { x: 1 as $t, y: 2 as $t, z: 3 as $t, }; let g = $vec3::from(m); assert_eq!(g, $vec3::new(1 as $t, 2 as $t, 3 as $t)); assert_eq!(m, g.into()); } #[test] fn test_vector4() { let m = mint::Vector4 { x: 1 as $t, y: 2 as $t, z: 3 as $t, w: 4 as $t, }; let g = $vec4::from(m); assert_eq!(g, $vec4::new(1 as $t, 2 as $t, 3 as $t, 4 as $t)); assert_eq!(m, g.into()); } }; } macro_rules! impl_float_tests { ($t:ty, $mat2:ident, $mat3:ident, $mat4:ident, $quat:ident, $vec2:ident, $vec3:ident, $vec4:ident) => { impl_vec_tests!($t, $vec2, $vec3, $vec4); use crate::{$mat2, $mat3, $mat4, $quat}; #[test] fn test_quaternion() { let m = mint::Quaternion { v: mint::Vector3 { x: 1.0, y: 2.0, z: 3.0, }, s: 4.0, }; let g = $quat::from(m); assert_eq!(g, $quat::from_xyzw(1.0, 2.0, 3.0, 4.0)); assert_eq!(m, g.into()); } #[test] fn test_matrix2() { let g = $mat2::from_cols_array_2d(&[[1.0, 2.0], [3.0, 4.0]]); let m = mint::ColumnMatrix2::from(g); assert_eq!(g, $mat2::from(m)); let mt = mint::RowMatrix2::from(g); assert_eq!(mt, mint::RowMatrix2::from([[1.0, 3.0], [2.0, 4.0]])); assert_eq!(g, $mat2::from(mt)); } #[test] fn test_matrix3() { let g = $mat3::from_cols_array_2d(&[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]); let m = mint::ColumnMatrix3::from(g); assert_eq!(g, $mat3::from(m)); let mt = mint::RowMatrix3::from(g); assert_eq!( mt, mint::RowMatrix3::from([[1.0, 4.0, 7.0], [2.0, 5.0, 8.0], [3.0, 6.0, 9.0]]) ); assert_eq!(g, $mat3::from(mt)); } #[test] fn test_matrix4() { let g = $mat4::from_cols_array_2d(&[ [1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [9.0, 10.0, 11.0, 12.0], [13.0, 14.0, 15.0, 16.0], ]); let m = mint::ColumnMatrix4::from(g); assert_eq!(g, $mat4::from(m)); let mt = mint::RowMatrix4::from(g); assert_eq!( mt, mint::RowMatrix4::from([ [1.0, 5.0, 9.0, 13.0], [2.0, 6.0, 10.0, 14.0], [3.0, 7.0, 11.0, 15.0], [4.0, 8.0, 12.0, 16.0] ]) ); assert_eq!(g, $mat4::from(mt)); } }; } mod f32 { impl_float_tests!(f32, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec4); #[test] fn test_point3a() { use crate::Vec3A; let m = mint::Point3 { x: 1.0, y: 2.0, z: 3.0, }; let g = Vec3A::from(m); assert_eq!(g, Vec3A::new(1.0, 2.0, 3.0)); assert_eq!(m, g.into()); } #[test] fn test_vector3a() { use crate::Vec3A; let m = mint::Vector3 { x: 1.0, y: 2.0, z: 3.0, }; let g = Vec3A::from(m); assert_eq!(g, Vec3A::new(1.0, 2.0, 3.0)); assert_eq!(m, g.into()); } #[test] fn test_mat3a_col_major() { use crate::Mat3A; let m = mint::ColumnMatrix3 { x: [0.0, 1.0, 2.0].into(), y: [3.0, 4.0, 5.0].into(), z: [6.0, 7.0, 8.0].into(), }; let expected = Mat3A::from_cols( [0.0, 1.0, 2.0].into(), [3.0, 4.0, 5.0].into(), [6.0, 7.0, 8.0].into(), ); assert_eq!(expected, m.into()); assert_eq!(m, expected.into()); } #[test] fn test_mat3a_row_major() { use crate::Mat3A; let m = mint::RowMatrix3 { x: [0.0, 1.0, 2.0].into(), y: [3.0, 4.0, 5.0].into(), z: [6.0, 7.0, 8.0].into(), }; let expected = Mat3A::from_cols( [0.0, 3.0, 6.0].into(), [1.0, 4.0, 7.0].into(), [2.0, 5.0, 8.0].into(), ); assert_eq!(expected, m.into()); assert_eq!(m, expected.into()); } } mod f64 { impl_float_tests!(f64, DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4); } mod i32 { impl_vec_tests!(i32, IVec2, IVec3, IVec4); } mod u32 { impl_vec_tests!(u32, UVec2, UVec3, UVec4); } }