Skip to main content

geo_nd/
transformation_farray2.rs

1use crate::{
2    FArray, FArray2, Float, QArray, Quaternion, SqMatrix, SqMatrix3, SqMatrix4, Transform,
3    Vector3, Vector4,
4};
5
6impl<F> Transform<F> for FArray2<F, 4, 16>
7where
8    F: Float,
9    QArray<F>: Quaternion<F>,
10    FArray2<F, 4, 16>: SqMatrix4<F> + std::ops::Mul<FArray<F, 4>, Output = FArray<F, 4>>,
11    FArray<F, 3>: Vector3<F>,
12    FArray<F, 4>: Vector4<F>,
13{
14    const UNIFORM_SCALING: bool = false;
15    type Vec3 = FArray<F, 3>;
16    type Vec4 = FArray<F, 4>;
17    type Quat = QArray<F>;
18    fn of_trs<A: AsRef<[F; 3]>>(t: A, r: Self::Quat, s: A) -> Option<Self> {
19        let t = t.as_ref();
20        let mut m = Self::default();
21        r.set_rotation4(&mut m);
22        m.scale_by(s);
23        m[3] = t[0];
24        m[7] = t[1];
25        m[11] = t[2];
26        Some(m)
27    }
28
29    fn of_trsu<A: AsRef<[F; 3]>>(t: A, r: Self::Quat, s: F) -> Self {
30        let t = t.as_ref();
31        let mut m = Self::default();
32        r.set_rotation4(&mut m);
33        m.scale_uniform_by(s);
34        m[3] = t[0];
35        m[7] = t[1];
36        m[11] = t[2];
37        m
38    }
39
40    fn is_uniform_scale(&self) -> bool {
41        false
42    }
43
44    fn scale(&self) -> Option<Self::Vec3> {
45        None
46    }
47
48    fn uniform_scale(&self) -> Option<F> {
49        None
50    }
51
52    fn translation(&self) -> Self::Vec3 {
53        [self[3], self[7], self[11]].into()
54    }
55
56    fn rotation(&self) -> Option<Self::Quat> {
57        None
58    }
59
60    fn set_identity(&mut self) {
61        *self = Self::identity();
62    }
63
64    fn set_scale<A: AsRef<[F; 3]>>(&mut self, _scale: A) -> bool {
65        false
66    }
67
68    fn set_uniform_scale(&mut self, scale: F) {
69        let s = self.determinant();
70        if s.abs() > F::epsilon() {
71            self.scale_uniform_by(scale / s);
72        }
73    }
74
75    fn set_translation<A: AsRef<[F; 3]>>(&mut self, translation: A) {
76        let t = translation.as_ref();
77        self[3] = t[0];
78        self[7] = t[1];
79        self[11] = t[2];
80    }
81
82    fn set_rotation(&mut self, rotation: Self::Quat) {
83        let s = self.determinant();
84        if s.abs() > F::epsilon() {
85            let mut m: FArray2<F, 4, 16> = [F::ZERO; 16].into();
86            rotation.set_rotation4(&mut m);
87            m.scale_uniform_by(s);
88            m[3] = self[3];
89            m[7] = self[7];
90            m[11] = self[11];
91        }
92    }
93
94    fn scale_uniform_by(&mut self, scale: F) {
95        for c in self.iter_mut().take(12) {
96            *c = *c * scale;
97        }
98    }
99
100    fn scale_by<A: AsRef<[F; 3]>>(&mut self, scale: A) -> bool {
101        for (i, c) in self.iter_mut().take(12).enumerate() {
102            *c = *c * scale.as_ref()[i / 4];
103        }
104        true
105    }
106
107    fn translate_by<A: AsRef<[F; 3]>>(&mut self, translation: A, scale: F) {
108        let translation = translation.as_ref();
109        for i in 0..3 {
110            self[i * 4 + 3] = self[i * 4 + 3] + translation[i] * scale;
111        }
112    }
113
114    fn rotate_by(&mut self, quaternion: &Self::Quat) {
115        let mut m: Self = [F::ZERO; 16].into();
116        quaternion.set_rotation4(&mut m);
117        *self = *self * m;
118    }
119
120    fn transform_by<T: Transform<F, Quat = Self::Quat>>(&mut self, transformer: &T) -> bool {
121        let m = transformer.as_mat4::<Self>();
122        *self = *self * m;
123        true
124    }
125
126    fn inverse_transform(&self) -> Option<Self> {
127        self.opt_inverse()
128    }
129
130    fn apply3_arr(&self, other: &[F; 3]) -> [F; 3] {
131        let v = [other[0], other[1], other[2], F::ONE];
132        let v = self.mul_vec_arr(&v);
133        [v[0], v[1], v[2]]
134    }
135
136    fn apply4_arr(&self, other: &[F; 4]) -> [F; 4] {
137        self.mul_vec_arr(other)
138    }
139
140    fn as_mat3<M: SqMatrix3<F>>(&self) -> M {
141        let mut m = M::default();
142        for (i, c) in m.iter_mut().enumerate() {
143            *c = self[i + i / 3];
144        }
145        m
146    }
147
148    fn as_mat4<M: SqMatrix4<F>>(&self) -> M {
149        self.as_ref().into()
150    }
151}