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