From cdbc9da46cd948035f3d696f71b4dfff44f5b33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Tue, 24 Mar 2020 10:16:31 +0100 Subject: [PATCH] Add From<[...; .]> impls for AoSoA Isometry and Similarity. --- src/geometry/isometry.rs | 27 ++--- src/geometry/isometry_conversion.rs | 156 ++++++++++++++++++++++--- src/geometry/similarity.rs | 65 ++++++----- src/geometry/similarity_conversion.rs | 144 ++++++++++++++++++++++- src/geometry/translation_conversion.rs | 81 +++++++------ 5 files changed, 369 insertions(+), 104 deletions(-) diff --git a/src/geometry/isometry.rs b/src/geometry/isometry.rs index c6a0ab1a..a02cbd08 100755 --- a/src/geometry/isometry.rs +++ b/src/geometry/isometry.rs @@ -17,7 +17,7 @@ use simba::simd::SimdRealField; use crate::base::allocator::Allocator; use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::storage::Owned; -use crate::base::{DefaultAllocator, MatrixN, VectorN}; +use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN}; use crate::geometry::{AbstractRotation, Point, Translation}; /// A direct isometry, i.e., a rotation followed by a translation, aka. a rigid-body motion, aka. an element of a Special Euclidean (SE) group. @@ -36,7 +36,7 @@ use crate::geometry::{AbstractRotation, Point, Translation}; DefaultAllocator: Allocator, Owned: Deserialize<'de>")) )] -pub struct Isometry +pub struct Isometry where DefaultAllocator: Allocator { /// The pure rotational part of this isometry. @@ -70,7 +70,7 @@ where } } -impl hash::Hash +impl hash::Hash for Isometry where DefaultAllocator: Allocator, @@ -82,19 +82,16 @@ where } } -impl + Copy> Copy +impl + Copy> Copy for Isometry where - N::Element: SimdRealField, DefaultAllocator: Allocator, Owned: Copy, { } -impl + Clone> Clone for Isometry -where - N::Element: SimdRealField, - DefaultAllocator: Allocator, +impl + Clone> Clone for Isometry +where DefaultAllocator: Allocator { #[inline] fn clone(&self) -> Self { @@ -102,10 +99,8 @@ where } } -impl> Isometry -where - N::Element: SimdRealField, - DefaultAllocator: Allocator, +impl> Isometry +where DefaultAllocator: Allocator { /// Creates a new isometry from its rotational and translational parts. /// @@ -128,7 +123,13 @@ where translation, } } +} +impl> Isometry +where + N::Element: SimdRealField, + DefaultAllocator: Allocator, +{ /// Inverts `self`. /// /// # Example diff --git a/src/geometry/isometry_conversion.rs b/src/geometry/isometry_conversion.rs index ca233276..7cb6fe85 100644 --- a/src/geometry/isometry_conversion.rs +++ b/src/geometry/isometry_conversion.rs @@ -3,7 +3,7 @@ use simba::simd::{PrimitiveSimdValue, SimdRealField, SimdValue}; use crate::base::allocator::Allocator; use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1}; -use crate::base::{DefaultAllocator, MatrixN}; +use crate::base::{DefaultAllocator, MatrixN, Scalar}; use crate::geometry::{ AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation, @@ -163,20 +163,140 @@ where } } -//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(), -// ])) -// } -//} +impl From<[Isometry; 2]> + for Isometry +where + N: From<[::Element; 2]>, + R: SimdValue + AbstractRotation + From<[::Element; 2]>, + R::Element: AbstractRotation, + N::Element: Scalar + Copy, + R::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Isometry; 2]) -> Self { + let tra = Translation::from([arr[0].translation.clone(), arr[1].translation.clone()]); + let rot = R::from([arr[0].rotation.clone(), arr[0].rotation.clone()]); + + Self::from_parts(tra, rot) + } +} + +impl From<[Isometry; 4]> + for Isometry +where + N: From<[::Element; 4]>, + R: SimdValue + AbstractRotation + From<[::Element; 4]>, + R::Element: AbstractRotation, + N::Element: Scalar + Copy, + R::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Isometry; 4]) -> Self { + let tra = Translation::from([ + arr[0].translation.clone(), + arr[1].translation.clone(), + arr[2].translation.clone(), + arr[3].translation.clone(), + ]); + let rot = R::from([ + arr[0].rotation.clone(), + arr[1].rotation.clone(), + arr[2].rotation.clone(), + arr[3].rotation.clone(), + ]); + + Self::from_parts(tra, rot) + } +} + +impl From<[Isometry; 8]> + for Isometry +where + N: From<[::Element; 8]>, + R: SimdValue + AbstractRotation + From<[::Element; 8]>, + R::Element: AbstractRotation, + N::Element: Scalar + Copy, + R::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Isometry; 8]) -> Self { + let tra = Translation::from([ + arr[0].translation.clone(), + arr[1].translation.clone(), + arr[2].translation.clone(), + arr[3].translation.clone(), + arr[4].translation.clone(), + arr[5].translation.clone(), + arr[6].translation.clone(), + arr[7].translation.clone(), + ]); + let rot = R::from([ + arr[0].rotation.clone(), + arr[1].rotation.clone(), + arr[2].rotation.clone(), + arr[3].rotation.clone(), + arr[4].rotation.clone(), + arr[5].rotation.clone(), + arr[6].rotation.clone(), + arr[7].rotation.clone(), + ]); + + Self::from_parts(tra, rot) + } +} + +impl From<[Isometry; 16]> + for Isometry +where + N: From<[::Element; 16]>, + R: SimdValue + AbstractRotation + From<[::Element; 16]>, + R::Element: AbstractRotation, + N::Element: Scalar + Copy, + R::Element: Scalar + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Isometry; 16]) -> Self { + let tra = Translation::from([ + arr[0].translation.clone(), + arr[1].translation.clone(), + arr[2].translation.clone(), + arr[3].translation.clone(), + arr[4].translation.clone(), + arr[5].translation.clone(), + arr[6].translation.clone(), + arr[7].translation.clone(), + arr[8].translation.clone(), + arr[9].translation.clone(), + arr[10].translation.clone(), + arr[11].translation.clone(), + arr[12].translation.clone(), + arr[13].translation.clone(), + arr[14].translation.clone(), + arr[15].translation.clone(), + ]); + let rot = R::from([ + arr[0].rotation.clone(), + arr[1].rotation.clone(), + arr[2].rotation.clone(), + arr[3].rotation.clone(), + arr[4].rotation.clone(), + arr[5].rotation.clone(), + arr[6].rotation.clone(), + arr[7].rotation.clone(), + arr[8].rotation.clone(), + arr[9].rotation.clone(), + arr[10].rotation.clone(), + arr[11].rotation.clone(), + arr[12].rotation.clone(), + arr[13].rotation.clone(), + arr[14].rotation.clone(), + arr[15].rotation.clone(), + ]); + + Self::from_parts(tra, rot) + } +} diff --git a/src/geometry/similarity.rs b/src/geometry/similarity.rs index 5260c927..701d534a 100755 --- a/src/geometry/similarity.rs +++ b/src/geometry/similarity.rs @@ -1,6 +1,8 @@ use approx::{AbsDiffEq, RelativeEq, UlpsEq}; +use num::Zero; use std::fmt; use std::hash; + #[cfg(feature = "abomonation-serialize")] use std::io::{Result as IOResult, Write}; @@ -16,7 +18,7 @@ use simba::simd::SimdRealField; use crate::base::allocator::Allocator; use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::storage::Owned; -use crate::base::{DefaultAllocator, MatrixN, VectorN}; +use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN}; use crate::geometry::{AbstractRotation, Isometry, Point, Translation}; /// A similarity, i.e., an uniform scaling, followed by a rotation, followed by a translation. @@ -37,7 +39,7 @@ use crate::geometry::{AbstractRotation, Isometry, Point, Translation}; DefaultAllocator: Allocator, Owned: Deserialize<'de>")) )] -pub struct Similarity +pub struct Similarity where DefaultAllocator: Allocator { /// The part of this similarity that does not include the scaling factor. @@ -46,7 +48,7 @@ where DefaultAllocator: Allocator } #[cfg(feature = "abomonation-serialize")] -impl Abomonation for Similarity +impl Abomonation for Similarity where Isometry: Abomonation, DefaultAllocator: Allocator, @@ -64,7 +66,7 @@ where } } -impl hash::Hash +impl hash::Hash for Similarity where DefaultAllocator: Allocator, @@ -76,29 +78,25 @@ where } } -impl + Copy> Copy +impl + Copy> Copy for Similarity where - N::Element: SimdRealField, DefaultAllocator: Allocator, Owned: Copy, { } -impl + Clone> Clone for Similarity -where - N::Element: SimdRealField, - DefaultAllocator: Allocator, +impl + Clone> Clone for Similarity +where DefaultAllocator: Allocator { #[inline] fn clone(&self) -> Self { - Similarity::from_isometry(self.isometry.clone(), self.scaling) + Similarity::from_isometry(self.isometry.clone(), self.scaling.clone()) } } -impl Similarity +impl Similarity where - N::Element: SimdRealField, R: AbstractRotation, DefaultAllocator: Allocator, { @@ -116,6 +114,30 @@ where Self { isometry, scaling } } + /// The scaling factor of this similarity transformation. + #[inline] + pub fn set_scaling(&mut self, scaling: N) { + assert!( + !scaling.is_zero(), + "The similarity scaling factor must not be zero." + ); + + self.scaling = scaling; + } + + /// The scaling factor of this similarity transformation. + #[inline] + pub fn scaling(&self) -> N { + self.scaling.clone() + } +} + +impl Similarity +where + N::Element: SimdRealField, + R: AbstractRotation, + DefaultAllocator: Allocator, +{ /// Creates a new similarity that applies only a scaling factor. #[inline] pub fn from_scaling(scaling: N) -> Self { @@ -139,23 +161,6 @@ where self.isometry.translation.vector *= self.scaling; } - /// The scaling factor of this similarity transformation. - #[inline] - pub fn set_scaling(&mut self, scaling: N) { - assert!( - !scaling.is_zero(), - "The similarity scaling factor must not be zero." - ); - - self.scaling = scaling; - } - - /// The scaling factor of this similarity transformation. - #[inline] - pub fn scaling(&self) -> N { - self.scaling - } - /// The similarity transformation that applies a scaling factor `scaling` before `self`. #[inline] #[must_use = "Did you mean to use prepend_scaling_mut()?"] diff --git a/src/geometry/similarity_conversion.rs b/src/geometry/similarity_conversion.rs index 032deff2..7953bc47 100644 --- a/src/geometry/similarity_conversion.rs +++ b/src/geometry/similarity_conversion.rs @@ -1,9 +1,11 @@ +use num::Zero; + 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}; -use crate::base::{DefaultAllocator, MatrixN}; +use crate::base::{DefaultAllocator, MatrixN, Scalar}; use crate::geometry::{ AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation, @@ -180,3 +182,141 @@ where sim.to_homogeneous() } } + +impl + From<[Similarity; 2]> for Similarity +where + N: From<[::Element; 2]>, + R: SimdValue + AbstractRotation + From<[::Element; 2]>, + R::Element: AbstractRotation, + N::Element: Scalar + Zero + Copy, + R::Element: Scalar + Zero + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Similarity; 2]) -> Self { + let iso = Isometry::from([arr[0].isometry.clone(), arr[1].isometry.clone()]); + let scale = N::from([arr[0].scaling(), arr[1].scaling()]); + + Self::from_isometry(iso, scale) + } +} + +impl + From<[Similarity; 4]> for Similarity +where + N: From<[::Element; 4]>, + R: SimdValue + AbstractRotation + From<[::Element; 4]>, + R::Element: AbstractRotation, + N::Element: Scalar + Zero + Copy, + R::Element: Scalar + Zero + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Similarity; 4]) -> Self { + let iso = Isometry::from([ + arr[0].isometry.clone(), + arr[1].isometry.clone(), + arr[2].isometry.clone(), + arr[3].isometry.clone(), + ]); + let scale = N::from([ + arr[0].scaling(), + arr[1].scaling(), + arr[2].scaling(), + arr[3].scaling(), + ]); + + Self::from_isometry(iso, scale) + } +} + +impl + From<[Similarity; 8]> for Similarity +where + N: From<[::Element; 8]>, + R: SimdValue + AbstractRotation + From<[::Element; 8]>, + R::Element: AbstractRotation, + N::Element: Scalar + Zero + Copy, + R::Element: Scalar + Zero + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Similarity; 8]) -> Self { + let iso = Isometry::from([ + arr[0].isometry.clone(), + arr[1].isometry.clone(), + arr[2].isometry.clone(), + arr[3].isometry.clone(), + arr[4].isometry.clone(), + arr[5].isometry.clone(), + arr[6].isometry.clone(), + arr[7].isometry.clone(), + ]); + let scale = N::from([ + arr[0].scaling(), + arr[1].scaling(), + arr[2].scaling(), + arr[3].scaling(), + arr[4].scaling(), + arr[5].scaling(), + arr[6].scaling(), + arr[7].scaling(), + ]); + + Self::from_isometry(iso, scale) + } +} + +impl + From<[Similarity; 16]> for Similarity +where + N: From<[::Element; 16]>, + R: SimdValue + AbstractRotation + From<[::Element; 16]>, + R::Element: AbstractRotation, + N::Element: Scalar + Zero + Copy, + R::Element: Scalar + Zero + Copy, + DefaultAllocator: Allocator + Allocator, +{ + #[inline] + fn from(arr: [Similarity; 16]) -> Self { + let iso = Isometry::from([ + arr[0].isometry.clone(), + arr[1].isometry.clone(), + arr[2].isometry.clone(), + arr[3].isometry.clone(), + arr[4].isometry.clone(), + arr[5].isometry.clone(), + arr[6].isometry.clone(), + arr[7].isometry.clone(), + arr[8].isometry.clone(), + arr[9].isometry.clone(), + arr[10].isometry.clone(), + arr[11].isometry.clone(), + arr[12].isometry.clone(), + arr[13].isometry.clone(), + arr[14].isometry.clone(), + arr[15].isometry.clone(), + ]); + let scale = N::from([ + arr[0].scaling(), + arr[1].scaling(), + arr[2].scaling(), + arr[3].scaling(), + arr[4].scaling(), + arr[5].scaling(), + arr[6].scaling(), + arr[7].scaling(), + arr[8].scaling(), + arr[9].scaling(), + arr[10].scaling(), + arr[11].scaling(), + arr[12].scaling(), + arr[13].scaling(), + arr[14].scaling(), + arr[15].scaling(), + ]); + + Self::from_isometry(iso, scale) + } +} diff --git a/src/geometry/translation_conversion.rs b/src/geometry/translation_conversion.rs index 2aff3ae3..6c43bc04 100644 --- a/src/geometry/translation_conversion.rs +++ b/src/geometry/translation_conversion.rs @@ -175,89 +175,88 @@ where DefaultAllocator: Allocator } } -impl From<[Translation; 2]> +impl From<[Translation; 2]> for Translation where N: From<[::Element; 2]>, - N::Element: Scalar + Copy, + N::Element: Scalar, DefaultAllocator: Allocator + Allocator, - >::Buffer: Copy, { #[inline] fn from(arr: [Translation; 2]) -> Self { - Self::from(VectorN::from([arr[0].vector, arr[1].vector])) + Self::from(VectorN::from([ + arr[0].vector.clone(), + arr[1].vector.clone(), + ])) } } -impl From<[Translation; 4]> +impl From<[Translation; 4]> for Translation where N: From<[::Element; 4]>, - N::Element: Scalar + Copy, + N::Element: Scalar, 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, + arr[0].vector.clone(), + arr[1].vector.clone(), + arr[2].vector.clone(), + arr[3].vector.clone(), ])) } } -impl From<[Translation; 8]> +impl From<[Translation; 8]> for Translation where N: From<[::Element; 8]>, - N::Element: Scalar + Copy, + N::Element: Scalar, 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, + arr[0].vector.clone(), + arr[1].vector.clone(), + arr[2].vector.clone(), + arr[3].vector.clone(), + arr[4].vector.clone(), + arr[5].vector.clone(), + arr[6].vector.clone(), + arr[7].vector.clone(), ])) } } -impl From<[Translation; 16]> +impl From<[Translation; 16]> for Translation where N: From<[::Element; 16]>, - N::Element: Scalar + Copy, + N::Element: Scalar, 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, + arr[0].vector.clone(), + arr[1].vector.clone(), + arr[2].vector.clone(), + arr[3].vector.clone(), + arr[4].vector.clone(), + arr[5].vector.clone(), + arr[6].vector.clone(), + arr[7].vector.clone(), + arr[8].vector.clone(), + arr[9].vector.clone(), + arr[10].vector.clone(), + arr[11].vector.clone(), + arr[12].vector.clone(), + arr[13].vector.clone(), + arr[14].vector.clone(), + arr[15].vector.clone(), ])) } }