nalgebra/geometry/
scale_conversion.rs

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
13/*
14 * This file provides the following conversions:
15 * =============================================
16 *
17 * Scale -> Scale
18 * Scale -> Transform
19 * Scale -> Matrix (homogeneous)
20 */
21
22impl<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}