Irrlicht 3D Engine
quaternion.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4 
5 #ifndef __IRR_QUATERNION_H_INCLUDED__
6 #define __IRR_QUATERNION_H_INCLUDED__
7 
8 #include "irrTypes.h"
9 #include "irrMath.h"
10 #include "matrix4.h"
11 #include "vector3d.h"
12 
13 // NOTE: You *only* need this when updating an application from Irrlicht before 1.8 to Irrlicht 1.8 or later.
14 // Between Irrlicht 1.7 and Irrlicht 1.8 the quaternion-matrix conversions changed.
15 // Before the fix they had mixed left- and right-handed rotations.
16 // To test if your code was affected by the change enable IRR_TEST_BROKEN_QUATERNION_USE and try to compile your application.
17 // This defines removes those functions so you get compile errors anywhere you use them in your code.
18 // For every line with a compile-errors you have to change the corresponding lines like that:
19 // - When you pass the matrix to the quaternion constructor then replace the matrix by the transposed matrix.
20 // - For uses of getMatrix() you have to use quaternion::getMatrix_transposed instead.
21 // #define IRR_TEST_BROKEN_QUATERNION_USE
22 
23 namespace irr
24 {
25 namespace core
26 {
27 
29 
32 {
33  public:
34 
36  quaternion() : X(0.0f), Y(0.0f), Z(0.0f), W(1.0f) {}
37 
39  quaternion(f32 x, f32 y, f32 z, f32 w) : X(x), Y(y), Z(z), W(w) { }
40 
42  quaternion(f32 x, f32 y, f32 z);
43 
45  quaternion(const vector3df& vec);
46 
47 #ifndef IRR_TEST_BROKEN_QUATERNION_USE
48  quaternion(const matrix4& mat);
50 #endif
51 
53  bool operator==(const quaternion& other) const;
54 
56  bool operator!=(const quaternion& other) const;
57 
59  inline quaternion& operator=(const quaternion& other);
60 
61 #ifndef IRR_TEST_BROKEN_QUATERNION_USE
62  inline quaternion& operator=(const matrix4& other);
64 #endif
65 
67  quaternion operator+(const quaternion& other) const;
68 
71  quaternion operator*(const quaternion& other) const;
72 
74  quaternion operator*(f32 s) const;
75 
78 
80  vector3df operator*(const vector3df& v) const;
81 
83  quaternion& operator*=(const quaternion& other);
84 
86  inline f32 dotProduct(const quaternion& other) const;
87 
89  inline quaternion& set(f32 x, f32 y, f32 z, f32 w);
90 
92  inline quaternion& set(f32 x, f32 y, f32 z);
93 
95  inline quaternion& set(const core::vector3df& vec);
96 
98  inline quaternion& set(const core::quaternion& quat);
99 
101  inline bool equals(const quaternion& other,
102  const f32 tolerance = ROUNDING_ERROR_f32 ) const;
103 
105  inline quaternion& normalize();
106 
107 #ifndef IRR_TEST_BROKEN_QUATERNION_USE
108  matrix4 getMatrix() const;
110 #endif
111  void getMatrixFast(matrix4 &dest) const;
113 
115  void getMatrix( matrix4 &dest, const core::vector3df &translation=core::vector3df() ) const;
116 
134  void getMatrixCenter( matrix4 &dest, const core::vector3df &center, const core::vector3df &translation ) const;
135 
137  inline void getMatrix_transposed( matrix4 &dest ) const;
138 
141 
143 
149  quaternion& lerp(quaternion q1, quaternion q2, f32 time);
150 
152 
164  f32 time, f32 threshold=.05f);
165 
167 
172  quaternion& fromAngleAxis (f32 angle, const vector3df& axis);
173 
175  void toAngleAxis (f32 &angle, core::vector3df& axis) const;
176 
178  void toEuler(vector3df& euler) const;
179 
182 
184  quaternion& rotationFromTo(const vector3df& from, const vector3df& to);
185 
187  f32 X; // vectorial (imaginary) part
190  f32 W; // real part
191 };
192 
193 
194 // Constructor which converts Euler angles to a quaternion
196 {
197  set(x,y,z);
198 }
199 
200 
201 // Constructor which converts Euler angles to a quaternion
203 {
204  set(vec.X,vec.Y,vec.Z);
205 }
206 
207 #ifndef IRR_TEST_BROKEN_QUATERNION_USE
208 // Constructor which converts a matrix to a quaternion
209 inline quaternion::quaternion(const matrix4& mat)
210 {
211  (*this) = mat;
212 }
213 #endif
214 
215 // equal operator
216 inline bool quaternion::operator==(const quaternion& other) const
217 {
218  return ((X == other.X) &&
219  (Y == other.Y) &&
220  (Z == other.Z) &&
221  (W == other.W));
222 }
223 
224 // inequality operator
225 inline bool quaternion::operator!=(const quaternion& other) const
226 {
227  return !(*this == other);
228 }
229 
230 // assignment operator
232 {
233  X = other.X;
234  Y = other.Y;
235  Z = other.Z;
236  W = other.W;
237  return *this;
238 }
239 
240 #ifndef IRR_TEST_BROKEN_QUATERNION_USE
241 // matrix assignment operator
243 {
244  const f32 diag = m[0] + m[5] + m[10] + 1;
245 
246  if( diag > 0.0f )
247  {
248  const f32 scale = sqrtf(diag) * 2.0f; // get scale from diagonal
249 
250  // TODO: speed this up
251  X = (m[6] - m[9]) / scale;
252  Y = (m[8] - m[2]) / scale;
253  Z = (m[1] - m[4]) / scale;
254  W = 0.25f * scale;
255  }
256  else
257  {
258  if (m[0]>m[5] && m[0]>m[10])
259  {
260  // 1st element of diag is greatest value
261  // find scale according to 1st element, and double it
262  const f32 scale = sqrtf(1.0f + m[0] - m[5] - m[10]) * 2.0f;
263 
264  // TODO: speed this up
265  X = 0.25f * scale;
266  Y = (m[4] + m[1]) / scale;
267  Z = (m[2] + m[8]) / scale;
268  W = (m[6] - m[9]) / scale;
269  }
270  else if (m[5]>m[10])
271  {
272  // 2nd element of diag is greatest value
273  // find scale according to 2nd element, and double it
274  const f32 scale = sqrtf(1.0f + m[5] - m[0] - m[10]) * 2.0f;
275 
276  // TODO: speed this up
277  X = (m[4] + m[1]) / scale;
278  Y = 0.25f * scale;
279  Z = (m[9] + m[6]) / scale;
280  W = (m[8] - m[2]) / scale;
281  }
282  else
283  {
284  // 3rd element of diag is greatest value
285  // find scale according to 3rd element, and double it
286  const f32 scale = sqrtf(1.0f + m[10] - m[0] - m[5]) * 2.0f;
287 
288  // TODO: speed this up
289  X = (m[8] + m[2]) / scale;
290  Y = (m[9] + m[6]) / scale;
291  Z = 0.25f * scale;
292  W = (m[1] - m[4]) / scale;
293  }
294  }
295 
296  return normalize();
297 }
298 #endif
299 
300 
301 // multiplication operator
302 inline quaternion quaternion::operator*(const quaternion& other) const
303 {
304  quaternion tmp;
305 
306  tmp.W = (other.W * W) - (other.X * X) - (other.Y * Y) - (other.Z * Z);
307  tmp.X = (other.W * X) + (other.X * W) + (other.Y * Z) - (other.Z * Y);
308  tmp.Y = (other.W * Y) + (other.Y * W) + (other.Z * X) - (other.X * Z);
309  tmp.Z = (other.W * Z) + (other.Z * W) + (other.X * Y) - (other.Y * X);
310 
311  return tmp;
312 }
313 
314 
315 // multiplication operator
317 {
318  return quaternion(s*X, s*Y, s*Z, s*W);
319 }
320 
321 
322 // multiplication operator
324 {
325  X*=s;
326  Y*=s;
327  Z*=s;
328  W*=s;
329  return *this;
330 }
331 
332 // multiplication operator
334 {
335  return (*this = other * (*this));
336 }
337 
338 // add operator
340 {
341  return quaternion(X+b.X, Y+b.Y, Z+b.Z, W+b.W);
342 }
343 
344 #ifndef IRR_TEST_BROKEN_QUATERNION_USE
345 // Creates a matrix from this quaternion
347 {
348  core::matrix4 m;
349  getMatrix(m);
350  return m;
351 }
352 #endif
353 
355 inline void quaternion::getMatrixFast( matrix4 &dest) const
356 {
357  // TODO:
358  // gpu quaternion skinning => fast Bones transform chain O_O YEAH!
359  // http://www.mrelusive.com/publications/papers/SIMD-From-Quaternion-to-Matrix-and-Back.pdf
360  dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
361  dest[1] = 2.0f*X*Y + 2.0f*Z*W;
362  dest[2] = 2.0f*X*Z - 2.0f*Y*W;
363  dest[3] = 0.0f;
364 
365  dest[4] = 2.0f*X*Y - 2.0f*Z*W;
366  dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
367  dest[6] = 2.0f*Z*Y + 2.0f*X*W;
368  dest[7] = 0.0f;
369 
370  dest[8] = 2.0f*X*Z + 2.0f*Y*W;
371  dest[9] = 2.0f*Z*Y - 2.0f*X*W;
372  dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
373  dest[11] = 0.0f;
374 
375  dest[12] = 0.f;
376  dest[13] = 0.f;
377  dest[14] = 0.f;
378  dest[15] = 1.f;
379 
380  dest.setDefinitelyIdentityMatrix(false);
381 }
382 
386 inline void quaternion::getMatrix(matrix4 &dest,
387  const core::vector3df &center) const
388 {
389  // ok creating a copy may be slower, but at least avoid internal
390  // state chance (also because otherwise we cannot keep this method "const").
391 
392  quaternion q( *this);
393  q.normalize();
394  f32 X = q.X;
395  f32 Y = q.Y;
396  f32 Z = q.Z;
397  f32 W = q.W;
398 
399  dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
400  dest[1] = 2.0f*X*Y + 2.0f*Z*W;
401  dest[2] = 2.0f*X*Z - 2.0f*Y*W;
402  dest[3] = 0.0f;
403 
404  dest[4] = 2.0f*X*Y - 2.0f*Z*W;
405  dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
406  dest[6] = 2.0f*Z*Y + 2.0f*X*W;
407  dest[7] = 0.0f;
408 
409  dest[8] = 2.0f*X*Z + 2.0f*Y*W;
410  dest[9] = 2.0f*Z*Y - 2.0f*X*W;
411  dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
412  dest[11] = 0.0f;
413 
414  dest[12] = center.X;
415  dest[13] = center.Y;
416  dest[14] = center.Z;
417  dest[15] = 1.f;
418 
419  dest.setDefinitelyIdentityMatrix ( false );
420 }
421 
422 
436  const core::vector3df &center,
437  const core::vector3df &translation) const
438 {
439  quaternion q(*this);
440  q.normalize();
441  f32 X = q.X;
442  f32 Y = q.Y;
443  f32 Z = q.Z;
444  f32 W = q.W;
445 
446  dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
447  dest[1] = 2.0f*X*Y + 2.0f*Z*W;
448  dest[2] = 2.0f*X*Z - 2.0f*Y*W;
449  dest[3] = 0.0f;
450 
451  dest[4] = 2.0f*X*Y - 2.0f*Z*W;
452  dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
453  dest[6] = 2.0f*Z*Y + 2.0f*X*W;
454  dest[7] = 0.0f;
455 
456  dest[8] = 2.0f*X*Z + 2.0f*Y*W;
457  dest[9] = 2.0f*Z*Y - 2.0f*X*W;
458  dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
459  dest[11] = 0.0f;
460 
461  dest.setRotationCenter ( center, translation );
462 }
463 
464 // Creates a matrix from this quaternion
466 {
467  quaternion q(*this);
468  q.normalize();
469  f32 X = q.X;
470  f32 Y = q.Y;
471  f32 Z = q.Z;
472  f32 W = q.W;
473 
474  dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
475  dest[4] = 2.0f*X*Y + 2.0f*Z*W;
476  dest[8] = 2.0f*X*Z - 2.0f*Y*W;
477  dest[12] = 0.0f;
478 
479  dest[1] = 2.0f*X*Y - 2.0f*Z*W;
480  dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
481  dest[9] = 2.0f*Z*Y + 2.0f*X*W;
482  dest[13] = 0.0f;
483 
484  dest[2] = 2.0f*X*Z + 2.0f*Y*W;
485  dest[6] = 2.0f*Z*Y - 2.0f*X*W;
486  dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
487  dest[14] = 0.0f;
488 
489  dest[3] = 0.f;
490  dest[7] = 0.f;
491  dest[11] = 0.f;
492  dest[15] = 1.f;
493 
494  dest.setDefinitelyIdentityMatrix(false);
495 }
496 
497 
498 // Inverts this quaternion
500 {
501  X = -X; Y = -Y; Z = -Z;
502  return *this;
503 }
504 
505 
506 // sets new quaternion
508 {
509  X = x;
510  Y = y;
511  Z = z;
512  W = w;
513  return *this;
514 }
515 
516 
517 // sets new quaternion based on Euler angles
519 {
520  f64 angle;
521 
522  angle = x * 0.5;
523  const f64 sr = sin(angle);
524  const f64 cr = cos(angle);
525 
526  angle = y * 0.5;
527  const f64 sp = sin(angle);
528  const f64 cp = cos(angle);
529 
530  angle = z * 0.5;
531  const f64 sy = sin(angle);
532  const f64 cy = cos(angle);
533 
534  const f64 cpcy = cp * cy;
535  const f64 spcy = sp * cy;
536  const f64 cpsy = cp * sy;
537  const f64 spsy = sp * sy;
538 
539  X = (f32)(sr * cpcy - cr * spsy);
540  Y = (f32)(cr * spcy + sr * cpsy);
541  Z = (f32)(cr * cpsy - sr * spcy);
542  W = (f32)(cr * cpcy + sr * spsy);
543 
544  return normalize();
545 }
546 
547 // sets new quaternion based on Euler angles
549 {
550  return set( vec.X, vec.Y, vec.Z);
551 }
552 
553 // sets new quaternion based on other quaternion
555 {
556  return (*this=quat);
557 }
558 
559 
561 inline bool quaternion::equals(const quaternion& other, const f32 tolerance) const
562 {
563  return core::equals( X, other.X, tolerance) &&
564  core::equals( Y, other.Y, tolerance) &&
565  core::equals( Z, other.Z, tolerance) &&
566  core::equals( W, other.W, tolerance);
567 }
568 
569 
570 // normalizes the quaternion
572 {
573  // removed conditional branch since it may slow down and anyway the condition was
574  // false even after normalization in some cases.
575  return (*this *= reciprocal_squareroot ( X*X + Y*Y + Z*Z + W*W ));
576 }
577 
578 // set this quaternion to the result of the linear interpolation between two quaternions
580 {
581  const f32 scale = 1.0f - time;
582  return (*this = (q1*scale) + (q2*time));
583 }
584 
585 
586 // set this quaternion to the result of the interpolation between two quaternions
587 inline quaternion& quaternion::slerp( quaternion q1, quaternion q2, f32 time, f32 threshold)
588 {
589  f32 angle = q1.dotProduct(q2);
590 
591  // make sure we use the short rotation
592  if (angle < 0.0f)
593  {
594  q1 *= -1.0f;
595  angle *= -1.0f;
596  }
597 
598  if (angle <= (1-threshold)) // spherical interpolation
599  {
600  const f32 theta = acosf(angle);
601  const f32 invsintheta = reciprocal(sinf(theta));
602  const f32 scale = sinf(theta * (1.0f-time)) * invsintheta;
603  const f32 invscale = sinf(theta * time) * invsintheta;
604  return (*this = (q1*scale) + (q2*invscale));
605  }
606  else // linear interpolation
607  return lerp(q1,q2,time);
608 }
609 
610 
611 // calculates the dot product
612 inline f32 quaternion::dotProduct(const quaternion& q2) const
613 {
614  return (X * q2.X) + (Y * q2.Y) + (Z * q2.Z) + (W * q2.W);
615 }
616 
617 
620 {
621  const f32 fHalfAngle = 0.5f*angle;
622  const f32 fSin = sinf(fHalfAngle);
623  W = cosf(fHalfAngle);
624  X = fSin*axis.X;
625  Y = fSin*axis.Y;
626  Z = fSin*axis.Z;
627  return *this;
628 }
629 
630 
631 inline void quaternion::toAngleAxis(f32 &angle, core::vector3df &axis) const
632 {
633  const f32 scale = sqrtf(X*X + Y*Y + Z*Z);
634 
635  if (core::iszero(scale) || W > 1.0f || W < -1.0f)
636  {
637  angle = 0.0f;
638  axis.X = 0.0f;
639  axis.Y = 1.0f;
640  axis.Z = 0.0f;
641  }
642  else
643  {
644  const f32 invscale = reciprocal(scale);
645  angle = 2.0f * acosf(W);
646  axis.X = X * invscale;
647  axis.Y = Y * invscale;
648  axis.Z = Z * invscale;
649  }
650 }
651 
652 inline void quaternion::toEuler(vector3df& euler) const
653 {
654  const f64 sqw = W*W;
655  const f64 sqx = X*X;
656  const f64 sqy = Y*Y;
657  const f64 sqz = Z*Z;
658  const f64 test = 2.0 * (Y*W - X*Z);
659 
660  if (core::equals(test, 1.0, 0.000001))
661  {
662  // heading = rotation about z-axis
663  euler.Z = (f32) (-2.0*atan2(X, W));
664  // bank = rotation about x-axis
665  euler.X = 0;
666  // attitude = rotation about y-axis
667  euler.Y = (f32) (core::PI64/2.0);
668  }
669  else if (core::equals(test, -1.0, 0.000001))
670  {
671  // heading = rotation about z-axis
672  euler.Z = (f32) (2.0*atan2(X, W));
673  // bank = rotation about x-axis
674  euler.X = 0;
675  // attitude = rotation about y-axis
676  euler.Y = (f32) (core::PI64/-2.0);
677  }
678  else
679  {
680  // heading = rotation about z-axis
681  euler.Z = (f32) atan2(2.0 * (X*Y +Z*W),(sqx - sqy - sqz + sqw));
682  // bank = rotation about x-axis
683  euler.X = (f32) atan2(2.0 * (Y*Z +X*W),(-sqx - sqy + sqz + sqw));
684  // attitude = rotation about y-axis
685  euler.Y = (f32) asin( clamp(test, -1.0, 1.0) );
686  }
687 }
688 
689 
691 {
692  // nVidia SDK implementation
693 
694  vector3df uv, uuv;
695  vector3df qvec(X, Y, Z);
696  uv = qvec.crossProduct(v);
697  uuv = qvec.crossProduct(uv);
698  uv *= (2.0f * W);
699  uuv *= 2.0f;
700 
701  return v + uv + uuv;
702 }
703 
704 // set quaternion to identity
706 {
707  W = 1.f;
708  X = 0.f;
709  Y = 0.f;
710  Z = 0.f;
711  return *this;
712 }
713 
715 {
716  // Based on Stan Melax's article in Game Programming Gems
717  // Copy, since cannot modify local
718  vector3df v0 = from;
719  vector3df v1 = to;
720  v0.normalize();
721  v1.normalize();
722 
723  const f32 d = v0.dotProduct(v1);
724  if (d >= 1.0f) // If dot == 1, vectors are the same
725  {
726  return makeIdentity();
727  }
728  else if (d <= -1.0f) // exactly opposite
729  {
730  core::vector3df axis(1.0f, 0.f, 0.f);
731  axis = axis.crossProduct(v0);
732  if (axis.getLength()==0)
733  {
734  axis.set(0.f,1.f,0.f);
735  axis = axis.crossProduct(v0);
736  }
737  // same as fromAngleAxis(core::PI, axis).normalize();
738  return set(axis.X, axis.Y, axis.Z, 0).normalize();
739  }
740 
741  const f32 s = sqrtf( (1+d)*2 ); // optimize inv_sqrt
742  const f32 invs = 1.f / s;
743  const vector3df c = v0.crossProduct(v1)*invs;
744  return set(c.X, c.Y, c.Z, s * 0.5f).normalize();
745 }
746 
747 
748 } // end namespace core
749 } // end namespace irr
750 
751 #endif
752 
f32 dotProduct(const quaternion &other) const
Calculates the dot product.
Definition: quaternion.h:612
vector3d< T > crossProduct(const vector3d< T > &p) const
Calculates the cross product with another vector.
Definition: vector3d.h:147
quaternion & makeIdentity()
Set quaternion to identity.
Definition: quaternion.h:705
void toEuler(vector3df &euler) const
Output this quaternion to an Euler angle (radians)
Definition: quaternion.h:652
const f64 PI64
Constant for 64bit PI.
Definition: irrMath.h:69
T Y
Y coordinate of the vector.
Definition: vector3d.h:413
bool iszero(const f64 a, const f64 tolerance=ROUNDING_ERROR_f64)
returns if a equals zero, taking rounding errors into account
Definition: irrMath.h:307
void getMatrixFast(matrix4 &dest) const
Faster method to create a rotation matrix, you should normalize the quaternion before!
Definition: quaternion.h:355
void setDefinitelyIdentityMatrix(bool isDefinitelyIdentityMatrix)
Sets if the matrix is definitely identity matrix.
Definition: matrix4.h:2330
float f32
32 bit floating point variable.
Definition: irrTypes.h:108
void toAngleAxis(f32 &angle, core::vector3df &axis) const
Fills an angle (radians) around an axis (unit vector)
Definition: quaternion.h:631
void setRotationCenter(const core::vector3df &center, const core::vector3df &translate)
Builds a combined matrix which translates to a center before rotation and translates from origin afte...
Definition: matrix4.h:2171
T X
X coordinate of the vector.
Definition: vector3d.h:410
quaternion & normalize()
Normalizes the quaternion.
Definition: quaternion.h:571
vector3d< T > & set(const T nx, const T ny, const T nz)
Definition: vector3d.h:113
Everything in the Irrlicht Engine can be found in this namespace.
Definition: aabbox3d.h:12
bool operator==(const quaternion &other) const
Equality operator.
Definition: quaternion.h:216
quaternion & operator *=(f32 s)
Multiplication operator with scalar.
Definition: quaternion.h:323
quaternion(f32 x, f32 y, f32 z, f32 w)
Constructor.
Definition: quaternion.h:39
double f64
64 bit floating point variable.
Definition: irrTypes.h:112
quaternion operator *(const quaternion &other) const
Definition: quaternion.h:302
bool equals(const quaternion &other, const f32 tolerance=ROUNDING_ERROR_f32) const
returns if this quaternion equals the other one, taking floating point rounding errors into account
Definition: quaternion.h:561
const f32 ROUNDING_ERROR_f32
Definition: irrMath.h:50
bool operator!=(const quaternion &other) const
inequality operator
Definition: quaternion.h:225
bool equals(const T a, const T b, const T tolerance=roundingError< T >())
returns if a equals b, taking possible rounding errors into account
Definition: irrMath.h:246
quaternion operator+(const quaternion &other) const
Add operator.
Definition: quaternion.h:339
REALINLINE f32 reciprocal(const f32 f)
Definition: irrMath.h:570
quaternion & fromAngleAxis(f32 angle, const vector3df &axis)
Set this quaternion to represent a rotation from angle and axis.
Definition: quaternion.h:619
f32 X
Quaternion elements.
Definition: quaternion.h:187
void getMatrix_transposed(matrix4 &dest) const
Creates a matrix from this quaternion.
Definition: quaternion.h:465
quaternion & slerp(quaternion q1, quaternion q2, f32 time, f32 threshold=.05f)
Set this quaternion to the result of the spherical interpolation between two quaternions.
Definition: quaternion.h:587
quaternion & rotationFromTo(const vector3df &from, const vector3df &to)
Set quaternion to represent a rotation from one vector to another.
Definition: quaternion.h:714
void getMatrixCenter(matrix4 &dest, const core::vector3df &center, const core::vector3df &translation) const
Definition: quaternion.h:435
vector3d< T > & normalize()
Normalizes the vector.
Definition: vector3d.h:168
4x4 matrix. Mostly used as transformation matrix for 3d calculations.
Definition: matrix4.h:45
T dotProduct(const vector3d< T > &other) const
Get the dot product with another vector.
Definition: vector3d.h:125
quaternion & operator=(const quaternion &other)
Assignment operator.
Definition: quaternion.h:231
matrix4 getMatrix() const
Creates a matrix from this quaternion.
Definition: quaternion.h:346
T Z
Z coordinate of the vector.
Definition: vector3d.h:416
Quaternion class for representing rotations.
Definition: quaternion.h:31
T getLength() const
Get length of the vector.
Definition: vector3d.h:117
REALINLINE f64 reciprocal_squareroot(const f64 x)
Definition: irrMath.h:532
quaternion & makeInverse()
Inverts this quaternion.
Definition: quaternion.h:499
quaternion & set(f32 x, f32 y, f32 z, f32 w)
Sets new quaternion.
Definition: quaternion.h:507
quaternion()
Default Constructor.
Definition: quaternion.h:36
const T clamp(const T &value, const T &low, const T &high)
clamps a value between low and high
Definition: irrMath.h:167
quaternion & lerp(quaternion q1, quaternion q2, f32 time)
Set this quaternion to the linear interpolation between two quaternions.
Definition: quaternion.h:579