From b3f347e45e5b42394d873ceb042f83c2dacaa6df Mon Sep 17 00:00:00 2001 From: sebcrozet Date: Mon, 23 Mar 2020 09:16:01 +0100 Subject: [PATCH] Add From<[...; .]> impls for all SIMD geometric sructures up to the isometry (excluded). --- src/base/conversion.rs | 107 ++++++++++++++++ src/base/unit.rs | 93 +++++++++++++- src/geometry/isometry_conversion.rs | 20 ++- src/geometry/point_conversion.rs | 88 +++++++++++++ src/geometry/quaternion.rs | 4 +- src/geometry/quaternion_construction.rs | 8 +- src/geometry/quaternion_conversion.rs | 156 +++++++++++++++++++++++- src/geometry/quaternion_coordinates.rs | 7 +- src/geometry/rotation_conversion.rs | 89 +++++++++++++- src/geometry/translation_conversion.rs | 88 +++++++++++++ src/geometry/unit_complex_conversion.rs | 74 ++++++++++- 11 files changed, 720 insertions(+), 14 deletions(-) diff --git a/src/base/conversion.rs b/src/base/conversion.rs index fc60711d..5259b766 100644 --- a/src/base/conversion.rs +++ b/src/base/conversion.rs @@ -9,6 +9,8 @@ use generic_array::ArrayLength; use std::ops::Mul; use typenum::Prod; +use simba::simd::{PrimitiveSimdValue, SimdValue}; + use crate::base::allocator::{Allocator, SameShapeAllocator}; use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; #[cfg(any(feature = "std", feature = "alloc"))] @@ -576,3 +578,108 @@ impl<'a, N: Scalar + Copy> From<&'a mut [N]> for DVectorSliceMut<'a, N> { Self::from_slice(slice, slice.len()) } } + +impl From<[MatrixMN; 2]> + for MatrixMN +where + N: From<[::Element; 2]>, + N::Element: Scalar + SimdValue, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [MatrixMN; 2]) -> Self { + let (nrows, ncols) = arr[0].data.shape(); + + Self::from_fn_generic(nrows, ncols, |i, j| { + [ + arr[0][(i, j)].inlined_clone(), + arr[1][(i, j)].inlined_clone(), + ] + .into() + }) + } +} + +impl From<[MatrixMN; 4]> + for MatrixMN +where + N: From<[::Element; 4]>, + N::Element: Scalar + SimdValue, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [MatrixMN; 4]) -> Self { + let (nrows, ncols) = arr[0].data.shape(); + + Self::from_fn_generic(nrows, ncols, |i, j| { + [ + arr[0][(i, j)].inlined_clone(), + arr[1][(i, j)].inlined_clone(), + arr[2][(i, j)].inlined_clone(), + arr[3][(i, j)].inlined_clone(), + ] + .into() + }) + } +} + +impl From<[MatrixMN; 8]> + for MatrixMN +where + N: From<[::Element; 8]>, + N::Element: Scalar + SimdValue, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [MatrixMN; 8]) -> Self { + let (nrows, ncols) = arr[0].data.shape(); + + Self::from_fn_generic(nrows, ncols, |i, j| { + [ + arr[0][(i, j)].inlined_clone(), + arr[1][(i, j)].inlined_clone(), + arr[2][(i, j)].inlined_clone(), + arr[3][(i, j)].inlined_clone(), + arr[4][(i, j)].inlined_clone(), + arr[5][(i, j)].inlined_clone(), + arr[6][(i, j)].inlined_clone(), + arr[7][(i, j)].inlined_clone(), + ] + .into() + }) + } +} + +impl From<[MatrixMN; 16]> + for MatrixMN +where + N: From<[::Element; 16]>, + N::Element: Scalar + SimdValue, + DefaultAllocator: Allocator + Allocator, +{ + fn from(arr: [MatrixMN; 16]) -> Self { + let (nrows, ncols) = arr[0].data.shape(); + + Self::from_fn_generic(nrows, ncols, |i, j| { + [ + arr[0][(i, j)].inlined_clone(), + arr[1][(i, j)].inlined_clone(), + arr[2][(i, j)].inlined_clone(), + arr[3][(i, j)].inlined_clone(), + arr[4][(i, j)].inlined_clone(), + arr[5][(i, j)].inlined_clone(), + arr[6][(i, j)].inlined_clone(), + arr[7][(i, j)].inlined_clone(), + arr[8][(i, j)].inlined_clone(), + arr[9][(i, j)].inlined_clone(), + arr[10][(i, j)].inlined_clone(), + arr[11][(i, j)].inlined_clone(), + arr[12][(i, j)].inlined_clone(), + arr[13][(i, j)].inlined_clone(), + arr[14][(i, j)].inlined_clone(), + arr[15][(i, j)].inlined_clone(), + ] + .into() + }) + } +} diff --git a/src/base/unit.rs b/src/base/unit.rs index 6f5ce999..acff561a 100644 --- a/src/base/unit.rs +++ b/src/base/unit.rs @@ -9,7 +9,9 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; -use crate::{RealField, SimdComplexField, SimdRealField}; +use crate::allocator::Allocator; +use crate::base::DefaultAllocator; +use crate::{Dim, MatrixMN, RealField, Scalar, SimdComplexField, SimdRealField}; /// A wrapper that ensures the underlying algebraic entity has a unit norm. /// @@ -240,3 +242,92 @@ impl Deref for Unit { unsafe { mem::transmute(self) } } } + +// NOTE: we can't use a generic implementation for `Unit` because +// num_complex::Complex does not implement `From[Complex<...>...]` (and can't +// because of the orphan rules). +impl + From<[Unit>; 2]> for Unit> +where + N: From<[::Element; 2]>, + N::Element: Scalar, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Unit>; 2]) -> Self { + Self::new_unchecked(MatrixMN::from([ + arr[0].clone().into_inner(), + arr[1].clone().into_inner(), + ])) + } +} + +impl + From<[Unit>; 4]> for Unit> +where + N: From<[::Element; 4]>, + N::Element: Scalar, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Unit>; 4]) -> Self { + Self::new_unchecked(MatrixMN::from([ + arr[0].clone().into_inner(), + arr[1].clone().into_inner(), + arr[2].clone().into_inner(), + arr[3].clone().into_inner(), + ])) + } +} + +impl + From<[Unit>; 8]> for Unit> +where + N: From<[::Element; 8]>, + N::Element: Scalar, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Unit>; 8]) -> Self { + Self::new_unchecked(MatrixMN::from([ + arr[0].clone().into_inner(), + arr[1].clone().into_inner(), + arr[2].clone().into_inner(), + arr[3].clone().into_inner(), + arr[4].clone().into_inner(), + arr[5].clone().into_inner(), + arr[6].clone().into_inner(), + arr[7].clone().into_inner(), + ])) + } +} + +impl + From<[Unit>; 16]> for Unit> +where + N: From<[::Element; 16]>, + N::Element: Scalar, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Unit>; 16]) -> Self { + Self::new_unchecked(MatrixMN::from([ + arr[0].clone().into_inner(), + arr[1].clone().into_inner(), + arr[2].clone().into_inner(), + arr[3].clone().into_inner(), + arr[4].clone().into_inner(), + arr[5].clone().into_inner(), + arr[6].clone().into_inner(), + arr[7].clone().into_inner(), + arr[8].clone().into_inner(), + arr[9].clone().into_inner(), + arr[10].clone().into_inner(), + arr[11].clone().into_inner(), + arr[12].clone().into_inner(), + arr[13].clone().into_inner(), + arr[14].clone().into_inner(), + arr[15].clone().into_inner(), + ])) + } +} diff --git a/src/geometry/isometry_conversion.rs b/src/geometry/isometry_conversion.rs index 28ec469d..ca233276 100644 --- a/src/geometry/isometry_conversion.rs +++ b/src/geometry/isometry_conversion.rs @@ -1,5 +1,5 @@ use simba::scalar::{RealField, SubsetOf, SupersetOf}; -use simba::simd::SimdRealField; +use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue}; use crate::base::allocator::Allocator; use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1}; @@ -162,3 +162,21 @@ where iso.to_homogeneous() } } + +//impl From<[Isometry; 2]> +// for Rotation +//where +// N: From<[::Element; 2]>, +// R: From<[R::Element; 2]>, +// N::Element: Scalar + Copy, +// R::Element: Scalar + Copy, +// DefaultAllocator: Allocator + Allocator, +//{ +// #[inline] +// fn from(arr: [Isometry; 2]) -> Self { +// Self::from_parts(MatrixN::from([ +// arr[0].clone().into_inner(), +// arr[1].clone().into_inner(), +// ])) +// } +//} diff --git a/src/geometry/point_conversion.rs b/src/geometry/point_conversion.rs index 277462e6..2fc0c507 100644 --- a/src/geometry/point_conversion.rs +++ b/src/geometry/point_conversion.rs @@ -1,5 +1,6 @@ use num::{One, Zero}; use simba::scalar::{ClosedDiv, SubsetOf, SupersetOf}; +use simba::simd::{PrimitiveSimdValue, SimdValue}; use crate::base::allocator::Allocator; use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; @@ -149,3 +150,90 @@ where DefaultAllocator: Allocator Point { coords } } } + +impl From<[Point; 2]> + for Point +where + N: From<[::Element; 2]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, + >::Buffer: Copy, +{ + #[inline] + fn from(arr: [Point; 2]) -> Self { + Self::from(VectorN::from([arr[0].coords, arr[1].coords])) + } +} + +impl From<[Point; 4]> + for Point +where + N: From<[::Element; 4]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, + >::Buffer: Copy, +{ + #[inline] + fn from(arr: [Point; 4]) -> Self { + Self::from(VectorN::from([ + arr[0].coords, + arr[1].coords, + arr[2].coords, + arr[3].coords, + ])) + } +} + +impl From<[Point; 8]> + for Point +where + N: From<[::Element; 8]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, + >::Buffer: Copy, +{ + #[inline] + fn from(arr: [Point; 8]) -> Self { + Self::from(VectorN::from([ + arr[0].coords, + arr[1].coords, + arr[2].coords, + arr[3].coords, + arr[4].coords, + arr[5].coords, + arr[6].coords, + arr[7].coords, + ])) + } +} + +impl From<[Point; 16]> + for Point +where + N: From<[::Element; 16]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, + >::Buffer: Copy, +{ + #[inline] + fn from(arr: [Point; 16]) -> Self { + Self::from(VectorN::from([ + arr[0].coords, + arr[1].coords, + arr[2].coords, + arr[3].coords, + arr[4].coords, + arr[5].coords, + arr[6].coords, + arr[7].coords, + arr[8].coords, + arr[9].coords, + arr[10].coords, + arr[11].coords, + arr[12].coords, + arr[13].coords, + arr[14].coords, + arr[15].coords, + ])) + } +} diff --git a/src/geometry/quaternion.rs b/src/geometry/quaternion.rs index a6a36e7b..1a593883 100755 --- a/src/geometry/quaternion.rs +++ b/src/geometry/quaternion.rs @@ -68,9 +68,9 @@ impl hash::Hash for Quaternion { } } -impl Copy for Quaternion {} +impl Copy for Quaternion {} -impl Clone for Quaternion { +impl Clone for Quaternion { #[inline] fn clone(&self) -> Self { Self::from(self.coords.clone()) diff --git a/src/geometry/quaternion_construction.rs b/src/geometry/quaternion_construction.rs index ef1e99cb..70d4c220 100644 --- a/src/geometry/quaternion_construction.rs +++ b/src/geometry/quaternion_construction.rs @@ -10,16 +10,16 @@ use rand::distributions::{Distribution, OpenClosed01, Standard}; use rand::Rng; use simba::scalar::RealField; -use simba::simd::SimdBool; +use simba::simd::{SimdBool, SimdValue}; use crate::base::dimension::U3; use crate::base::storage::Storage; use crate::base::{Matrix3, Matrix4, Unit, Vector, Vector3, Vector4}; -use crate::SimdRealField; +use crate::{Scalar, SimdRealField}; use crate::geometry::{Quaternion, Rotation3, UnitQuaternion}; -impl Quaternion { +impl Quaternion { /// Creates a quaternion from a 4D vector. The quaternion scalar part corresponds to the `w` /// vector component. #[inline] @@ -45,7 +45,9 @@ impl Quaternion { pub fn new(w: N, i: N, j: N, k: N) -> Self { Self::from(Vector4::new(i, j, k, w)) } +} +impl Quaternion { /// Constructs a pure quaternion. #[inline] pub fn from_imag(vector: Vector3) -> Self { diff --git a/src/geometry/quaternion_conversion.rs b/src/geometry/quaternion_conversion.rs index d9cc6c4a..1b88be8c 100644 --- a/src/geometry/quaternion_conversion.rs +++ b/src/geometry/quaternion_conversion.rs @@ -1,7 +1,7 @@ use num::Zero; use simba::scalar::{RealField, SubsetOf, SupersetOf}; -use simba::simd::{SimdRealField, SimdValue}; +use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue}; #[cfg(feature = "mint")] use mint; @@ -260,3 +260,157 @@ impl From> for Quaternion { Self { coords } } } + +impl From<[Quaternion; 2]> for Quaternion +where + N: From<[::Element; 2]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [Quaternion; 2]) -> Self { + Self::from(Vector4::from([arr[0].coords, arr[1].coords])) + } +} + +impl From<[Quaternion; 4]> for Quaternion +where + N: From<[::Element; 4]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [Quaternion; 4]) -> Self { + Self::from(Vector4::from([ + arr[0].coords, + arr[1].coords, + arr[2].coords, + arr[3].coords, + ])) + } +} + +impl From<[Quaternion; 8]> for Quaternion +where + N: From<[::Element; 8]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [Quaternion; 8]) -> Self { + Self::from(Vector4::from([ + arr[0].coords, + arr[1].coords, + arr[2].coords, + arr[3].coords, + arr[4].coords, + arr[5].coords, + arr[6].coords, + arr[7].coords, + ])) + } +} + +impl From<[Quaternion; 16]> for Quaternion +where + N: From<[::Element; 16]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [Quaternion; 16]) -> Self { + Self::from(Vector4::from([ + arr[0].coords, + arr[1].coords, + arr[2].coords, + arr[3].coords, + arr[4].coords, + arr[5].coords, + arr[6].coords, + arr[7].coords, + arr[8].coords, + arr[9].coords, + arr[10].coords, + arr[11].coords, + arr[12].coords, + arr[13].coords, + arr[14].coords, + arr[15].coords, + ])) + } +} + +impl From<[UnitQuaternion; 2]> + for UnitQuaternion +where + N: From<[::Element; 2]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [UnitQuaternion; 2]) -> Self { + Self::new_unchecked(Quaternion::from([arr[0].into_inner(), arr[1].into_inner()])) + } +} + +impl From<[UnitQuaternion; 4]> + for UnitQuaternion +where + N: From<[::Element; 4]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [UnitQuaternion; 4]) -> Self { + Self::new_unchecked(Quaternion::from([ + arr[0].into_inner(), + arr[1].into_inner(), + arr[2].into_inner(), + arr[3].into_inner(), + ])) + } +} + +impl From<[UnitQuaternion; 8]> + for UnitQuaternion +where + N: From<[::Element; 8]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [UnitQuaternion; 8]) -> Self { + Self::new_unchecked(Quaternion::from([ + arr[0].into_inner(), + arr[1].into_inner(), + arr[2].into_inner(), + arr[3].into_inner(), + arr[4].into_inner(), + arr[5].into_inner(), + arr[6].into_inner(), + arr[7].into_inner(), + ])) + } +} + +impl From<[UnitQuaternion; 16]> + for UnitQuaternion +where + N: From<[::Element; 16]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [UnitQuaternion; 16]) -> Self { + Self::new_unchecked(Quaternion::from([ + arr[0].into_inner(), + arr[1].into_inner(), + arr[2].into_inner(), + arr[3].into_inner(), + arr[4].into_inner(), + arr[5].into_inner(), + arr[6].into_inner(), + arr[7].into_inner(), + arr[8].into_inner(), + arr[9].into_inner(), + arr[10].into_inner(), + arr[11].into_inner(), + arr[12].into_inner(), + arr[13].into_inner(), + arr[14].into_inner(), + arr[15].into_inner(), + ])) + } +} diff --git a/src/geometry/quaternion_coordinates.rs b/src/geometry/quaternion_coordinates.rs index 50e340bf..0d318087 100644 --- a/src/geometry/quaternion_coordinates.rs +++ b/src/geometry/quaternion_coordinates.rs @@ -1,13 +1,14 @@ use std::mem; use std::ops::{Deref, DerefMut}; -use simba::simd::SimdRealField; +use simba::simd::SimdValue; use crate::base::coordinates::IJKW; +use crate::Scalar; use crate::geometry::Quaternion; -impl Deref for Quaternion { +impl Deref for Quaternion { type Target = IJKW; #[inline] @@ -16,7 +17,7 @@ impl Deref for Quaternion { } } -impl DerefMut for Quaternion { +impl DerefMut for Quaternion { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { unsafe { mem::transmute(self) } diff --git a/src/geometry/rotation_conversion.rs b/src/geometry/rotation_conversion.rs index 0b40dfbd..c49b92c4 100644 --- a/src/geometry/rotation_conversion.rs +++ b/src/geometry/rotation_conversion.rs @@ -1,13 +1,14 @@ 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}; +use crate::base::{DefaultAllocator, Matrix2, Matrix3, Matrix4, MatrixN, Scalar}; use crate::geometry::{ AbstractRotation, Isometry, Rotation, Rotation2, Rotation3, Similarity, SuperTCategoryOf, @@ -243,3 +244,89 @@ impl From> for Matrix3 { q.into_inner() } } + +impl From<[Rotation; 2]> + for Rotation +where + N: From<[::Element; 2]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Rotation; 2]) -> Self { + Self::from_matrix_unchecked(MatrixN::from([ + arr[0].clone().into_inner(), + arr[1].clone().into_inner(), + ])) + } +} + +impl From<[Rotation; 4]> + for Rotation +where + N: From<[::Element; 4]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Rotation; 4]) -> Self { + Self::from_matrix_unchecked(MatrixN::from([ + arr[0].clone().into_inner(), + arr[1].clone().into_inner(), + arr[2].clone().into_inner(), + arr[3].clone().into_inner(), + ])) + } +} + +impl From<[Rotation; 8]> + for Rotation +where + N: From<[::Element; 8]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Rotation; 8]) -> Self { + Self::from_matrix_unchecked(MatrixN::from([ + arr[0].clone().into_inner(), + arr[1].clone().into_inner(), + arr[2].clone().into_inner(), + arr[3].clone().into_inner(), + arr[4].clone().into_inner(), + arr[5].clone().into_inner(), + arr[6].clone().into_inner(), + arr[7].clone().into_inner(), + ])) + } +} + +impl From<[Rotation; 16]> + for Rotation +where + N: From<[::Element; 16]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Rotation; 16]) -> Self { + Self::from_matrix_unchecked(MatrixN::from([ + arr[0].clone().into_inner(), + arr[1].clone().into_inner(), + arr[2].clone().into_inner(), + arr[3].clone().into_inner(), + arr[4].clone().into_inner(), + arr[5].clone().into_inner(), + arr[6].clone().into_inner(), + arr[7].clone().into_inner(), + arr[8].clone().into_inner(), + arr[9].clone().into_inner(), + arr[10].clone().into_inner(), + arr[11].clone().into_inner(), + arr[12].clone().into_inner(), + arr[13].clone().into_inner(), + arr[14].clone().into_inner(), + arr[15].clone().into_inner(), + ])) + } +} diff --git a/src/geometry/translation_conversion.rs b/src/geometry/translation_conversion.rs index a7368ed2..2aff3ae3 100644 --- a/src/geometry/translation_conversion.rs +++ b/src/geometry/translation_conversion.rs @@ -1,6 +1,7 @@ use num::{One, Zero}; use simba::scalar::{RealField, SubsetOf, SupersetOf}; +use simba::simd::PrimitiveSimdValue; use crate::base::allocator::Allocator; use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; @@ -173,3 +174,90 @@ where DefaultAllocator: Allocator Translation { vector } } } + +impl From<[Translation; 2]> + for Translation +where + N: From<[::Element; 2]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, + >::Buffer: Copy, +{ + #[inline] + fn from(arr: [Translation; 2]) -> Self { + Self::from(VectorN::from([arr[0].vector, arr[1].vector])) + } +} + +impl From<[Translation; 4]> + for Translation +where + N: From<[::Element; 4]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, + >::Buffer: Copy, +{ + #[inline] + fn from(arr: [Translation; 4]) -> Self { + Self::from(VectorN::from([ + arr[0].vector, + arr[1].vector, + arr[2].vector, + arr[3].vector, + ])) + } +} + +impl From<[Translation; 8]> + for Translation +where + N: From<[::Element; 8]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, + >::Buffer: Copy, +{ + #[inline] + fn from(arr: [Translation; 8]) -> Self { + Self::from(VectorN::from([ + arr[0].vector, + arr[1].vector, + arr[2].vector, + arr[3].vector, + arr[4].vector, + arr[5].vector, + arr[6].vector, + arr[7].vector, + ])) + } +} + +impl From<[Translation; 16]> + for Translation +where + N: From<[::Element; 16]>, + N::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, + >::Buffer: Copy, +{ + #[inline] + fn from(arr: [Translation; 16]) -> Self { + Self::from(VectorN::from([ + arr[0].vector, + arr[1].vector, + arr[2].vector, + arr[3].vector, + arr[4].vector, + arr[5].vector, + arr[6].vector, + arr[7].vector, + arr[8].vector, + arr[9].vector, + arr[10].vector, + arr[11].vector, + arr[12].vector, + arr[13].vector, + arr[14].vector, + arr[15].vector, + ])) + } +} diff --git a/src/geometry/unit_complex_conversion.rs b/src/geometry/unit_complex_conversion.rs index 4a9402cb..250da3a9 100644 --- a/src/geometry/unit_complex_conversion.rs +++ b/src/geometry/unit_complex_conversion.rs @@ -2,10 +2,10 @@ use num::Zero; use num_complex::Complex; use simba::scalar::{RealField, SubsetOf, SupersetOf}; -use simba::simd::SimdRealField; +use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue}; use crate::base::dimension::U2; -use crate::base::{Matrix2, Matrix3}; +use crate::base::{Matrix2, Matrix3, Scalar}; use crate::geometry::{ AbstractRotation, Isometry, Rotation2, Similarity, SuperTCategoryOf, TAffine, Transform, Translation, UnitComplex, @@ -189,3 +189,73 @@ where N::Element: SimdRealField q.to_rotation_matrix().into_inner() } } + +impl From<[UnitComplex; 2]> for UnitComplex +where + N: From<[::Element; 2]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [UnitComplex; 2]) -> Self { + Self::new_unchecked(Complex { + re: N::from([arr[0].re, arr[1].re]), + im: N::from([arr[0].im, arr[1].im]), + }) + } +} + +impl From<[UnitComplex; 4]> for UnitComplex +where + N: From<[::Element; 4]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [UnitComplex; 4]) -> Self { + Self::new_unchecked(Complex { + re: N::from([arr[0].re, arr[1].re, arr[2].re, arr[3].re]), + im: N::from([arr[0].im, arr[1].im, arr[2].im, arr[3].im]), + }) + } +} + +impl From<[UnitComplex; 8]> for UnitComplex +where + N: From<[::Element; 8]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [UnitComplex; 8]) -> Self { + Self::new_unchecked(Complex { + re: N::from([ + arr[0].re, arr[1].re, arr[2].re, arr[3].re, arr[4].re, arr[5].re, arr[6].re, + arr[7].re, + ]), + im: N::from([ + arr[0].im, arr[1].im, arr[2].im, arr[3].im, arr[4].im, arr[5].im, arr[6].im, + arr[7].im, + ]), + }) + } +} + +impl From<[UnitComplex; 16]> for UnitComplex +where + N: From<[::Element; 16]>, + N::Element: Scalar + Copy, +{ + #[inline] + fn from(arr: [UnitComplex; 16]) -> Self { + Self::new_unchecked(Complex { + re: N::from([ + arr[0].re, arr[1].re, arr[2].re, arr[3].re, arr[4].re, arr[5].re, arr[6].re, + arr[7].re, arr[8].re, arr[9].re, arr[10].re, arr[11].re, arr[12].re, arr[13].re, + arr[14].re, arr[15].re, + ]), + im: N::from([ + arr[0].im, arr[1].im, arr[2].im, arr[3].im, arr[4].im, arr[5].im, arr[6].im, + arr[7].im, arr[8].im, arr[9].im, arr[10].im, arr[11].im, arr[12].im, arr[13].im, + arr[14].im, arr[15].im, + ]), + }) + } +}