master
ブランチ master
VulkanExample / dep / include / glm / detail / type_quat.inl
11.4 KB、397行 生 Blame 履歴
1#include "../trigonometric.hpp"
2#include "../exponential.hpp"
3#include "../ext/quaternion_common.hpp"
4#include "../ext/quaternion_geometric.hpp"
5#include <limits>
6
7namespace glm{
8namespace detail
9{
10 template <typename T>
11 struct genTypeTrait<qua<T> >
12 {
13 static const genTypeEnum GENTYPE = GENTYPE_QUAT;
14 };
15
16 template<typename T, qualifier Q, bool Aligned>
17 struct compute_dot<qua<T, Q>, T, Aligned>
18 {
19 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(qua<T, Q> const& a, qua<T, Q> const& b)
20 {
21 vec<4, T, Q> tmp(a.w * b.w, a.x * b.x, a.y * b.y, a.z * b.z);
22 return (tmp.x + tmp.y) + (tmp.z + tmp.w);
23 }
24 };
25
26 template<typename T, qualifier Q, bool Aligned>
27 struct compute_quat_add
28 {
29 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, qua<T, Q> const& p)
30 {
31 return qua<T, Q>::wxyz(q.w + p.w, q.x + p.x, q.y + p.y, q.z + p.z);
32 }
33 };
34
35 template<typename T, qualifier Q, bool Aligned>
36 struct compute_quat_sub
37 {
38 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, qua<T, Q> const& p)
39 {
40 return qua<T, Q>::wxyz(q.w - p.w, q.x - p.x, q.y - p.y, q.z - p.z);
41 }
42 };
43
44 template<typename T, qualifier Q, bool Aligned>
45 struct compute_quat_mul_scalar
46 {
47 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, T s)
48 {
49 return qua<T, Q>::wxyz(q.w * s, q.x * s, q.y * s, q.z * s);
50 }
51 };
52
53 template<typename T, qualifier Q, bool Aligned>
54 struct compute_quat_div_scalar
55 {
56 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, T s)
57 {
58 return qua<T, Q>::wxyz(q.w / s, q.x / s, q.y / s, q.z / s);
59 }
60 };
61
62 template<typename T, qualifier Q, bool Aligned>
63 struct compute_quat_mul_vec4
64 {
65 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(qua<T, Q> const& q, vec<4, T, Q> const& v)
66 {
67 return vec<4, T, Q>(q * vec<3, T, Q>(v), v.w);
68 }
69 };
70}//namespace detail
71
72 // -- Component accesses --
73
74 template<typename T, qualifier Q>
75 GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & qua<T, Q>::operator[](typename qua<T, Q>::length_type i)
76 {
77 GLM_ASSERT_LENGTH(i, this->length());
78# ifdef GLM_FORCE_QUAT_DATA_WXYZ
79 return (&w)[i];
80# else
81 return (&x)[i];
82# endif
83 }
84
85 template<typename T, qualifier Q>
86 GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& qua<T, Q>::operator[](typename qua<T, Q>::length_type i) const
87 {
88 GLM_ASSERT_LENGTH(i, this->length());
89# ifdef GLM_FORCE_QUAT_DATA_WXYZ
90 return (&w)[i];
91# else
92 return (&x)[i];
93# endif
94 }
95
96 // -- Implicit basic constructors --
97
98# if GLM_CONFIG_CTOR_INIT == GLM_ENABLE
99 template<typename T, qualifier Q>
100 GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua()
101# ifdef GLM_FORCE_QUAT_DATA_WXYZ
102 : w(1), x(0), y(0), z(0)
103# else
104 : x(0), y(0), z(0), w(1)
105# endif
106 {}
107# endif
108
109 template<typename T, qualifier Q>
110 template<qualifier P>
111 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(qua<T, P> const& q)
112# ifdef GLM_FORCE_QUAT_DATA_WXYZ
113 : w(q.w), x(q.x), y(q.y), z(q.z)
114# else
115 : x(q.x), y(q.y), z(q.z), w(q.w)
116# endif
117 {}
118
119 // -- Explicit basic constructors --
120
121 template<typename T, qualifier Q>
122 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(T s, vec<3, T, Q> const& v)
123# ifdef GLM_FORCE_QUAT_DATA_WXYZ
124 : w(s), x(v.x), y(v.y), z(v.z)
125# else
126 : x(v.x), y(v.y), z(v.z), w(s)
127# endif
128 {}
129
130 template <typename T, qualifier Q>
131# ifdef GLM_FORCE_QUAT_DATA_XYZW
132 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(T _x, T _y, T _z, T _w)
133# else
134 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(T _w, T _x, T _y, T _z)
135# endif
136# ifdef GLM_FORCE_QUAT_DATA_WXYZ
137 : w(_w), x(_x), y(_y), z(_z)
138# else
139 : x(_x), y(_y), z(_z), w(_w)
140# endif
141 {}
142
143 template <typename T, qualifier Q>
144 GLM_CONSTEXPR qua<T, Q> qua<T, Q>::wxyz(T w, T x, T y, T z) {
145# ifdef GLM_FORCE_QUAT_DATA_XYZW
146 return qua<T, Q>(x, y, z, w);
147# else
148 return qua<T, Q>(w, x, y, z);
149# endif
150 }
151
152 // -- Conversion constructors --
153
154 template<typename T, qualifier Q>
155 template<typename U, qualifier P>
156 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(qua<U, P> const& q)
157# ifdef GLM_FORCE_QUAT_DATA_WXYZ
158 : w(static_cast<T>(q.w)), x(static_cast<T>(q.x)), y(static_cast<T>(q.y)), z(static_cast<T>(q.z))
159# else
160 : x(static_cast<T>(q.x)), y(static_cast<T>(q.y)), z(static_cast<T>(q.z)), w(static_cast<T>(q.w))
161# endif
162 {}
163
164 //template<typename valType>
165 //GLM_FUNC_QUALIFIER qua<valType>::qua
166 //(
167 // valType const& pitch,
168 // valType const& yaw,
169 // valType const& roll
170 //)
171 //{
172 // vec<3, valType> eulerAngle(pitch * valType(0.5), yaw * valType(0.5), roll * valType(0.5));
173 // vec<3, valType> c = glm::cos(eulerAngle * valType(0.5));
174 // vec<3, valType> s = glm::sin(eulerAngle * valType(0.5));
175 //
176 // this->w = c.x * c.y * c.z + s.x * s.y * s.z;
177 // this->x = s.x * c.y * c.z - c.x * s.y * s.z;
178 // this->y = c.x * s.y * c.z + s.x * c.y * s.z;
179 // this->z = c.x * c.y * s.z - s.x * s.y * c.z;
180 //}
181
182 template<typename T, qualifier Q>
183 GLM_FUNC_QUALIFIER qua<T, Q>::qua(vec<3, T, Q> const& u, vec<3, T, Q> const& v)
184 {
185 T norm_u_norm_v = sqrt(dot(u, u) * dot(v, v));
186 T real_part = norm_u_norm_v + dot(u, v);
187 vec<3, T, Q> t;
188
189 if(real_part < static_cast<T>(1.e-6f) * norm_u_norm_v)
190 {
191 // If u and v are exactly opposite, rotate 180 degrees
192 // around an arbitrary orthogonal axis. Axis normalisation
193 // can happen later, when we normalise the quaternion.
194 real_part = static_cast<T>(0);
195 t = abs(u.x) > abs(u.z) ? vec<3, T, Q>(-u.y, u.x, static_cast<T>(0)) : vec<3, T, Q>(static_cast<T>(0), -u.z, u.y);
196 }
197 else
198 {
199 // Otherwise, build quaternion the standard way.
200 t = cross(u, v);
201 }
202
203 *this = normalize(qua<T, Q>::wxyz(real_part, t.x, t.y, t.z));
204 }
205
206 template<typename T, qualifier Q>
207 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(vec<3, T, Q> const& eulerAngle)
208 {
209 vec<3, T, Q> c = glm::cos(eulerAngle * T(0.5));
210 vec<3, T, Q> s = glm::sin(eulerAngle * T(0.5));
211
212 this->w = c.x * c.y * c.z + s.x * s.y * s.z;
213 this->x = s.x * c.y * c.z - c.x * s.y * s.z;
214 this->y = c.x * s.y * c.z + s.x * c.y * s.z;
215 this->z = c.x * c.y * s.z - s.x * s.y * c.z;
216 }
217
218 template<typename T, qualifier Q>
219 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(mat<3, 3, T, Q> const& m)
220 {
221 *this = quat_cast(m);
222 }
223
224 template<typename T, qualifier Q>
225 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(mat<4, 4, T, Q> const& m)
226 {
227 *this = quat_cast(m);
228 }
229
230 template<typename T, qualifier Q>
231 GLM_FUNC_QUALIFIER qua<T, Q>::operator mat<3, 3, T, Q>() const
232 {
233 return mat3_cast(*this);
234 }
235
236 template<typename T, qualifier Q>
237 GLM_FUNC_QUALIFIER qua<T, Q>::operator mat<4, 4, T, Q>() const
238 {
239 return mat4_cast(*this);
240 }
241
242 // -- Unary arithmetic operators --
243
244 template<typename T, qualifier Q>
245 template<typename U>
246 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator=(qua<U, Q> const& q)
247 {
248 this->w = static_cast<T>(q.w);
249 this->x = static_cast<T>(q.x);
250 this->y = static_cast<T>(q.y);
251 this->z = static_cast<T>(q.z);
252 return *this;
253 }
254
255 template<typename T, qualifier Q>
256 template<typename U>
257 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator+=(qua<U, Q> const& q)
258 {
259 return (*this = detail::compute_quat_add<T, Q, detail::is_aligned<Q>::value>::call(*this, qua<T, Q>(q)));
260 }
261
262 template<typename T, qualifier Q>
263 template<typename U>
264 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator-=(qua<U, Q> const& q)
265 {
266 return (*this = detail::compute_quat_sub<T, Q, detail::is_aligned<Q>::value>::call(*this, qua<T, Q>(q)));
267 }
268
269 template<typename T, qualifier Q>
270 template<typename U>
271 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator*=(qua<U, Q> const& r)
272 {
273 qua<T, Q> const p(*this);
274 qua<T, Q> const q(r);
275
276 this->w = p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z;
277 this->x = p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y;
278 this->y = p.w * q.y + p.y * q.w + p.z * q.x - p.x * q.z;
279 this->z = p.w * q.z + p.z * q.w + p.x * q.y - p.y * q.x;
280 return *this;
281 }
282
283 template<typename T, qualifier Q>
284 template<typename U>
285 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator*=(U s)
286 {
287 return (*this = detail::compute_quat_mul_scalar<T, Q, detail::is_aligned<Q>::value>::call(*this, static_cast<U>(s)));
288 }
289
290 template<typename T, qualifier Q>
291 template<typename U>
292 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator/=(U s)
293 {
294 return (*this = detail::compute_quat_div_scalar<T, Q, detail::is_aligned<Q>::value>::call(*this, static_cast<U>(s)));
295 }
296
297 // -- Unary bit operators --
298
299 template<typename T, qualifier Q>
300 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator+(qua<T, Q> const& q)
301 {
302 return q;
303 }
304
305 template<typename T, qualifier Q>
306 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator-(qua<T, Q> const& q)
307 {
308 return qua<T, Q>::wxyz(-q.w, -q.x, -q.y, -q.z);
309 }
310
311 // -- Binary operators --
312
313 template<typename T, qualifier Q>
314 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator+(qua<T, Q> const& q, qua<T, Q> const& p)
315 {
316 return qua<T, Q>(q) += p;
317 }
318
319 template<typename T, qualifier Q>
320 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator-(qua<T, Q> const& q, qua<T, Q> const& p)
321 {
322 return qua<T, Q>(q) -= p;
323 }
324
325 template<typename T, qualifier Q>
326 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator*(qua<T, Q> const& q, qua<T, Q> const& p)
327 {
328 return qua<T, Q>(q) *= p;
329 }
330
331 template<typename T, qualifier Q>
332 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(qua<T, Q> const& q, vec<3, T, Q> const& v)
333 {
334 vec<3, T, Q> const QuatVector(q.x, q.y, q.z);
335 vec<3, T, Q> const uv(glm::cross(QuatVector, v));
336 vec<3, T, Q> const uuv(glm::cross(QuatVector, uv));
337
338 return v + ((uv * q.w) + uuv) * static_cast<T>(2);
339 }
340
341 template<typename T, qualifier Q>
342 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua<T, Q> const& q)
343 {
344 return glm::inverse(q) * v;
345 }
346
347 template<typename T, qualifier Q>
348 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(qua<T, Q> const& q, vec<4, T, Q> const& v)
349 {
350 return detail::compute_quat_mul_vec4<T, Q, detail::is_aligned<Q>::value>::call(q, v);
351 }
352
353 template<typename T, qualifier Q>
354 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v, qua<T, Q> const& q)
355 {
356 return glm::inverse(q) * v;
357 }
358
359 template<typename T, qualifier Q>
360 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator*(qua<T, Q> const& q, T const& s)
361 {
362 return qua<T, Q>::wxyz(
363 q.w * s, q.x * s, q.y * s, q.z * s);
364 }
365
366 template<typename T, qualifier Q>
367 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator*(T const& s, qua<T, Q> const& q)
368 {
369 return q * s;
370 }
371
372 template<typename T, qualifier Q>
373 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator/(qua<T, Q> const& q, T const& s)
374 {
375 return qua<T, Q>::wxyz(
376 q.w / s, q.x / s, q.y / s, q.z / s);
377 }
378
379 // -- Boolean operators --
380
381 template<typename T, qualifier Q>
382 GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(qua<T, Q> const& q1, qua<T, Q> const& q2)
383 {
384 return q1.x == q2.x && q1.y == q2.y && q1.z == q2.z && q1.w == q2.w;
385 }
386
387 template<typename T, qualifier Q>
388 GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(qua<T, Q> const& q1, qua<T, Q> const& q2)
389 {
390 return q1.x != q2.x || q1.y != q2.y || q1.z != q2.z || q1.w != q2.w;
391 }
392}//namespace glm
393
394#if GLM_CONFIG_SIMD == GLM_ENABLE
395# include "type_quat_simd.inl"
396#endif
397