1use serde::Serialize;
3
4use crate::FArray;
5use crate::{Float, QArray, Quaternion, SqMatrix4, Transform, Vector};
6
7#[derive(Clone, Copy, Debug)] pub struct FQArrayTrans<F>
15where
16 F: Float + Serialize,
17 FArray<F, 4>: Vector<F, 4>,
18 QArray<F>: Quaternion<F>,
19{
20 quat: QArray<F>,
22 trans_scale: [F; 4],
24}
25
26macro_rules! fqarray_basic_traits {
28 { $f:ty, $ty:ty } => {
29
30 impl std::default::Default for $ty
32 {
33 fn default() -> Self {
34 use num_traits::{One, Zero};
35 Self {
36 quat: QArray::default(),
37 trans_scale: [<$f>::zero(), <$f>
38 ::zero(), <$f>::zero(), <$f>::one()]
39 }
40 }
41 }
42
43 impl std::fmt::Display for $ty
45 {
46 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
47 write!(
48 f,
49 "trans[+({},{},{}) rot{} *{}]",
50 self.trans_scale[0],
51 self.trans_scale[1],
52 self.trans_scale[2],
53 self.quat,
54 self.trans_scale[3],
55 )
56 }
57 }
58 }
59}
60
61macro_rules! fqarray_transform_trait {
63 { $f:ty, $v:ty, $q:ty, $ty:ty } => {
64
65 impl Transform<$f, $v, $q> for $ty
67 {
68 fn of_trs(t: $v, r: $q, s: $f) -> Self {
72 Self {
73 quat: r,
74 trans_scale: [t[0], t[1], t[2], s],
75 }
76 }
77
78 fn scale(&self) -> $f {
81 self.trans_scale[3]
82 }
83
84 fn translation(&self) -> $v {
87 [
88 self.trans_scale[0],
89 self.trans_scale[1],
90 self.trans_scale[2],
91 ]
92 .into()
93 }
94
95 fn rotation(&self) -> QArray<$f> {
98 self.quat
99 }
100
101 fn inverse(&self) -> Self {
104 use num_traits::{Float, One};
105 let scale = self.trans_scale[3];
106 if scale.abs() < <$f>::epsilon() {
107 Self::default()
108 } else {
109 let scale = <$f>::one() / scale;
110 let trans: $v = [
111 self.trans_scale[0],
112 self.trans_scale[1],
113 self.trans_scale[2],
114 ]
115 .into();
116 let iquat = self.quat.conjugate();
117 let trans = iquat.apply3(&trans);
118 let trans = trans * -scale;
119 Self::of_trs(trans, iquat, scale)
120 }
121 }
122
123 fn invert(&mut self) {
126 *self = self.inverse();
127 }
128
129 fn as_mat<M: SqMatrix4<$f>>(&self) -> M {
132 let mut m = M::default();
133 self.quat.set_rotation4(&mut m);
134 m *= self.trans_scale[3];
135 m[3] = self.trans_scale[0];
136 m[7] = self.trans_scale[1];
137 m[11] = self.trans_scale[2];
138 m
139 }
140 }
141 }
142}
143
144macro_rules! fqarray_traits {
147 { $f:ty, $v:ty, $q:ty, $ty:ty } => {
148 fqarray_basic_traits! {$f, $ty}
149 fqarray_transform_trait! {$f, $v, $q, $ty}
150 }
151}
152
153fqarray_traits! {f32, FArray<f32,3>, QArray<f32>, FQArrayTrans<f32>}
154fqarray_traits! {f64, FArray<f64,3>, QArray<f64>, FQArrayTrans<f64>}