use simba::scalar::{RealField, SubsetOf, SupersetOf}; use crate::base::allocator::Allocator; use crate::base::dimension::{DimMin, DimName, DimNameAdd, DimNameSum, U1}; use crate::base::{DefaultAllocator, MatrixN}; use crate::geometry::{ AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation, }; /* * This file provides the following conversions: * ============================================= * * Isometry -> Isometry * Isometry -> Similarity * Isometry -> Transform * Isometry -> Matrix (homogeneous) */ impl SubsetOf> for Isometry where N1: RealField, N2: RealField + SupersetOf, R1: AbstractRotation + SubsetOf, R2: AbstractRotation, DefaultAllocator: Allocator + Allocator, { #[inline] fn to_superset(&self) -> Isometry { Isometry::from_parts(self.translation.to_superset(), self.rotation.to_superset()) } #[inline] fn is_in_subset(iso: &Isometry) -> bool { crate::is_convertible::<_, Translation>(&iso.translation) && crate::is_convertible::<_, R1>(&iso.rotation) } #[inline] fn from_superset_unchecked(iso: &Isometry) -> Self { Isometry::from_parts( iso.translation.to_subset_unchecked(), iso.rotation.to_subset_unchecked(), ) } } impl SubsetOf> for Isometry where N1: RealField, N2: RealField + SupersetOf, R1: AbstractRotation + SubsetOf, R2: AbstractRotation, DefaultAllocator: Allocator + Allocator, { #[inline] fn to_superset(&self) -> Similarity { Similarity::from_isometry(self.to_superset(), N2::one()) } #[inline] fn is_in_subset(sim: &Similarity) -> bool { crate::is_convertible::<_, Isometry>(&sim.isometry) && sim.scaling() == N2::one() } #[inline] fn from_superset_unchecked(sim: &Similarity) -> Self { crate::convert_ref_unchecked(&sim.isometry) } } impl SubsetOf> for Isometry where N1: RealField, N2: RealField + SupersetOf, C: SuperTCategoryOf, R: AbstractRotation + SubsetOf>> + SubsetOf>>, D: DimNameAdd + DimMin, // needed by .is_special_orthogonal() DefaultAllocator: Allocator + Allocator + Allocator, DimNameSum> + Allocator, DimNameSum> + Allocator, DimNameSum> + Allocator<(usize, usize), D> + Allocator + Allocator, { #[inline] fn to_superset(&self) -> Transform { Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) } #[inline] fn is_in_subset(t: &Transform) -> bool { >::is_in_subset(t.matrix()) } #[inline] fn from_superset_unchecked(t: &Transform) -> Self { Self::from_superset_unchecked(t.matrix()) } } impl SubsetOf>> for Isometry where N1: RealField, N2: RealField + SupersetOf, R: AbstractRotation + SubsetOf>> + SubsetOf>>, D: DimNameAdd + DimMin, // needed by .is_special_orthogonal() DefaultAllocator: Allocator + Allocator + Allocator, DimNameSum> + Allocator, DimNameSum> + Allocator, DimNameSum> + Allocator<(usize, usize), D> + Allocator + Allocator, { #[inline] fn to_superset(&self) -> MatrixN> { self.to_homogeneous().to_superset() } #[inline] fn is_in_subset(m: &MatrixN>) -> bool { let rot = m.fixed_slice::(0, 0); let bottom = m.fixed_slice::(D::dim(), 0); // Scalar types agree. m.iter().all(|e| SupersetOf::::is_in_subset(e)) && // The block part is a rotation. rot.is_special_orthogonal(N2::default_epsilon() * crate::convert(100.0)) && // The bottom row is (0, 0, ..., 1) bottom.iter().all(|e| e.is_zero()) && m[(D::dim(), D::dim())] == N2::one() } #[inline] fn from_superset_unchecked(m: &MatrixN>) -> Self { let t = m.fixed_slice::(0, D::dim()).into_owned(); let t = Translation { vector: crate::convert_unchecked(t), }; Self::from_parts(t, crate::convert_unchecked(m.clone_owned())) } } impl From> for MatrixN> where D: DimNameAdd, R: SubsetOf>>, DefaultAllocator: Allocator, DimNameSum> + Allocator, { #[inline] fn from(iso: Isometry) -> Self { iso.to_homogeneous() } }