Merge pull request #845 from dimforge/glam

Add conversions from/to glam types.
This commit is contained in:
Sébastien Crozet 2021-03-06 14:04:51 +01:00 committed by GitHub
commit 48248ae0a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 816 additions and 256 deletions

View File

@ -6,6 +6,12 @@ This project adheres to [Semantic Versioning](https://semver.org/).
## [0.25.2] - WIP ## [0.25.2] - WIP
### Added ### Added
- A `convert-glam` cargo feature to enable implementations of `From` traits to convert
between `glam` types and `nalgebra` types.
- A `convert-glam-unchecked` cargo feature to enable some extra `glam`/`nalgebra` conversions that may
lead to unexpected results if used improperly. For example, this enables the conversion from a
`glam::Mat4` to a `na::Isometry3`. This conversion will be cheap (without any check) but willlead to
unexpected results if the glam matrix contains non-isometric components (like scaling for example).
- A `cast` method has been added to most types. This can be used to change the - A `cast` method has been added to most types. This can be used to change the
type of the components of a given entity. Example: `vector.cast::<f32>()`. type of the components of a given entity. Example: `vector.cast::<f32>()`.

View File

@ -24,11 +24,6 @@ path = "src/lib.rs"
[features] [features]
default = [ "std" ] default = [ "std" ]
std = [ "matrixmultiply", "simba/std" ] std = [ "matrixmultiply", "simba/std" ]
rand-no-std = [ "rand-package" ]
rand = [ "rand-no-std", "rand-package/std", "rand-package/std_rng", "rand_distr" ]
arbitrary = [ "quickcheck" ]
serde-serialize = [ "serde", "num-complex/serde" ]
abomonation-serialize = [ "abomonation" ]
sparse = [ ] sparse = [ ]
debug = [ "approx/num-complex", "rand" ] debug = [ "approx/num-complex", "rand" ]
alloc = [ ] alloc = [ ]
@ -36,11 +31,26 @@ io = [ "pest", "pest_derive" ]
compare = [ "matrixcompare-core" ] compare = [ "matrixcompare-core" ]
libm = [ "simba/libm" ] libm = [ "simba/libm" ]
libm-force = [ "simba/libm_force" ] libm-force = [ "simba/libm_force" ]
proptest-support = [ "proptest" ]
no_unsound_assume_init = [ ] no_unsound_assume_init = [ ]
# This feature is only used for tests, and enables tests that require more time to run # Conversion
slow-tests = [] convert-mint = [ "mint" ]
convert-glam = [ "glam" ]
convert-glam-unchecked = [ "convert-glam" ] # Unable edgy conversions like Mat4 -> Isometry3
convert-bytemuck = [ "bytemuck" ]
# Serialization
serde-serialize = [ "serde", "num-complex/serde" ]
abomonation-serialize = [ "abomonation" ]
# Randomness
rand-no-std = [ "rand-package" ]
rand = [ "rand-no-std", "rand-package/std", "rand-package/std_rng", "rand_distr" ]
# Tests
arbitrary = [ "quickcheck" ]
proptest-support = [ "proptest" ]
slow-tests = []
[dependencies] [dependencies]
typenum = "1.12" typenum = "1.12"
@ -57,6 +67,7 @@ matrixmultiply = { version = "0.3", optional = true }
serde = { version = "1.0", default-features = false, features = [ "derive" ], optional = true } serde = { version = "1.0", default-features = false, features = [ "derive" ], optional = true }
abomonation = { version = "0.7", optional = true } abomonation = { version = "0.7", optional = true }
mint = { version = "0.5", optional = true } mint = { version = "0.5", optional = true }
glam = { version = "0.13", optional = true }
quickcheck = { version = "1", optional = true } quickcheck = { version = "1", optional = true }
pest = { version = "2", optional = true } pest = { version = "2", optional = true }
pest_derive = { version = "2", optional = true } pest_derive = { version = "2", optional = true }

View File

@ -1,7 +1,5 @@
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::vec::Vec; use alloc::vec::Vec;
#[cfg(feature = "mint")]
use mint;
use simba::scalar::{SubsetOf, SupersetOf}; use simba::scalar::{SubsetOf, SupersetOf};
use std::convert::{AsMut, AsRef, From, Into}; use std::convert::{AsMut, AsRef, From, Into};
use std::mem; use std::mem;
@ -235,119 +233,6 @@ impl_from_into_asref_2D!(
(U6, U2) => (6, 2); (U6, U3) => (6, 3); (U6, U4) => (6, 4); (U6, U5) => (6, 5); (U6, U6) => (6, 6); (U6, U2) => (6, 2); (U6, U3) => (6, 3); (U6, U4) => (6, 4); (U6, U5) => (6, 5); (U6, U6) => (6, 6);
); );
#[cfg(feature = "mint")]
macro_rules! impl_from_into_mint_1D(
($($NRows: ident => $VT:ident [$SZ: expr]);* $(;)*) => {$(
impl<N> From<mint::$VT<N>> for MatrixMN<N, $NRows, U1>
where N: Scalar,
DefaultAllocator: Allocator<N, $NRows, U1> {
#[inline]
fn from(v: mint::$VT<N>) -> Self {
unsafe {
let mut res = Self::new_uninitialized();
ptr::copy_nonoverlapping(&v.x, (*res.as_mut_ptr()).data.ptr_mut(), $SZ);
res.assume_init()
}
}
}
impl<N, S> Into<mint::$VT<N>> for Matrix<N, $NRows, U1, S>
where N: Scalar,
S: ContiguousStorage<N, $NRows, U1> {
#[inline]
fn into(self) -> mint::$VT<N> {
unsafe {
let mut res: mint::$VT<N> = mem::MaybeUninit::uninit().assume_init();
ptr::copy_nonoverlapping(self.data.ptr(), &mut res.x, $SZ);
res
}
}
}
impl<N, S> AsRef<mint::$VT<N>> for Matrix<N, $NRows, U1, S>
where N: Scalar,
S: ContiguousStorage<N, $NRows, U1> {
#[inline]
fn as_ref(&self) -> &mint::$VT<N> {
unsafe {
mem::transmute(self.data.ptr())
}
}
}
impl<N, S> AsMut<mint::$VT<N>> for Matrix<N, $NRows, U1, S>
where N: Scalar,
S: ContiguousStorageMut<N, $NRows, U1> {
#[inline]
fn as_mut(&mut self) -> &mut mint::$VT<N> {
unsafe {
mem::transmute(self.data.ptr_mut())
}
}
}
)*}
);
// Implement for vectors of dimension 2 .. 4.
#[cfg(feature = "mint")]
impl_from_into_mint_1D!(
U2 => Vector2[2];
U3 => Vector3[3];
U4 => Vector4[4];
);
#[cfg(feature = "mint")]
macro_rules! impl_from_into_mint_2D(
($(($NRows: ty, $NCols: ty) => $MV:ident{ $($component:ident),* }[$SZRows: expr]);* $(;)*) => {$(
impl<N> From<mint::$MV<N>> for MatrixMN<N, $NRows, $NCols>
where N: Scalar,
DefaultAllocator: Allocator<N, $NRows, $NCols> {
#[inline]
fn from(m: mint::$MV<N>) -> Self {
unsafe {
let mut res = Self::new_uninitialized();
let mut ptr = (*res.as_mut_ptr()).data.ptr_mut();
$(
ptr::copy_nonoverlapping(&m.$component.x, ptr, $SZRows);
ptr = ptr.offset($SZRows);
)*
let _ = ptr;
res.assume_init()
}
}
}
impl<N> Into<mint::$MV<N>> for MatrixMN<N, $NRows, $NCols>
where N: Scalar,
DefaultAllocator: Allocator<N, $NRows, $NCols> {
#[inline]
fn into(self) -> mint::$MV<N> {
unsafe {
let mut res: mint::$MV<N> = mem::MaybeUninit::uninit().assume_init();
let mut ptr = self.data.ptr();
$(
ptr::copy_nonoverlapping(ptr, &mut res.$component.x, $SZRows);
ptr = ptr.offset($SZRows);
)*
let _ = ptr;
res
}
}
}
)*}
);
// Implement for matrices with shape 2x2 .. 4x4.
#[cfg(feature = "mint")]
impl_from_into_mint_2D!(
(U2, U2) => ColumnMatrix2{x, y}[2];
(U2, U3) => ColumnMatrix2x3{x, y, z}[2];
(U3, U3) => ColumnMatrix3{x, y, z}[3];
(U3, U4) => ColumnMatrix3x4{x, y, z, w}[3];
(U4, U4) => ColumnMatrix4{x, y, z, w}[4];
);
impl<'a, N, R, C, RStride, CStride> From<MatrixSlice<'a, N, R, C, RStride, CStride>> impl<'a, N, R, C, RStride, CStride> From<MatrixSlice<'a, N, R, C, RStride, CStride>>
for Matrix<N, R, C, ArrayStorage<N, R, C>> for Matrix<N, R, C, ArrayStorage<N, R, C>>
where where

View File

@ -22,8 +22,6 @@ mod conversion;
mod edition; mod edition;
pub mod indexing; pub mod indexing;
mod matrix; mod matrix;
#[cfg(feature = "alga")]
mod matrix_alga;
mod matrix_simba; mod matrix_simba;
mod matrix_slice; mod matrix_slice;
mod norm; mod norm;

View File

@ -6,8 +6,6 @@ mod op_macros;
mod abstract_rotation; mod abstract_rotation;
mod point; mod point;
#[cfg(feature = "alga")]
mod point_alga;
mod point_alias; mod point_alias;
mod point_construction; mod point_construction;
mod point_conversion; mod point_conversion;
@ -16,8 +14,6 @@ mod point_ops;
mod point_simba; mod point_simba;
mod rotation; mod rotation;
#[cfg(feature = "alga")]
mod rotation_alga;
mod rotation_alias; mod rotation_alias;
mod rotation_construction; mod rotation_construction;
mod rotation_conversion; mod rotation_conversion;
@ -27,8 +23,6 @@ mod rotation_simba; // TODO: implement Rotation methods.
mod rotation_specialization; mod rotation_specialization;
mod quaternion; mod quaternion;
#[cfg(feature = "alga")]
mod quaternion_alga;
mod quaternion_construction; mod quaternion_construction;
mod quaternion_conversion; mod quaternion_conversion;
mod quaternion_coordinates; mod quaternion_coordinates;
@ -36,23 +30,17 @@ mod quaternion_ops;
mod quaternion_simba; mod quaternion_simba;
mod dual_quaternion; mod dual_quaternion;
#[cfg(feature = "alga")]
mod dual_quaternion_alga;
mod dual_quaternion_construction; mod dual_quaternion_construction;
mod dual_quaternion_conversion; mod dual_quaternion_conversion;
mod dual_quaternion_ops; mod dual_quaternion_ops;
mod unit_complex; mod unit_complex;
#[cfg(feature = "alga")]
mod unit_complex_alga;
mod unit_complex_construction; mod unit_complex_construction;
mod unit_complex_conversion; mod unit_complex_conversion;
mod unit_complex_ops; mod unit_complex_ops;
mod unit_complex_simba; mod unit_complex_simba;
mod translation; mod translation;
#[cfg(feature = "alga")]
mod translation_alga;
mod translation_alias; mod translation_alias;
mod translation_construction; mod translation_construction;
mod translation_conversion; mod translation_conversion;
@ -61,8 +49,6 @@ mod translation_ops;
mod translation_simba; mod translation_simba;
mod isometry; mod isometry;
#[cfg(feature = "alga")]
mod isometry_alga;
mod isometry_alias; mod isometry_alias;
mod isometry_construction; mod isometry_construction;
mod isometry_conversion; mod isometry_conversion;
@ -71,8 +57,6 @@ mod isometry_ops;
mod isometry_simba; mod isometry_simba;
mod similarity; mod similarity;
#[cfg(feature = "alga")]
mod similarity_alga;
mod similarity_alias; mod similarity_alias;
mod similarity_construction; mod similarity_construction;
mod similarity_conversion; mod similarity_conversion;
@ -82,8 +66,6 @@ mod similarity_simba;
mod swizzle; mod swizzle;
mod transform; mod transform;
#[cfg(feature = "alga")]
mod transform_alga;
mod transform_alias; mod transform_alias;
mod transform_construction; mod transform_construction;
mod transform_conversion; mod transform_conversion;

View File

@ -6,23 +6,14 @@ use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, Matrix, Scalar, VectorN}; use crate::base::{DefaultAllocator, Matrix, Scalar, VectorN};
#[cfg(feature = "mint")]
use crate::base::dimension::{U2, U3};
#[cfg(feature = "mint")]
use crate::base::storage::{Storage, StorageMut};
use crate::geometry::Point; use crate::geometry::Point;
#[cfg(feature = "mint")]
use mint;
#[cfg(feature = "mint")]
use std::convert::{AsMut, AsRef, From, Into};
/* /*
* This file provides the following conversions: * This file provides the following conversions:
* ============================================= * =============================================
* *
* Point -> Point * Point -> Point
* Point -> Vector (homogeneous) * Point -> Vector (homogeneous)
*
* mint::Point <-> Point
*/ */
impl<N1, N2, D> SubsetOf<Point<N2, D>> for Point<N1, D> impl<N1, N2, D> SubsetOf<Point<N2, D>> for Point<N1, D>
@ -80,57 +71,6 @@ where
} }
} }
#[cfg(feature = "mint")]
macro_rules! impl_from_into_mint_1D(
($($NRows: ident => $PT:ident, $VT:ident [$SZ: expr]);* $(;)*) => {$(
impl<N> From<mint::$PT<N>> for Point<N, $NRows>
where N: Scalar {
#[inline]
fn from(p: mint::$PT<N>) -> Self {
Self {
coords: VectorN::from(mint::$VT::from(p)),
}
}
}
impl<N> Into<mint::$PT<N>> for Point<N, $NRows>
where N: Scalar {
#[inline]
fn into(self) -> mint::$PT<N> {
let mint_vec: mint::$VT<N> = self.coords.into();
mint::$PT::from(mint_vec)
}
}
impl<N> AsRef<mint::$PT<N>> for Point<N, $NRows>
where N: Scalar {
#[inline]
fn as_ref(&self) -> &mint::$PT<N> {
unsafe {
&*(self.coords.data.ptr() as *const mint::$PT<N>)
}
}
}
impl<N> AsMut<mint::$PT<N>> for Point<N, $NRows>
where N: Scalar {
#[inline]
fn as_mut(&mut self) -> &mut mint::$PT<N> {
unsafe {
&mut *(self.coords.data.ptr_mut() as *mut mint::$PT<N>)
}
}
}
)*}
);
// Implement for points of dimension 2, 3.
#[cfg(feature = "mint")]
impl_from_into_mint_1D!(
U2 => Point2, Vector2[2];
U3 => Point3, Vector3[3];
);
impl<N: Scalar + Zero + One, D: DimName> From<Point<N, D>> for VectorN<N, DimNameSum<D, U1>> impl<N: Scalar + Zero + One, D: DimName> From<Point<N, D>> for VectorN<N, DimNameSum<D, U1>>
where where
D: DimNameAdd<U1>, D: DimNameAdd<U1>,

View File

@ -3,9 +3,6 @@ use num::Zero;
use simba::scalar::{RealField, SubsetOf, SupersetOf}; use simba::scalar::{RealField, SubsetOf, SupersetOf};
use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue}; use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue};
#[cfg(feature = "mint")]
use mint;
use crate::base::dimension::U3; use crate::base::dimension::U3;
use crate::base::{Matrix3, Matrix4, Scalar, Vector4}; use crate::base::{Matrix3, Matrix4, Scalar, Vector4};
use crate::geometry::{ use crate::geometry::{
@ -26,9 +23,6 @@ use crate::geometry::{
* UnitQuaternion -> Transform<U3> * UnitQuaternion -> Transform<U3>
* UnitQuaternion -> Matrix<U4> (homogeneous) * UnitQuaternion -> Matrix<U4> (homogeneous)
* *
* mint::Quaternion <-> Quaternion
* UnitQuaternion -> mint::Quaternion
*
* NOTE: * NOTE:
* UnitQuaternion -> Quaternion is already provided by: Unit<T> -> T * UnitQuaternion -> Quaternion is already provided by: Unit<T> -> T
*/ */
@ -206,41 +200,6 @@ impl<N1: RealField, N2: RealField + SupersetOf<N1>> SubsetOf<Matrix4<N2>> for Un
} }
} }
#[cfg(feature = "mint")]
impl<N: Scalar> From<mint::Quaternion<N>> for Quaternion<N> {
fn from(q: mint::Quaternion<N>) -> Self {
Self::new(q.s, q.v.x, q.v.y, q.v.z)
}
}
#[cfg(feature = "mint")]
impl<N: Scalar> Into<mint::Quaternion<N>> for Quaternion<N> {
fn into(self) -> mint::Quaternion<N> {
mint::Quaternion {
v: mint::Vector3 {
x: self[0].inlined_clone(),
y: self[1].inlined_clone(),
z: self[2].inlined_clone(),
},
s: self[3].inlined_clone(),
}
}
}
#[cfg(feature = "mint")]
impl<N: Scalar + SimdValue> Into<mint::Quaternion<N>> for UnitQuaternion<N> {
fn into(self) -> mint::Quaternion<N> {
mint::Quaternion {
v: mint::Vector3 {
x: self[0].inlined_clone(),
y: self[1].inlined_clone(),
z: self[2].inlined_clone(),
},
s: self[3].inlined_clone(),
}
}
}
impl<N: SimdRealField> From<UnitQuaternion<N>> for Matrix4<N> impl<N: SimdRealField> From<UnitQuaternion<N>> for Matrix4<N>
where where
N::Element: SimdRealField, N::Element: SimdRealField,

View File

@ -3,9 +3,6 @@ use num::Zero;
use simba::scalar::{RealField, SubsetOf, SupersetOf}; use simba::scalar::{RealField, SubsetOf, SupersetOf};
use simba::simd::{PrimitiveSimdValue, SimdValue}; use simba::simd::{PrimitiveSimdValue, SimdValue};
#[cfg(feature = "mint")]
use mint;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1}; use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, Matrix2, Matrix3, Matrix4, MatrixN, Scalar}; use crate::base::{DefaultAllocator, Matrix2, Matrix3, Matrix4, MatrixN, Scalar};
@ -27,7 +24,6 @@ use crate::geometry::{
* Rotation -> Similarity * Rotation -> Similarity
* Rotation -> Transform * Rotation -> Transform
* Rotation -> Matrix (homogeneous) * Rotation -> Matrix (homogeneous)
* mint::EulerAngles -> Rotation
*/ */
@ -236,13 +232,6 @@ where
} }
} }
#[cfg(feature = "mint")]
impl<N: RealField> From<mint::EulerAngles<N, mint::IntraXYZ>> for Rotation3<N> {
fn from(euler: mint::EulerAngles<N, mint::IntraXYZ>) -> Self {
Self::from_euler_angles(euler.a, euler.b, euler.c)
}
}
impl<N: RealField> From<Rotation2<N>> for Matrix3<N> { impl<N: RealField> From<Rotation2<N>> for Matrix3<N> {
#[inline] #[inline]
fn from(q: Rotation2<N>) -> Self { fn from(q: Rotation2<N>) -> Self {

View File

@ -123,6 +123,7 @@ pub mod linalg;
pub mod proptest; pub mod proptest;
#[cfg(feature = "sparse")] #[cfg(feature = "sparse")]
pub mod sparse; pub mod sparse;
mod third_party;
pub use crate::base::*; pub use crate::base::*;
pub use crate::geometry::*; pub use crate::geometry::*;

10
src/third_party/alga/mod.rs vendored Normal file
View File

@ -0,0 +1,10 @@
mod alga_dual_quaternion;
mod alga_isometry;
mod alga_matrix;
mod alga_point;
mod alga_quaternion;
mod alga_rotation;
mod alga_similarity;
mod alga_transform;
mod alga_translation;
mod alga_unit_complex;

54
src/third_party/glam/glam_isometry.rs vendored Normal file
View File

@ -0,0 +1,54 @@
use crate::{Isometry2, Isometry3};
use glam::{DMat3, DMat4, Mat3, Mat4};
impl From<Isometry2<f32>> for Mat3 {
fn from(iso: Isometry2<f32>) -> Mat3 {
iso.to_homogeneous().into()
}
}
impl From<Isometry3<f32>> for Mat4 {
fn from(iso: Isometry3<f32>) -> Mat4 {
iso.to_homogeneous().into()
}
}
impl From<Isometry2<f64>> for DMat3 {
fn from(iso: Isometry2<f64>) -> DMat3 {
iso.to_homogeneous().into()
}
}
impl From<Isometry3<f64>> for DMat4 {
fn from(iso: Isometry3<f64>) -> DMat4 {
iso.to_homogeneous().into()
}
}
#[cfg(feature = "convert-glam-unchecked")]
mod unchecked {
use crate::{Isometry2, Isometry3, Matrix3, Matrix4};
use glam::{DMat3, DMat4, Mat3, Mat4};
impl From<Mat3> for Isometry2<f32> {
fn from(mat3: Mat3) -> Isometry2<f32> {
crate::convert_unchecked(Matrix3::from(mat3))
}
}
impl From<Mat4> for Isometry3<f32> {
fn from(mat4: Mat4) -> Isometry3<f32> {
crate::convert_unchecked(Matrix4::from(mat4))
}
}
impl From<DMat3> for Isometry2<f64> {
fn from(mat3: DMat3) -> Isometry2<f64> {
crate::convert_unchecked(Matrix3::from(mat3))
}
}
impl From<DMat4> for Isometry3<f64> {
fn from(mat4: DMat4) -> Isometry3<f64> {
crate::convert_unchecked(Matrix4::from(mat4))
}
}
}

210
src/third_party/glam/glam_matrix.rs vendored Normal file
View File

@ -0,0 +1,210 @@
use crate::storage::Storage;
use crate::{Matrix, Matrix2, Matrix3, Matrix4, Vector, Vector2, Vector3, Vector4, U2, U3, U4};
use glam::{
BVec2, BVec3, BVec4, DMat2, DMat3, DMat4, DVec2, DVec3, DVec4, IVec2, IVec3, IVec4, Mat2, Mat3,
Mat4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec3A, Vec4,
};
macro_rules! impl_vec_conversion(
($N: ty, $Vec2: ty, $Vec3: ty, $Vec4: ty) => {
impl From<$Vec2> for Vector2<$N> {
#[inline]
fn from(e: $Vec2) -> Vector2<$N> {
(*e.as_ref()).into()
}
}
impl<S> From<Vector<$N, U2, S>> for $Vec2
where
S: Storage<$N, U2>,
{
#[inline]
fn from(e: Vector<$N, U2, S>) -> $Vec2 {
<$Vec2>::new(e[0], e[1])
}
}
impl From<$Vec3> for Vector3<$N> {
#[inline]
fn from(e: $Vec3) -> Vector3<$N> {
(*e.as_ref()).into()
}
}
impl<S> From<Vector<$N, U3, S>> for $Vec3
where
S: Storage<$N, U3>,
{
#[inline]
fn from(e: Vector<$N, U3, S>) -> $Vec3 {
<$Vec3>::new(e[0], e[1], e[2])
}
}
impl From<$Vec4> for Vector4<$N> {
#[inline]
fn from(e: $Vec4) -> Vector4<$N> {
(*e.as_ref()).into()
}
}
impl<S> From<Vector<$N, U4, S>> for $Vec4
where
S: Storage<$N, U4>,
{
#[inline]
fn from(e: Vector<$N, U4, S>) -> $Vec4 {
<$Vec4>::new(e[0], e[1], e[2], e[3])
}
}
}
);
impl_vec_conversion!(f32, Vec2, Vec3, Vec4);
impl_vec_conversion!(f64, DVec2, DVec3, DVec4);
impl_vec_conversion!(i32, IVec2, IVec3, IVec4);
impl_vec_conversion!(u32, UVec2, UVec3, UVec4);
impl_vec_conversion!(bool, BVec2, BVec3, BVec4);
impl From<Vec3A> for Vector3<f32> {
#[inline]
fn from(e: Vec3A) -> Vector3<f32> {
(*e.as_ref()).into()
}
}
impl<S> From<Vector<f32, U3, S>> for Vec3A
where
S: Storage<f32, U3>,
{
#[inline]
fn from(e: Vector<f32, U3, S>) -> Vec3A {
Vec3A::new(e[0], e[1], e[2])
}
}
impl From<Mat2> for Matrix2<f32> {
#[inline]
fn from(e: Mat2) -> Matrix2<f32> {
e.to_cols_array_2d().into()
}
}
impl<S> From<Matrix<f32, U2, U2, S>> for Mat2
where
S: Storage<f32, U2, U2>,
{
#[inline]
fn from(e: Matrix<f32, U2, U2, S>) -> Mat2 {
Mat2::from_cols(
Vec2::new(e[(0, 0)], e[(1, 0)]),
Vec2::new(e[(0, 1)], e[(1, 1)]),
)
}
}
impl From<Mat3> for Matrix3<f32> {
#[inline]
fn from(e: Mat3) -> Matrix3<f32> {
e.to_cols_array_2d().into()
}
}
impl<S> From<Matrix<f32, U3, U3, S>> for Mat3
where
S: Storage<f32, U3, U3>,
{
#[inline]
fn from(e: Matrix<f32, U3, U3, S>) -> Mat3 {
Mat3::from_cols(
Vec3::new(e[(0, 0)], e[(1, 0)], e[(2, 0)]),
Vec3::new(e[(0, 1)], e[(1, 1)], e[(2, 1)]),
Vec3::new(e[(0, 2)], e[(1, 2)], e[(2, 2)]),
)
}
}
impl From<Mat4> for Matrix4<f32> {
#[inline]
fn from(e: Mat4) -> Matrix4<f32> {
e.to_cols_array_2d().into()
}
}
impl<S> From<Matrix<f32, U4, U4, S>> for Mat4
where
S: Storage<f32, U4, U4>,
{
#[inline]
fn from(e: Matrix<f32, U4, U4, S>) -> Mat4 {
Mat4::from_cols(
Vec4::new(e[(0, 0)], e[(1, 0)], e[(2, 0)], e[(3, 0)]),
Vec4::new(e[(0, 1)], e[(1, 1)], e[(2, 1)], e[(3, 1)]),
Vec4::new(e[(0, 2)], e[(1, 2)], e[(2, 2)], e[(3, 2)]),
Vec4::new(e[(0, 3)], e[(1, 3)], e[(2, 3)], e[(3, 3)]),
)
}
}
impl From<DMat2> for Matrix2<f64> {
#[inline]
fn from(e: DMat2) -> Matrix2<f64> {
e.to_cols_array_2d().into()
}
}
impl<S> From<Matrix<f64, U2, U2, S>> for DMat2
where
S: Storage<f64, U2, U2>,
{
#[inline]
fn from(e: Matrix<f64, U2, U2, S>) -> DMat2 {
DMat2::from_cols(
DVec2::new(e[(0, 0)], e[(1, 0)]),
DVec2::new(e[(0, 1)], e[(1, 1)]),
)
}
}
impl From<DMat3> for Matrix3<f64> {
#[inline]
fn from(e: DMat3) -> Matrix3<f64> {
e.to_cols_array_2d().into()
}
}
impl<S> From<Matrix<f64, U3, U3, S>> for DMat3
where
S: Storage<f64, U3, U3>,
{
#[inline]
fn from(e: Matrix<f64, U3, U3, S>) -> DMat3 {
DMat3::from_cols(
DVec3::new(e[(0, 0)], e[(1, 0)], e[(2, 0)]),
DVec3::new(e[(0, 1)], e[(1, 1)], e[(2, 1)]),
DVec3::new(e[(0, 2)], e[(1, 2)], e[(2, 2)]),
)
}
}
impl From<DMat4> for Matrix4<f64> {
#[inline]
fn from(e: DMat4) -> Matrix4<f64> {
e.to_cols_array_2d().into()
}
}
impl<S> From<Matrix<f64, U4, U4, S>> for DMat4
where
S: Storage<f64, U4, U4>,
{
#[inline]
fn from(e: Matrix<f64, U4, U4, S>) -> DMat4 {
DMat4::from_cols(
DVec4::new(e[(0, 0)], e[(1, 0)], e[(2, 0)], e[(3, 0)]),
DVec4::new(e[(0, 1)], e[(1, 1)], e[(2, 1)], e[(3, 1)]),
DVec4::new(e[(0, 2)], e[(1, 2)], e[(2, 2)], e[(3, 2)]),
DVec4::new(e[(0, 3)], e[(1, 3)], e[(2, 3)], e[(3, 3)]),
)
}
}

71
src/third_party/glam/glam_point.rs vendored Normal file
View File

@ -0,0 +1,71 @@
use crate::{Point2, Point3, Point4};
use glam::{
BVec2, BVec3, BVec4, DVec2, DVec3, DVec4, IVec2, IVec3, IVec4, UVec2, UVec3, UVec4, Vec2, Vec3,
Vec3A, Vec4,
};
macro_rules! impl_point_conversion(
($N: ty, $Vec2: ty, $Vec3: ty, $Vec4: ty) => {
impl From<$Vec2> for Point2<$N> {
#[inline]
fn from(e: $Vec2) -> Point2<$N> {
(*e.as_ref()).into()
}
}
impl From<Point2<$N>> for $Vec2 {
#[inline]
fn from(e: Point2<$N>) -> $Vec2 {
<$Vec2>::new(e[0], e[1])
}
}
impl From<$Vec3> for Point3<$N> {
#[inline]
fn from(e: $Vec3) -> Point3<$N> {
(*e.as_ref()).into()
}
}
impl From<Point3<$N>> for $Vec3 {
#[inline]
fn from(e: Point3<$N>) -> $Vec3 {
<$Vec3>::new(e[0], e[1], e[2])
}
}
impl From<$Vec4> for Point4<$N> {
#[inline]
fn from(e: $Vec4) -> Point4<$N> {
(*e.as_ref()).into()
}
}
impl From<Point4<$N>> for $Vec4 {
#[inline]
fn from(e: Point4<$N>) -> $Vec4 {
<$Vec4>::new(e[0], e[1], e[2], e[3])
}
}
}
);
impl_point_conversion!(f32, Vec2, Vec3, Vec4);
impl_point_conversion!(f64, DVec2, DVec3, DVec4);
impl_point_conversion!(i32, IVec2, IVec3, IVec4);
impl_point_conversion!(u32, UVec2, UVec3, UVec4);
impl_point_conversion!(bool, BVec2, BVec3, BVec4);
impl From<Vec3A> for Point3<f32> {
#[inline]
fn from(e: Vec3A) -> Point3<f32> {
(*e.as_ref()).into()
}
}
impl From<Point3<f32>> for Vec3A {
#[inline]
fn from(e: Point3<f32>) -> Vec3A {
Vec3A::new(e[0], e[1], e[2])
}
}

64
src/third_party/glam/glam_quaternion.rs vendored Normal file
View File

@ -0,0 +1,64 @@
use crate::{Quaternion, UnitQuaternion};
use glam::{DQuat, Quat};
impl From<Quat> for Quaternion<f32> {
#[inline]
fn from(e: Quat) -> Quaternion<f32> {
Quaternion::new(e.w, e.x, e.y, e.z)
}
}
impl From<Quaternion<f32>> for Quat {
#[inline]
fn from(e: Quaternion<f32>) -> Quat {
Quat::from_xyzw(e.i, e.j, e.k, e.w)
}
}
impl From<UnitQuaternion<f32>> for Quat {
#[inline]
fn from(e: UnitQuaternion<f32>) -> Quat {
Quat::from_xyzw(e.i, e.j, e.k, e.w)
}
}
impl From<DQuat> for Quaternion<f64> {
#[inline]
fn from(e: DQuat) -> Quaternion<f64> {
Quaternion::new(e.w, e.x, e.y, e.z)
}
}
impl From<Quaternion<f64>> for DQuat {
#[inline]
fn from(e: Quaternion<f64>) -> DQuat {
DQuat::from_xyzw(e.i, e.j, e.k, e.w)
}
}
impl From<UnitQuaternion<f64>> for DQuat {
#[inline]
fn from(e: UnitQuaternion<f64>) -> DQuat {
DQuat::from_xyzw(e.i, e.j, e.k, e.w)
}
}
#[cfg(feature = "convert-glam-unchecked")]
mod unchecked {
use crate::{Quaternion, UnitQuaternion};
use glam::{DQuat, Quat};
impl From<Quat> for UnitQuaternion<f32> {
#[inline]
fn from(e: Quat) -> UnitQuaternion<f32> {
UnitQuaternion::new_unchecked(Quaternion::from(e))
}
}
impl From<DQuat> for UnitQuaternion<f64> {
#[inline]
fn from(e: DQuat) -> UnitQuaternion<f64> {
UnitQuaternion::new_unchecked(Quaternion::from(e))
}
}
}

64
src/third_party/glam/glam_rotation.rs vendored Normal file
View File

@ -0,0 +1,64 @@
use crate::{Rotation2, Rotation3, UnitQuaternion};
use glam::{DMat2, DQuat, Mat2, Quat};
impl From<Rotation2<f32>> for Mat2 {
#[inline]
fn from(e: Rotation2<f32>) -> Mat2 {
e.into_inner().into()
}
}
impl From<Rotation2<f64>> for DMat2 {
#[inline]
fn from(e: Rotation2<f64>) -> DMat2 {
e.into_inner().into()
}
}
impl From<Rotation3<f32>> for Quat {
#[inline]
fn from(e: Rotation3<f32>) -> Quat {
UnitQuaternion::from(e).into()
}
}
impl From<Rotation3<f64>> for DQuat {
#[inline]
fn from(e: Rotation3<f64>) -> DQuat {
UnitQuaternion::from(e).into()
}
}
#[cfg(feature = "convert-glam-unchecked")]
mod unchecked {
use crate::{Rotation2, Rotation3, UnitQuaternion};
use glam::{DMat2, DQuat, Mat2, Quat};
impl From<Mat2> for Rotation2<f32> {
#[inline]
fn from(e: Mat2) -> Rotation2<f32> {
Rotation2::from_matrix_unchecked(e.into())
}
}
impl From<DMat2> for Rotation2<f64> {
#[inline]
fn from(e: DMat2) -> Rotation2<f64> {
Rotation2::from_matrix_unchecked(e.into())
}
}
impl From<Quat> for Rotation3<f32> {
#[inline]
fn from(e: Quat) -> Rotation3<f32> {
Rotation3::from(UnitQuaternion::from(e))
}
}
impl From<DQuat> for Rotation3<f64> {
#[inline]
fn from(e: DQuat) -> Rotation3<f64> {
Rotation3::from(UnitQuaternion::from(e))
}
}
}

54
src/third_party/glam/glam_similarity.rs vendored Normal file
View File

@ -0,0 +1,54 @@
use crate::{Similarity2, Similarity3};
use glam::{DMat3, DMat4, Mat3, Mat4};
impl From<Similarity2<f32>> for Mat3 {
fn from(iso: Similarity2<f32>) -> Mat3 {
iso.to_homogeneous().into()
}
}
impl From<Similarity3<f32>> for Mat4 {
fn from(iso: Similarity3<f32>) -> Mat4 {
iso.to_homogeneous().into()
}
}
impl From<Similarity2<f64>> for DMat3 {
fn from(iso: Similarity2<f64>) -> DMat3 {
iso.to_homogeneous().into()
}
}
impl From<Similarity3<f64>> for DMat4 {
fn from(iso: Similarity3<f64>) -> DMat4 {
iso.to_homogeneous().into()
}
}
#[cfg(feature = "convert-glam-unchecked")]
mod unchecked {
use crate::{Matrix3, Matrix4, Similarity2, Similarity3};
use glam::{DMat3, DMat4, Mat3, Mat4};
impl From<Mat3> for Similarity2<f32> {
fn from(mat3: Mat3) -> Similarity2<f32> {
crate::convert_unchecked(Matrix3::from(mat3))
}
}
impl From<Mat4> for Similarity3<f32> {
fn from(mat4: Mat4) -> Similarity3<f32> {
crate::convert_unchecked(Matrix4::from(mat4))
}
}
impl From<DMat3> for Similarity2<f64> {
fn from(mat3: DMat3) -> Similarity2<f64> {
crate::convert_unchecked(Matrix3::from(mat3))
}
}
impl From<DMat4> for Similarity3<f64> {
fn from(mat4: DMat4) -> Similarity3<f64> {
crate::convert_unchecked(Matrix4::from(mat4))
}
}
}

View File

@ -0,0 +1,36 @@
use crate::UnitComplex;
use glam::{DMat2, Mat2};
impl From<UnitComplex<f32>> for Mat2 {
#[inline]
fn from(e: UnitComplex<f32>) -> Mat2 {
e.to_rotation_matrix().into_inner().into()
}
}
impl From<UnitComplex<f64>> for DMat2 {
#[inline]
fn from(e: UnitComplex<f64>) -> DMat2 {
e.to_rotation_matrix().into_inner().into()
}
}
#[cfg(feature = "convert-glam-unchecked")]
mod unchecked {
use crate::{Rotation2, UnitComplex};
use glam::{DMat2, Mat2};
impl From<Mat2> for UnitComplex<f32> {
#[inline]
fn from(e: Mat2) -> UnitComplex<f32> {
Rotation2::from_matrix_unchecked(e.into()).into()
}
}
impl From<DMat2> for UnitComplex<f64> {
#[inline]
fn from(e: DMat2) -> UnitComplex<f64> {
Rotation2::from_matrix_unchecked(e.into()).into()
}
}
}

7
src/third_party/glam/mod.rs vendored Normal file
View File

@ -0,0 +1,7 @@
mod glam_isometry;
mod glam_matrix;
mod glam_point;
mod glam_quaternion;
mod glam_rotation;
mod glam_similarity;
mod glam_unit_complex;

117
src/third_party/mint/mint_matrix.rs vendored Normal file
View File

@ -0,0 +1,117 @@
use std::convert::{AsMut, AsRef, From, Into};
use std::mem;
use std::ptr;
use crate::base::allocator::Allocator;
use crate::base::dimension::{U1, U2, U3, U4};
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut};
use crate::base::{DefaultAllocator, Matrix, MatrixMN, Scalar};
macro_rules! impl_from_into_mint_1D(
($($NRows: ident => $VT:ident [$SZ: expr]);* $(;)*) => {$(
impl<N> From<mint::$VT<N>> for MatrixMN<N, $NRows, U1>
where N: Scalar,
DefaultAllocator: Allocator<N, $NRows, U1> {
#[inline]
fn from(v: mint::$VT<N>) -> Self {
unsafe {
let mut res = Self::new_uninitialized();
ptr::copy_nonoverlapping(&v.x, (*res.as_mut_ptr()).data.ptr_mut(), $SZ);
res.assume_init()
}
}
}
impl<N, S> Into<mint::$VT<N>> for Matrix<N, $NRows, U1, S>
where N: Scalar,
S: ContiguousStorage<N, $NRows, U1> {
#[inline]
fn into(self) -> mint::$VT<N> {
unsafe {
let mut res: mint::$VT<N> = mem::MaybeUninit::uninit().assume_init();
ptr::copy_nonoverlapping(self.data.ptr(), &mut res.x, $SZ);
res
}
}
}
impl<N, S> AsRef<mint::$VT<N>> for Matrix<N, $NRows, U1, S>
where N: Scalar,
S: ContiguousStorage<N, $NRows, U1> {
#[inline]
fn as_ref(&self) -> &mint::$VT<N> {
unsafe {
mem::transmute(self.data.ptr())
}
}
}
impl<N, S> AsMut<mint::$VT<N>> for Matrix<N, $NRows, U1, S>
where N: Scalar,
S: ContiguousStorageMut<N, $NRows, U1> {
#[inline]
fn as_mut(&mut self) -> &mut mint::$VT<N> {
unsafe {
mem::transmute(self.data.ptr_mut())
}
}
}
)*}
);
// Implement for vectors of dimension 2 .. 4.
impl_from_into_mint_1D!(
U2 => Vector2[2];
U3 => Vector3[3];
U4 => Vector4[4];
);
macro_rules! impl_from_into_mint_2D(
($(($NRows: ty, $NCols: ty) => $MV:ident{ $($component:ident),* }[$SZRows: expr]);* $(;)*) => {$(
impl<N> From<mint::$MV<N>> for MatrixMN<N, $NRows, $NCols>
where N: Scalar,
DefaultAllocator: Allocator<N, $NRows, $NCols> {
#[inline]
fn from(m: mint::$MV<N>) -> Self {
unsafe {
let mut res = Self::new_uninitialized();
let mut ptr = (*res.as_mut_ptr()).data.ptr_mut();
$(
ptr::copy_nonoverlapping(&m.$component.x, ptr, $SZRows);
ptr = ptr.offset($SZRows);
)*
let _ = ptr;
res.assume_init()
}
}
}
impl<N> Into<mint::$MV<N>> for MatrixMN<N, $NRows, $NCols>
where N: Scalar,
DefaultAllocator: Allocator<N, $NRows, $NCols> {
#[inline]
fn into(self) -> mint::$MV<N> {
unsafe {
let mut res: mint::$MV<N> = mem::MaybeUninit::uninit().assume_init();
let mut ptr = self.data.ptr();
$(
ptr::copy_nonoverlapping(ptr, &mut res.$component.x, $SZRows);
ptr = ptr.offset($SZRows);
)*
let _ = ptr;
res
}
}
}
)*}
);
// Implement for matrices with shape 2x2 .. 4x4.
impl_from_into_mint_2D!(
(U2, U2) => ColumnMatrix2{x, y}[2];
(U2, U3) => ColumnMatrix2x3{x, y, z}[2];
(U3, U3) => ColumnMatrix3{x, y, z}[3];
(U3, U4) => ColumnMatrix3x4{x, y, z, w}[3];
(U4, U4) => ColumnMatrix4{x, y, z, w}[4];
);

52
src/third_party/mint/mint_point.rs vendored Normal file
View File

@ -0,0 +1,52 @@
use crate::base::storage::{Storage, StorageMut};
use crate::{Point, Scalar, VectorN, U2, U3};
use std::convert::{AsMut, AsRef};
macro_rules! impl_from_into_mint_1D(
($($NRows: ident => $PT:ident, $VT:ident [$SZ: expr]);* $(;)*) => {$(
impl<N> From<mint::$PT<N>> for Point<N, $NRows>
where N: Scalar {
#[inline]
fn from(p: mint::$PT<N>) -> Self {
Self {
coords: VectorN::from(mint::$VT::from(p)),
}
}
}
impl<N> Into<mint::$PT<N>> for Point<N, $NRows>
where N: Scalar {
#[inline]
fn into(self) -> mint::$PT<N> {
let mint_vec: mint::$VT<N> = self.coords.into();
mint::$PT::from(mint_vec)
}
}
impl<N> AsRef<mint::$PT<N>> for Point<N, $NRows>
where N: Scalar {
#[inline]
fn as_ref(&self) -> &mint::$PT<N> {
unsafe {
&*(self.coords.data.ptr() as *const mint::$PT<N>)
}
}
}
impl<N> AsMut<mint::$PT<N>> for Point<N, $NRows>
where N: Scalar {
#[inline]
fn as_mut(&mut self) -> &mut mint::$PT<N> {
unsafe {
&mut *(self.coords.data.ptr_mut() as *mut mint::$PT<N>)
}
}
}
)*}
);
// Implement for points of dimension 2, 3.
impl_from_into_mint_1D!(
U2 => Point2, Vector2[2];
U3 => Point3, Vector3[3];
);

33
src/third_party/mint/mint_quaternion.rs vendored Normal file
View File

@ -0,0 +1,33 @@
use crate::{Quaternion, Scalar, SimdValue, UnitQuaternion};
impl<N: Scalar> From<mint::Quaternion<N>> for Quaternion<N> {
fn from(q: mint::Quaternion<N>) -> Self {
Self::new(q.s, q.v.x, q.v.y, q.v.z)
}
}
impl<N: Scalar> Into<mint::Quaternion<N>> for Quaternion<N> {
fn into(self) -> mint::Quaternion<N> {
mint::Quaternion {
v: mint::Vector3 {
x: self[0].inlined_clone(),
y: self[1].inlined_clone(),
z: self[2].inlined_clone(),
},
s: self[3].inlined_clone(),
}
}
}
impl<N: Scalar + SimdValue> Into<mint::Quaternion<N>> for UnitQuaternion<N> {
fn into(self) -> mint::Quaternion<N> {
mint::Quaternion {
v: mint::Vector3 {
x: self[0].inlined_clone(),
y: self[1].inlined_clone(),
z: self[2].inlined_clone(),
},
s: self[3].inlined_clone(),
}
}
}

7
src/third_party/mint/mint_rotation.rs vendored Normal file
View File

@ -0,0 +1,7 @@
use crate::{RealField, Rotation3};
impl<N: RealField> From<mint::EulerAngles<N, mint::IntraXYZ>> for Rotation3<N> {
fn from(euler: mint::EulerAngles<N, mint::IntraXYZ>) -> Self {
Self::from_euler_angles(euler.a, euler.b, euler.c)
}
}

4
src/third_party/mint/mod.rs vendored Normal file
View File

@ -0,0 +1,4 @@
mod mint_matrix;
mod mint_point;
mod mint_quaternion;
mod mint_rotation;

6
src/third_party/mod.rs vendored Normal file
View File

@ -0,0 +1,6 @@
#[cfg(feature = "alga")]
mod alga;
#[cfg(feature = "glam")]
mod glam;
#[cfg(feature = "mint")]
mod mint;