1use num::{One, Zero};
2
3use simba::scalar::{RealField, SubsetOf, SupersetOf};
4use simba::simd::PrimitiveSimdValue;
5
6use crate::base::allocator::Allocator;
7use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
8use crate::base::{Const, DefaultAllocator, OMatrix, OVector, SVector, Scalar};
9
10use crate::geometry::{Scale, SuperTCategoryOf, TAffine, Transform};
11use crate::Point;
12
13impl<T1, T2, const D: usize> SubsetOf<Scale<T2, D>> for Scale<T1, D>
23where
24 T1: Scalar,
25 T2: Scalar + SupersetOf<T1>,
26{
27 #[inline]
28 fn to_superset(&self) -> Scale<T2, D> {
29 Scale::from(self.vector.to_superset())
30 }
31
32 #[inline]
33 fn is_in_subset(rot: &Scale<T2, D>) -> bool {
34 crate::is_convertible::<_, SVector<T1, D>>(&rot.vector)
35 }
36
37 #[inline]
38 fn from_superset_unchecked(rot: &Scale<T2, D>) -> Self {
39 Scale {
40 vector: rot.vector.to_subset_unchecked(),
41 }
42 }
43}
44
45impl<T1, T2, C, const D: usize> SubsetOf<Transform<T2, C, D>> for Scale<T1, D>
46where
47 T1: RealField,
48 T2: RealField + SupersetOf<T1>,
49 C: SuperTCategoryOf<TAffine>,
50 Const<D>: DimNameAdd<U1>,
51 DefaultAllocator: Allocator<T1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
52 + Allocator<T1, DimNameSum<Const<D>, U1>, U1>
53 + Allocator<T2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
54{
55 #[inline]
56 fn to_superset(&self) -> Transform<T2, C, D> {
57 Transform::from_matrix_unchecked(self.to_homogeneous().to_superset())
58 }
59
60 #[inline]
61 fn is_in_subset(t: &Transform<T2, C, D>) -> bool {
62 <Self as SubsetOf<_>>::is_in_subset(t.matrix())
63 }
64
65 #[inline]
66 fn from_superset_unchecked(t: &Transform<T2, C, D>) -> Self {
67 Self::from_superset_unchecked(t.matrix())
68 }
69}
70
71impl<T1, T2, const D: usize>
72 SubsetOf<OMatrix<T2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>> for Scale<T1, D>
73where
74 T1: RealField,
75 T2: RealField + SupersetOf<T1>,
76 Const<D>: DimNameAdd<U1>,
77 DefaultAllocator: Allocator<T1, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
78 + Allocator<T1, DimNameSum<Const<D>, U1>, U1>
79 + Allocator<T2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
80{
81 #[inline]
82 fn to_superset(&self) -> OMatrix<T2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> {
83 self.to_homogeneous().to_superset()
84 }
85
86 #[inline]
87 fn is_in_subset(m: &OMatrix<T2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>) -> bool {
88 if m[(D, D)] != T2::one() {
89 return false;
90 }
91 for i in 0..D + 1 {
92 for j in 0..D + 1 {
93 if i != j && m[(i, j)] != T2::zero() {
94 return false;
95 }
96 }
97 }
98 true
99 }
100
101 #[inline]
102 fn from_superset_unchecked(
103 m: &OMatrix<T2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
104 ) -> Self {
105 let v = m.fixed_slice::<D, D>(0, 0).diagonal();
106 Self {
107 vector: crate::convert_unchecked(v),
108 }
109 }
110}
111
112impl<T: Scalar + Zero + One, const D: usize> From<Scale<T, D>>
113 for OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
114where
115 Const<D>: DimNameAdd<U1>,
116 DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
117 + Allocator<T, DimNameSum<Const<D>, U1>, U1>
118 + Allocator<T, Const<D>>,
119{
120 #[inline]
121 fn from(t: Scale<T, D>) -> Self {
122 t.to_homogeneous()
123 }
124}
125
126impl<T: Scalar, const D: usize> From<OVector<T, Const<D>>> for Scale<T, D> {
127 #[inline]
128 fn from(vector: OVector<T, Const<D>>) -> Self {
129 Scale { vector }
130 }
131}
132
133impl<T: Scalar, const D: usize> From<[T; D]> for Scale<T, D> {
134 #[inline]
135 fn from(coords: [T; D]) -> Self {
136 Scale {
137 vector: coords.into(),
138 }
139 }
140}
141
142impl<T: Scalar, const D: usize> From<Point<T, D>> for Scale<T, D> {
143 #[inline]
144 fn from(pt: Point<T, D>) -> Self {
145 Scale { vector: pt.coords }
146 }
147}
148
149impl<T: Scalar, const D: usize> From<Scale<T, D>> for [T; D] {
150 #[inline]
151 fn from(t: Scale<T, D>) -> Self {
152 t.vector.into()
153 }
154}
155
156impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Scale<T::Element, D>; 2]> for Scale<T, D>
157where
158 T: From<[<T as simba::simd::SimdValue>::Element; 2]>,
159 T::Element: Scalar,
160{
161 #[inline]
162 fn from(arr: [Scale<T::Element, D>; 2]) -> Self {
163 Self::from(OVector::from([
164 arr[0].vector.clone(),
165 arr[1].vector.clone(),
166 ]))
167 }
168}
169
170impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Scale<T::Element, D>; 4]> for Scale<T, D>
171where
172 T: From<[<T as simba::simd::SimdValue>::Element; 4]>,
173 T::Element: Scalar,
174{
175 #[inline]
176 fn from(arr: [Scale<T::Element, D>; 4]) -> Self {
177 Self::from(OVector::from([
178 arr[0].vector.clone(),
179 arr[1].vector.clone(),
180 arr[2].vector.clone(),
181 arr[3].vector.clone(),
182 ]))
183 }
184}
185
186impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Scale<T::Element, D>; 8]> for Scale<T, D>
187where
188 T: From<[<T as simba::simd::SimdValue>::Element; 8]>,
189 T::Element: Scalar,
190{
191 #[inline]
192 fn from(arr: [Scale<T::Element, D>; 8]) -> Self {
193 Self::from(OVector::from([
194 arr[0].vector.clone(),
195 arr[1].vector.clone(),
196 arr[2].vector.clone(),
197 arr[3].vector.clone(),
198 arr[4].vector.clone(),
199 arr[5].vector.clone(),
200 arr[6].vector.clone(),
201 arr[7].vector.clone(),
202 ]))
203 }
204}
205
206impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Scale<T::Element, D>; 16]>
207 for Scale<T, D>
208where
209 T: From<[<T as simba::simd::SimdValue>::Element; 16]>,
210 T::Element: Scalar,
211{
212 #[inline]
213 fn from(arr: [Scale<T::Element, D>; 16]) -> Self {
214 Self::from(OVector::from([
215 arr[0].vector.clone(),
216 arr[1].vector.clone(),
217 arr[2].vector.clone(),
218 arr[3].vector.clone(),
219 arr[4].vector.clone(),
220 arr[5].vector.clone(),
221 arr[6].vector.clone(),
222 arr[7].vector.clone(),
223 arr[8].vector.clone(),
224 arr[9].vector.clone(),
225 arr[10].vector.clone(),
226 arr[11].vector.clone(),
227 arr[12].vector.clone(),
228 arr[13].vector.clone(),
229 arr[14].vector.clone(),
230 arr[15].vector.clone(),
231 ]))
232 }
233}