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/).
## [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]
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

View File

@ -1,6 +1,6 @@
[package]
name = "nalgebra"
version = "0.25.1"
version = "0.25.2"
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."
@ -24,11 +24,6 @@ path = "src/lib.rs"
[features]
default = [ "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 = [ ]
debug = [ "approx/num-complex", "rand" ]
alloc = [ ]
@ -36,10 +31,25 @@ io = [ "pest", "pest_derive" ]
compare = [ "matrixcompare-core" ]
libm = [ "simba/libm" ]
libm-force = [ "simba/libm_force" ]
proptest-support = [ "proptest" ]
no_unsound_assume_init = [ ]
# This feature is only used for tests, and enables tests that require more time to run
# Conversion
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]
@ -57,6 +67,7 @@ matrixmultiply = { version = "0.3", optional = true }
serde = { version = "1.0", default-features = false, features = [ "derive" ], optional = true }
abomonation = { version = "0.7", optional = true }
mint = { version = "0.5", optional = true }
glam = { version = "0.13", optional = true }
quickcheck = { version = "1", optional = true }
pest = { version = "2", optional = true }
pest_derive = { version = "2", optional = true }

View File

@ -1,7 +1,5 @@
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::vec::Vec;
#[cfg(feature = "mint")]
use mint;
use simba::scalar::{SubsetOf, SupersetOf};
use std::convert::{AsMut, AsRef, From, Into};
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);
);
#[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>>
for Matrix<N, R, C, ArrayStorage<N, R, C>>
where

View File

@ -16,7 +16,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "abomonation-serialize")]
use abomonation::Abomonation;
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, Field};
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, Field, SupersetOf};
use simba::simd::SimdPartialOrd;
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
}
/// 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.
///
/// The initialization closure is given the first component of this matrix:

View File

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

View File

@ -5,6 +5,7 @@ use crate::{
use num::{One, Zero};
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
use simba::scalar::SupersetOf;
impl<N: Scalar> DualQuaternion<N> {
/// Creates a dual quaternion from its rotation and translation components.
@ -49,6 +50,22 @@ impl<N: Scalar> DualQuaternion<N> {
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>
@ -129,6 +146,22 @@ impl<N: SimdRealField> UnitDualQuaternion<N> {
pub fn identity() -> Self {
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>

View File

@ -10,15 +10,16 @@ use rand::{
Rng,
};
use simba::scalar::SupersetOf;
use simba::simd::SimdRealField;
use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, U2};
use crate::base::{DefaultAllocator, Vector2, Vector3};
use crate::geometry::{
use crate::{
AbstractRotation, Isometry, Isometry2, Isometry3, IsometryMatrix2, IsometryMatrix3, Point,
Point3, Rotation, Rotation3, Translation, Translation2, Translation3, UnitComplex,
Point3, Rotation, Rotation3, Scalar, Translation, Translation2, Translation3, UnitComplex,
UnitQuaternion,
};
@ -153,6 +154,22 @@ where
pub fn rotation(angle: N) -> Self {
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>
@ -191,6 +208,22 @@ where
pub fn rotation(angle: N) -> Self {
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.
@ -387,6 +420,22 @@ where
N::Element: SimdRealField,
{
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>
@ -394,6 +443,22 @@ where
N::Element: SimdRealField,
{
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

View File

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

View File

@ -15,7 +15,7 @@ use crate::{
Point1, Point2, Point3, Point4, Point5, Point6, Vector1, Vector2, Vector3, Vector4, Vector5,
Vector6,
};
use simba::scalar::ClosedDiv;
use simba::scalar::{ClosedDiv, SupersetOf};
use crate::geometry::Point;
@ -119,6 +119,23 @@ where
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::{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;
#[cfg(feature = "mint")]
use mint;
#[cfg(feature = "mint")]
use std::convert::{AsMut, AsRef, From, Into};
/*
* This file provides the following conversions:
* =============================================
*
* Point -> Point
* Point -> Vector (homogeneous)
*
* mint::Point <-> Point
*/
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>>
where
D: DimNameAdd<U1>,

View File

@ -13,7 +13,7 @@ use rand::{
use num::{One, Zero};
use simba::scalar::RealField;
use simba::scalar::{RealField, SupersetOf};
use simba::simd::SimdBool;
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 {
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> {
@ -199,6 +215,23 @@ where
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
/// (the rotation angle).
///

View File

@ -3,9 +3,6 @@ use num::Zero;
use simba::scalar::{RealField, SubsetOf, SupersetOf};
use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue};
#[cfg(feature = "mint")]
use mint;
use crate::base::dimension::U3;
use crate::base::{Matrix3, Matrix4, Scalar, Vector4};
use crate::geometry::{
@ -26,17 +23,14 @@ use crate::geometry::{
* UnitQuaternion -> Transform<U3>
* UnitQuaternion -> Matrix<U4> (homogeneous)
*
* mint::Quaternion <-> Quaternion
* UnitQuaternion -> mint::Quaternion
*
* NOTE:
* UnitQuaternion -> Quaternion is already provided by: Unit<T> -> T
*/
impl<N1, N2> SubsetOf<Quaternion<N2>> for Quaternion<N1>
where
N1: SimdRealField,
N2: SimdRealField + SupersetOf<N1>,
N1: Scalar,
N2: Scalar + SupersetOf<N1>,
{
#[inline]
fn to_superset(&self) -> Quaternion<N2> {
@ -58,8 +52,8 @@ where
impl<N1, N2> SubsetOf<UnitQuaternion<N2>> for UnitQuaternion<N1>
where
N1: SimdRealField,
N2: SimdRealField + SupersetOf<N1>,
N1: Scalar,
N2: Scalar + SupersetOf<N1>,
{
#[inline]
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>
where
N::Element: SimdRealField,

View File

@ -1,6 +1,6 @@
use num::{One, Zero};
use simba::scalar::{ClosedAdd, ClosedMul};
use simba::scalar::{ClosedAdd, ClosedMul, SupersetOf};
use crate::base::allocator::Allocator;
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>
where
N: Scalar + Zero + One + ClosedAdd + ClosedMul,

View File

@ -3,9 +3,6 @@ use num::Zero;
use simba::scalar::{RealField, SubsetOf, SupersetOf};
use simba::simd::{PrimitiveSimdValue, SimdValue};
#[cfg(feature = "mint")]
use mint;
use crate::base::allocator::Allocator;
use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1};
use crate::base::{DefaultAllocator, Matrix2, Matrix3, Matrix4, MatrixN, Scalar};
@ -27,7 +24,6 @@ use crate::geometry::{
* Rotation -> Similarity
* Rotation -> Transform
* 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> {
#[inline]
fn from(q: Rotation2<N>) -> Self {

View File

@ -10,15 +10,16 @@ use rand::{
Rng,
};
use simba::scalar::SupersetOf;
use simba::simd::SimdRealField;
use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, U2, U3};
use crate::base::{DefaultAllocator, Vector2, Vector3};
use crate::geometry::{
AbstractRotation, Isometry, Point, Point3, Rotation2, Rotation3, Similarity, Translation,
UnitComplex, UnitQuaternion,
use crate::{
AbstractRotation, Isometry, Point, Point3, Rotation2, Rotation3, Scalar, Similarity,
Translation, UnitComplex, UnitQuaternion,
};
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R>
@ -158,6 +159,22 @@ where
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>>
@ -184,12 +201,28 @@ where
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.
macro_rules! similarity_construction_impl(
($Rot: ty) => {
impl<N: SimdRealField> Similarity<N, U3, $Rot>
($Rot: ident) => {
impl<N: SimdRealField> Similarity<N, U3, $Rot<N>>
where N::Element: SimdRealField {
/// Creates a new similarity from a translation, rotation axis-angle, and scaling
/// factor.
@ -219,7 +252,23 @@ macro_rules! similarity_construction_impl(
#[inline]
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
@ -260,7 +309,7 @@ macro_rules! similarity_construction_impl(
up: &Vector3<N>,
scaling: N)
-> 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.
@ -308,7 +357,7 @@ macro_rules! similarity_construction_impl(
up: &Vector3<N>,
scaling: N)
-> 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.
@ -346,11 +395,11 @@ macro_rules! similarity_construction_impl(
up: &Vector3<N>,
scaling: N)
-> 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!(UnitQuaternion<N>);
similarity_construction_impl!(Rotation3);
similarity_construction_impl!(UnitQuaternion);

View File

@ -10,7 +10,7 @@ use rand::{
Rng,
};
use simba::scalar::ClosedAdd;
use simba::scalar::{ClosedAdd, SupersetOf};
use crate::base::allocator::Allocator;
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;
impl<N: Scalar + Zero, D: DimName> Translation<N, D>
impl<N: Scalar, D: DimName> Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
{
@ -37,9 +37,29 @@ where
/// assert_eq!(t * p, p);
/// ```
#[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()))
}
/// 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>

View File

@ -12,9 +12,9 @@ use num_complex::Complex;
use crate::base::dimension::{U1, U2};
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 simba::scalar::RealField;
use simba::scalar::{RealField, SupersetOf};
use simba::simd::SimdRealField;
/// # Identity
@ -118,6 +118,22 @@ impl<N: SimdRealField> UnitComplex<N>
where
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.
///
/// Same as `self.as_ref()`.

View File

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