1 use num::{One, Zero}; 2 3 use alga::general::{RealField, SubsetOf, SupersetOf}; 4 use alga::linear::Rotation; 5 6 use crate::base::allocator::Allocator; 7 use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; 8 use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN}; 9 10 use crate::geometry::{Isometry, Point, Similarity, SuperTCategoryOf, TAffine, Transform, Translation}; 11 12 /* 13 * This file provides the following conversions: 14 * ============================================= 15 * 16 * Translation -> Translation 17 * Translation -> Isometry 18 * Translation -> Similarity 19 * Translation -> Transform 20 * Translation -> Matrix (homogeneous) 21 */ 22 23 impl<N1, N2, D: DimName> SubsetOf<Translation<N2, D>> for Translation<N1, D> 24 where 25 N1: Scalar, 26 N2: Scalar + SupersetOf<N1>, 27 DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>, 28 { 29 #[inline] to_superset(&self) -> Translation<N2, D>30 fn to_superset(&self) -> Translation<N2, D> { 31 Translation::from(self.vector.to_superset()) 32 } 33 34 #[inline] is_in_subset(rot: &Translation<N2, D>) -> bool35 fn is_in_subset(rot: &Translation<N2, D>) -> bool { 36 crate::is_convertible::<_, VectorN<N1, D>>(&rot.vector) 37 } 38 39 #[inline] from_superset_unchecked(rot: &Translation<N2, D>) -> Self40 unsafe fn from_superset_unchecked(rot: &Translation<N2, D>) -> Self { 41 Translation { 42 vector: rot.vector.to_subset_unchecked(), 43 } 44 } 45 } 46 47 impl<N1, N2, D: DimName, R> SubsetOf<Isometry<N2, D, R>> for Translation<N1, D> 48 where 49 N1: RealField, 50 N2: RealField + SupersetOf<N1>, 51 R: Rotation<Point<N2, D>>, 52 DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>, 53 { 54 #[inline] to_superset(&self) -> Isometry<N2, D, R>55 fn to_superset(&self) -> Isometry<N2, D, R> { 56 Isometry::from_parts(self.to_superset(), R::identity()) 57 } 58 59 #[inline] is_in_subset(iso: &Isometry<N2, D, R>) -> bool60 fn is_in_subset(iso: &Isometry<N2, D, R>) -> bool { 61 iso.rotation == R::identity() 62 } 63 64 #[inline] from_superset_unchecked(iso: &Isometry<N2, D, R>) -> Self65 unsafe fn from_superset_unchecked(iso: &Isometry<N2, D, R>) -> Self { 66 Self::from_superset_unchecked(&iso.translation) 67 } 68 } 69 70 impl<N1, N2, D: DimName, R> SubsetOf<Similarity<N2, D, R>> for Translation<N1, D> 71 where 72 N1: RealField, 73 N2: RealField + SupersetOf<N1>, 74 R: Rotation<Point<N2, D>>, 75 DefaultAllocator: Allocator<N1, D> + Allocator<N2, D>, 76 { 77 #[inline] to_superset(&self) -> Similarity<N2, D, R>78 fn to_superset(&self) -> Similarity<N2, D, R> { 79 Similarity::from_parts(self.to_superset(), R::identity(), N2::one()) 80 } 81 82 #[inline] is_in_subset(sim: &Similarity<N2, D, R>) -> bool83 fn is_in_subset(sim: &Similarity<N2, D, R>) -> bool { 84 sim.isometry.rotation == R::identity() && sim.scaling() == N2::one() 85 } 86 87 #[inline] from_superset_unchecked(sim: &Similarity<N2, D, R>) -> Self88 unsafe fn from_superset_unchecked(sim: &Similarity<N2, D, R>) -> Self { 89 Self::from_superset_unchecked(&sim.isometry.translation) 90 } 91 } 92 93 impl<N1, N2, D, C> SubsetOf<Transform<N2, D, C>> for Translation<N1, D> 94 where 95 N1: RealField, 96 N2: RealField + SupersetOf<N1>, 97 C: SuperTCategoryOf<TAffine>, 98 D: DimNameAdd<U1>, 99 DefaultAllocator: Allocator<N1, D> 100 + Allocator<N2, D> 101 + Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>> 102 + Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>, 103 { 104 #[inline] to_superset(&self) -> Transform<N2, D, C>105 fn to_superset(&self) -> Transform<N2, D, C> { 106 Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) 107 } 108 109 #[inline] is_in_subset(t: &Transform<N2, D, C>) -> bool110 fn is_in_subset(t: &Transform<N2, D, C>) -> bool { 111 <Self as SubsetOf<_>>::is_in_subset(t.matrix()) 112 } 113 114 #[inline] from_superset_unchecked(t: &Transform<N2, D, C>) -> Self115 unsafe fn from_superset_unchecked(t: &Transform<N2, D, C>) -> Self { 116 Self::from_superset_unchecked(t.matrix()) 117 } 118 } 119 120 impl<N1, N2, D> SubsetOf<MatrixN<N2, DimNameSum<D, U1>>> for Translation<N1, D> 121 where 122 N1: RealField, 123 N2: RealField + SupersetOf<N1>, 124 D: DimNameAdd<U1>, 125 DefaultAllocator: Allocator<N1, D> 126 + Allocator<N2, D> 127 + Allocator<N1, DimNameSum<D, U1>, DimNameSum<D, U1>> 128 + Allocator<N2, DimNameSum<D, U1>, DimNameSum<D, U1>>, 129 { 130 #[inline] to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>>131 fn to_superset(&self) -> MatrixN<N2, DimNameSum<D, U1>> { 132 self.to_homogeneous().to_superset() 133 } 134 135 #[inline] is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool136 fn is_in_subset(m: &MatrixN<N2, DimNameSum<D, U1>>) -> bool { 137 let id = m.fixed_slice::<DimNameSum<D, U1>, D>(0, 0); 138 139 // Scalar types agree. 140 m.iter().all(|e| SupersetOf::<N1>::is_in_subset(e)) && 141 // The block part does nothing. 142 id.is_identity(N2::zero()) && 143 // The normalization factor is one. 144 m[(D::dim(), D::dim())] == N2::one() 145 } 146 147 #[inline] from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self148 unsafe fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self { 149 let t = m.fixed_slice::<D, U1>(0, D::dim()); 150 Self { 151 vector: crate::convert_unchecked(t.into_owned()), 152 } 153 } 154 } 155 156 impl<N: Scalar + Zero + One, D: DimName> From<Translation<N, D>> for MatrixN<N, DimNameSum<D, U1>> 157 where 158 D: DimNameAdd<U1>, 159 DefaultAllocator: Allocator<N, D> + Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>, 160 { 161 #[inline] from(t: Translation<N, D>) -> Self162 fn from(t: Translation<N, D>) -> Self { 163 t.to_homogeneous() 164 } 165 } 166 167 impl<N: Scalar, D: DimName> From<VectorN<N, D>> for Translation<N, D> 168 where DefaultAllocator: Allocator<N, D> 169 { 170 #[inline] from(vector: VectorN<N, D>) -> Self171 fn from(vector: VectorN<N, D>) -> Self { 172 Translation { vector } 173 } 174 } 175