5 #ifndef __IRR_QUATERNION_H_INCLUDED__
6 #define __IRR_QUATERNION_H_INCLUDED__
16 #define IRR_TEST_BROKEN_QUATERNION_USE 0
42 #if !IRR_TEST_BROKEN_QUATERNION_USE
56 #if !IRR_TEST_BROKEN_QUATERNION_USE
101 #if !IRR_TEST_BROKEN_QUATERNION_USE
156 f32 time,
f32 threshold=.05f);
199 #if !IRR_TEST_BROKEN_QUATERNION_USE
210 return ((
X == other.
X) &&
219 return !(*
this == other);
232 #if !IRR_TEST_BROKEN_QUATERNION_USE
236 const f32 diag = m[0] + m[5] + m[10] + 1;
240 const f32 scale = sqrtf(diag) * 2.0f;
243 X = (m[6] - m[9]) / scale;
244 Y = (m[8] - m[2]) / scale;
245 Z = (m[1] - m[4]) / scale;
250 if (m[0]>m[5] && m[0]>m[10])
254 const f32 scale = sqrtf(1.0f + m[0] - m[5] - m[10]) * 2.0f;
258 Y = (m[4] + m[1]) / scale;
259 Z = (m[2] + m[8]) / scale;
260 W = (m[6] - m[9]) / scale;
266 const f32 scale = sqrtf(1.0f + m[5] - m[0] - m[10]) * 2.0f;
269 X = (m[4] + m[1]) / scale;
271 Z = (m[9] + m[6]) / scale;
272 W = (m[8] - m[2]) / scale;
278 const f32 scale = sqrtf(1.0f + m[10] - m[0] - m[5]) * 2.0f;
281 X = (m[8] + m[2]) / scale;
282 Y = (m[9] + m[6]) / scale;
284 W = (m[1] - m[4]) / scale;
298 tmp.
W = (other.
W *
W) - (other.
X *
X) - (other.
Y *
Y) - (other.
Z *
Z);
299 tmp.
X = (other.
W *
X) + (other.
X *
W) + (other.
Y *
Z) - (other.
Z *
Y);
300 tmp.
Y = (other.
W *
Y) + (other.
Y *
W) + (other.
Z *
X) - (other.
X *
Z);
301 tmp.
Z = (other.
W *
Z) + (other.
Z *
W) + (other.
X *
Y) - (other.
Y *
X);
327 return (*
this = other * (*
this));
336 #if !IRR_TEST_BROKEN_QUATERNION_USE
352 dest[0] = 1.0f - 2.0f*
Y*
Y - 2.0f*
Z*
Z;
353 dest[1] = 2.0f*
X*
Y + 2.0f*Z*
W;
354 dest[2] = 2.0f*
X*Z - 2.0f*
Y*
W;
357 dest[4] = 2.0f*
X*
Y - 2.0f*Z*
W;
358 dest[5] = 1.0f - 2.0f*
X*
X - 2.0f*Z*
Z;
359 dest[6] = 2.0f*Z*
Y + 2.0f*
X*
W;
362 dest[8] = 2.0f*
X*Z + 2.0f*
Y*
W;
363 dest[9] = 2.0f*Z*
Y - 2.0f*
X*
W;
364 dest[10] = 1.0f - 2.0f*
X*
X - 2.0f*
Y*
Y;
392 dest[0] = 1.0f - 2.0f*
Y*
Y - 2.0f*
Z*
Z;
393 dest[1] = 2.0f*
X*
Y + 2.0f*Z*
W;
394 dest[2] = 2.0f*
X*Z - 2.0f*
Y*
W;
397 dest[4] = 2.0f*
X*
Y - 2.0f*Z*
W;
398 dest[5] = 1.0f - 2.0f*
X*
X - 2.0f*Z*
Z;
399 dest[6] = 2.0f*Z*
Y + 2.0f*
X*
W;
402 dest[8] = 2.0f*
X*Z + 2.0f*
Y*
W;
403 dest[9] = 2.0f*Z*
Y - 2.0f*
X*
W;
404 dest[10] = 1.0f - 2.0f*
X*
X - 2.0f*
Y*
Y;
413 dest[0] = 1.0f - 2.0f*
Y*
Y - 2.0f*
Z*
Z;
414 dest[4] = 2.0f*
X*
Y + 2.0f*Z*
W;
415 dest[8] = 2.0f*
X*Z - 2.0f*
Y*
W;
418 dest[1] = 2.0f*
X*
Y - 2.0f*Z*
W;
419 dest[5] = 1.0f - 2.0f*
X*
X - 2.0f*Z*
Z;
420 dest[9] = 2.0f*Z*
Y + 2.0f*
X*
W;
423 dest[2] = 2.0f*
X*Z + 2.0f*
Y*
W;
424 dest[6] = 2.0f*Z*
Y - 2.0f*
X*
W;
425 dest[10] = 1.0f - 2.0f*
X*
X - 2.0f*
Y*
Y;
462 const f64 sr = sin(angle);
463 const f64 cr = cos(angle);
466 const f64 sp = sin(angle);
467 const f64 cp = cos(angle);
470 const f64 sy = sin(angle);
471 const f64 cy = cos(angle);
473 const f64 cpcy = cp * cy;
474 const f64 spcy = sp * cy;
475 const f64 cpsy = cp * sy;
476 const f64 spsy = sp * sy;
478 X = (
f32)(sr * cpcy - cr * spsy);
479 Y = (
f32)(cr * spcy + sr * cpsy);
480 Z = (
f32)(cr * cpsy - sr * spcy);
481 W = (
f32)(cr * cpcy + sr * spsy);
489 return set(vec.
X, vec.
Y, vec.
Z);
525 const f32 scale = 1.0f - time;
526 return (*
this = (q1*scale) + (q2*time));
542 if (angle <= (1-threshold))
544 const f32 theta = acosf(angle);
546 const f32 scale = sinf(theta * (1.0f-time)) * invsintheta;
547 const f32 invscale = sinf(theta * time) * invsintheta;
548 return (*
this = (q1*scale) + (q2*invscale));
551 return lerp(q1,q2,time);
558 return (
X * q2.
X) + (
Y * q2.
Y) + (
Z * q2.
Z) + (
W * q2.
W);
565 const f32 fHalfAngle = 0.5f*angle;
566 const f32 fSin = sinf(fHalfAngle);
567 W = cosf(fHalfAngle);
577 const f32 scale = sqrtf(
X*
X +
Y*
Y +
Z*
Z);
589 angle = 2.0f * acosf(
W);
590 axis.
X =
X * invscale;
591 axis.
Y =
Y * invscale;
592 axis.
Z = Z * invscale;
602 const f64 test = 2.0 * (Y*W - X*
Z);
607 euler.
Z = (
f32) (-2.0*atan2(X, W));
616 euler.
Z = (
f32) (2.0*atan2(X, W));
625 euler.
Z = (
f32) atan2(2.0 * (X*Y +Z*W),(sqx - sqy - sqz + sqw));
627 euler.
X = (
f32) atan2(2.0 * (Y*Z +X*W),(-sqx - sqy + sqz + sqw));
629 euler.
Y = (
f32) asin(
clamp(test, -1.0, 1.0) );
678 axis.
set(0.f,1.f,0.f);
685 const f32 s = sqrtf( (1+d)*2 );
686 const f32 invs = 1.f / s;
quaternion & makeIdentity()
Set quaternion to identity.
const f64 PI64
Constant for 64bit PI.
T Y
Y coordinate of the vector.
bool iszero(const f64 a, const f64 tolerance=ROUNDING_ERROR_f64)
returns if a equals zero, taking rounding errors into account
void setDefinitelyIdentityMatrix(bool isDefinitelyIdentityMatrix)
Sets if the matrix is definitely identity matrix.
float f32
32 bit floating point variable.
f32 dotProduct(const quaternion &other) const
Calculates the dot product.
void toAngleAxis(f32 &angle, core::vector3df &axis) const
Fills an angle (radians) around an axis (unit vector)
void setRotationCenter(const core::vector3df ¢er, const core::vector3df &translate)
Builds a combined matrix which translates to a center before rotation and translates from origin afte...
T X
X coordinate of the vector.
quaternion & normalize()
Normalizes the quaternion.
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 ...
vector3d< T > & set(const T nx, const T ny, const T nz)
void toEuler(vector3df &euler) const
Output this quaternion to an euler angle (radians)
Everything in the Irrlicht Engine can be found in this namespace.
quaternion(f32 x, f32 y, f32 z, f32 w)
Constructor.
double f64
64 bit floating point variable.
vector3d< T > crossProduct(const vector3d< T > &p) const
Calculates the cross product with another vector.
const f32 ROUNDING_ERROR_f32
quaternion operator+(const quaternion &other) const
Add operator.
REALINLINE f32 reciprocal(const f32 f)
void getMatrixCenter(matrix4 &dest, const core::vector3df ¢er, const core::vector3df &translation) const
quaternion & fromAngleAxis(f32 angle, const vector3df &axis)
Create quaternion from rotation angle and rotation axis.
f32 X
Quaternion elements.
quaternion & slerp(quaternion q1, quaternion q2, f32 time, f32 threshold=.05f)
Set this quaternion to the result of the spherical interpolation between two quaternions.
quaternion & rotationFromTo(const vector3df &from, const vector3df &to)
Set quaternion to represent a rotation from one vector to another.
vector3d< T > & normalize()
Normalizes the vector.
4x4 matrix. Mostly used as transformation matrix for 3d calculations.
quaternion & operator=(const quaternion &other)
Assignment operator.
bool operator!=(const quaternion &other) const
inequality operator
T Z
Z coordinate of the vector.
Quaternion class for representing rotations.
T dotProduct(const vector3d< T > &other) const
Get the dot product with another vector.
quaternion operator*(const quaternion &other) const
Multiplication operator.
bool equals(const f64 a, const f64 b, const f64 tolerance=ROUNDING_ERROR_f64)
returns if a equals b, taking possible rounding errors into account
REALINLINE f64 reciprocal_squareroot(const f64 x)
matrix4 getMatrix() const
Creates a matrix from this quaternion.
quaternion & makeInverse()
Inverts this quaternion.
bool operator==(const quaternion &other) const
Equalilty operator.
T getLength() const
Get length of the vector.
quaternion & set(f32 x, f32 y, f32 z, f32 w)
Sets new quaternion.
quaternion()
Default Constructor.
const T clamp(const T &value, const T &low, const T &high)
clamps a value between low and high
quaternion & lerp(quaternion q1, quaternion q2, f32 time)
Set this quaternion to the linear interpolation between two quaternions.
quaternion & operator*=(f32 s)
Multiplication operator with scalar.
void getMatrix_transposed(matrix4 &dest) const
Creates a matrix from this quaternion.