From 7028cbe09c688437910a25623098762bf0fa592d Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 28 Mar 2016 22:28:34 +1000 Subject: Move Irrlicht to src/others. --- .../doc/html/quaternion_8h_source.html | 730 +++++++++++++++++++++ 1 file changed, 730 insertions(+) create mode 100644 src/others/irrlicht-1.8.1/doc/html/quaternion_8h_source.html (limited to 'src/others/irrlicht-1.8.1/doc/html/quaternion_8h_source.html') diff --git a/src/others/irrlicht-1.8.1/doc/html/quaternion_8h_source.html b/src/others/irrlicht-1.8.1/doc/html/quaternion_8h_source.html new file mode 100644 index 0000000..2221a49 --- /dev/null +++ b/src/others/irrlicht-1.8.1/doc/html/quaternion_8h_source.html @@ -0,0 +1,730 @@ + + + + +Irrlicht 3D Engine: quaternion.h Source File + + + + + + + + + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + +
+
Irrlicht 3D Engine + +
+ +
+ + + + + + +
+
+
+ + + + +
+
+ +
+
+
+ +
+
+
+
quaternion.h
+
+
+Go to the documentation of this file.
00001 // Copyright (C) 2002-2012 Nikolaus Gebhardt
+00002 // This file is part of the "Irrlicht Engine".
+00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
+00004 
+00005 #ifndef __IRR_QUATERNION_H_INCLUDED__
+00006 #define __IRR_QUATERNION_H_INCLUDED__
+00007 
+00008 #include "irrTypes.h"
+00009 #include "irrMath.h"
+00010 #include "matrix4.h"
+00011 #include "vector3d.h"
+00012 
+00013 // Between Irrlicht 1.7 and Irrlicht 1.8 the quaternion-matrix conversions got fixed.
+00014 // This define disables all involved functions completely to allow finding all places 
+00015 // where the wrong conversions had been in use.
+00016 #define IRR_TEST_BROKEN_QUATERNION_USE 0
+00017 
+00018 namespace irr
+00019 {
+00020 namespace core
+00021 {
+00022 
+00024 
+00026 class quaternion
+00027 {
+00028     public:
+00029 
+00031         quaternion() : X(0.0f), Y(0.0f), Z(0.0f), W(1.0f) {}
+00032 
+00034         quaternion(f32 x, f32 y, f32 z, f32 w) : X(x), Y(y), Z(z), W(w) { }
+00035 
+00037         quaternion(f32 x, f32 y, f32 z);
+00038 
+00040         quaternion(const vector3df& vec);
+00041 
+00042 #if !IRR_TEST_BROKEN_QUATERNION_USE
+00043 
+00044         quaternion(const matrix4& mat);
+00045 #endif
+00046 
+00048         bool operator==(const quaternion& other) const;
+00049 
+00051         bool operator!=(const quaternion& other) const;
+00052 
+00054         inline quaternion& operator=(const quaternion& other);
+00055 
+00056 #if !IRR_TEST_BROKEN_QUATERNION_USE
+00057 
+00058         inline quaternion& operator=(const matrix4& other);
+00059 #endif
+00060 
+00062         quaternion operator+(const quaternion& other) const;
+00063 
+00065         quaternion operator*(const quaternion& other) const;
+00066 
+00068         quaternion operator*(f32 s) const;
+00069 
+00071         quaternion& operator*=(f32 s);
+00072 
+00074         vector3df operator*(const vector3df& v) const;
+00075 
+00077         quaternion& operator*=(const quaternion& other);
+00078 
+00080         inline f32 dotProduct(const quaternion& other) const;
+00081 
+00083         inline quaternion& set(f32 x, f32 y, f32 z, f32 w);
+00084 
+00086         inline quaternion& set(f32 x, f32 y, f32 z);
+00087 
+00089         inline quaternion& set(const core::vector3df& vec);
+00090 
+00092         inline quaternion& set(const core::quaternion& quat);
+00093 
+00095         inline bool equals(const quaternion& other,
+00096                 const f32 tolerance = ROUNDING_ERROR_f32 ) const;
+00097 
+00099         inline quaternion& normalize();
+00100 
+00101 #if !IRR_TEST_BROKEN_QUATERNION_USE
+00102 
+00103         matrix4 getMatrix() const;
+00104 #endif 
+00105 
+00107         void getMatrix( matrix4 &dest, const core::vector3df &translation=core::vector3df() ) const;
+00108 
+00126         void getMatrixCenter( matrix4 &dest, const core::vector3df &center, const core::vector3df &translation ) const;
+00127 
+00129         inline void getMatrix_transposed( matrix4 &dest ) const;
+00130 
+00132         quaternion& makeInverse();
+00133 
+00135 
+00141         quaternion& lerp(quaternion q1, quaternion q2, f32 time);
+00142 
+00144 
+00155         quaternion& slerp(quaternion q1, quaternion q2,
+00156                 f32 time, f32 threshold=.05f);
+00157 
+00159 
+00164         quaternion& fromAngleAxis (f32 angle, const vector3df& axis);
+00165 
+00167         void toAngleAxis (f32 &angle, core::vector3df& axis) const;
+00168 
+00170         void toEuler(vector3df& euler) const;
+00171 
+00173         quaternion& makeIdentity();
+00174 
+00176         quaternion& rotationFromTo(const vector3df& from, const vector3df& to);
+00177 
+00179         f32 X; // vectorial (imaginary) part
+00180         f32 Y;
+00181         f32 Z;
+00182         f32 W; // real part
+00183 };
+00184 
+00185 
+00186 // Constructor which converts euler angles to a quaternion
+00187 inline quaternion::quaternion(f32 x, f32 y, f32 z)
+00188 {
+00189     set(x,y,z);
+00190 }
+00191 
+00192 
+00193 // Constructor which converts euler angles to a quaternion
+00194 inline quaternion::quaternion(const vector3df& vec)
+00195 {
+00196     set(vec.X,vec.Y,vec.Z);
+00197 }
+00198 
+00199 #if !IRR_TEST_BROKEN_QUATERNION_USE
+00200 // Constructor which converts a matrix to a quaternion
+00201 inline quaternion::quaternion(const matrix4& mat)
+00202 {
+00203     (*this) = mat;
+00204 }
+00205 #endif
+00206 
+00207 // equal operator
+00208 inline bool quaternion::operator==(const quaternion& other) const
+00209 {
+00210     return ((X == other.X) &&
+00211         (Y == other.Y) &&
+00212         (Z == other.Z) &&
+00213         (W == other.W));
+00214 }
+00215 
+00216 // inequality operator
+00217 inline bool quaternion::operator!=(const quaternion& other) const
+00218 {
+00219     return !(*this == other);
+00220 }
+00221 
+00222 // assignment operator
+00223 inline quaternion& quaternion::operator=(const quaternion& other)
+00224 {
+00225     X = other.X;
+00226     Y = other.Y;
+00227     Z = other.Z;
+00228     W = other.W;
+00229     return *this;
+00230 }
+00231 
+00232 #if !IRR_TEST_BROKEN_QUATERNION_USE
+00233 // matrix assignment operator
+00234 inline quaternion& quaternion::operator=(const matrix4& m)
+00235 {
+00236     const f32 diag = m[0] + m[5] + m[10] + 1;
+00237 
+00238     if( diag > 0.0f )
+00239     {
+00240         const f32 scale = sqrtf(diag) * 2.0f; // get scale from diagonal
+00241 
+00242         // TODO: speed this up
+00243         X = (m[6] - m[9]) / scale;
+00244         Y = (m[8] - m[2]) / scale;
+00245         Z = (m[1] - m[4]) / scale;
+00246         W = 0.25f * scale;
+00247     }
+00248     else
+00249     {
+00250         if (m[0]>m[5] && m[0]>m[10])
+00251         {
+00252             // 1st element of diag is greatest value
+00253             // find scale according to 1st element, and double it
+00254             const f32 scale = sqrtf(1.0f + m[0] - m[5] - m[10]) * 2.0f;
+00255 
+00256             // TODO: speed this up
+00257             X = 0.25f * scale;
+00258             Y = (m[4] + m[1]) / scale;
+00259             Z = (m[2] + m[8]) / scale;
+00260             W = (m[6] - m[9]) / scale;
+00261         }
+00262         else if (m[5]>m[10])
+00263         {
+00264             // 2nd element of diag is greatest value
+00265             // find scale according to 2nd element, and double it
+00266             const f32 scale = sqrtf(1.0f + m[5] - m[0] - m[10]) * 2.0f;
+00267 
+00268             // TODO: speed this up
+00269             X = (m[4] + m[1]) / scale;
+00270             Y = 0.25f * scale;
+00271             Z = (m[9] + m[6]) / scale;
+00272             W = (m[8] - m[2]) / scale;
+00273         }
+00274         else
+00275         {
+00276             // 3rd element of diag is greatest value
+00277             // find scale according to 3rd element, and double it
+00278             const f32 scale = sqrtf(1.0f + m[10] - m[0] - m[5]) * 2.0f;
+00279 
+00280             // TODO: speed this up
+00281             X = (m[8] + m[2]) / scale;
+00282             Y = (m[9] + m[6]) / scale;
+00283             Z = 0.25f * scale;
+00284             W = (m[1] - m[4]) / scale;
+00285         }
+00286     }
+00287 
+00288     return normalize();
+00289 }
+00290 #endif
+00291 
+00292 
+00293 // multiplication operator
+00294 inline quaternion quaternion::operator*(const quaternion& other) const
+00295 {
+00296     quaternion tmp;
+00297 
+00298     tmp.W = (other.W * W) - (other.X * X) - (other.Y * Y) - (other.Z * Z);
+00299     tmp.X = (other.W * X) + (other.X * W) + (other.Y * Z) - (other.Z * Y);
+00300     tmp.Y = (other.W * Y) + (other.Y * W) + (other.Z * X) - (other.X * Z);
+00301     tmp.Z = (other.W * Z) + (other.Z * W) + (other.X * Y) - (other.Y * X);
+00302 
+00303     return tmp;
+00304 }
+00305 
+00306 
+00307 // multiplication operator
+00308 inline quaternion quaternion::operator*(f32 s) const
+00309 {
+00310     return quaternion(s*X, s*Y, s*Z, s*W);
+00311 }
+00312 
+00313 
+00314 // multiplication operator
+00315 inline quaternion& quaternion::operator*=(f32 s)
+00316 {
+00317     X*=s;
+00318     Y*=s;
+00319     Z*=s;
+00320     W*=s;
+00321     return *this;
+00322 }
+00323 
+00324 // multiplication operator
+00325 inline quaternion& quaternion::operator*=(const quaternion& other)
+00326 {
+00327     return (*this = other * (*this));
+00328 }
+00329 
+00330 // add operator
+00331 inline quaternion quaternion::operator+(const quaternion& b) const
+00332 {
+00333     return quaternion(X+b.X, Y+b.Y, Z+b.Z, W+b.W);
+00334 }
+00335 
+00336 #if !IRR_TEST_BROKEN_QUATERNION_USE
+00337 // Creates a matrix from this quaternion
+00338 inline matrix4 quaternion::getMatrix() const
+00339 {
+00340     core::matrix4 m;
+00341     getMatrix(m);
+00342     return m;
+00343 }
+00344 #endif
+00345 
+00349 inline void quaternion::getMatrix(matrix4 &dest,
+00350         const core::vector3df &center) const
+00351 {
+00352     dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
+00353     dest[1] = 2.0f*X*Y + 2.0f*Z*W;
+00354     dest[2] = 2.0f*X*Z - 2.0f*Y*W;
+00355     dest[3] = 0.0f;
+00356 
+00357     dest[4] = 2.0f*X*Y - 2.0f*Z*W;
+00358     dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
+00359     dest[6] = 2.0f*Z*Y + 2.0f*X*W;
+00360     dest[7] = 0.0f;
+00361 
+00362     dest[8] = 2.0f*X*Z + 2.0f*Y*W;
+00363     dest[9] = 2.0f*Z*Y - 2.0f*X*W;
+00364     dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
+00365     dest[11] = 0.0f;
+00366 
+00367     dest[12] = center.X;
+00368     dest[13] = center.Y;
+00369     dest[14] = center.Z;
+00370     dest[15] = 1.f;
+00371 
+00372     dest.setDefinitelyIdentityMatrix ( false );
+00373 }
+00374 
+00375 
+00388 inline void quaternion::getMatrixCenter(matrix4 &dest,
+00389                     const core::vector3df &center,
+00390                     const core::vector3df &translation) const
+00391 {
+00392     dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
+00393     dest[1] = 2.0f*X*Y + 2.0f*Z*W;
+00394     dest[2] = 2.0f*X*Z - 2.0f*Y*W;
+00395     dest[3] = 0.0f;
+00396 
+00397     dest[4] = 2.0f*X*Y - 2.0f*Z*W;
+00398     dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
+00399     dest[6] = 2.0f*Z*Y + 2.0f*X*W;
+00400     dest[7] = 0.0f;
+00401 
+00402     dest[8] = 2.0f*X*Z + 2.0f*Y*W;
+00403     dest[9] = 2.0f*Z*Y - 2.0f*X*W;
+00404     dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
+00405     dest[11] = 0.0f;
+00406 
+00407     dest.setRotationCenter ( center, translation );
+00408 }
+00409 
+00410 // Creates a matrix from this quaternion
+00411 inline void quaternion::getMatrix_transposed(matrix4 &dest) const
+00412 {
+00413     dest[0] = 1.0f - 2.0f*Y*Y - 2.0f*Z*Z;
+00414     dest[4] = 2.0f*X*Y + 2.0f*Z*W;
+00415     dest[8] = 2.0f*X*Z - 2.0f*Y*W;
+00416     dest[12] = 0.0f;
+00417 
+00418     dest[1] = 2.0f*X*Y - 2.0f*Z*W;
+00419     dest[5] = 1.0f - 2.0f*X*X - 2.0f*Z*Z;
+00420     dest[9] = 2.0f*Z*Y + 2.0f*X*W;
+00421     dest[13] = 0.0f;
+00422 
+00423     dest[2] = 2.0f*X*Z + 2.0f*Y*W;
+00424     dest[6] = 2.0f*Z*Y - 2.0f*X*W;
+00425     dest[10] = 1.0f - 2.0f*X*X - 2.0f*Y*Y;
+00426     dest[14] = 0.0f;
+00427 
+00428     dest[3] = 0.f;
+00429     dest[7] = 0.f;
+00430     dest[11] = 0.f;
+00431     dest[15] = 1.f;
+00432 
+00433     dest.setDefinitelyIdentityMatrix(false);
+00434 }
+00435 
+00436 
+00437 // Inverts this quaternion
+00438 inline quaternion& quaternion::makeInverse()
+00439 {
+00440     X = -X; Y = -Y; Z = -Z;
+00441     return *this;
+00442 }
+00443 
+00444 
+00445 // sets new quaternion
+00446 inline quaternion& quaternion::set(f32 x, f32 y, f32 z, f32 w)
+00447 {
+00448     X = x;
+00449     Y = y;
+00450     Z = z;
+00451     W = w;
+00452     return *this;
+00453 }
+00454 
+00455 
+00456 // sets new quaternion based on euler angles
+00457 inline quaternion& quaternion::set(f32 x, f32 y, f32 z)
+00458 {
+00459     f64 angle;
+00460 
+00461     angle = x * 0.5;
+00462     const f64 sr = sin(angle);
+00463     const f64 cr = cos(angle);
+00464 
+00465     angle = y * 0.5;
+00466     const f64 sp = sin(angle);
+00467     const f64 cp = cos(angle);
+00468 
+00469     angle = z * 0.5;
+00470     const f64 sy = sin(angle);
+00471     const f64 cy = cos(angle);
+00472 
+00473     const f64 cpcy = cp * cy;
+00474     const f64 spcy = sp * cy;
+00475     const f64 cpsy = cp * sy;
+00476     const f64 spsy = sp * sy;
+00477 
+00478     X = (f32)(sr * cpcy - cr * spsy);
+00479     Y = (f32)(cr * spcy + sr * cpsy);
+00480     Z = (f32)(cr * cpsy - sr * spcy);
+00481     W = (f32)(cr * cpcy + sr * spsy);
+00482 
+00483     return normalize();
+00484 }
+00485 
+00486 // sets new quaternion based on euler angles
+00487 inline quaternion& quaternion::set(const core::vector3df& vec)
+00488 {
+00489     return set(vec.X, vec.Y, vec.Z);
+00490 }
+00491 
+00492 // sets new quaternion based on other quaternion
+00493 inline quaternion& quaternion::set(const core::quaternion& quat)
+00494 {
+00495     return (*this=quat);
+00496 }
+00497 
+00498 
+00500 inline bool quaternion::equals(const quaternion& other, const f32 tolerance) const
+00501 {
+00502     return core::equals(X, other.X, tolerance) &&
+00503         core::equals(Y, other.Y, tolerance) &&
+00504         core::equals(Z, other.Z, tolerance) &&
+00505         core::equals(W, other.W, tolerance);
+00506 }
+00507 
+00508 
+00509 // normalizes the quaternion
+00510 inline quaternion& quaternion::normalize()
+00511 {
+00512     const f32 n = X*X + Y*Y + Z*Z + W*W;
+00513 
+00514     if (n == 1)
+00515         return *this;
+00516 
+00517     //n = 1.0f / sqrtf(n);
+00518     return (*this *= reciprocal_squareroot ( n ));
+00519 }
+00520 
+00521 
+00522 // set this quaternion to the result of the linear interpolation between two quaternions
+00523 inline quaternion& quaternion::lerp(quaternion q1, quaternion q2, f32 time)
+00524 {
+00525     const f32 scale = 1.0f - time;
+00526     return (*this = (q1*scale) + (q2*time));
+00527 }
+00528 
+00529 
+00530 // set this quaternion to the result of the interpolation between two quaternions
+00531 inline quaternion& quaternion::slerp(quaternion q1, quaternion q2, f32 time, f32 threshold)
+00532 {
+00533     f32 angle = q1.dotProduct(q2);
+00534 
+00535     // make sure we use the short rotation
+00536     if (angle < 0.0f)
+00537     {
+00538         q1 *= -1.0f;
+00539         angle *= -1.0f;
+00540     }
+00541 
+00542     if (angle <= (1-threshold)) // spherical interpolation
+00543     {
+00544         const f32 theta = acosf(angle);
+00545         const f32 invsintheta = reciprocal(sinf(theta));
+00546         const f32 scale = sinf(theta * (1.0f-time)) * invsintheta;
+00547         const f32 invscale = sinf(theta * time) * invsintheta;
+00548         return (*this = (q1*scale) + (q2*invscale));
+00549     }
+00550     else // linear interploation
+00551         return lerp(q1,q2,time);
+00552 }
+00553 
+00554 
+00555 // calculates the dot product
+00556 inline f32 quaternion::dotProduct(const quaternion& q2) const
+00557 {
+00558     return (X * q2.X) + (Y * q2.Y) + (Z * q2.Z) + (W * q2.W);
+00559 }
+00560 
+00561 
+00563 inline quaternion& quaternion::fromAngleAxis(f32 angle, const vector3df& axis)
+00564 {
+00565     const f32 fHalfAngle = 0.5f*angle;
+00566     const f32 fSin = sinf(fHalfAngle);
+00567     W = cosf(fHalfAngle);
+00568     X = fSin*axis.X;
+00569     Y = fSin*axis.Y;
+00570     Z = fSin*axis.Z;
+00571     return *this;
+00572 }
+00573 
+00574 
+00575 inline void quaternion::toAngleAxis(f32 &angle, core::vector3df &axis) const
+00576 {
+00577     const f32 scale = sqrtf(X*X + Y*Y + Z*Z);
+00578 
+00579     if (core::iszero(scale) || W > 1.0f || W < -1.0f)
+00580     {
+00581         angle = 0.0f;
+00582         axis.X = 0.0f;
+00583         axis.Y = 1.0f;
+00584         axis.Z = 0.0f;
+00585     }
+00586     else
+00587     {
+00588         const f32 invscale = reciprocal(scale);
+00589         angle = 2.0f * acosf(W);
+00590         axis.X = X * invscale;
+00591         axis.Y = Y * invscale;
+00592         axis.Z = Z * invscale;
+00593     }
+00594 }
+00595 
+00596 inline void quaternion::toEuler(vector3df& euler) const
+00597 {
+00598     const f64 sqw = W*W;
+00599     const f64 sqx = X*X;
+00600     const f64 sqy = Y*Y;
+00601     const f64 sqz = Z*Z;
+00602     const f64 test = 2.0 * (Y*W - X*Z);
+00603 
+00604     if (core::equals(test, 1.0, 0.000001))
+00605     {
+00606         // heading = rotation about z-axis
+00607         euler.Z = (f32) (-2.0*atan2(X, W));
+00608         // bank = rotation about x-axis
+00609         euler.X = 0;
+00610         // attitude = rotation about y-axis
+00611         euler.Y = (f32) (core::PI64/2.0);
+00612     }
+00613     else if (core::equals(test, -1.0, 0.000001))
+00614     {
+00615         // heading = rotation about z-axis
+00616         euler.Z = (f32) (2.0*atan2(X, W));
+00617         // bank = rotation about x-axis
+00618         euler.X = 0;
+00619         // attitude = rotation about y-axis
+00620         euler.Y = (f32) (core::PI64/-2.0);
+00621     }
+00622     else
+00623     {
+00624         // heading = rotation about z-axis
+00625         euler.Z = (f32) atan2(2.0 * (X*Y +Z*W),(sqx - sqy - sqz + sqw));
+00626         // bank = rotation about x-axis
+00627         euler.X = (f32) atan2(2.0 * (Y*Z +X*W),(-sqx - sqy + sqz + sqw));
+00628         // attitude = rotation about y-axis
+00629         euler.Y = (f32) asin( clamp(test, -1.0, 1.0) );
+00630     }
+00631 }
+00632 
+00633 
+00634 inline vector3df quaternion::operator* (const vector3df& v) const
+00635 {
+00636     // nVidia SDK implementation
+00637 
+00638     vector3df uv, uuv;
+00639     vector3df qvec(X, Y, Z);
+00640     uv = qvec.crossProduct(v);
+00641     uuv = qvec.crossProduct(uv);
+00642     uv *= (2.0f * W);
+00643     uuv *= 2.0f;
+00644 
+00645     return v + uv + uuv;
+00646 }
+00647 
+00648 // set quaternion to identity
+00649 inline core::quaternion& quaternion::makeIdentity()
+00650 {
+00651     W = 1.f;
+00652     X = 0.f;
+00653     Y = 0.f;
+00654     Z = 0.f;
+00655     return *this;
+00656 }
+00657 
+00658 inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const vector3df& to)
+00659 {
+00660     // Based on Stan Melax's article in Game Programming Gems
+00661     // Copy, since cannot modify local
+00662     vector3df v0 = from;
+00663     vector3df v1 = to;
+00664     v0.normalize();
+00665     v1.normalize();
+00666 
+00667     const f32 d = v0.dotProduct(v1);
+00668     if (d >= 1.0f) // If dot == 1, vectors are the same
+00669     {
+00670         return makeIdentity();
+00671     }
+00672     else if (d <= -1.0f) // exactly opposite
+00673     {
+00674         core::vector3df axis(1.0f, 0.f, 0.f);
+00675         axis = axis.crossProduct(v0);
+00676         if (axis.getLength()==0)
+00677         {
+00678             axis.set(0.f,1.f,0.f);
+00679             axis = axis.crossProduct(v0);
+00680         }
+00681         // same as fromAngleAxis(core::PI, axis).normalize();
+00682         return set(axis.X, axis.Y, axis.Z, 0).normalize();
+00683     }
+00684 
+00685     const f32 s = sqrtf( (1+d)*2 ); // optimize inv_sqrt
+00686     const f32 invs = 1.f / s;
+00687     const vector3df c = v0.crossProduct(v1)*invs;
+00688     return set(c.X, c.Y, c.Z, s * 0.5f).normalize();
+00689 }
+00690 
+00691 
+00692 } // end namespace core
+00693 } // end namespace irr
+00694 
+00695 #endif
+00696 
+
+
+ + + + + -- cgit v1.1