use num::Zero; use alga::general::{SubsetOf, SupersetOf, Real}; use alga::linear::Rotation as AlgaRotation; use core::{ColumnVector, SquareMatrix}; use core::dimension::{U1, U3, U4}; use core::storage::OwnedStorage; use core::allocator::{Allocator, OwnedAllocator}; use geometry::{PointBase, QuaternionBase, UnitQuaternionBase, OwnedUnitQuaternionBase, RotationBase, OwnedRotation, IsometryBase, SimilarityBase, TransformBase, SuperTCategoryOf, TAffine, TranslationBase}; /* * This file provides the following conversions: * ============================================= * * Quaternion -> Quaternion * UnitQuaternion -> UnitQuaternion * UnitQuaternion -> RotationBase * UnitQuaternion -> IsometryBase * UnitQuaternion -> SimilarityBase * UnitQuaternion -> TransformBase * UnitQuaternion -> Matrix (homogeneous) * * NOTE: * UnitQuaternion -> Quaternion is already provided by: Unit -> T */ impl SubsetOf> for QuaternionBase where N1: Real, N2: Real + SupersetOf, SA: OwnedStorage, SB: OwnedStorage, SA::Alloc: OwnedAllocator, SB::Alloc: OwnedAllocator { #[inline] fn to_superset(&self) -> QuaternionBase { QuaternionBase::from_vector(self.coords.to_superset()) } #[inline] fn is_in_subset(q: &QuaternionBase) -> bool { ::is_convertible::<_, ColumnVector>(&q.coords) } #[inline] unsafe fn from_superset_unchecked(q: &QuaternionBase) -> Self { Self::from_vector(q.coords.to_subset_unchecked()) } } impl SubsetOf> for UnitQuaternionBase where N1: Real, N2: Real + SupersetOf, SA: OwnedStorage, SB: OwnedStorage, SA::Alloc: OwnedAllocator, SB::Alloc: OwnedAllocator { #[inline] fn to_superset(&self) -> UnitQuaternionBase { UnitQuaternionBase::new_unchecked(self.as_ref().to_superset()) } #[inline] fn is_in_subset(uq: &UnitQuaternionBase) -> bool { ::is_convertible::<_, QuaternionBase>(uq.as_ref()) } #[inline] unsafe fn from_superset_unchecked(uq: &UnitQuaternionBase) -> Self { Self::new_unchecked(::convert_ref_unchecked(uq.as_ref())) } } impl SubsetOf> for UnitQuaternionBase where N1: Real, N2: Real + SupersetOf, SA: OwnedStorage, SB: OwnedStorage, SA::Alloc: OwnedAllocator + Allocator, SB::Alloc: OwnedAllocator + Allocator + Allocator { #[inline] fn to_superset(&self) -> RotationBase { let q: OwnedUnitQuaternionBase = self.to_superset(); q.to_rotation_matrix() } #[inline] fn is_in_subset(rot: &RotationBase) -> bool { ::is_convertible::<_, OwnedRotation>(rot) } #[inline] unsafe fn from_superset_unchecked(rot: &RotationBase) -> Self { let q = OwnedUnitQuaternionBase::::from_rotation_matrix(rot); ::convert_unchecked(q) } } impl SubsetOf> for UnitQuaternionBase where N1: Real, N2: Real + SupersetOf, SA: OwnedStorage, SB: OwnedStorage, R: AlgaRotation> + SupersetOf>, SA::Alloc: OwnedAllocator, SB::Alloc: OwnedAllocator { #[inline] fn to_superset(&self) -> IsometryBase { IsometryBase::from_parts(TranslationBase::identity(), ::convert_ref(self)) } #[inline] fn is_in_subset(iso: &IsometryBase) -> bool { iso.translation.vector.is_zero() } #[inline] unsafe fn from_superset_unchecked(iso: &IsometryBase) -> Self { ::convert_ref_unchecked(&iso.rotation) } } impl SubsetOf> for UnitQuaternionBase where N1: Real, N2: Real + SupersetOf, SA: OwnedStorage, SB: OwnedStorage, R: AlgaRotation> + SupersetOf>, SA::Alloc: OwnedAllocator, SB::Alloc: OwnedAllocator { #[inline] fn to_superset(&self) -> SimilarityBase { SimilarityBase::from_isometry(::convert_ref(self), N2::one()) } #[inline] fn is_in_subset(sim: &SimilarityBase) -> bool { sim.isometry.translation.vector.is_zero() && sim.scaling() == N2::one() } #[inline] unsafe fn from_superset_unchecked(sim: &SimilarityBase) -> Self { ::convert_ref_unchecked(&sim.isometry) } } impl SubsetOf> for UnitQuaternionBase where N1: Real, N2: Real + SupersetOf, SA: OwnedStorage, SB: OwnedStorage, C: SuperTCategoryOf, SA::Alloc: OwnedAllocator + Allocator + Allocator + Allocator, SB::Alloc: OwnedAllocator + Allocator + Allocator { #[inline] fn to_superset(&self) -> TransformBase { TransformBase::from_matrix_unchecked(self.to_homogeneous().to_superset()) } #[inline] fn is_in_subset(t: &TransformBase) -> bool { >::is_in_subset(t.matrix()) } #[inline] unsafe fn from_superset_unchecked(t: &TransformBase) -> Self { Self::from_superset_unchecked(t.matrix()) } } impl SubsetOf> for UnitQuaternionBase where N1: Real, N2: Real + SupersetOf, SA: OwnedStorage, SB: OwnedStorage, SA::Alloc: OwnedAllocator + Allocator + Allocator + Allocator, SB::Alloc: OwnedAllocator + Allocator + Allocator { #[inline] fn to_superset(&self) -> SquareMatrix { self.to_homogeneous().to_superset() } #[inline] fn is_in_subset(m: &SquareMatrix) -> bool { ::is_convertible::<_, OwnedRotation>(m) } #[inline] unsafe fn from_superset_unchecked(m: &SquareMatrix) -> Self { let rot: OwnedRotation = ::convert_ref_unchecked(m); Self::from_rotation_matrix(&rot) } }