Merge pull request #846 from dimforge/dev

Release v0.25.2
This commit is contained in:
Sébastien Crozet 2021-03-06 14:17:31 +01:00 committed by GitHub
commit e9535d5cb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 1120 additions and 283 deletions

View File

@ -4,6 +4,17 @@ documented here.
This project adheres to [Semantic Versioning](https://semver.org/). This project adheres to [Semantic Versioning](https://semver.org/).
## [0.25.2]
### 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
type of the components of a given entity. Example: `vector.cast::<f32>()`.
## [0.25.1] ## [0.25.1]
This release replaces the version 0.25.0 which has been yanked. The 0.25.0 version This release replaces the version 0.25.0 which has been yanked. The 0.25.0 version
added significant complication to build `nalgebra` targeting a `#[no-std]` platform added significant complication to build `nalgebra` targeting a `#[no-std]` platform

View File

@ -1,6 +1,6 @@
[package] [package]
name = "nalgebra" name = "nalgebra"
version = "0.25.1" version = "0.25.2"
authors = [ "Sébastien Crozet <developer@crozet.re>" ] authors = [ "Sébastien Crozet <developer@crozet.re>" ]
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices." description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."
@ -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

@ -16,7 +16,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
use abomonation::Abomonation; use abomonation::Abomonation;
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, Field}; use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, Field, SupersetOf};
use simba::simd::SimdPartialOrd; use simba::simd::SimdPartialOrd;
use crate::base::allocator::{Allocator, SameShapeAllocator, SameShapeC, SameShapeR}; use crate::base::allocator::{Allocator, SameShapeAllocator, SameShapeC, SameShapeR};
@ -610,6 +610,23 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
res res
} }
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::Vector3;
/// let q = Vector3::new(1.0f64, 2.0, 3.0);
/// let q2 = q.cast::<f32>();
/// assert_eq!(q2, Vector3::new(1.0f32, 2.0, 3.0));
/// ```
pub fn cast<N2: Scalar>(self) -> MatrixMN<N2, R, C>
where
MatrixMN<N2, R, C>: SupersetOf<Self>,
DefaultAllocator: Allocator<N2, R, C>,
{
crate::convert(self)
}
/// Similar to `self.iter().fold(init, f)` except that `init` is replaced by a closure. /// Similar to `self.iter().fold(init, f)` except that `init` is replaced by a closure.
/// ///
/// The initialization closure is given the first component of this matrix: /// The initialization closure is given the first component of this matrix:

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

@ -5,6 +5,7 @@ use crate::{
use num::{One, Zero}; use num::{One, Zero};
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
use simba::scalar::SupersetOf;
impl<N: Scalar> DualQuaternion<N> { impl<N: Scalar> DualQuaternion<N> {
/// Creates a dual quaternion from its rotation and translation components. /// Creates a dual quaternion from its rotation and translation components.
@ -49,6 +50,22 @@ impl<N: Scalar> DualQuaternion<N> {
Quaternion::from_real(N::zero()), Quaternion::from_real(N::zero()),
) )
} }
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::{Quaternion, DualQuaternion};
/// let q = DualQuaternion::from_real(Quaternion::new(1.0f64, 2.0, 3.0, 4.0));
/// let q2 = q.cast::<f32>();
/// assert_eq!(q2, DualQuaternion::from_real(Quaternion::new(1.0f32, 2.0, 3.0, 4.0)));
/// ```
pub fn cast<To: Scalar>(self) -> DualQuaternion<To>
where
DualQuaternion<To>: SupersetOf<Self>,
{
crate::convert(self)
}
} }
impl<N: SimdRealField> DualQuaternion<N> impl<N: SimdRealField> DualQuaternion<N>
@ -129,6 +146,22 @@ impl<N: SimdRealField> UnitDualQuaternion<N> {
pub fn identity() -> Self { pub fn identity() -> Self {
Self::new_unchecked(DualQuaternion::identity()) Self::new_unchecked(DualQuaternion::identity())
} }
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::UnitDualQuaternion;
/// let q = UnitDualQuaternion::<f64>::identity();
/// let q2 = q.cast::<f32>();
/// assert_eq!(q2, UnitDualQuaternion::<f32>::identity());
/// ```
pub fn cast<To: Scalar>(self) -> UnitDualQuaternion<To>
where
UnitDualQuaternion<To>: SupersetOf<Self>,
{
crate::convert(self)
}
} }
impl<N: SimdRealField> UnitDualQuaternion<N> impl<N: SimdRealField> UnitDualQuaternion<N>

View File

@ -10,15 +10,16 @@ use rand::{
Rng, Rng,
}; };
use simba::scalar::SupersetOf;
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, U2}; use crate::base::dimension::{DimName, U2};
use crate::base::{DefaultAllocator, Vector2, Vector3}; use crate::base::{DefaultAllocator, Vector2, Vector3};
use crate::geometry::{ use crate::{
AbstractRotation, Isometry, Isometry2, Isometry3, IsometryMatrix2, IsometryMatrix3, Point, AbstractRotation, Isometry, Isometry2, Isometry3, IsometryMatrix2, IsometryMatrix3, Point,
Point3, Rotation, Rotation3, Translation, Translation2, Translation3, UnitComplex, Point3, Rotation, Rotation3, Scalar, Translation, Translation2, Translation3, UnitComplex,
UnitQuaternion, UnitQuaternion,
}; };
@ -153,6 +154,22 @@ where
pub fn rotation(angle: N) -> Self { pub fn rotation(angle: N) -> Self {
Self::new(Vector2::zeros(), angle) Self::new(Vector2::zeros(), angle)
} }
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::IsometryMatrix2;
/// let iso = IsometryMatrix2::<f64>::identity();
/// let iso2 = iso.cast::<f32>();
/// assert_eq!(iso2, IsometryMatrix2::<f32>::identity());
/// ```
pub fn cast<To: Scalar>(self) -> IsometryMatrix2<To>
where
IsometryMatrix2<To>: SupersetOf<Self>,
{
crate::convert(self)
}
} }
impl<N: SimdRealField> Isometry2<N> impl<N: SimdRealField> Isometry2<N>
@ -191,6 +208,22 @@ where
pub fn rotation(angle: N) -> Self { pub fn rotation(angle: N) -> Self {
Self::new(Vector2::zeros(), angle) Self::new(Vector2::zeros(), angle)
} }
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::Isometry2;
/// let iso = Isometry2::<f64>::identity();
/// let iso2 = iso.cast::<f32>();
/// assert_eq!(iso2, Isometry2::<f32>::identity());
/// ```
pub fn cast<To: Scalar>(self) -> Isometry2<To>
where
Isometry2<To>: SupersetOf<Self>,
{
crate::convert(self)
}
} }
// 3D rotation. // 3D rotation.
@ -387,6 +420,22 @@ where
N::Element: SimdRealField, N::Element: SimdRealField,
{ {
basic_isometry_construction_impl!(UnitQuaternion<N>); basic_isometry_construction_impl!(UnitQuaternion<N>);
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::Isometry3;
/// let iso = Isometry3::<f64>::identity();
/// let iso2 = iso.cast::<f32>();
/// assert_eq!(iso2, Isometry3::<f32>::identity());
/// ```
pub fn cast<To: Scalar>(self) -> Isometry3<To>
where
Isometry3<To>: SupersetOf<Self>,
{
crate::convert(self)
}
} }
impl<N: SimdRealField> IsometryMatrix3<N> impl<N: SimdRealField> IsometryMatrix3<N>
@ -394,6 +443,22 @@ where
N::Element: SimdRealField, N::Element: SimdRealField,
{ {
basic_isometry_construction_impl!(Rotation3<N>); basic_isometry_construction_impl!(Rotation3<N>);
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::IsometryMatrix3;
/// let iso = IsometryMatrix3::<f64>::identity();
/// let iso2 = iso.cast::<f32>();
/// assert_eq!(iso2, IsometryMatrix3::<f32>::identity());
/// ```
pub fn cast<To: Scalar>(self) -> IsometryMatrix3<To>
where
IsometryMatrix3<To>: SupersetOf<Self>,
{
crate::convert(self)
}
} }
/// # Construction from a 3D eye position and target point /// # Construction from a 3D eye position and target point

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

@ -15,7 +15,7 @@ use crate::{
Point1, Point2, Point3, Point4, Point5, Point6, Vector1, Vector2, Vector3, Vector4, Vector5, Point1, Point2, Point3, Point4, Point5, Point6, Vector1, Vector2, Vector3, Vector4, Vector5,
Vector6, Vector6,
}; };
use simba::scalar::ClosedDiv; use simba::scalar::{ClosedDiv, SupersetOf};
use crate::geometry::Point; use crate::geometry::Point;
@ -119,6 +119,23 @@ where
None None
} }
} }
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::Point2;
/// let pt = Point2::new(1.0f64, 2.0);
/// let pt2 = pt.cast::<f32>();
/// assert_eq!(pt2, Point2::new(1.0f32, 2.0));
/// ```
pub fn cast<To: Scalar>(self) -> Point<To, D>
where
Point<To, D>: SupersetOf<Self>,
DefaultAllocator: Allocator<To, D>,
{
crate::convert(self)
}
} }
/* /*

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

@ -13,7 +13,7 @@ use rand::{
use num::{One, Zero}; use num::{One, Zero};
use simba::scalar::RealField; use simba::scalar::{RealField, SupersetOf};
use simba::simd::SimdBool; use simba::simd::SimdBool;
use crate::base::dimension::U3; use crate::base::dimension::U3;
@ -49,6 +49,22 @@ impl<N: Scalar> Quaternion<N> {
pub fn new(w: N, i: N, j: N, k: N) -> Self { pub fn new(w: N, i: N, j: N, k: N) -> Self {
Self::from(Vector4::new(i, j, k, w)) Self::from(Vector4::new(i, j, k, w))
} }
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::Quaternion;
/// let q = Quaternion::new(1.0f64, 2.0, 3.0, 4.0);
/// let q2 = q.cast::<f32>();
/// assert_eq!(q2, Quaternion::new(1.0f32, 2.0, 3.0, 4.0));
/// ```
pub fn cast<To: Scalar>(self) -> Quaternion<To>
where
To: SupersetOf<N>,
{
crate::convert(self)
}
} }
impl<N: SimdRealField> Quaternion<N> { impl<N: SimdRealField> Quaternion<N> {
@ -199,6 +215,23 @@ where
Self::new_unchecked(Quaternion::identity()) Self::new_unchecked(Quaternion::identity())
} }
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::UnitQuaternion;
/// # use approx::assert_relative_eq;
/// let q = UnitQuaternion::from_euler_angles(1.0f64, 2.0, 3.0);
/// let q2 = q.cast::<f32>();
/// assert_relative_eq!(q2, UnitQuaternion::from_euler_angles(1.0f32, 2.0, 3.0), epsilon = 1.0e-6);
/// ```
pub fn cast<To: Scalar>(self) -> UnitQuaternion<To>
where
To: SupersetOf<N>,
{
crate::convert(self)
}
/// Creates a new quaternion from a unit vector (the rotation axis) and an angle /// Creates a new quaternion from a unit vector (the rotation axis) and an angle
/// (the rotation angle). /// (the rotation angle).
/// ///

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,17 +23,14 @@ 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
*/ */
impl<N1, N2> SubsetOf<Quaternion<N2>> for Quaternion<N1> impl<N1, N2> SubsetOf<Quaternion<N2>> for Quaternion<N1>
where where
N1: SimdRealField, N1: Scalar,
N2: SimdRealField + SupersetOf<N1>, N2: Scalar + SupersetOf<N1>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Quaternion<N2> { fn to_superset(&self) -> Quaternion<N2> {
@ -58,8 +52,8 @@ where
impl<N1, N2> SubsetOf<UnitQuaternion<N2>> for UnitQuaternion<N1> impl<N1, N2> SubsetOf<UnitQuaternion<N2>> for UnitQuaternion<N1>
where where
N1: SimdRealField, N1: Scalar,
N2: SimdRealField + SupersetOf<N1>, N2: Scalar + SupersetOf<N1>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> UnitQuaternion<N2> { fn to_superset(&self) -> UnitQuaternion<N2> {
@ -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

@ -1,6 +1,6 @@
use num::{One, Zero}; use num::{One, Zero};
use simba::scalar::{ClosedAdd, ClosedMul}; use simba::scalar::{ClosedAdd, ClosedMul, SupersetOf};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::DimName; use crate::base::dimension::DimName;
@ -31,6 +31,28 @@ where
} }
} }
impl<N: Scalar, D: DimName> Rotation<N, D>
where
DefaultAllocator: Allocator<N, D, D>,
{
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::Rotation2;
/// let rot = Rotation2::<f64>::identity();
/// let rot2 = rot.cast::<f32>();
/// assert_eq!(rot2, Rotation2::<f32>::identity());
/// ```
pub fn cast<To: Scalar>(self) -> Rotation<To, D>
where
Rotation<To, D>: SupersetOf<Self>,
DefaultAllocator: Allocator<To, D, D>,
{
crate::convert(self)
}
}
impl<N, D: DimName> One for Rotation<N, D> impl<N, D: DimName> One for Rotation<N, D>
where where
N: Scalar + Zero + One + ClosedAdd + ClosedMul, N: Scalar + Zero + One + ClosedAdd + ClosedMul,

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

@ -10,15 +10,16 @@ use rand::{
Rng, Rng,
}; };
use simba::scalar::SupersetOf;
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, U2, U3}; use crate::base::dimension::{DimName, U2, U3};
use crate::base::{DefaultAllocator, Vector2, Vector3}; use crate::base::{DefaultAllocator, Vector2, Vector3};
use crate::geometry::{ use crate::{
AbstractRotation, Isometry, Point, Point3, Rotation2, Rotation3, Similarity, Translation, AbstractRotation, Isometry, Point, Point3, Rotation2, Rotation3, Scalar, Similarity,
UnitComplex, UnitQuaternion, Translation, UnitComplex, UnitQuaternion,
}; };
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R> impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R>
@ -158,6 +159,22 @@ where
scaling, scaling,
) )
} }
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::SimilarityMatrix2;
/// let sim = SimilarityMatrix2::<f64>::identity();
/// let sim2 = sim.cast::<f32>();
/// assert_eq!(sim2, SimilarityMatrix2::<f32>::identity());
/// ```
pub fn cast<To: Scalar>(self) -> Similarity<To, U2, Rotation2<To>>
where
Similarity<To, U2, Rotation2<To>>: SupersetOf<Self>,
{
crate::convert(self)
}
} }
impl<N: SimdRealField> Similarity<N, U2, UnitComplex<N>> impl<N: SimdRealField> Similarity<N, U2, UnitComplex<N>>
@ -184,12 +201,28 @@ where
scaling, scaling,
) )
} }
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::Similarity2;
/// let sim = Similarity2::<f64>::identity();
/// let sim2 = sim.cast::<f32>();
/// assert_eq!(sim2, Similarity2::<f32>::identity());
/// ```
pub fn cast<To: Scalar>(self) -> Similarity<To, U2, UnitComplex<To>>
where
Similarity<To, U2, UnitComplex<To>>: SupersetOf<Self>,
{
crate::convert(self)
}
} }
// 3D rotation. // 3D rotation.
macro_rules! similarity_construction_impl( macro_rules! similarity_construction_impl(
($Rot: ty) => { ($Rot: ident) => {
impl<N: SimdRealField> Similarity<N, U3, $Rot> impl<N: SimdRealField> Similarity<N, U3, $Rot<N>>
where N::Element: SimdRealField { where N::Element: SimdRealField {
/// Creates a new similarity from a translation, rotation axis-angle, and scaling /// Creates a new similarity from a translation, rotation axis-angle, and scaling
/// factor. /// factor.
@ -219,7 +252,23 @@ macro_rules! similarity_construction_impl(
#[inline] #[inline]
pub fn new(translation: Vector3<N>, axisangle: Vector3<N>, scaling: N) -> Self pub fn new(translation: Vector3<N>, axisangle: Vector3<N>, scaling: N) -> Self
{ {
Self::from_isometry(Isometry::<_, U3, $Rot>::new(translation, axisangle), scaling) Self::from_isometry(Isometry::<_, U3, $Rot<N>>::new(translation, axisangle), scaling)
}
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::Similarity3;
/// let sim = Similarity3::<f64>::identity();
/// let sim2 = sim.cast::<f32>();
/// assert_eq!(sim2, Similarity3::<f32>::identity());
/// ```
pub fn cast<To: Scalar>(self) -> Similarity<To, U3, $Rot<To>>
where
Similarity<To, U3, $Rot<To>>: SupersetOf<Self>,
{
crate::convert(self)
} }
/// Creates an similarity that corresponds to a scaling factor and a local frame of /// Creates an similarity that corresponds to a scaling factor and a local frame of
@ -260,7 +309,7 @@ macro_rules! similarity_construction_impl(
up: &Vector3<N>, up: &Vector3<N>,
scaling: N) scaling: N)
-> Self { -> Self {
Self::from_isometry(Isometry::<_, U3, $Rot>::face_towards(eye, target, up), scaling) Self::from_isometry(Isometry::<_, U3, $Rot<N>>::face_towards(eye, target, up), scaling)
} }
/// Deprecated: Use [SimilarityMatrix3::face_towards] instead. /// Deprecated: Use [SimilarityMatrix3::face_towards] instead.
@ -308,7 +357,7 @@ macro_rules! similarity_construction_impl(
up: &Vector3<N>, up: &Vector3<N>,
scaling: N) scaling: N)
-> Self { -> Self {
Self::from_isometry(Isometry::<_, U3, $Rot>::look_at_rh(eye, target, up), scaling) Self::from_isometry(Isometry::<_, U3, $Rot<N>>::look_at_rh(eye, target, up), scaling)
} }
/// Builds a left-handed look-at view matrix including a scaling factor. /// Builds a left-handed look-at view matrix including a scaling factor.
@ -346,11 +395,11 @@ macro_rules! similarity_construction_impl(
up: &Vector3<N>, up: &Vector3<N>,
scaling: N) scaling: N)
-> Self { -> Self {
Self::from_isometry(Isometry::<_, _, $Rot>::look_at_lh(eye, target, up), scaling) Self::from_isometry(Isometry::<_, _, $Rot<N>>::look_at_lh(eye, target, up), scaling)
} }
} }
} }
); );
similarity_construction_impl!(Rotation3<N>); similarity_construction_impl!(Rotation3);
similarity_construction_impl!(UnitQuaternion<N>); similarity_construction_impl!(UnitQuaternion);

View File

@ -10,7 +10,7 @@ use rand::{
Rng, Rng,
}; };
use simba::scalar::ClosedAdd; use simba::scalar::{ClosedAdd, SupersetOf};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, U1, U2, U3, U4, U5, U6}; use crate::base::dimension::{DimName, U1, U2, U3, U4, U5, U6};
@ -18,7 +18,7 @@ use crate::base::{DefaultAllocator, Scalar, VectorN};
use crate::geometry::Translation; use crate::geometry::Translation;
impl<N: Scalar + Zero, D: DimName> Translation<N, D> impl<N: Scalar, D: DimName> Translation<N, D>
where where
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<N, D>,
{ {
@ -37,9 +37,29 @@ where
/// assert_eq!(t * p, p); /// assert_eq!(t * p, p);
/// ``` /// ```
#[inline] #[inline]
pub fn identity() -> Translation<N, D> { pub fn identity() -> Translation<N, D>
where
N: Zero,
{
Self::from(VectorN::<N, D>::from_element(N::zero())) Self::from(VectorN::<N, D>::from_element(N::zero()))
} }
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::Translation2;
/// let tra = Translation2::new(1.0f64, 2.0);
/// let tra2 = tra.cast::<f32>();
/// assert_eq!(tra2, Translation2::new(1.0f32, 2.0));
/// ```
pub fn cast<To: Scalar>(self) -> Translation<To, D>
where
Translation<To, D>: SupersetOf<Self>,
DefaultAllocator: Allocator<To, D>,
{
crate::convert(self)
}
} }
impl<N: Scalar + Zero + ClosedAdd, D: DimName> One for Translation<N, D> impl<N: Scalar + Zero + ClosedAdd, D: DimName> One for Translation<N, D>

View File

@ -12,9 +12,9 @@ use num_complex::Complex;
use crate::base::dimension::{U1, U2}; use crate::base::dimension::{U1, U2};
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{Matrix2, Unit, Vector, Vector2}; use crate::base::{Matrix2, Scalar, Unit, Vector, Vector2};
use crate::geometry::{Rotation2, UnitComplex}; use crate::geometry::{Rotation2, UnitComplex};
use simba::scalar::RealField; use simba::scalar::{RealField, SupersetOf};
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
/// # Identity /// # Identity
@ -118,6 +118,22 @@ impl<N: SimdRealField> UnitComplex<N>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
{ {
/// Cast the components of `self` to another type.
///
/// # Example
/// ```
/// # use nalgebra::UnitComplex;
/// let c = UnitComplex::new(1.0f64);
/// let c2 = c.cast::<f32>();
/// assert_eq!(c2, UnitComplex::new(1.0f32));
/// ```
pub fn cast<To: Scalar>(self) -> UnitComplex<To>
where
UnitComplex<To>: SupersetOf<Self>,
{
crate::convert(self)
}
/// The underlying complex number. /// The underlying complex number.
/// ///
/// Same as `self.as_ref()`. /// Same as `self.as_ref()`.

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;