Add From<[...; .]> impls for AoSoA Isometry and Similarity.

This commit is contained in:
Sébastien Crozet 2020-03-24 10:16:31 +01:00
parent 26595049c9
commit cdbc9da46c
5 changed files with 369 additions and 104 deletions

View File

@ -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<N, D>,
Owned<N, D>: Deserialize<'de>"))
)]
pub struct Isometry<N: SimdRealField, D: DimName, R>
pub struct Isometry<N: Scalar, D: DimName, R>
where DefaultAllocator: Allocator<N, D>
{
/// The pure rotational part of this isometry.
@ -70,7 +70,7 @@ where
}
}
impl<N: SimdRealField + hash::Hash, D: DimName + hash::Hash, R: hash::Hash> hash::Hash
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash, R: hash::Hash> hash::Hash
for Isometry<N, D, R>
where
DefaultAllocator: Allocator<N, D>,
@ -82,19 +82,16 @@ where
}
}
impl<N: SimdRealField, D: DimName + Copy, R: AbstractRotation<N, D> + Copy> Copy
impl<N: Scalar + Copy, D: DimName + Copy, R: AbstractRotation<N, D> + Copy> Copy
for Isometry<N, D, R>
where
N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D>,
Owned<N, D>: Copy,
{
}
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D> + Clone> Clone for Isometry<N, D, R>
where
N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D>,
impl<N: Scalar, D: DimName, R: AbstractRotation<N, D> + Clone> Clone for Isometry<N, D, R>
where DefaultAllocator: Allocator<N, D>
{
#[inline]
fn clone(&self) -> Self {
@ -102,10 +99,8 @@ where
}
}
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> Isometry<N, D, R>
where
N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D>,
impl<N: Scalar, D: DimName, R: AbstractRotation<N, D>> Isometry<N, D, R>
where DefaultAllocator: Allocator<N, D>
{
/// Creates a new isometry from its rotational and translational parts.
///
@ -128,7 +123,13 @@ where
translation,
}
}
}
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D>> Isometry<N, D, R>
where
N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D>,
{
/// Inverts `self`.
///
/// # Example

View File

@ -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<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R>; 2]>
// for Rotation<N, D>
//where
// N: From<[<N as SimdValue>::Element; 2]>,
// R: From<[R::Element; 2]>,
// N::Element: Scalar + Copy,
// R::Element: Scalar + Copy,
// DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
//{
// #[inline]
// fn from(arr: [Isometry<N::Element, D, R>; 2]) -> Self {
// Self::from_parts(MatrixN::from([
// arr[0].clone().into_inner(),
// arr[1].clone().into_inner(),
// ]))
// }
//}
impl<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 2]>
for Isometry<N, D, R>
where
N: From<[<N as SimdValue>::Element; 2]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 2]>,
R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Copy,
R::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{
#[inline]
fn from(arr: [Isometry<N::Element, D, R::Element>; 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<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 4]>
for Isometry<N, D, R>
where
N: From<[<N as SimdValue>::Element; 4]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 4]>,
R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Copy,
R::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{
#[inline]
fn from(arr: [Isometry<N::Element, D, R::Element>; 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<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 8]>
for Isometry<N, D, R>
where
N: From<[<N as SimdValue>::Element; 8]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 8]>,
R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Copy,
R::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{
#[inline]
fn from(arr: [Isometry<N::Element, D, R::Element>; 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<N: Scalar + PrimitiveSimdValue, D: DimName, R> From<[Isometry<N::Element, D, R::Element>; 16]>
for Isometry<N, D, R>
where
N: From<[<N as SimdValue>::Element; 16]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 16]>,
R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Copy,
R::Element: Scalar + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{
#[inline]
fn from(arr: [Isometry<N::Element, D, R::Element>; 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)
}
}

View File

@ -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<N, D>,
Owned<N, D>: Deserialize<'de>"))
)]
pub struct Similarity<N: SimdRealField, D: DimName, R>
pub struct Similarity<N: Scalar, D: DimName, R>
where DefaultAllocator: Allocator<N, D>
{
/// The part of this similarity that does not include the scaling factor.
@ -46,7 +48,7 @@ where DefaultAllocator: Allocator<N, D>
}
#[cfg(feature = "abomonation-serialize")]
impl<N: SimdRealField, D: DimName, R> Abomonation for Similarity<N, D, R>
impl<N: Scalar, D: DimName, R> Abomonation for Similarity<N, D, R>
where
Isometry<N, D, R>: Abomonation,
DefaultAllocator: Allocator<N, D>,
@ -64,7 +66,7 @@ where
}
}
impl<N: SimdRealField + hash::Hash, D: DimName + hash::Hash, R: hash::Hash> hash::Hash
impl<N: Scalar + hash::Hash, D: DimName + hash::Hash, R: hash::Hash> hash::Hash
for Similarity<N, D, R>
where
DefaultAllocator: Allocator<N, D>,
@ -76,29 +78,25 @@ where
}
}
impl<N: SimdRealField, D: DimName + Copy, R: AbstractRotation<N, D> + Copy> Copy
impl<N: Scalar + Copy + Zero, D: DimName + Copy, R: AbstractRotation<N, D> + Copy> Copy
for Similarity<N, D, R>
where
N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D>,
Owned<N, D>: Copy,
{
}
impl<N: SimdRealField, D: DimName, R: AbstractRotation<N, D> + Clone> Clone for Similarity<N, D, R>
where
N::Element: SimdRealField,
DefaultAllocator: Allocator<N, D>,
impl<N: Scalar + Zero, D: DimName, R: AbstractRotation<N, D> + Clone> Clone for Similarity<N, D, R>
where DefaultAllocator: Allocator<N, D>
{
#[inline]
fn clone(&self) -> Self {
Similarity::from_isometry(self.isometry.clone(), self.scaling)
Similarity::from_isometry(self.isometry.clone(), self.scaling.clone())
}
}
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R>
impl<N: Scalar + Zero, D: DimName, R> Similarity<N, D, R>
where
N::Element: SimdRealField,
R: AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{
@ -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<N: SimdRealField, D: DimName, R> Similarity<N, D, R>
where
N::Element: SimdRealField,
R: AbstractRotation<N, D>,
DefaultAllocator: Allocator<N, D>,
{
/// 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()?"]

View File

@ -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<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R>
From<[Similarity<N::Element, D, R::Element>; 2]> for Similarity<N, D, R>
where
N: From<[<N as SimdValue>::Element; 2]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 2]>,
R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Zero + Copy,
R::Element: Scalar + Zero + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{
#[inline]
fn from(arr: [Similarity<N::Element, D, R::Element>; 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<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R>
From<[Similarity<N::Element, D, R::Element>; 4]> for Similarity<N, D, R>
where
N: From<[<N as SimdValue>::Element; 4]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 4]>,
R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Zero + Copy,
R::Element: Scalar + Zero + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{
#[inline]
fn from(arr: [Similarity<N::Element, D, R::Element>; 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<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R>
From<[Similarity<N::Element, D, R::Element>; 8]> for Similarity<N, D, R>
where
N: From<[<N as SimdValue>::Element; 8]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 8]>,
R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Zero + Copy,
R::Element: Scalar + Zero + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{
#[inline]
fn from(arr: [Similarity<N::Element, D, R::Element>; 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<N: Scalar + Zero + PrimitiveSimdValue, D: DimName, R>
From<[Similarity<N::Element, D, R::Element>; 16]> for Similarity<N, D, R>
where
N: From<[<N as SimdValue>::Element; 16]>,
R: SimdValue + AbstractRotation<N, D> + From<[<R as SimdValue>::Element; 16]>,
R::Element: AbstractRotation<N::Element, D>,
N::Element: Scalar + Zero + Copy,
R::Element: Scalar + Zero + Copy,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
{
#[inline]
fn from(arr: [Similarity<N::Element, D, R::Element>; 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)
}
}

View File

@ -175,89 +175,88 @@ where DefaultAllocator: Allocator<N, D>
}
}
impl<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 2]>
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 2]>
for Translation<N, D>
where
N: From<[<N as simba::simd::SimdValue>::Element; 2]>,
N::Element: Scalar + Copy,
N::Element: Scalar,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy,
{
#[inline]
fn from(arr: [Translation<N::Element, D>; 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<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 4]>
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 4]>
for Translation<N, D>
where
N: From<[<N as simba::simd::SimdValue>::Element; 4]>,
N::Element: Scalar + Copy,
N::Element: Scalar,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy,
{
#[inline]
fn from(arr: [Translation<N::Element, D>; 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<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 8]>
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 8]>
for Translation<N, D>
where
N: From<[<N as simba::simd::SimdValue>::Element; 8]>,
N::Element: Scalar + Copy,
N::Element: Scalar,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy,
{
#[inline]
fn from(arr: [Translation<N::Element, D>; 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<N: Scalar + Copy + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 16]>
impl<N: Scalar + PrimitiveSimdValue, D: DimName> From<[Translation<N::Element, D>; 16]>
for Translation<N, D>
where
N: From<[<N as simba::simd::SimdValue>::Element; 16]>,
N::Element: Scalar + Copy,
N::Element: Scalar,
DefaultAllocator: Allocator<N, D> + Allocator<N::Element, D>,
<DefaultAllocator as Allocator<N::Element, D>>::Buffer: Copy,
{
#[inline]
fn from(arr: [Translation<N::Element, D>; 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(),
]))
}
}