1 | /** |
---|
2 | @file Quat.h |
---|
3 | |
---|
4 | Quaternion |
---|
5 | |
---|
6 | @maintainer Morgan McGuire, matrix@graphics3d.com |
---|
7 | |
---|
8 | @created 2002-01-23 |
---|
9 | @edited 2006-05-10 |
---|
10 | */ |
---|
11 | |
---|
12 | #ifndef G3D_QUAT_H |
---|
13 | #define G3D_QUAT_H |
---|
14 | |
---|
15 | #include "G3D/platform.h" |
---|
16 | #include "G3D/g3dmath.h" |
---|
17 | #include "G3D/Vector3.h" |
---|
18 | #include "G3D/Matrix3.h" |
---|
19 | #include <string> |
---|
20 | |
---|
21 | namespace G3D { |
---|
22 | |
---|
23 | /** |
---|
24 | Unit quaternions are used in computer graphics to represent |
---|
25 | rotation about an axis. Any 3x3 rotation matrix can |
---|
26 | be stored as a quaternion. |
---|
27 | |
---|
28 | A quaternion represents the sum of a real scalar and |
---|
29 | an imaginary vector: ix + jy + kz + w. A unit quaternion |
---|
30 | representing a rotation by A about axis v has the form |
---|
31 | [sin(A/2)*v, cos(A/2)]. For a unit quaternion, q.conj() == q.inverse() |
---|
32 | is a rotation by -A about v. -q is the same rotation as q |
---|
33 | (negate both the axis and angle). |
---|
34 | |
---|
35 | A non-unit quaterion q represents the same rotation as |
---|
36 | q.unitize() (Dam98 pg 28). |
---|
37 | |
---|
38 | Although quaternion-vector operations (eg. Quat + Vector3) are |
---|
39 | well defined, they are not supported by this class because |
---|
40 | they typically are bugs when they appear in code. |
---|
41 | |
---|
42 | Do not subclass. |
---|
43 | |
---|
44 | <B>BETA API -- subject to change</B> |
---|
45 | @cite Erik B. Dam, Martin Koch, Martin Lillholm, Quaternions, Interpolation and Animation. Technical Report DIKU-TR-98/5, Department of Computer Science, University of Copenhagen, Denmark. 1998. |
---|
46 | */ |
---|
47 | class Quat { |
---|
48 | private: |
---|
49 | // Hidden operators |
---|
50 | bool operator<(const Quat&) const; |
---|
51 | bool operator>(const Quat&) const; |
---|
52 | bool operator<=(const Quat&) const; |
---|
53 | bool operator>=(const Quat&) const; |
---|
54 | |
---|
55 | public: |
---|
56 | |
---|
57 | /** |
---|
58 | q = [sin(angle / 2) * axis, cos(angle / 2)] |
---|
59 | |
---|
60 | In Watt & Watt's notation, s = w, v = (x, y, z) |
---|
61 | In the Real-Time Rendering notation, u = (x, y, z), w = w |
---|
62 | */ |
---|
63 | float x, y, z, w; |
---|
64 | |
---|
65 | /** |
---|
66 | Initializes to a zero degree rotation. |
---|
67 | */ |
---|
68 | inline Quat() : x(0), y(0), z(0), w(1) {} |
---|
69 | |
---|
70 | Quat( |
---|
71 | const Matrix3& rot); |
---|
72 | |
---|
73 | inline Quat(float _x, float _y, float _z, float _w) : |
---|
74 | x(_x), y(_y), z(_z), w(_w) {} |
---|
75 | |
---|
76 | /** Defaults to a pure vector quaternion */ |
---|
77 | inline Quat(const Vector3& v, float _w = 0) : x(v.x), y(v.y), z(v.z), w(_w) { |
---|
78 | } |
---|
79 | |
---|
80 | /** |
---|
81 | The real part of the quaternion. |
---|
82 | */ |
---|
83 | inline const float& real() const { |
---|
84 | return w; |
---|
85 | } |
---|
86 | |
---|
87 | inline float& real() { |
---|
88 | return w; |
---|
89 | } |
---|
90 | |
---|
91 | /** Note: two quats can represent the Quat::sameRotation and not be equal. */ |
---|
92 | bool fuzzyEq(const Quat& q) { |
---|
93 | return G3D::fuzzyEq(x, q.x) && G3D::fuzzyEq(y, q.y) && G3D::fuzzyEq(z, q.z) && G3D::fuzzyEq(w, q.w); |
---|
94 | } |
---|
95 | |
---|
96 | /** True if these quaternions represent the same rotation (note that every rotation is |
---|
97 | represented by two values; q and -q). |
---|
98 | */ |
---|
99 | bool sameRotation(const Quat& q) { |
---|
100 | return fuzzyEq(q) || fuzzyEq(-q); |
---|
101 | } |
---|
102 | |
---|
103 | inline Quat operator-() const { |
---|
104 | return Quat(-x, -y, -z, -w); |
---|
105 | } |
---|
106 | |
---|
107 | /** |
---|
108 | Returns the imaginary part (x, y, z) |
---|
109 | */ |
---|
110 | inline const Vector3& imag() const { |
---|
111 | return *(reinterpret_cast<const Vector3*>(this)); |
---|
112 | } |
---|
113 | |
---|
114 | inline Vector3& imag() { |
---|
115 | return *(reinterpret_cast<Vector3*>(this)); |
---|
116 | } |
---|
117 | |
---|
118 | /** q = [sin(angle/2)*axis, cos(angle/2)] */ |
---|
119 | static Quat fromAxisAngleRotation( |
---|
120 | const Vector3& axis, |
---|
121 | float angle); |
---|
122 | |
---|
123 | /** Returns the axis and angle of rotation represented |
---|
124 | by this quaternion (i.e. q = [sin(angle/2)*axis, cos(angle/2)]) */ |
---|
125 | void toAxisAngleRotation( |
---|
126 | Vector3& axis, |
---|
127 | double& angle) const; |
---|
128 | |
---|
129 | void toAxisAngleRotation( |
---|
130 | Vector3& axis, |
---|
131 | float& angle) const { |
---|
132 | double d; |
---|
133 | toAxisAngleRotation(axis, d); |
---|
134 | angle = (float)d; |
---|
135 | } |
---|
136 | |
---|
137 | Matrix3 toRotationMatrix() const; |
---|
138 | |
---|
139 | void toRotationMatrix( |
---|
140 | Matrix3& rot) const; |
---|
141 | |
---|
142 | /** |
---|
143 | Spherical linear interpolation: linear interpolation along the |
---|
144 | shortest (3D) great-circle route between two quaternions. |
---|
145 | |
---|
146 | Note: Correct rotations are expected between 0 and PI in the right order. |
---|
147 | |
---|
148 | @cite Based on Game Physics -- David Eberly pg 538-540 |
---|
149 | @param threshold Critical angle between between rotations at which |
---|
150 | the algorithm switches to normalized lerp, which is more |
---|
151 | numerically stable in those situations. 0.0 will always slerp. |
---|
152 | */ |
---|
153 | Quat slerp( |
---|
154 | const Quat& other, |
---|
155 | float alpha, |
---|
156 | float threshold = 0.05f) const; |
---|
157 | |
---|
158 | /** Normalized linear interpolation of quaternion components. */ |
---|
159 | Quat nlerp(const Quat& other, float alpha) const; |
---|
160 | |
---|
161 | /** |
---|
162 | Negates the imaginary part. |
---|
163 | */ |
---|
164 | inline Quat conj() const { |
---|
165 | return Quat(-x, -y, -z, w); |
---|
166 | } |
---|
167 | |
---|
168 | inline float sum() const { |
---|
169 | return x + y + z + w; |
---|
170 | } |
---|
171 | |
---|
172 | inline float average() const { |
---|
173 | return sum() / 4.0f; |
---|
174 | } |
---|
175 | |
---|
176 | inline Quat operator*(float s) const { |
---|
177 | return Quat(x * s, y * s, z * s, w * s); |
---|
178 | } |
---|
179 | |
---|
180 | /** @cite Based on Watt & Watt, page 360 */ |
---|
181 | friend Quat operator* (float s, const Quat& q); |
---|
182 | |
---|
183 | inline Quat operator/(float s) const { |
---|
184 | return Quat(x / s, y / s, z / s, w / s); |
---|
185 | } |
---|
186 | |
---|
187 | inline float dot(const Quat& other) const { |
---|
188 | return (x * other.x) + (y * other.y) + (z * other.z) + (w * other.w); |
---|
189 | } |
---|
190 | |
---|
191 | /** Note that q<SUP>-1</SUP> = q.conj() for a unit quaternion. |
---|
192 | @cite Dam99 page 13 */ |
---|
193 | inline Quat inverse() const { |
---|
194 | return conj() / dot(*this); |
---|
195 | } |
---|
196 | |
---|
197 | Quat operator-(const Quat& other) const; |
---|
198 | |
---|
199 | Quat operator+(const Quat& other) const; |
---|
200 | |
---|
201 | /** |
---|
202 | Quaternion multiplication (composition of rotations). |
---|
203 | Note that this does not commute. |
---|
204 | */ |
---|
205 | Quat operator*(const Quat& other) const; |
---|
206 | |
---|
207 | /* (*this) * other.inverse() */ |
---|
208 | Quat operator/(const Quat& other) const { |
---|
209 | return (*this) * other.inverse(); |
---|
210 | } |
---|
211 | |
---|
212 | |
---|
213 | /** Is the magnitude nearly 1.0? */ |
---|
214 | inline bool isUnit(float tolerance = 1e-5) const { |
---|
215 | return abs(dot(*this) - 1.0f) < tolerance; |
---|
216 | } |
---|
217 | |
---|
218 | |
---|
219 | inline float magnitude() const { |
---|
220 | return sqrtf(dot(*this)); |
---|
221 | } |
---|
222 | |
---|
223 | inline Quat log() const { |
---|
224 | if ((x == 0) && (y == 0) && (z == 0)) { |
---|
225 | if (w > 0) { |
---|
226 | return Quat(0, 0, 0, ::logf(w)); |
---|
227 | } else if (w < 0) { |
---|
228 | // Log of a negative number. Multivalued, any number of the form |
---|
229 | // (PI * v, ln(-q.w)) |
---|
230 | return Quat((float)G3D_PI, 0, 0, ::logf(-w)); |
---|
231 | } else { |
---|
232 | // log of zero! |
---|
233 | return Quat((float)nan(), (float)nan(), (float)nan(), (float)nan()); |
---|
234 | } |
---|
235 | } else { |
---|
236 | // Partly imaginary. |
---|
237 | float imagLen = sqrtf(x * x + y * y + z * z); |
---|
238 | float len = sqrtf(imagLen * imagLen + w * w); |
---|
239 | float theta = atan2f(imagLen, (float)w); |
---|
240 | float t = theta / imagLen; |
---|
241 | return Quat(t * x, t * y, t * z, ::logf(len)); |
---|
242 | } |
---|
243 | } |
---|
244 | /** log q = [Av, 0] where q = [sin(A) * v, cos(A)]. |
---|
245 | Only for unit quaternions |
---|
246 | debugAssertM(isUnit(), "Log only defined for unit quaternions"); |
---|
247 | // Solve for A in q = [sin(A)*v, cos(A)] |
---|
248 | Vector3 u(x, y, z); |
---|
249 | double len = u.magnitude(); |
---|
250 | |
---|
251 | if (len == 0.0) { |
---|
252 | return |
---|
253 | } |
---|
254 | double A = atan2((double)w, len); |
---|
255 | Vector3 v = u / len; |
---|
256 | |
---|
257 | return Quat(v * A, 0); |
---|
258 | } |
---|
259 | */ |
---|
260 | |
---|
261 | /** exp q = [sin(A) * v, cos(A)] where q = [Av, 0]. |
---|
262 | Only defined for pure-vector quaternions */ |
---|
263 | inline Quat exp() const { |
---|
264 | debugAssertM(w == 0, "exp only defined for vector quaternions"); |
---|
265 | Vector3 u(x, y, z); |
---|
266 | float A = u.magnitude(); |
---|
267 | Vector3 v = u / A; |
---|
268 | return Quat(sinf(A) * v, cosf(A)); |
---|
269 | } |
---|
270 | |
---|
271 | |
---|
272 | /** |
---|
273 | Raise this quaternion to a power. For a rotation, this is |
---|
274 | the effect of rotating x times as much as the original |
---|
275 | quaterion. |
---|
276 | |
---|
277 | Note that q.pow(a).pow(b) == q.pow(a + b) |
---|
278 | @cite Dam98 pg 21 |
---|
279 | */ |
---|
280 | inline Quat pow(float x) const { |
---|
281 | return (log() * x).exp(); |
---|
282 | } |
---|
283 | |
---|
284 | |
---|
285 | /** |
---|
286 | @deprecated |
---|
287 | Use toUnit() |
---|
288 | */ |
---|
289 | inline Quat unitize() const { |
---|
290 | float mag2 = dot(*this); |
---|
291 | if (G3D::fuzzyEq(mag2, 1.0f)) { |
---|
292 | return *this; |
---|
293 | } else { |
---|
294 | return *this / sqrtf(mag2); |
---|
295 | } |
---|
296 | } |
---|
297 | |
---|
298 | /** |
---|
299 | Returns a unit quaterion obtained by dividing through by |
---|
300 | the magnitude. |
---|
301 | */ |
---|
302 | inline Quat toUnit() const { |
---|
303 | return unitize(); |
---|
304 | } |
---|
305 | |
---|
306 | /** |
---|
307 | The linear algebra 2-norm, sqrt(q dot q). This matches |
---|
308 | the value used in Dam's 1998 tech report but differs from the |
---|
309 | n(q) value used in Eberly's 1999 paper, which is the square of the |
---|
310 | norm. |
---|
311 | */ |
---|
312 | inline float norm() const { |
---|
313 | return magnitude(); |
---|
314 | } |
---|
315 | |
---|
316 | // access quaternion as q[0] = q.x, q[1] = q.y, q[2] = q.z, q[3] = q.w |
---|
317 | // |
---|
318 | // WARNING. These member functions rely on |
---|
319 | // (1) Quat not having virtual functions |
---|
320 | // (2) the data packed in a 4*sizeof(float) memory block |
---|
321 | const float& operator[] (int i) const; |
---|
322 | float& operator[] (int i); |
---|
323 | |
---|
324 | /** Generate uniform random unit quaternion (i.e. random "direction") |
---|
325 | @cite From "Uniform Random Rotations", Ken Shoemake, Graphics Gems III. |
---|
326 | */ |
---|
327 | static Quat unitRandom(); |
---|
328 | |
---|
329 | // 2-char swizzles |
---|
330 | |
---|
331 | Vector2 xx() const; |
---|
332 | Vector2 yx() const; |
---|
333 | Vector2 zx() const; |
---|
334 | Vector2 wx() const; |
---|
335 | Vector2 xy() const; |
---|
336 | Vector2 yy() const; |
---|
337 | Vector2 zy() const; |
---|
338 | Vector2 wy() const; |
---|
339 | Vector2 xz() const; |
---|
340 | Vector2 yz() const; |
---|
341 | Vector2 zz() const; |
---|
342 | Vector2 wz() const; |
---|
343 | Vector2 xw() const; |
---|
344 | Vector2 yw() const; |
---|
345 | Vector2 zw() const; |
---|
346 | Vector2 ww() const; |
---|
347 | |
---|
348 | // 3-char swizzles |
---|
349 | |
---|
350 | Vector3 xxx() const; |
---|
351 | Vector3 yxx() const; |
---|
352 | Vector3 zxx() const; |
---|
353 | Vector3 wxx() const; |
---|
354 | Vector3 xyx() const; |
---|
355 | Vector3 yyx() const; |
---|
356 | Vector3 zyx() const; |
---|
357 | Vector3 wyx() const; |
---|
358 | Vector3 xzx() const; |
---|
359 | Vector3 yzx() const; |
---|
360 | Vector3 zzx() const; |
---|
361 | Vector3 wzx() const; |
---|
362 | Vector3 xwx() const; |
---|
363 | Vector3 ywx() const; |
---|
364 | Vector3 zwx() const; |
---|
365 | Vector3 wwx() const; |
---|
366 | Vector3 xxy() const; |
---|
367 | Vector3 yxy() const; |
---|
368 | Vector3 zxy() const; |
---|
369 | Vector3 wxy() const; |
---|
370 | Vector3 xyy() const; |
---|
371 | Vector3 yyy() const; |
---|
372 | Vector3 zyy() const; |
---|
373 | Vector3 wyy() const; |
---|
374 | Vector3 xzy() const; |
---|
375 | Vector3 yzy() const; |
---|
376 | Vector3 zzy() const; |
---|
377 | Vector3 wzy() const; |
---|
378 | Vector3 xwy() const; |
---|
379 | Vector3 ywy() const; |
---|
380 | Vector3 zwy() const; |
---|
381 | Vector3 wwy() const; |
---|
382 | Vector3 xxz() const; |
---|
383 | Vector3 yxz() const; |
---|
384 | Vector3 zxz() const; |
---|
385 | Vector3 wxz() const; |
---|
386 | Vector3 xyz() const; |
---|
387 | Vector3 yyz() const; |
---|
388 | Vector3 zyz() const; |
---|
389 | Vector3 wyz() const; |
---|
390 | Vector3 xzz() const; |
---|
391 | Vector3 yzz() const; |
---|
392 | Vector3 zzz() const; |
---|
393 | Vector3 wzz() const; |
---|
394 | Vector3 xwz() const; |
---|
395 | Vector3 ywz() const; |
---|
396 | Vector3 zwz() const; |
---|
397 | Vector3 wwz() const; |
---|
398 | Vector3 xxw() const; |
---|
399 | Vector3 yxw() const; |
---|
400 | Vector3 zxw() const; |
---|
401 | Vector3 wxw() const; |
---|
402 | Vector3 xyw() const; |
---|
403 | Vector3 yyw() const; |
---|
404 | Vector3 zyw() const; |
---|
405 | Vector3 wyw() const; |
---|
406 | Vector3 xzw() const; |
---|
407 | Vector3 yzw() const; |
---|
408 | Vector3 zzw() const; |
---|
409 | Vector3 wzw() const; |
---|
410 | Vector3 xww() const; |
---|
411 | Vector3 yww() const; |
---|
412 | Vector3 zww() const; |
---|
413 | Vector3 www() const; |
---|
414 | |
---|
415 | // 4-char swizzles |
---|
416 | |
---|
417 | Vector4 xxxx() const; |
---|
418 | Vector4 yxxx() const; |
---|
419 | Vector4 zxxx() const; |
---|
420 | Vector4 wxxx() const; |
---|
421 | Vector4 xyxx() const; |
---|
422 | Vector4 yyxx() const; |
---|
423 | Vector4 zyxx() const; |
---|
424 | Vector4 wyxx() const; |
---|
425 | Vector4 xzxx() const; |
---|
426 | Vector4 yzxx() const; |
---|
427 | Vector4 zzxx() const; |
---|
428 | Vector4 wzxx() const; |
---|
429 | Vector4 xwxx() const; |
---|
430 | Vector4 ywxx() const; |
---|
431 | Vector4 zwxx() const; |
---|
432 | Vector4 wwxx() const; |
---|
433 | Vector4 xxyx() const; |
---|
434 | Vector4 yxyx() const; |
---|
435 | Vector4 zxyx() const; |
---|
436 | Vector4 wxyx() const; |
---|
437 | Vector4 xyyx() const; |
---|
438 | Vector4 yyyx() const; |
---|
439 | Vector4 zyyx() const; |
---|
440 | Vector4 wyyx() const; |
---|
441 | Vector4 xzyx() const; |
---|
442 | Vector4 yzyx() const; |
---|
443 | Vector4 zzyx() const; |
---|
444 | Vector4 wzyx() const; |
---|
445 | Vector4 xwyx() const; |
---|
446 | Vector4 ywyx() const; |
---|
447 | Vector4 zwyx() const; |
---|
448 | Vector4 wwyx() const; |
---|
449 | Vector4 xxzx() const; |
---|
450 | Vector4 yxzx() const; |
---|
451 | Vector4 zxzx() const; |
---|
452 | Vector4 wxzx() const; |
---|
453 | Vector4 xyzx() const; |
---|
454 | Vector4 yyzx() const; |
---|
455 | Vector4 zyzx() const; |
---|
456 | Vector4 wyzx() const; |
---|
457 | Vector4 xzzx() const; |
---|
458 | Vector4 yzzx() const; |
---|
459 | Vector4 zzzx() const; |
---|
460 | Vector4 wzzx() const; |
---|
461 | Vector4 xwzx() const; |
---|
462 | Vector4 ywzx() const; |
---|
463 | Vector4 zwzx() const; |
---|
464 | Vector4 wwzx() const; |
---|
465 | Vector4 xxwx() const; |
---|
466 | Vector4 yxwx() const; |
---|
467 | Vector4 zxwx() const; |
---|
468 | Vector4 wxwx() const; |
---|
469 | Vector4 xywx() const; |
---|
470 | Vector4 yywx() const; |
---|
471 | Vector4 zywx() const; |
---|
472 | Vector4 wywx() const; |
---|
473 | Vector4 xzwx() const; |
---|
474 | Vector4 yzwx() const; |
---|
475 | Vector4 zzwx() const; |
---|
476 | Vector4 wzwx() const; |
---|
477 | Vector4 xwwx() const; |
---|
478 | Vector4 ywwx() const; |
---|
479 | Vector4 zwwx() const; |
---|
480 | Vector4 wwwx() const; |
---|
481 | Vector4 xxxy() const; |
---|
482 | Vector4 yxxy() const; |
---|
483 | Vector4 zxxy() const; |
---|
484 | Vector4 wxxy() const; |
---|
485 | Vector4 xyxy() const; |
---|
486 | Vector4 yyxy() const; |
---|
487 | Vector4 zyxy() const; |
---|
488 | Vector4 wyxy() const; |
---|
489 | Vector4 xzxy() const; |
---|
490 | Vector4 yzxy() const; |
---|
491 | Vector4 zzxy() const; |
---|
492 | Vector4 wzxy() const; |
---|
493 | Vector4 xwxy() const; |
---|
494 | Vector4 ywxy() const; |
---|
495 | Vector4 zwxy() const; |
---|
496 | Vector4 wwxy() const; |
---|
497 | Vector4 xxyy() const; |
---|
498 | Vector4 yxyy() const; |
---|
499 | Vector4 zxyy() const; |
---|
500 | Vector4 wxyy() const; |
---|
501 | Vector4 xyyy() const; |
---|
502 | Vector4 yyyy() const; |
---|
503 | Vector4 zyyy() const; |
---|
504 | Vector4 wyyy() const; |
---|
505 | Vector4 xzyy() const; |
---|
506 | Vector4 yzyy() const; |
---|
507 | Vector4 zzyy() const; |
---|
508 | Vector4 wzyy() const; |
---|
509 | Vector4 xwyy() const; |
---|
510 | Vector4 ywyy() const; |
---|
511 | Vector4 zwyy() const; |
---|
512 | Vector4 wwyy() const; |
---|
513 | Vector4 xxzy() const; |
---|
514 | Vector4 yxzy() const; |
---|
515 | Vector4 zxzy() const; |
---|
516 | Vector4 wxzy() const; |
---|
517 | Vector4 xyzy() const; |
---|
518 | Vector4 yyzy() const; |
---|
519 | Vector4 zyzy() const; |
---|
520 | Vector4 wyzy() const; |
---|
521 | Vector4 xzzy() const; |
---|
522 | Vector4 yzzy() const; |
---|
523 | Vector4 zzzy() const; |
---|
524 | Vector4 wzzy() const; |
---|
525 | Vector4 xwzy() const; |
---|
526 | Vector4 ywzy() const; |
---|
527 | Vector4 zwzy() const; |
---|
528 | Vector4 wwzy() const; |
---|
529 | Vector4 xxwy() const; |
---|
530 | Vector4 yxwy() const; |
---|
531 | Vector4 zxwy() const; |
---|
532 | Vector4 wxwy() const; |
---|
533 | Vector4 xywy() const; |
---|
534 | Vector4 yywy() const; |
---|
535 | Vector4 zywy() const; |
---|
536 | Vector4 wywy() const; |
---|
537 | Vector4 xzwy() const; |
---|
538 | Vector4 yzwy() const; |
---|
539 | Vector4 zzwy() const; |
---|
540 | Vector4 wzwy() const; |
---|
541 | Vector4 xwwy() const; |
---|
542 | Vector4 ywwy() const; |
---|
543 | Vector4 zwwy() const; |
---|
544 | Vector4 wwwy() const; |
---|
545 | Vector4 xxxz() const; |
---|
546 | Vector4 yxxz() const; |
---|
547 | Vector4 zxxz() const; |
---|
548 | Vector4 wxxz() const; |
---|
549 | Vector4 xyxz() const; |
---|
550 | Vector4 yyxz() const; |
---|
551 | Vector4 zyxz() const; |
---|
552 | Vector4 wyxz() const; |
---|
553 | Vector4 xzxz() const; |
---|
554 | Vector4 yzxz() const; |
---|
555 | Vector4 zzxz() const; |
---|
556 | Vector4 wzxz() const; |
---|
557 | Vector4 xwxz() const; |
---|
558 | Vector4 ywxz() const; |
---|
559 | Vector4 zwxz() const; |
---|
560 | Vector4 wwxz() const; |
---|
561 | Vector4 xxyz() const; |
---|
562 | Vector4 yxyz() const; |
---|
563 | Vector4 zxyz() const; |
---|
564 | Vector4 wxyz() const; |
---|
565 | Vector4 xyyz() const; |
---|
566 | Vector4 yyyz() const; |
---|
567 | Vector4 zyyz() const; |
---|
568 | Vector4 wyyz() const; |
---|
569 | Vector4 xzyz() const; |
---|
570 | Vector4 yzyz() const; |
---|
571 | Vector4 zzyz() const; |
---|
572 | Vector4 wzyz() const; |
---|
573 | Vector4 xwyz() const; |
---|
574 | Vector4 ywyz() const; |
---|
575 | Vector4 zwyz() const; |
---|
576 | Vector4 wwyz() const; |
---|
577 | Vector4 xxzz() const; |
---|
578 | Vector4 yxzz() const; |
---|
579 | Vector4 zxzz() const; |
---|
580 | Vector4 wxzz() const; |
---|
581 | Vector4 xyzz() const; |
---|
582 | Vector4 yyzz() const; |
---|
583 | Vector4 zyzz() const; |
---|
584 | Vector4 wyzz() const; |
---|
585 | Vector4 xzzz() const; |
---|
586 | Vector4 yzzz() const; |
---|
587 | Vector4 zzzz() const; |
---|
588 | Vector4 wzzz() const; |
---|
589 | Vector4 xwzz() const; |
---|
590 | Vector4 ywzz() const; |
---|
591 | Vector4 zwzz() const; |
---|
592 | Vector4 wwzz() const; |
---|
593 | Vector4 xxwz() const; |
---|
594 | Vector4 yxwz() const; |
---|
595 | Vector4 zxwz() const; |
---|
596 | Vector4 wxwz() const; |
---|
597 | Vector4 xywz() const; |
---|
598 | Vector4 yywz() const; |
---|
599 | Vector4 zywz() const; |
---|
600 | Vector4 wywz() const; |
---|
601 | Vector4 xzwz() const; |
---|
602 | Vector4 yzwz() const; |
---|
603 | Vector4 zzwz() const; |
---|
604 | Vector4 wzwz() const; |
---|
605 | Vector4 xwwz() const; |
---|
606 | Vector4 ywwz() const; |
---|
607 | Vector4 zwwz() const; |
---|
608 | Vector4 wwwz() const; |
---|
609 | Vector4 xxxw() const; |
---|
610 | Vector4 yxxw() const; |
---|
611 | Vector4 zxxw() const; |
---|
612 | Vector4 wxxw() const; |
---|
613 | Vector4 xyxw() const; |
---|
614 | Vector4 yyxw() const; |
---|
615 | Vector4 zyxw() const; |
---|
616 | Vector4 wyxw() const; |
---|
617 | Vector4 xzxw() const; |
---|
618 | Vector4 yzxw() const; |
---|
619 | Vector4 zzxw() const; |
---|
620 | Vector4 wzxw() const; |
---|
621 | Vector4 xwxw() const; |
---|
622 | Vector4 ywxw() const; |
---|
623 | Vector4 zwxw() const; |
---|
624 | Vector4 wwxw() const; |
---|
625 | Vector4 xxyw() const; |
---|
626 | Vector4 yxyw() const; |
---|
627 | Vector4 zxyw() const; |
---|
628 | Vector4 wxyw() const; |
---|
629 | Vector4 xyyw() const; |
---|
630 | Vector4 yyyw() const; |
---|
631 | Vector4 zyyw() const; |
---|
632 | Vector4 wyyw() const; |
---|
633 | Vector4 xzyw() const; |
---|
634 | Vector4 yzyw() const; |
---|
635 | Vector4 zzyw() const; |
---|
636 | Vector4 wzyw() const; |
---|
637 | Vector4 xwyw() const; |
---|
638 | Vector4 ywyw() const; |
---|
639 | Vector4 zwyw() const; |
---|
640 | Vector4 wwyw() const; |
---|
641 | Vector4 xxzw() const; |
---|
642 | Vector4 yxzw() const; |
---|
643 | Vector4 zxzw() const; |
---|
644 | Vector4 wxzw() const; |
---|
645 | Vector4 xyzw() const; |
---|
646 | Vector4 yyzw() const; |
---|
647 | Vector4 zyzw() const; |
---|
648 | Vector4 wyzw() const; |
---|
649 | Vector4 xzzw() const; |
---|
650 | Vector4 yzzw() const; |
---|
651 | Vector4 zzzw() const; |
---|
652 | Vector4 wzzw() const; |
---|
653 | Vector4 xwzw() const; |
---|
654 | Vector4 ywzw() const; |
---|
655 | Vector4 zwzw() const; |
---|
656 | Vector4 wwzw() const; |
---|
657 | Vector4 xxww() const; |
---|
658 | Vector4 yxww() const; |
---|
659 | Vector4 zxww() const; |
---|
660 | Vector4 wxww() const; |
---|
661 | Vector4 xyww() const; |
---|
662 | Vector4 yyww() const; |
---|
663 | Vector4 zyww() const; |
---|
664 | Vector4 wyww() const; |
---|
665 | Vector4 xzww() const; |
---|
666 | Vector4 yzww() const; |
---|
667 | Vector4 zzww() const; |
---|
668 | Vector4 wzww() const; |
---|
669 | Vector4 xwww() const; |
---|
670 | Vector4 ywww() const; |
---|
671 | Vector4 zwww() const; |
---|
672 | Vector4 wwww() const; |
---|
673 | }; |
---|
674 | |
---|
675 | inline Quat exp(const Quat& q) { |
---|
676 | return q.exp(); |
---|
677 | } |
---|
678 | |
---|
679 | inline Quat log(const Quat& q) { |
---|
680 | return q.log(); |
---|
681 | } |
---|
682 | |
---|
683 | inline G3D::Quat operator*(double s, const G3D::Quat& q) { |
---|
684 | return q * (float)s; |
---|
685 | } |
---|
686 | |
---|
687 | inline G3D::Quat operator*(float s, const G3D::Quat& q) { |
---|
688 | return q * s; |
---|
689 | } |
---|
690 | |
---|
691 | } // Namespace G3D |
---|
692 | |
---|
693 | // Outside the namespace to avoid overloading confusion for C++ |
---|
694 | inline G3D::Quat pow(const G3D::Quat& q, double x) { |
---|
695 | return q.pow((float)x); |
---|
696 | } |
---|
697 | |
---|
698 | |
---|
699 | |
---|
700 | #include "Quat.inl" |
---|
701 | |
---|
702 | #endif |
---|