Clutter Engine 0.0.1
Loading...
Searching...
No Matches
dual_quaternion.inl
1
2
3#include "../geometric.hpp"
4#include <limits>
5
6namespace glm
7{
8 // -- Component accesses --
9
10 template<typename T, qualifier Q>
11 GLM_FUNC_QUALIFIER typename tdualquat<T, Q>::part_type & tdualquat<T, Q>::operator[](typename tdualquat<T, Q>::length_type i)
12 {
13 assert(i >= 0 && i < this->length());
14 return (&real)[i];
15 }
16
17 template<typename T, qualifier Q>
18 GLM_FUNC_QUALIFIER typename tdualquat<T, Q>::part_type const& tdualquat<T, Q>::operator[](typename tdualquat<T, Q>::length_type i) const
19 {
20 assert(i >= 0 && i < this->length());
21 return (&real)[i];
22 }
23
24 // -- Implicit basic constructors --
25
26# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE
27 template<typename T, qualifier Q>
28 GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat()
29# if GLM_CONFIG_DEFAULTED_FUNCTIONS != GLM_DISABLE
30 : real(qua<T, Q>())
31 , dual(qua<T, Q>(0, 0, 0, 0))
32# endif
33 {}
34
35 template<typename T, qualifier Q>
36 GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(tdualquat<T, Q> const& d)
37 : real(d.real)
38 , dual(d.dual)
39 {}
40# endif
41
42 template<typename T, qualifier Q>
43 template<qualifier P>
44 GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(tdualquat<T, P> const& d)
45 : real(d.real)
46 , dual(d.dual)
47 {}
48
49 // -- Explicit basic constructors --
50
51 template<typename T, qualifier Q>
52 GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(qua<T, Q> const& r)
53 : real(r), dual(qua<T, Q>(0, 0, 0, 0))
54 {}
55
56 template<typename T, qualifier Q>
57 GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(qua<T, Q> const& q, vec<3, T, Q> const& p)
58 : real(q), dual(
59 T(-0.5) * ( p.x*q.x + p.y*q.y + p.z*q.z),
60 T(+0.5) * ( p.x*q.w + p.y*q.z - p.z*q.y),
61 T(+0.5) * (-p.x*q.z + p.y*q.w + p.z*q.x),
62 T(+0.5) * ( p.x*q.y - p.y*q.x + p.z*q.w))
63 {}
64
65 template<typename T, qualifier Q>
66 GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(qua<T, Q> const& r, qua<T, Q> const& d)
67 : real(r), dual(d)
68 {}
69
70 // -- Conversion constructors --
71
72 template<typename T, qualifier Q>
73 template<typename U, qualifier P>
74 GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(tdualquat<U, P> const& q)
75 : real(q.real)
76 , dual(q.dual)
77 {}
78
79 template<typename T, qualifier Q>
80 GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(mat<2, 4, T, Q> const& m)
81 {
82 *this = dualquat_cast(m);
83 }
84
85 template<typename T, qualifier Q>
86 GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, Q>::tdualquat(mat<3, 4, T, Q> const& m)
87 {
88 *this = dualquat_cast(m);
89 }
90
91 // -- Unary arithmetic operators --
92
93# if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE
94 template<typename T, qualifier Q>
95 GLM_FUNC_QUALIFIER tdualquat<T, Q> & tdualquat<T, Q>::operator=(tdualquat<T, Q> const& q)
96 {
97 this->real = q.real;
98 this->dual = q.dual;
99 return *this;
100 }
101# endif
102
103 template<typename T, qualifier Q>
104 template<typename U>
105 GLM_FUNC_QUALIFIER tdualquat<T, Q> & tdualquat<T, Q>::operator=(tdualquat<U, Q> const& q)
106 {
107 this->real = q.real;
108 this->dual = q.dual;
109 return *this;
110 }
111
112 template<typename T, qualifier Q>
113 template<typename U>
114 GLM_FUNC_QUALIFIER tdualquat<T, Q> & tdualquat<T, Q>::operator*=(U s)
115 {
116 this->real *= static_cast<T>(s);
117 this->dual *= static_cast<T>(s);
118 return *this;
119 }
120
121 template<typename T, qualifier Q>
122 template<typename U>
123 GLM_FUNC_QUALIFIER tdualquat<T, Q> & tdualquat<T, Q>::operator/=(U s)
124 {
125 this->real /= static_cast<T>(s);
126 this->dual /= static_cast<T>(s);
127 return *this;
128 }
129
130 // -- Unary bit operators --
131
132 template<typename T, qualifier Q>
133 GLM_FUNC_QUALIFIER tdualquat<T, Q> operator+(tdualquat<T, Q> const& q)
134 {
135 return q;
136 }
137
138 template<typename T, qualifier Q>
139 GLM_FUNC_QUALIFIER tdualquat<T, Q> operator-(tdualquat<T, Q> const& q)
140 {
141 return tdualquat<T, Q>(-q.real, -q.dual);
142 }
143
144 // -- Binary operators --
145
146 template<typename T, qualifier Q>
147 GLM_FUNC_QUALIFIER tdualquat<T, Q> operator+(tdualquat<T, Q> const& q, tdualquat<T, Q> const& p)
148 {
149 return tdualquat<T, Q>(q.real + p.real,q.dual + p.dual);
150 }
151
152 template<typename T, qualifier Q>
153 GLM_FUNC_QUALIFIER tdualquat<T, Q> operator*(tdualquat<T, Q> const& p, tdualquat<T, Q> const& o)
154 {
155 return tdualquat<T, Q>(p.real * o.real,p.real * o.dual + p.dual * o.real);
156 }
157
158 template<typename T, qualifier Q>
159 GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(tdualquat<T, Q> const& q, vec<3, T, Q> const& v)
160 {
161 vec<3, T, Q> const real_v3(q.real.x,q.real.y,q.real.z);
162 vec<3, T, Q> const dual_v3(q.dual.x,q.dual.y,q.dual.z);
163 return (cross(real_v3, cross(real_v3,v) + v * q.real.w + dual_v3) + dual_v3 * q.real.w - real_v3 * q.dual.w) * T(2) + v;
164 }
165
166 template<typename T, qualifier Q>
167 GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(vec<3, T, Q> const& v, tdualquat<T, Q> const& q)
168 {
169 return glm::inverse(q) * v;
170 }
171
172 template<typename T, qualifier Q>
173 GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(tdualquat<T, Q> const& q, vec<4, T, Q> const& v)
174 {
175 return vec<4, T, Q>(q * vec<3, T, Q>(v), v.w);
176 }
177
178 template<typename T, qualifier Q>
179 GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(vec<4, T, Q> const& v, tdualquat<T, Q> const& q)
180 {
181 return glm::inverse(q) * v;
182 }
183
184 template<typename T, qualifier Q>
185 GLM_FUNC_QUALIFIER tdualquat<T, Q> operator*(tdualquat<T, Q> const& q, T const& s)
186 {
187 return tdualquat<T, Q>(q.real * s, q.dual * s);
188 }
189
190 template<typename T, qualifier Q>
191 GLM_FUNC_QUALIFIER tdualquat<T, Q> operator*(T const& s, tdualquat<T, Q> const& q)
192 {
193 return q * s;
194 }
195
196 template<typename T, qualifier Q>
197 GLM_FUNC_QUALIFIER tdualquat<T, Q> operator/(tdualquat<T, Q> const& q, T const& s)
198 {
199 return tdualquat<T, Q>(q.real / s, q.dual / s);
200 }
201
202 // -- Boolean operators --
203
204 template<typename T, qualifier Q>
205 GLM_FUNC_QUALIFIER bool operator==(tdualquat<T, Q> const& q1, tdualquat<T, Q> const& q2)
206 {
207 return (q1.real == q2.real) && (q1.dual == q2.dual);
208 }
209
210 template<typename T, qualifier Q>
211 GLM_FUNC_QUALIFIER bool operator!=(tdualquat<T, Q> const& q1, tdualquat<T, Q> const& q2)
212 {
213 return (q1.real != q2.real) || (q1.dual != q2.dual);
214 }
215
216 // -- Operations --
217
218 template<typename T, qualifier Q>
220 {
221 return tdualquat<T, Q>(
222 qua<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)),
223 qua<T, Q>(static_cast<T>(0), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)));
224 }
225
226 template<typename T, qualifier Q>
227 GLM_FUNC_QUALIFIER tdualquat<T, Q> normalize(tdualquat<T, Q> const& q)
228 {
229 return q / length(q.real);
230 }
231
232 template<typename T, qualifier Q>
233 GLM_FUNC_QUALIFIER tdualquat<T, Q> lerp(tdualquat<T, Q> const& x, tdualquat<T, Q> const& y, T const& a)
234 {
235 // Dual Quaternion Linear blend aka DLB:
236 // Lerp is only defined in [0, 1]
237 assert(a >= static_cast<T>(0));
238 assert(a <= static_cast<T>(1));
239 T const k = dot(x.real,y.real) < static_cast<T>(0) ? -a : a;
240 T const one(1);
241 return tdualquat<T, Q>(x * (one - a) + y * k);
242 }
243
244 template<typename T, qualifier Q>
245 GLM_FUNC_QUALIFIER tdualquat<T, Q> inverse(tdualquat<T, Q> const& q)
246 {
247 const glm::qua<T, Q> real = conjugate(q.real);
248 const glm::qua<T, Q> dual = conjugate(q.dual);
249 return tdualquat<T, Q>(real, dual + (real * (-2.0f * dot(real,dual))));
250 }
251
252 template<typename T, qualifier Q>
253 GLM_FUNC_QUALIFIER mat<2, 4, T, Q> mat2x4_cast(tdualquat<T, Q> const& x)
254 {
255 return mat<2, 4, T, Q>( x[0].x, x[0].y, x[0].z, x[0].w, x[1].x, x[1].y, x[1].z, x[1].w );
256 }
257
258 template<typename T, qualifier Q>
259 GLM_FUNC_QUALIFIER mat<3, 4, T, Q> mat3x4_cast(tdualquat<T, Q> const& x)
260 {
261 qua<T, Q> r = x.real / length2(x.real);
262
263 qua<T, Q> const rr(r.w * x.real.w, r.x * x.real.x, r.y * x.real.y, r.z * x.real.z);
264 r *= static_cast<T>(2);
265
266 T const xy = r.x * x.real.y;
267 T const xz = r.x * x.real.z;
268 T const yz = r.y * x.real.z;
269 T const wx = r.w * x.real.x;
270 T const wy = r.w * x.real.y;
271 T const wz = r.w * x.real.z;
272
273 vec<4, T, Q> const a(
274 rr.w + rr.x - rr.y - rr.z,
275 xy - wz,
276 xz + wy,
277 -(x.dual.w * r.x - x.dual.x * r.w + x.dual.y * r.z - x.dual.z * r.y));
278
279 vec<4, T, Q> const b(
280 xy + wz,
281 rr.w + rr.y - rr.x - rr.z,
282 yz - wx,
283 -(x.dual.w * r.y - x.dual.x * r.z - x.dual.y * r.w + x.dual.z * r.x));
284
285 vec<4, T, Q> const c(
286 xz - wy,
287 yz + wx,
288 rr.w + rr.z - rr.x - rr.y,
289 -(x.dual.w * r.z + x.dual.x * r.y - x.dual.y * r.x - x.dual.z * r.w));
290
291 return mat<3, 4, T, Q>(a, b, c);
292 }
293
294 template<typename T, qualifier Q>
295 GLM_FUNC_QUALIFIER tdualquat<T, Q> dualquat_cast(mat<2, 4, T, Q> const& x)
296 {
297 return tdualquat<T, Q>(
298 qua<T, Q>( x[0].w, x[0].x, x[0].y, x[0].z ),
299 qua<T, Q>( x[1].w, x[1].x, x[1].y, x[1].z ));
300 }
301
302 template<typename T, qualifier Q>
303 GLM_FUNC_QUALIFIER tdualquat<T, Q> dualquat_cast(mat<3, 4, T, Q> const& x)
304 {
305 qua<T, Q> real;
306
307 T const trace = x[0].x + x[1].y + x[2].z;
308 if(trace > static_cast<T>(0))
309 {
310 T const r = sqrt(T(1) + trace);
311 T const invr = static_cast<T>(0.5) / r;
312 real.w = static_cast<T>(0.5) * r;
313 real.x = (x[2].y - x[1].z) * invr;
314 real.y = (x[0].z - x[2].x) * invr;
315 real.z = (x[1].x - x[0].y) * invr;
316 }
317 else if(x[0].x > x[1].y && x[0].x > x[2].z)
318 {
319 T const r = sqrt(T(1) + x[0].x - x[1].y - x[2].z);
320 T const invr = static_cast<T>(0.5) / r;
321 real.x = static_cast<T>(0.5)*r;
322 real.y = (x[1].x + x[0].y) * invr;
323 real.z = (x[0].z + x[2].x) * invr;
324 real.w = (x[2].y - x[1].z) * invr;
325 }
326 else if(x[1].y > x[2].z)
327 {
328 T const r = sqrt(T(1) + x[1].y - x[0].x - x[2].z);
329 T const invr = static_cast<T>(0.5) / r;
330 real.x = (x[1].x + x[0].y) * invr;
331 real.y = static_cast<T>(0.5) * r;
332 real.z = (x[2].y + x[1].z) * invr;
333 real.w = (x[0].z - x[2].x) * invr;
334 }
335 else
336 {
337 T const r = sqrt(T(1) + x[2].z - x[0].x - x[1].y);
338 T const invr = static_cast<T>(0.5) / r;
339 real.x = (x[0].z + x[2].x) * invr;
340 real.y = (x[2].y + x[1].z) * invr;
341 real.z = static_cast<T>(0.5) * r;
342 real.w = (x[1].x - x[0].y) * invr;
343 }
344
345 qua<T, Q> dual;
346 dual.x = static_cast<T>(0.5) * ( x[0].w * real.w + x[1].w * real.z - x[2].w * real.y);
347 dual.y = static_cast<T>(0.5) * (-x[0].w * real.z + x[1].w * real.w + x[2].w * real.x);
348 dual.z = static_cast<T>(0.5) * ( x[0].w * real.y - x[1].w * real.x + x[2].w * real.w);
349 dual.w = -static_cast<T>(0.5) * ( x[0].w * real.x + x[1].w * real.y + x[2].w * real.z);
350 return tdualquat<T, Q>(real, dual);
351 }
352}//namespace glm
GLM_FUNC_QUALIFIER vec< L, T, Q > normalize(vec< L, T, Q > const &x)
Definition func_geometric.inl:190
GLM_FUNC_QUALIFIER vec< 3, T, Q > cross(vec< 3, T, Q > const &x, vec< 3, T, Q > const &y)
Definition func_geometric.inl:175
GLM_FUNC_QUALIFIER mat< C, R, T, Q > inverse(mat< C, R, T, Q > const &m)
Definition func_matrix.inl:388
GLM_FUNC_DECL qua< T, Q > conjugate(qua< T, Q > const &q)
Definition quaternion_common.inl:76
GLM_FUNC_DECL qua< T, Q > lerp(qua< T, Q > const &x, qua< T, Q > const &y, T a)
Definition quaternion_common.inl:29
GLM_FUNC_DECL GLM_CONSTEXPR genType one()
Definition constants.inl:12
GLM_FUNC_DECL tdualquat< T, Q > dual_quat_identity()
Definition dual_quaternion.inl:219
GLM_FUNC_DECL mat< 2, 4, T, Q > mat2x4_cast(tdualquat< T, Q > const &x)
Definition dual_quaternion.inl:253
GLM_FUNC_DECL tdualquat< T, Q > dualquat_cast(mat< 2, 4, T, Q > const &x)
Definition dual_quaternion.inl:295
GLM_FUNC_DECL mat< 3, 4, T, Q > mat3x4_cast(tdualquat< T, Q > const &x)
Definition dual_quaternion.inl:259
GLM_FUNC_DECL T length2(vec< L, T, Q > const &x)
Definition norm.inl:26
Core features
Definition common.hpp:21
Definition qualifier.hpp:36
Definition type_quat.hpp:20
Definition dual_quaternion.hpp:38
Definition qualifier.hpp:35