• Página principal
  • Clases
  • Archivos
  • Lista de archivos

Maths.h

00001 //-----------------------------------------------------------------------------
00002 // Copyright (c) 2005-2009 dhpoware. All Rights Reserved.
00003 //
00004 // Permission is hereby granted, free of charge, to any person obtaining a
00005 // copy of this software and associated documentation files (the "Software"),
00006 // to deal in the Software without restriction, including without limitation
00007 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 // and/or sell copies of the Software, and to permit persons to whom the
00009 // Software is furnished to do so, subject to the following conditions:
00010 //
00011 // The above copyright notice and this permission notice shall be included in
00012 // all copies or substantial portions of the Software.
00013 //
00014 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00019 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
00020 // IN THE SOFTWARE.
00021 //-----------------------------------------------------------------------------
00022 
00023 #if !defined(MATHS_H)
00024 #define MATHS_H
00025 
00026 #include <cmath>
00027 #include <cstdlib>
00028 
00029 //-----------------------------------------------------------------------------
00030 // Classes.
00031 
00032 class Vector2;
00033 class Vector3;
00034 class Vector4;
00035 class Matrix4;
00036 
00039 class Math
00040 {
00041 public:
00042         static const float PI;
00043         static const float HALF_PI;
00044         static const float QUARTER_PI;
00045         static const float TWO_PI;
00046         static const float INV_PI;
00047         static const float INV_TWO_PI;
00048         static const float EPSILON;
00049 
00057         template <typename T>
00058         static T lerp(const T &a, const T &b, float t)
00059         {
00060                 return a + (b - a) * t;
00061         }
00062 
00071         template <typename T>
00072         static T bilerp(const T &a, const T &b, const T &c, const T &d, float u, float v)
00073         {
00074                 return a * ((1.0f - u) * (1.0f - v))
00075                         + b * (u * (1.0f - v))
00076                         + c * (v * (1.0f - u))
00077                         + d * (u * v);
00078         }
00079 
00085         static void cartesianToSpherical(float x, float y, float z, float &rho, float &phi, float &theta)
00086         {
00087                 rho = sqrtf((x * x) + (y * y) + (z * z));
00088                 phi = asinf(y / rho);
00089                 theta = atan2f(z, x);
00090         }
00091 
00097         static void sphericalToCartesian(float rho, float phi, float theta, float &x, float &y, float &z)
00098         {
00099                 x = rho * cosf(phi) * cosf(theta);
00100                 y = rho * sinf(phi);
00101                 z = rho * cosf(phi) * sinf(theta);
00102         }
00103 
00107         void cylindricalToCartesian(float radius, float theta, float height, unsigned int axis, float &x, float &y, float &z)
00108         {
00109                 if (axis == 0)
00110                 {
00111                         x = height;
00112                         y = cosf(theta) * radius;
00113                         z = sinf(theta) * radius;
00114                 }
00115                 else if (axis == 1)
00116                 {
00117                         y = height;
00118                         z = cosf(theta) * radius;
00119                         x = sinf(theta) * radius;
00120                 }
00121                 else
00122                 {
00123                         z = height;
00124                         x = cosf(theta) * radius;
00125                         y = sinf(theta) * radius;
00126                 }
00127         }
00128 
00132         void cartesianToCylindrical(float x, float y, float z, float& radius, float& theta, float& height, unsigned int axis, float tolerance = EPSILON)
00133         {
00134                 if (axis == 0)
00135                 {
00136                         radius = sqrtf((y * y) + (z * z));
00137                         theta = radius < tolerance ? 0 : atan2(z,y);
00138                         height = x;
00139                 }
00140                 else if (axis == 1)
00141                 {
00142                         radius = sqrtf((z * z) + (x * x));
00143                         theta = radius < tolerance ? 0 : atan2(x,z);
00144                         height = y;
00145                 }
00146                 else
00147                 {
00148                         radius = sqrtf((x * x) + (y * y));
00149                         theta = radius < tolerance ? 0 : atan2(y,x);
00150                         height = z;
00151                 }
00152         }
00153 
00156         void polarToCartesian(float radius, float theta, float& x, float& y)
00157         {
00158                 x = cosf(theta) * radius;
00159                 y = sinf(theta) * radius;
00160         }
00161 
00164         void cartesian_to_polar(float x, float y, float& radius, float& theta, float tolerance = EPSILON)
00165         {
00166                 radius = sqrtf((x * x) + (y * y));
00167                 theta = radius < tolerance ? 0 : atan2(y,x);
00168         }
00169 
00173         static bool closeEnough(float f1, float f2)
00174         {
00175                 return fabsf((f1 - f2) / ((f2 == 0.0f) ? 1.0f : f2)) < EPSILON;
00176         }
00177 
00178         static float degreesToRadians(float degrees)
00179         {
00180                 return (degrees * PI) / 180.0f;
00181         }
00182 
00183         static float radiansToDegrees(float radians)
00184         {
00185                 return (radians * 180.0f) / PI;
00186         }
00187 
00192         static long floatToLong(float f)
00193         {
00194                 long fpBits = *reinterpret_cast<const long*>(&f);
00195                 long shift = 23 - (((fpBits & 0x7fffffff) >> 23) - 127);
00196                 long result = ((fpBits & 0x7fffff) | (1 << 23)) >> shift;
00197 
00198                 result = (result ^ (fpBits >> 31)) - (fpBits >> 31);
00199                 result &= ~((((fpBits & 0x7fffffff) >> 23) - 127) >> 31);
00200 
00201                 return result;
00202         }
00203 
00204         static bool isPower2(int x)
00205         {
00206                 return ((x > 0) && ((x & (x - 1)) == 0));
00207         }
00208 
00209         static int nextPower2(int x);
00210 
00213         static int nextMultipleOf(int multiple, int value)
00214         {
00215                 return multiple * ((value + (multiple - 1)) / multiple);
00216         }
00217 
00220         static float random(float min, float max)
00221         {
00222                 return min + (max - min)
00223                         * (static_cast<float>(rand()) / static_cast<float>(RAND_MAX));
00224         }
00225 
00235         static float smoothstep(float a, float b, float x)
00236         {
00237                 if (x < a)
00238                 {
00239                         return 0.0f;
00240                 }
00241                 else if (x >= b)
00242                 {
00243                         return 1.0f;
00244                 }
00245                 else
00246                 {
00247                         x = (x - a) / (b - a);
00248                         return x * x * (3.0f - 2.0f * x);
00249                 }
00250         }
00251 
00252 };
00253 
00254 //-----------------------------------------------------------------------------
00255 
00258 class Vector2
00259 {
00260         friend Vector2 operator*(float lhs, const Vector2 &rhs);
00261         friend Vector2 operator-(const Vector2 &v);
00262 
00263 public:
00264         float x, y;
00265 
00266         static float distance(const Vector2 &pt1, const Vector2 &pt2);
00267         static float distanceSq(const Vector2 &pt1, const Vector2 &pt2);  
00268         static float dot(const Vector2 &p, const Vector2 &q);
00269         static Vector2 lerp(const Vector2 &p, const Vector2 &q, float t);
00270         static void orthogonalize(Vector2 &v1, Vector2 &v2);
00271         static Vector2 proj(const Vector2 &p, const Vector2 &q);
00272         static Vector2 perp(const Vector2 &p, const Vector2 &q);
00273         static Vector2 reflect(const Vector2 &i, const Vector2 &n);
00274 
00275         Vector2() {}
00276         Vector2(float x_, float y_);
00277         ~Vector2() {}
00278 
00279         bool operator==(const Vector2 &rhs) const;
00280         bool operator!=(const Vector2 &rhs) const;
00281 
00282         Vector2 &operator+=(const Vector2 &rhs);
00283         Vector2 &operator-=(const Vector2 &rhs);
00284         Vector2 &operator*=(float scalar);
00285         Vector2 &operator/=(float scalar);
00286 
00287         Vector2 operator+(const Vector2 &rhs) const;
00288         Vector2 operator-(const Vector2 &rhs) const;
00289         Vector2 operator*(float scalar) const;
00290         Vector2 operator/(float scalar) const;
00291 
00292         float magnitude() const;
00293         float magnitudeSq() const;
00294         Vector2 inverse() const;
00295         void normalize();
00296         void set(float x_, float y_);
00297 };
00298 
00299 inline Vector2 operator*(float lhs, const Vector2 &rhs)
00300 {
00301         return Vector2(lhs * rhs.x, lhs * rhs.y);
00302 }
00303 
00304 inline Vector2 operator-(const Vector2 &v)
00305 {
00306         return Vector2(-v.x, -v.y);
00307 }
00308 
00311 inline float Vector2::distance(const Vector2 &pt1, const Vector2 &pt2)
00312 {
00313         return sqrtf(distanceSq(pt1, pt2));
00314 }
00315 
00318 inline float Vector2::distanceSq(const Vector2 &pt1, const Vector2 &pt2)
00319 {
00320         return ((pt1.x - pt2.x) * (pt1.x - pt2.x))
00321                 + ((pt1.y - pt2.y) * (pt1.y - pt2.y));
00322 }
00323 
00324 inline float Vector2::dot(const Vector2 &p, const Vector2 &q)
00325 {
00326         return (p.x * q.x) + (p.y * q.y);
00327 }
00328 
00331 inline Vector2 Vector2::lerp(const Vector2 &p, const Vector2 &q, float t)
00332 {
00333         return p + t * (q - p);
00334 }
00335 
00339 inline void Vector2::orthogonalize(Vector2 &v1, Vector2 &v2)
00340 {
00341         v2 = v2 - proj(v2, v1);
00342         v2.normalize();
00343 }
00344 
00347 inline Vector2 Vector2::proj(const Vector2 &p, const Vector2 &q)
00348 {
00349         float length =  q.magnitude();
00350         return (Vector2::dot(p, q) / (length * length)) * q;
00351 }
00352 
00355 inline Vector2 Vector2::perp(const Vector2 &p, const Vector2 &q)
00356 {
00357         float length = q.magnitude();
00358         return p - ((Vector2::dot(p, q) / (length * length)) * q);
00359 }
00360 
00364 inline Vector2 Vector2::reflect(const Vector2 &i, const Vector2 &n)
00365 {
00366         return i - 2.0f * Vector2::proj(i, n);
00367 }
00368 
00369 inline Vector2::Vector2(float x_, float y_) : x(x_), y(y_) {}
00370 
00371 inline bool Vector2::operator==(const Vector2 &rhs) const
00372 {
00373         return Math::closeEnough(x, rhs.x) && Math::closeEnough(y, rhs.y);
00374 }
00375 
00376 inline bool Vector2::operator!=(const Vector2 &rhs) const
00377 {
00378         return !(*this == rhs);
00379 }
00380 
00381 inline Vector2 &Vector2::operator+=(const Vector2 &rhs)
00382 {
00383         x += rhs.x, y += rhs.y;
00384         return *this;
00385 }
00386 
00387 inline Vector2 &Vector2::operator-=(const Vector2 &rhs)
00388 {
00389         x -= rhs.x, y -= rhs.y;
00390         return *this;
00391 }
00392 
00393 inline Vector2 &Vector2::operator*=(float scalar)
00394 {
00395         x *= scalar, y *= scalar;
00396         return *this;
00397 }
00398 
00399 inline Vector2 &Vector2::operator/=(float scalar)
00400 {
00401         x /= scalar, y /= scalar;
00402         return *this;
00403 }
00404 
00405 inline Vector2 Vector2::operator+(const Vector2 &rhs) const
00406 {
00407         Vector2 tmp(*this);
00408         tmp += rhs;
00409         return tmp;
00410 }
00411 
00412 inline Vector2 Vector2::operator-(const Vector2 &rhs) const
00413 {
00414         Vector2 tmp(*this);
00415         tmp -= rhs;
00416         return tmp;
00417 }
00418 
00419 inline Vector2 Vector2::operator*(float scalar) const
00420 {
00421         return Vector2(x * scalar, y * scalar);
00422 }
00423 
00424 inline Vector2 Vector2::operator/(float scalar) const
00425 {
00426         return Vector2(x / scalar, y / scalar);
00427 }
00428 
00429 inline float Vector2::magnitude() const
00430 {
00431         return sqrtf((x * x) + (y * y));
00432 }
00433 
00434 inline float Vector2::magnitudeSq() const
00435 {
00436         return (x * x) + (y * y);
00437 }
00438 
00439 inline Vector2 Vector2::inverse() const
00440 {
00441         return Vector2(-x, -y);
00442 }
00443 
00444 inline void Vector2::normalize()
00445 {
00446         float invMag = 1.0f / magnitude();
00447         x *= invMag, y *= invMag;
00448 }
00449 
00450 inline void Vector2::set(float x_, float y_)
00451 {
00452         x = x_, y = y_;
00453 }
00454 
00455 //-----------------------------------------------------------------------------
00456 
00459 class Vector3
00460 {
00461         friend Vector3 operator*(float lhs, const Vector3 &rhs);
00462         friend Vector3 operator-(const Vector3 &v);
00463 
00464 public:
00465         float x, y, z;
00466 
00467         static Vector3 cross(const Vector3 &p, const Vector3 &q);
00468         static float distance(const Vector3 &pt1, const Vector3 &pt2);
00469         static float distanceSq(const Vector3 &pt1, const Vector3 &pt2);  
00470         static float dot(const Vector3 &p, const Vector3 &q);
00471         static Vector3 lerp(const Vector3 &p, const Vector3 &q, float t);
00472         static void orthogonalize(Vector3 &v1, Vector3 &v2);
00473         static void orthogonalize(Vector3 &v1, Vector3 &v2, Vector3 &v3);
00474         static Vector3 proj(const Vector3 &p, const Vector3 &q);
00475         static Vector3 perp(const Vector3 &p, const Vector3 &q);
00476         static Vector3 reflect(const Vector3 &i, const Vector3 &n);
00477 
00478         Vector3() {}
00479         Vector3(float x_, float y_, float z_);
00480         ~Vector3() {}
00481 
00482         bool operator==(const Vector3 &rhs) const;
00483         bool operator!=(const Vector3 &rhs) const;
00484 
00485         Vector3 &operator+=(const Vector3 &rhs);
00486         Vector3 &operator-=(const Vector3 &rhs);
00487         Vector3 &operator*=(float scalar);
00488         Vector3 &operator/=(float scalar);
00489 
00490         Vector3 operator+(const Vector3 &rhs) const;
00491         Vector3 operator-(const Vector3 &rhs) const;
00492         Vector3 operator*(float scalar) const;
00493         Vector3 operator/(float scalar) const;
00494 
00495         float magnitude() const;
00496         float magnitudeSq() const;
00497         Vector3 inverse() const;
00498         void normalize();
00499         void set(float x_, float y_, float z_);
00500 };
00501 
00502 inline Vector3 operator*(float lhs, const Vector3 &rhs)
00503 {
00504         return Vector3(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
00505 }
00506 
00507 inline Vector3 operator-(const Vector3 &v)
00508 {
00509         return Vector3(-v.x, -v.y, -v.z);
00510 }
00511 
00512 inline Vector3 Vector3::cross(const Vector3 &p, const Vector3 &q)
00513 {
00514         return Vector3((p.y * q.z) - (p.z * q.y),
00515                 (p.z * q.x) - (p.x * q.z),
00516                 (p.x * q.y) - (p.y * q.x));
00517 }
00518 
00521 inline float Vector3::distance(const Vector3 &pt1, const Vector3 &pt2)
00522 {
00523         return sqrtf(distanceSq(pt1, pt2));
00524 }
00525 
00528 inline float Vector3::distanceSq(const Vector3 &pt1, const Vector3 &pt2)
00529 {
00530         return ((pt1.x - pt2.x) * (pt1.x - pt2.x))
00531                 + ((pt1.y - pt2.y) * (pt1.y - pt2.y))
00532                 + ((pt1.z - pt2.z) * (pt1.z - pt2.z));
00533 }
00534 
00535 inline float Vector3::dot(const Vector3 &p, const Vector3 &q)
00536 {
00537         return (p.x * q.x) + (p.y * q.y) + (p.z * q.z);
00538 }
00539 
00542 inline Vector3 Vector3::lerp(const Vector3 &p, const Vector3 &q, float t)
00543 {
00544         return p + t * (q - p);
00545 }
00546 
00550 inline void Vector3::orthogonalize(Vector3 &v1, Vector3 &v2)
00551 {
00552         v2 = v2 - proj(v2, v1);
00553         v2.normalize();
00554 }
00555 
00559 inline void Vector3::orthogonalize(Vector3 &v1, Vector3 &v2, Vector3 &v3)
00560 {
00561         v2 = v2 - proj(v2, v1);
00562         v2.normalize();
00563 
00564         v3 = v3 - proj(v3, v1) - proj(v3, v2);
00565         v3.normalize();
00566 }
00567 
00570 inline Vector3 Vector3::proj(const Vector3 &p, const Vector3 &q)
00571 {       
00572         float length =  q.magnitude();
00573         return (Vector3::dot(p, q) / (length * length)) * q;
00574 }
00575 
00578 inline Vector3 Vector3::perp(const Vector3 &p, const Vector3 &q)
00579 {
00580         float length = q.magnitude();
00581         return p - ((Vector3::dot(p, q) / (length * length)) * q);
00582 }
00583 
00587 inline Vector3 Vector3::reflect(const Vector3 &i, const Vector3 &n)
00588 {
00589         return i - 2.0f * Vector3::proj(i, n);
00590 }
00591 
00592 inline Vector3::Vector3(float x_, float y_, float z_) : x(x_), y(y_), z(z_) {}
00593 
00594 inline Vector3 &Vector3::operator+=(const Vector3 &rhs)
00595 {
00596         x += rhs.x, y += rhs.y, z += rhs.z;
00597         return *this;
00598 }
00599 
00600 inline bool Vector3::operator==(const Vector3 &rhs) const
00601 {
00602         return Math::closeEnough(x, rhs.x) && Math::closeEnough(y, rhs.y)
00603                 && Math::closeEnough(z, rhs.z);
00604 }
00605 
00606 inline bool Vector3::operator!=(const Vector3 &rhs) const
00607 {
00608         return !(*this == rhs);
00609 }
00610 
00611 inline Vector3 &Vector3::operator-=(const Vector3 &rhs)
00612 {
00613         x -= rhs.x, y -= rhs.y, z -= rhs.z;
00614         return *this;
00615 }
00616 
00617 inline Vector3 &Vector3::operator*=(float scalar)
00618 {
00619         x *= scalar, y *= scalar, z *= scalar;
00620         return *this;
00621 }
00622 
00623 inline Vector3 &Vector3::operator/=(float scalar)
00624 {
00625         x /= scalar, y /= scalar, z /= scalar;
00626         return *this;
00627 }
00628 
00629 inline Vector3 Vector3::operator+(const Vector3 &rhs) const
00630 {
00631         Vector3 tmp(*this);
00632         tmp += rhs;
00633         return tmp;
00634 }
00635 
00636 inline Vector3 Vector3::operator-(const Vector3 &rhs) const
00637 {
00638         Vector3 tmp(*this);
00639         tmp -= rhs;
00640         return tmp;
00641 }
00642 
00643 inline Vector3 Vector3::operator*(float scalar) const
00644 {
00645         return Vector3(x * scalar, y * scalar, z * scalar);    
00646 }
00647 
00648 inline Vector3 Vector3::operator/(float scalar) const
00649 {
00650         return Vector3(x / scalar, y / scalar, z / scalar);
00651 }
00652 
00653 inline float Vector3::magnitude() const
00654 {
00655         return sqrtf((x * x) + (y * y) + (z * z));
00656 }
00657 
00658 inline float Vector3::magnitudeSq() const
00659 {
00660         return (x * x) + (y * y) + (z * z);
00661 }
00662 
00663 inline Vector3 Vector3::inverse() const
00664 {
00665         return Vector3(-x, -y, -z);
00666 }
00667 
00668 inline void Vector3::normalize()
00669 {
00670         float invMag = 1.0f / magnitude();
00671         x *= invMag, y *= invMag, z *= invMag;
00672 }
00673 
00674 inline void Vector3::set(float x_, float y_, float z_)
00675 {
00676         x = x_, y = y_, z = z_;
00677 }
00678 
00679 //-----------------------------------------------------------------------------
00680 
00684 class Vector4
00685 {
00686         friend Vector4 operator*(float lhs, const Vector4 &rhs);
00687         friend Vector4 operator-(const Vector4 &v);
00688 
00689 public:
00690         float x, y, z, w;
00691 
00692         static float distance(const Vector4 &pt1, const Vector4 &pt2);
00693         static float distanceSq(const Vector4 &pt1, const Vector4 &pt2);
00694         static float dot(const Vector4 &p, const Vector4 &q);
00695         static Vector4 lerp(const Vector4 &p, const Vector4 &q, float t);
00696 
00697         Vector4() {}
00698         Vector4(float x_, float y_, float z_, float w_);
00699         Vector4(const Vector3 &v, float w_);
00700         ~Vector4() {}
00701 
00702         bool operator==(const Vector4 &rhs) const;
00703         bool operator!=(const Vector4 &rhs) const;
00704 
00705         Vector4 &operator+=(const Vector4 &rhs);
00706         Vector4 &operator-=(const Vector4 &rhs);
00707         Vector4 &operator*=(float scalar);
00708         Vector4 &operator/=(float scalar);
00709 
00710         Vector4 operator+(const Vector4 &rhs) const;
00711         Vector4 operator-(const Vector4 &rhs) const;
00712         Vector4 operator*(float scalar) const;
00713         Vector4 operator/(float scalar) const;
00714 
00715         float magnitude() const;
00716         float magnitudeSq() const;
00717         Vector4 inverse() const;
00718         void normalize();
00719         void set(float x_, float y_, float z_, float w_);
00720         Vector3 toVector3() const;
00721 };
00722 
00723 inline Vector4 operator*(float lhs, const Vector4 &rhs)
00724 {
00725         return Vector4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w);
00726 }
00727 
00728 inline Vector4 operator-(const Vector4 &v)
00729 {
00730         return Vector4(-v.x, -v.y, -v.z, -v.w);
00731 }
00732 
00735 inline float Vector4::distance(const Vector4 &pt1, const Vector4 &pt2)
00736 {
00737         return sqrtf(distanceSq(pt1, pt2));
00738 }
00739 
00742 inline float Vector4::distanceSq(const Vector4 &pt1, const Vector4 &pt2)
00743 {
00744         return ((pt1.x - pt2.x) * (pt1.x - pt2.x))
00745                 + ((pt1.y - pt2.y) * (pt1.y - pt2.y))
00746                 + ((pt1.z - pt2.z) * (pt1.z - pt2.z))
00747                 + ((pt1.w - pt2.w) * (pt1.w - pt2.w));
00748 }
00749 
00750 inline float Vector4::dot(const Vector4 &p, const Vector4 &q)
00751 {
00752         return (p.x * q.x) + (p.y * q.y) + (p.z * q.z) + (p.w * q.w);
00753 }
00754 
00757 inline Vector4 Vector4::lerp(const Vector4 &p, const Vector4 &q, float t)
00758 {
00759         return p + t * (q - p);
00760 }
00761 
00762 inline Vector4::Vector4(float x_, float y_, float z_, float w_) : x(x_), y(y_), z(z_), w(w_) {}
00763 
00764 inline Vector4::Vector4(const Vector3 &v, float w_) : x(v.x), y(v.y), z(v.z), w(w_) {}
00765 
00766 inline Vector4 &Vector4::operator+=(const Vector4 &rhs)
00767 {
00768         x += rhs.x, y += rhs.y, z += rhs.z, w += rhs.w;
00769         return *this;
00770 }
00771 
00772 inline bool Vector4::operator==(const Vector4 &rhs) const
00773 {
00774         return Math::closeEnough(x, rhs.x) && Math::closeEnough(y, rhs.y)
00775                 && Math::closeEnough(z, rhs.z) && Math::closeEnough(w, rhs.w);
00776 }
00777 
00778 inline bool Vector4::operator!=(const Vector4 &rhs) const
00779 {
00780         return !(*this == rhs);
00781 }
00782 
00783 inline Vector4 &Vector4::operator-=(const Vector4 &rhs)
00784 {
00785         x -= rhs.x, y -= rhs.y, z -= rhs.z, w -= rhs.w;
00786         return *this;
00787 }
00788 
00789 inline Vector4 &Vector4::operator*=(float scalar)
00790 {
00791         x *= scalar, y *= scalar, z *= scalar, w *= scalar;
00792         return *this;
00793 }
00794 
00795 inline Vector4 &Vector4::operator/=(float scalar)
00796 {
00797         x /= scalar, y /= scalar, z /= scalar, w /= scalar;
00798         return *this;
00799 }
00800 
00801 inline Vector4 Vector4::operator+(const Vector4 &rhs) const
00802 {
00803         Vector4 tmp(*this);
00804         tmp += rhs;
00805         return tmp;
00806 }
00807 
00808 inline Vector4 Vector4::operator-(const Vector4 &rhs) const
00809 {
00810         Vector4 tmp(*this);
00811         tmp -= rhs;
00812         return tmp;
00813 }
00814 
00815 inline Vector4 Vector4::operator*(float scalar) const
00816 {
00817         return Vector4(x * scalar, y * scalar, z * scalar, w * scalar);
00818 }
00819 
00820 inline Vector4 Vector4::operator/(float scalar) const
00821 {
00822         return Vector4(x / scalar, y / scalar, z / scalar, w / scalar);
00823 }
00824 
00825 inline float Vector4::magnitude() const
00826 {
00827         return sqrtf((x * x) + (y * y) + (z * z) + (w * w));
00828 }
00829 
00830 inline float Vector4::magnitudeSq() const
00831 {
00832         return (x * x) + (y * y) + (z * z) + (w * w);
00833 }
00834 
00835 inline Vector4 Vector4::inverse() const
00836 {
00837         return Vector4(-x, -y, -z, -w);
00838 }
00839 
00840 inline void Vector4::normalize()
00841 {
00842         float invMag = 1.0f / magnitude();
00843         x *= invMag, y *= invMag, z *= invMag, w *= invMag;
00844 }
00845 
00846 inline void Vector4::set(float x_, float y_, float z_, float w_)
00847 {
00848         x = x_, y = y_, z = z_, w = w_;
00849 }
00850 
00851 inline Vector3 Vector4::toVector3() const
00852 {
00853         return (w != 0.0f) ? Vector3(x / w, y / w, z / w) : Vector3(x, y, z);
00854 }
00855 
00856 //-----------------------------------------------------------------------------
00857 
00863 class Matrix3
00864 {
00865         friend Vector3 operator*(const Vector3 &lhs, const Matrix3 &rhs);
00866         friend Matrix3 operator*(float scalar, const Matrix3 &rhs);
00867 
00868 public:
00869         static const Matrix3 IDENTITY;
00870         static Matrix3 createFromAxes(const Vector3 &x, const Vector3 &y, const Vector3 &z);
00871         static Matrix3 createFromAxesTransposed(const Vector3 &x, const Vector3 &y, const Vector3 &z);
00872         static Matrix3 createFromHeadPitchRoll(float headDegrees, float pitchDegrees, float rollDegrees);
00873         static Matrix3 createMirror(const Vector3 &planeNormal);
00874         static Matrix3 createOrient(const Vector3 &from, const Vector3 &to);
00875         static Matrix3 createRotate(const Vector3 &axis, float degrees);
00876         static Matrix3 createScale(float sx, float sy, float sz);
00877 
00878         Matrix3() {}
00879         Matrix3(float m11, float m12, float m13,
00880                 float m21, float m22, float m23,
00881                 float m31, float m32, float m33);
00882         ~Matrix3() {}
00883 
00884         float *operator[](int row);
00885         const float *operator[](int row) const;
00886 
00887         bool operator==(const Matrix3 &rhs) const;
00888         bool operator!=(const Matrix3 &rhs) const;
00889 
00890         Matrix3 &operator+=(const Matrix3 &rhs);
00891         Matrix3 &operator-=(const Matrix3 &rhs);
00892         Matrix3 &operator*=(const Matrix3 &rhs);
00893         Matrix3 &operator*=(float scalar);
00894         Matrix3 &operator/=(float scalar);
00895 
00896         Matrix3 operator+(const Matrix3 &rhs) const;
00897         Matrix3 operator-(const Matrix3 &rhs) const;
00898         Matrix3 operator*(const Matrix3 &rhs) const;
00899         Matrix3 operator*(float scalar) const;
00900         Matrix3 operator/(float scalar) const;
00901 
00902         float determinant() const;
00903         void fromAxes(const Vector3 &x, const Vector3 &y, const Vector3 &z);
00904         void fromAxesTransposed(const Vector3 &x, const Vector3 &y, const Vector3 &z);
00905         void fromHeadPitchRoll(float headDegrees, float pitchDegrees, float rollDegrees);
00906         void identity();
00907         Matrix3 inverse() const;
00908         void orient(const Vector3 &from, const Vector3 &to);
00909         void rotate(const Vector3 &axis, float degrees);
00910         void scale(float sx, float sy, float sz);
00911         void toAxes(Vector3 &x, Vector3 &y, Vector3 &z) const;
00912         void toAxesTransposed(Vector3 &x, Vector3 &y, Vector3 &z) const;
00913         void toHeadPitchRoll(float &headDegrees, float &pitchDegrees, float &rollDegrees) const;
00914         Matrix3 transpose() const;
00915 
00916 private:
00917         float mtx[3][3];
00918 };
00919 
00920 inline Vector3 operator*(const Vector3 &lhs, const Matrix3 &rhs)
00921 {
00922         return Vector3(
00923                 (lhs.x * rhs.mtx[0][0]) + (lhs.y * rhs.mtx[1][0]) + (lhs.z * rhs.mtx[2][0]),
00924                 (lhs.x * rhs.mtx[0][1]) + (lhs.y * rhs.mtx[1][1]) + (lhs.z * rhs.mtx[2][1]),
00925                 (lhs.x * rhs.mtx[0][2]) + (lhs.y * rhs.mtx[1][2]) + (lhs.z * rhs.mtx[2][2]));
00926 }
00927 
00928 inline Matrix3 operator*(float scalar, const Matrix3 &rhs)
00929 {
00930         return rhs * scalar;
00931 }
00932 
00933 inline Matrix3 Matrix3::createFromAxes(const Vector3 &x, const Vector3 &y, const Vector3 &z)
00934 {
00935         Matrix3 tmp;
00936         tmp.createFromAxes(x, y, z);
00937         return tmp;
00938 }
00939 
00940 inline Matrix3 Matrix3::createFromAxesTransposed(const Vector3 &x, const Vector3 &y, const Vector3 &z)
00941 {
00942         Matrix3 tmp;
00943         tmp.fromAxesTransposed(x, y, z);
00944         return tmp;
00945 }
00946 
00947 inline Matrix3 Matrix3::createFromHeadPitchRoll(float headDegrees, float pitchDegrees, float rollDegrees)
00948 {
00949         Matrix3 tmp;
00950         tmp.fromHeadPitchRoll(headDegrees, pitchDegrees, rollDegrees);
00951         return tmp;
00952 }
00953 
00954 inline Matrix3 Matrix3::createOrient(const Vector3 &from, const Vector3 &to)
00955 {
00956         Matrix3 tmp;
00957         tmp.orient(from, to);
00958         return tmp;
00959 }
00960 
00961 inline Matrix3 Matrix3::createRotate(const Vector3 &axis, float degrees)
00962 {
00963         Matrix3 tmp;
00964         tmp.rotate(axis, degrees);
00965         return tmp;
00966 }
00967 
00968 inline Matrix3 Matrix3::createScale(float sx, float sy, float sz)
00969 {
00970         Matrix3 tmp;
00971         tmp.scale(sx, sy, sz);
00972         return tmp;
00973 }
00974 
00975 inline Matrix3::Matrix3(float m11, float m12, float m13,
00976                                                           float m21, float m22, float m23,
00977                                                           float m31, float m32, float m33)
00978 {
00979         mtx[0][0] = m11, mtx[0][1] = m12, mtx[0][2] = m13;
00980         mtx[1][0] = m21, mtx[1][1] = m22, mtx[1][2] = m23;
00981         mtx[2][0] = m31, mtx[2][1] = m32, mtx[2][2] = m33;
00982 }
00983 
00984 inline float *Matrix3::operator[](int row)
00985 {
00986         return mtx[row];
00987 }
00988 
00989 inline const float *Matrix3::operator[](int row) const
00990 {
00991         return mtx[row];
00992 }
00993 
00994 inline bool Matrix3::operator==(const Matrix3 &rhs) const
00995 {
00996         return Math::closeEnough(mtx[0][0], rhs.mtx[0][0])
00997                 && Math::closeEnough(mtx[0][1], rhs.mtx[0][1])
00998                 && Math::closeEnough(mtx[0][2], rhs.mtx[0][2])
00999                 && Math::closeEnough(mtx[1][0], rhs.mtx[1][0])
01000                 && Math::closeEnough(mtx[1][1], rhs.mtx[1][1])
01001                 && Math::closeEnough(mtx[1][2], rhs.mtx[1][2])
01002                 && Math::closeEnough(mtx[2][0], rhs.mtx[2][0])
01003                 && Math::closeEnough(mtx[2][1], rhs.mtx[2][1])
01004                 && Math::closeEnough(mtx[2][2], rhs.mtx[2][2]);
01005 }
01006 
01007 inline bool Matrix3::operator!=(const Matrix3 &rhs) const
01008 {
01009         return !(*this == rhs);
01010 }
01011 
01012 inline Matrix3 &Matrix3::operator+=(const Matrix3 &rhs)
01013 {
01014         mtx[0][0] += rhs.mtx[0][0], mtx[0][1] += rhs.mtx[0][1], mtx[0][2] += rhs.mtx[0][2];
01015         mtx[1][0] += rhs.mtx[1][0], mtx[1][1] += rhs.mtx[1][1], mtx[1][2] += rhs.mtx[1][2];
01016         mtx[2][0] += rhs.mtx[2][0], mtx[2][1] += rhs.mtx[2][1], mtx[2][2] += rhs.mtx[2][2];
01017         return *this;
01018 }
01019 
01020 inline Matrix3 &Matrix3::operator-=(const Matrix3 &rhs)
01021 {
01022         mtx[0][0] -= rhs.mtx[0][0], mtx[0][1] -= rhs.mtx[0][1], mtx[0][2] -= rhs.mtx[0][2];
01023         mtx[1][0] -= rhs.mtx[1][0], mtx[1][1] -= rhs.mtx[1][1], mtx[1][2] -= rhs.mtx[1][2];
01024         mtx[2][0] -= rhs.mtx[2][0], mtx[2][1] -= rhs.mtx[2][1], mtx[2][2] -= rhs.mtx[2][2];
01025         return *this;
01026 }
01027 
01028 inline Matrix3 &Matrix3::operator*=(const Matrix3 &rhs)
01029 {
01030         Matrix3 tmp;
01031 
01032         // Row 1.
01033         tmp.mtx[0][0] = (mtx[0][0] * rhs.mtx[0][0]) + (mtx[0][1] * rhs.mtx[1][0]) + (mtx[0][2] * rhs.mtx[2][0]);
01034         tmp.mtx[0][1] = (mtx[0][0] * rhs.mtx[0][1]) + (mtx[0][1] * rhs.mtx[1][1]) + (mtx[0][2] * rhs.mtx[2][1]);
01035         tmp.mtx[0][2] = (mtx[0][0] * rhs.mtx[0][2]) + (mtx[0][1] * rhs.mtx[1][2]) + (mtx[0][2] * rhs.mtx[2][2]);
01036 
01037         // Row 2.
01038         tmp.mtx[1][0] = (mtx[1][0] * rhs.mtx[0][0]) + (mtx[1][1] * rhs.mtx[1][0]) + (mtx[1][2] * rhs.mtx[2][0]);
01039         tmp.mtx[1][1] = (mtx[1][0] * rhs.mtx[0][1]) + (mtx[1][1] * rhs.mtx[1][1]) + (mtx[1][2] * rhs.mtx[2][1]);
01040         tmp.mtx[1][2] = (mtx[1][0] * rhs.mtx[0][2]) + (mtx[1][1] * rhs.mtx[1][2]) + (mtx[1][2] * rhs.mtx[2][2]);
01041 
01042         // Row 3.
01043         tmp.mtx[2][0] = (mtx[2][0] * rhs.mtx[0][0]) + (mtx[2][1] * rhs.mtx[1][0]) + (mtx[2][2] * rhs.mtx[2][0]);
01044         tmp.mtx[2][1] = (mtx[2][0] * rhs.mtx[0][1]) + (mtx[2][1] * rhs.mtx[1][1]) + (mtx[2][2] * rhs.mtx[2][1]);
01045         tmp.mtx[2][2] = (mtx[2][0] * rhs.mtx[0][2]) + (mtx[2][1] * rhs.mtx[1][2]) + (mtx[2][2] * rhs.mtx[2][2]);
01046 
01047         *this = tmp;
01048         return *this;
01049 }
01050 
01051 inline Matrix3 &Matrix3::operator*=(float scalar)
01052 {
01053         mtx[0][0] *= scalar, mtx[0][1] *= scalar, mtx[0][2] *= scalar;
01054         mtx[1][0] *= scalar, mtx[1][1] *= scalar, mtx[1][2] *= scalar;
01055         mtx[2][0] *= scalar, mtx[2][1] *= scalar, mtx[2][2] *= scalar;
01056         return *this;
01057 }
01058 
01059 inline Matrix3 &Matrix3::operator/=(float scalar)
01060 {
01061         mtx[0][0] /= scalar, mtx[0][1] /= scalar, mtx[0][2] /= scalar;
01062         mtx[1][0] /= scalar, mtx[1][1] /= scalar, mtx[1][2] /= scalar;
01063         mtx[2][0] /= scalar, mtx[2][1] /= scalar, mtx[2][2] /= scalar;
01064         return *this;
01065 }
01066 
01067 inline Matrix3 Matrix3::operator+(const Matrix3 &rhs) const
01068 {
01069         Matrix3 tmp(*this);
01070         tmp += rhs;
01071         return tmp;
01072 }
01073 
01074 inline Matrix3 Matrix3::operator-(const Matrix3 &rhs) const
01075 {
01076         Matrix3 tmp(*this);
01077         tmp -= rhs;
01078         return tmp;
01079 }
01080 
01081 inline Matrix3 Matrix3::operator*(const Matrix3 &rhs) const
01082 {
01083         Matrix3 tmp(*this);
01084         tmp *= rhs;
01085         return tmp;
01086 }
01087 
01088 inline Matrix3 Matrix3::operator*(float scalar) const
01089 {
01090         Matrix3 tmp(*this);
01091         tmp *= scalar;
01092         return tmp;
01093 }
01094 
01095 inline Matrix3 Matrix3::operator/(float scalar) const
01096 {
01097         Matrix3 tmp(*this);
01098         tmp /= scalar;
01099         return tmp;
01100 }
01101 
01102 inline float Matrix3::determinant() const
01103 {
01104         return (mtx[0][0] * (mtx[1][1] * mtx[2][2] - mtx[1][2] * mtx[2][1]))
01105                 - (mtx[0][1] * (mtx[1][0] * mtx[2][2] - mtx[1][2] * mtx[2][0]))
01106                 + (mtx[0][2] * (mtx[1][0] * mtx[2][1] - mtx[1][1] * mtx[2][0]));
01107 }
01108 
01109 inline void Matrix3::fromAxes(const Vector3 &x, const Vector3 &y, const Vector3 &z)
01110 {
01111         mtx[0][0] = x.x,  mtx[0][1] = x.y,  mtx[0][2] = x.z;
01112         mtx[1][0] = y.x,  mtx[1][1] = y.y,  mtx[1][2] = y.z;
01113         mtx[2][0] = z.x,  mtx[2][1] = z.y,  mtx[2][2] = z.z;
01114 }
01115 
01116 inline void Matrix3::fromAxesTransposed(const Vector3 &x, const Vector3 &y, const Vector3 &z)
01117 {
01118         mtx[0][0] = x.x,  mtx[0][1] = y.x,  mtx[0][2] = z.x;
01119         mtx[1][0] = x.y,  mtx[1][1] = y.y,  mtx[1][2] = z.y;
01120         mtx[2][0] = x.z,  mtx[2][1] = y.z,  mtx[2][2] = z.z;
01121 }
01122 
01123 inline void Matrix3::identity()
01124 {
01125         mtx[0][0] = 1.0f, mtx[0][1] = 0.0f, mtx[0][2] = 0.0f;
01126         mtx[1][0] = 0.0f, mtx[1][1] = 1.0f, mtx[1][2] = 0.0f;
01127         mtx[2][0] = 0.0f, mtx[2][1] = 0.0f, mtx[2][2] = 1.0f;
01128 }
01129 
01130 inline void Matrix3::toAxes(Vector3 &x, Vector3 &y, Vector3 &z) const
01131 {
01132         x.set(mtx[0][0], mtx[0][1], mtx[0][2]);
01133         y.set(mtx[1][0], mtx[1][1], mtx[1][2]);
01134         z.set(mtx[2][0], mtx[2][1], mtx[2][2]);
01135 }
01136 
01137 inline void Matrix3::toAxesTransposed(Vector3 &x, Vector3 &y, Vector3 &z) const
01138 {
01139         x.set(mtx[0][0], mtx[1][0], mtx[2][0]);
01140         y.set(mtx[0][1], mtx[1][1], mtx[2][1]);
01141         z.set(mtx[0][2], mtx[1][2], mtx[2][2]);
01142 }
01143 
01144 inline Matrix3 Matrix3::transpose() const
01145 {
01146         Matrix3 tmp;
01147 
01148         tmp[0][0] = mtx[0][0], tmp[0][1] = mtx[1][0], tmp[0][2] = mtx[2][0];
01149         tmp[1][0] = mtx[0][1], tmp[1][1] = mtx[1][1], tmp[1][2] = mtx[2][1];
01150         tmp[2][0] = mtx[0][2], tmp[2][1] = mtx[1][2], tmp[2][2] = mtx[2][2];
01151 
01152         return tmp;
01153 }
01154 
01155 //-----------------------------------------------------------------------------
01156 
01162 class Matrix4
01163 {
01164         friend Vector4 operator*(const Vector4 &lhs, const Matrix4 &rhs);
01165         friend Vector3 operator*(const Vector3 &lhs, const Matrix4 &rhs);
01166         friend Matrix4 operator*(float scalar, const Matrix4 &rhs);
01167 
01168 public:
01169         static const Matrix4 IDENTITY;
01170         static Matrix4 createFromAxes(const Vector3 &x, const Vector3 &y, const Vector3 &z);
01171         static Matrix4 createFromAxesTransposed(const Vector3 &x, const Vector3 &y, const Vector3 &z);
01172         static Matrix4 createFromHeadPitchRoll(float headDegrees, float pitchDegrees, float rollDegrees);
01173         static Matrix4 createMirror(const Vector3 &planeNormal, const Vector3 &pointOnPlane);
01174         static Matrix4 createOrient(const Vector3 &from, const Vector3 &to);
01175         static Matrix4 createRotate(const Vector3 &axis, float degrees);
01176         static Matrix4 createScale(float sx, float sy, float sz);
01177         static Matrix4 createTranslate(float tx, float ty, float tz);
01178 
01179         Matrix4() {}
01180         Matrix4(float m11, float m12, float m13, float m14,
01181                 float m21, float m22, float m23, float m24,
01182                 float m31, float m32, float m33, float m34,
01183                 float m41, float m42, float m43, float m44);
01184         ~Matrix4() {}
01185 
01186         float *operator[](int row);
01187         const float *operator[](int row) const;
01188 
01189         bool operator==(const Matrix4 &rhs) const;
01190         bool operator!=(const Matrix4 &rhs) const;
01191 
01192         Matrix4 &operator+=(const Matrix4 &rhs);
01193         Matrix4 &operator-=(const Matrix4 &rhs);
01194         Matrix4 &operator*=(const Matrix4 &rhs);
01195         Matrix4 &operator*=(float scalar);
01196         Matrix4 &operator/=(float scalar);
01197 
01198         Matrix4 operator+(const Matrix4 &rhs) const;
01199         Matrix4 operator-(const Matrix4 &rhs) const;
01200         Matrix4 operator*(const Matrix4 &rhs) const;
01201         Matrix4 operator*(float scalar) const;
01202         Matrix4 operator/(float scalar) const;
01203 
01204         float determinant() const;
01205         void fromAxes(const Vector3 &x, const Vector3 &y, const Vector3 &z);
01206         void fromAxesTransposed(const Vector3 &x, const Vector3 &y, const Vector3 &z);
01207         void fromHeadPitchRoll(float headDegrees, float pitchDegrees, float rollDegrees);
01208         void identity();
01209         Matrix4 inverse() const;
01210         void orient(const Vector3 &from, const Vector3 &to);
01211         void rotate(const Vector3 &axis, float degrees);
01212         void scale(float sx, float sy, float sz);
01213         void toAxes(Vector3 &x, Vector3 &y, Vector3 &z) const;
01214         void toAxesTransposed(Vector3 &x, Vector3 &y, Vector3 &z) const;
01215         void toHeadPitchRoll(float &headDegrees, float &pitchDegrees, float &rollDegrees) const;
01216         void translate(float tx, float ty, float tz);
01217         Matrix4 transpose() const;
01218 
01219         const float * getRaw() const;
01220         float * getRawWritable();
01221 
01222 private:
01223         float mtx[4][4];
01224 };
01225 
01226 inline Vector4 operator*(const Vector4 &lhs, const Matrix4 &rhs)
01227 {
01228         return Vector4(
01229                 (lhs.x * rhs.mtx[0][0]) + (lhs.y * rhs.mtx[1][0]) + (lhs.z * rhs.mtx[2][0]) + (lhs.w * rhs.mtx[3][0]),
01230                 (lhs.x * rhs.mtx[0][1]) + (lhs.y * rhs.mtx[1][1]) + (lhs.z * rhs.mtx[2][1]) + (lhs.w * rhs.mtx[3][1]),
01231                 (lhs.x * rhs.mtx[0][2]) + (lhs.y * rhs.mtx[1][2]) + (lhs.z * rhs.mtx[2][2]) + (lhs.w * rhs.mtx[3][2]),
01232                 (lhs.x * rhs.mtx[0][3]) + (lhs.y * rhs.mtx[1][3]) + (lhs.z * rhs.mtx[2][3]) + (lhs.w * rhs.mtx[3][3]));
01233 }
01234 
01235 inline Vector3 operator*(const Vector3 &lhs, const Matrix4 &rhs)
01236 {
01237         return Vector3(
01238                 (lhs.x * rhs.mtx[0][0]) + (lhs.y * rhs.mtx[1][0]) + (lhs.z * rhs.mtx[2][0]),
01239                 (lhs.x * rhs.mtx[0][1]) + (lhs.y * rhs.mtx[1][1]) + (lhs.z * rhs.mtx[2][1]),
01240                 (lhs.x * rhs.mtx[0][2]) + (lhs.y * rhs.mtx[1][2]) + (lhs.z * rhs.mtx[2][2]));
01241 }
01242 
01243 inline Matrix4 operator*(float scalar, const Matrix4 &rhs)
01244 {
01245         return rhs * scalar;
01246 }
01247 
01248 inline Matrix4 Matrix4::createFromAxes(const Vector3 &x, const Vector3 &y, const Vector3 &z)
01249 {
01250         Matrix4 tmp;
01251         tmp.fromAxes(x, y, z);
01252         return tmp;
01253 }
01254 
01255 inline Matrix4 Matrix4::createFromAxesTransposed(const Vector3 &x, const Vector3 &y, const Vector3 &z)
01256 {
01257         Matrix4 tmp;
01258         tmp.fromAxesTransposed(x, y, z);
01259         return tmp;
01260 }
01261 
01262 inline Matrix4 Matrix4::createFromHeadPitchRoll(float headDegrees, float pitchDegrees, float rollDegrees)
01263 {
01264         Matrix4 tmp;
01265         tmp.fromHeadPitchRoll(headDegrees, pitchDegrees, rollDegrees);
01266         return tmp;
01267 }
01268 
01269 inline Matrix4 Matrix4::createOrient(const Vector3 &from, const Vector3 &to)
01270 {
01271         Matrix4 tmp;
01272         tmp.orient(from, to);
01273         return tmp;
01274 }
01275 
01276 inline Matrix4 Matrix4::createRotate(const Vector3 &axis, float degrees)
01277 {
01278         Matrix4 tmp;
01279         tmp.rotate(axis, degrees);
01280         return tmp;
01281 }
01282 
01283 inline Matrix4 Matrix4::createScale(float sx, float sy, float sz)
01284 {
01285         Matrix4 tmp;
01286         tmp.scale(sx, sy, sz);
01287         return tmp;
01288 }
01289 
01290 inline Matrix4 Matrix4::createTranslate(float tx, float ty, float tz)
01291 {
01292         Matrix4 tmp;
01293         tmp.translate(tx, ty, tz);
01294         return tmp;
01295 }
01296 
01297 inline Matrix4::Matrix4(float m11, float m12, float m13, float m14,
01298                                                           float m21, float m22, float m23, float m24,
01299                                                           float m31, float m32, float m33, float m34,
01300                                                           float m41, float m42, float m43, float m44)
01301 {
01302         mtx[0][0] = m11, mtx[0][1] = m12, mtx[0][2] = m13, mtx[0][3] = m14;
01303         mtx[1][0] = m21, mtx[1][1] = m22, mtx[1][2] = m23, mtx[1][3] = m24;
01304         mtx[2][0] = m31, mtx[2][1] = m32, mtx[2][2] = m33, mtx[2][3] = m34;
01305         mtx[3][0] = m41, mtx[3][1] = m42, mtx[3][2] = m43, mtx[3][3] = m44;
01306 }
01307 
01308 inline float *Matrix4::operator[](int row)
01309 {
01310         return mtx[row];
01311 }
01312 
01313 inline const float *Matrix4::operator[](int row) const
01314 {
01315         return mtx[row];
01316 }
01317 
01318 inline bool Matrix4::operator==(const Matrix4 &rhs) const
01319 {
01320         return Math::closeEnough(mtx[0][0], rhs.mtx[0][0])
01321                 && Math::closeEnough(mtx[0][1], rhs.mtx[0][1])
01322                 && Math::closeEnough(mtx[0][2], rhs.mtx[0][2])
01323                 && Math::closeEnough(mtx[0][3], rhs.mtx[0][3])
01324                 && Math::closeEnough(mtx[1][0], rhs.mtx[1][0])
01325                 && Math::closeEnough(mtx[1][1], rhs.mtx[1][1])
01326                 && Math::closeEnough(mtx[1][2], rhs.mtx[1][2])
01327                 && Math::closeEnough(mtx[1][3], rhs.mtx[1][3])
01328                 && Math::closeEnough(mtx[2][0], rhs.mtx[2][0])
01329                 && Math::closeEnough(mtx[2][1], rhs.mtx[2][1])
01330                 && Math::closeEnough(mtx[2][2], rhs.mtx[2][2])
01331                 && Math::closeEnough(mtx[2][3], rhs.mtx[2][3])
01332                 && Math::closeEnough(mtx[3][0], rhs.mtx[3][0])
01333                 && Math::closeEnough(mtx[3][1], rhs.mtx[3][1])
01334                 && Math::closeEnough(mtx[3][2], rhs.mtx[3][2])
01335                 && Math::closeEnough(mtx[3][3], rhs.mtx[3][3]);
01336 }
01337 
01338 inline bool Matrix4::operator!=(const Matrix4 &rhs) const
01339 {
01340         return !(*this == rhs);
01341 }
01342 
01343 inline Matrix4 &Matrix4::operator+=(const Matrix4 &rhs)
01344 {
01345         mtx[0][0] += rhs.mtx[0][0], mtx[0][1] += rhs.mtx[0][1], mtx[0][2] += rhs.mtx[0][2], mtx[0][3] += rhs.mtx[0][3];
01346         mtx[1][0] += rhs.mtx[1][0], mtx[1][1] += rhs.mtx[1][1], mtx[1][2] += rhs.mtx[1][2], mtx[1][3] += rhs.mtx[1][3];
01347         mtx[2][0] += rhs.mtx[2][0], mtx[2][1] += rhs.mtx[2][1], mtx[2][2] += rhs.mtx[2][2], mtx[2][3] += rhs.mtx[2][3];
01348         mtx[3][0] += rhs.mtx[3][0], mtx[3][1] += rhs.mtx[3][1], mtx[3][2] += rhs.mtx[3][2], mtx[3][3] += rhs.mtx[3][3];
01349         return *this;
01350 }
01351 
01352 inline Matrix4 &Matrix4::operator-=(const Matrix4 &rhs)
01353 {
01354         mtx[0][0] -= rhs.mtx[0][0], mtx[0][1] -= rhs.mtx[0][1], mtx[0][2] -= rhs.mtx[0][2], mtx[0][3] -= rhs.mtx[0][3];
01355         mtx[1][0] -= rhs.mtx[1][0], mtx[1][1] -= rhs.mtx[1][1], mtx[1][2] -= rhs.mtx[1][2], mtx[1][3] -= rhs.mtx[1][3];
01356         mtx[2][0] -= rhs.mtx[2][0], mtx[2][1] -= rhs.mtx[2][1], mtx[2][2] -= rhs.mtx[2][2], mtx[2][3] -= rhs.mtx[2][3];
01357         mtx[3][0] -= rhs.mtx[3][0], mtx[3][1] -= rhs.mtx[3][1], mtx[3][2] -= rhs.mtx[3][2], mtx[3][3] -= rhs.mtx[3][3];
01358         return *this;
01359 }
01360 
01361 inline Matrix4 &Matrix4::operator*=(const Matrix4 &rhs)
01362 {
01363         Matrix4 tmp;
01364 
01365         // Row 1.
01366         tmp.mtx[0][0] = (mtx[0][0] * rhs.mtx[0][0]) + (mtx[0][1] * rhs.mtx[1][0]) + (mtx[0][2] * rhs.mtx[2][0]) + (mtx[0][3] * rhs.mtx[3][0]);
01367         tmp.mtx[0][1] = (mtx[0][0] * rhs.mtx[0][1]) + (mtx[0][1] * rhs.mtx[1][1]) + (mtx[0][2] * rhs.mtx[2][1]) + (mtx[0][3] * rhs.mtx[3][1]);
01368         tmp.mtx[0][2] = (mtx[0][0] * rhs.mtx[0][2]) + (mtx[0][1] * rhs.mtx[1][2]) + (mtx[0][2] * rhs.mtx[2][2]) + (mtx[0][3] * rhs.mtx[3][2]);
01369         tmp.mtx[0][3] = (mtx[0][0] * rhs.mtx[0][3]) + (mtx[0][1] * rhs.mtx[1][3]) + (mtx[0][2] * rhs.mtx[2][3]) + (mtx[0][3] * rhs.mtx[3][3]);
01370 
01371         // Row 2.
01372         tmp.mtx[1][0] = (mtx[1][0] * rhs.mtx[0][0]) + (mtx[1][1] * rhs.mtx[1][0]) + (mtx[1][2] * rhs.mtx[2][0]) + (mtx[1][3] * rhs.mtx[3][0]);
01373         tmp.mtx[1][1] = (mtx[1][0] * rhs.mtx[0][1]) + (mtx[1][1] * rhs.mtx[1][1]) + (mtx[1][2] * rhs.mtx[2][1]) + (mtx[1][3] * rhs.mtx[3][1]);
01374         tmp.mtx[1][2] = (mtx[1][0] * rhs.mtx[0][2]) + (mtx[1][1] * rhs.mtx[1][2]) + (mtx[1][2] * rhs.mtx[2][2]) + (mtx[1][3] * rhs.mtx[3][2]);
01375         tmp.mtx[1][3] = (mtx[1][0] * rhs.mtx[0][3]) + (mtx[1][1] * rhs.mtx[1][3]) + (mtx[1][2] * rhs.mtx[2][3]) + (mtx[1][3] * rhs.mtx[3][3]);
01376 
01377         // Row 3.
01378         tmp.mtx[2][0] = (mtx[2][0] * rhs.mtx[0][0]) + (mtx[2][1] * rhs.mtx[1][0]) + (mtx[2][2] * rhs.mtx[2][0]) + (mtx[2][3] * rhs.mtx[3][0]);
01379         tmp.mtx[2][1] = (mtx[2][0] * rhs.mtx[0][1]) + (mtx[2][1] * rhs.mtx[1][1]) + (mtx[2][2] * rhs.mtx[2][1]) + (mtx[2][3] * rhs.mtx[3][1]);
01380         tmp.mtx[2][2] = (mtx[2][0] * rhs.mtx[0][2]) + (mtx[2][1] * rhs.mtx[1][2]) + (mtx[2][2] * rhs.mtx[2][2]) + (mtx[2][3] * rhs.mtx[3][2]);
01381         tmp.mtx[2][3] = (mtx[2][0] * rhs.mtx[0][3]) + (mtx[2][1] * rhs.mtx[1][3]) + (mtx[2][2] * rhs.mtx[2][3]) + (mtx[2][3] * rhs.mtx[3][3]);
01382 
01383         // Row 4.
01384         tmp.mtx[3][0] = (mtx[3][0] * rhs.mtx[0][0]) + (mtx[3][1] * rhs.mtx[1][0]) + (mtx[3][2] * rhs.mtx[2][0]) + (mtx[3][3] * rhs.mtx[3][0]);
01385         tmp.mtx[3][1] = (mtx[3][0] * rhs.mtx[0][1]) + (mtx[3][1] * rhs.mtx[1][1]) + (mtx[3][2] * rhs.mtx[2][1]) + (mtx[3][3] * rhs.mtx[3][1]);
01386         tmp.mtx[3][2] = (mtx[3][0] * rhs.mtx[0][2]) + (mtx[3][1] * rhs.mtx[1][2]) + (mtx[3][2] * rhs.mtx[2][2]) + (mtx[3][3] * rhs.mtx[3][2]);
01387         tmp.mtx[3][3] = (mtx[3][0] * rhs.mtx[0][3]) + (mtx[3][1] * rhs.mtx[1][3]) + (mtx[3][2] * rhs.mtx[2][3]) + (mtx[3][3] * rhs.mtx[3][3]);
01388 
01389         *this = tmp;
01390         return *this;
01391 }
01392 
01393 inline Matrix4 &Matrix4::operator*=(float scalar)
01394 {
01395         mtx[0][0] *= scalar, mtx[0][1] *= scalar, mtx[0][2] *= scalar, mtx[0][3] *= scalar;
01396         mtx[1][0] *= scalar, mtx[1][1] *= scalar, mtx[1][2] *= scalar, mtx[1][3] *= scalar;
01397         mtx[2][0] *= scalar, mtx[2][1] *= scalar, mtx[2][2] *= scalar, mtx[2][3] *= scalar;
01398         mtx[3][0] *= scalar, mtx[3][1] *= scalar, mtx[3][2] *= scalar, mtx[3][3] *= scalar;
01399         return *this;
01400 }
01401 
01402 inline Matrix4 &Matrix4::operator/=(float scalar)
01403 {
01404         mtx[0][0] /= scalar, mtx[0][1] /= scalar, mtx[0][2] /= scalar, mtx[0][3] /= scalar;
01405         mtx[1][0] /= scalar, mtx[1][1] /= scalar, mtx[1][2] /= scalar, mtx[1][3] /= scalar;
01406         mtx[2][0] /= scalar, mtx[2][1] /= scalar, mtx[2][2] /= scalar, mtx[2][3] /= scalar;
01407         mtx[3][0] /= scalar, mtx[3][1] /= scalar, mtx[3][2] /= scalar, mtx[3][3] /= scalar;
01408         return *this;
01409 }
01410 
01411 inline Matrix4 Matrix4::operator+(const Matrix4 &rhs) const
01412 {
01413         Matrix4 tmp(*this);
01414         tmp += rhs;
01415         return tmp;
01416 }
01417 
01418 inline Matrix4 Matrix4::operator-(const Matrix4 &rhs) const
01419 {
01420         Matrix4 tmp(*this);
01421         tmp -= rhs;
01422         return tmp;
01423 }
01424 
01425 inline Matrix4 Matrix4::operator*(const Matrix4 &rhs) const
01426 {
01427         Matrix4 tmp(*this);
01428         tmp *= rhs;
01429         return tmp;
01430 }
01431 
01432 inline Matrix4 Matrix4::operator*(float scalar) const
01433 {
01434         Matrix4 tmp(*this);
01435         tmp *= scalar;
01436         return tmp;
01437 }
01438 
01439 inline Matrix4 Matrix4::operator/(float scalar) const
01440 {
01441         Matrix4 tmp(*this);
01442         tmp /= scalar;
01443         return tmp;
01444 }
01445 
01446 inline float Matrix4::determinant() const
01447 {
01448         return (mtx[0][0] * mtx[1][1] - mtx[1][0] * mtx[0][1])
01449                 * (mtx[2][2] * mtx[3][3] - mtx[3][2] * mtx[2][3])
01450                 - (mtx[0][0] * mtx[2][1] - mtx[2][0] * mtx[0][1])
01451                 * (mtx[1][2] * mtx[3][3] - mtx[3][2] * mtx[1][3])
01452                 + (mtx[0][0] * mtx[3][1] - mtx[3][0] * mtx[0][1])
01453                 * (mtx[1][2] * mtx[2][3] - mtx[2][2] * mtx[1][3])
01454                 + (mtx[1][0] * mtx[2][1] - mtx[2][0] * mtx[1][1])
01455                 * (mtx[0][2] * mtx[3][3] - mtx[3][2] * mtx[0][3])
01456                 - (mtx[1][0] * mtx[3][1] - mtx[3][0] * mtx[1][1])
01457                 * (mtx[0][2] * mtx[2][3] - mtx[2][2] * mtx[0][3])
01458                 + (mtx[2][0] * mtx[3][1] - mtx[3][0] * mtx[2][1])
01459                 * (mtx[0][2] * mtx[1][3] - mtx[1][2] * mtx[0][3]);
01460 }
01461 
01462 inline void Matrix4::fromAxes(const Vector3 &x, const Vector3 &y, const Vector3 &z)
01463 {
01464         mtx[0][0] = x.x,  mtx[0][1] = x.y,  mtx[0][2] = x.z,  mtx[0][3] = 0.0f;
01465         mtx[1][0] = y.x,  mtx[1][1] = y.y,  mtx[1][2] = y.z,  mtx[1][3] = 0.0f;
01466         mtx[2][0] = z.x,  mtx[2][1] = z.y,  mtx[2][2] = z.z,  mtx[2][3] = 0.0f;
01467         mtx[3][0] = 0.0f, mtx[3][1] = 0.0f, mtx[3][2] = 0.0f, mtx[3][3] = 1.0f;
01468 }
01469 
01470 inline void Matrix4::fromAxesTransposed(const Vector3 &x, const Vector3 &y, const Vector3 &z)
01471 {
01472         mtx[0][0] = x.x,  mtx[0][1] = y.x,  mtx[0][2] = z.x,  mtx[0][3] = 0.0f;
01473         mtx[1][0] = x.y,  mtx[1][1] = y.y,  mtx[1][2] = z.y,  mtx[1][3] = 0.0f;
01474         mtx[2][0] = x.z,  mtx[2][1] = y.z,  mtx[2][2] = z.z,  mtx[2][3] = 0.0f;
01475         mtx[3][0] = 0.0f, mtx[3][1] = 0.0f, mtx[3][2] = 0.0f, mtx[3][3] = 1.0f;
01476 }
01477 
01478 inline void Matrix4::identity()
01479 {
01480         mtx[0][0] = 1.0f, mtx[0][1] = 0.0f, mtx[0][2] = 0.0f, mtx[0][3] = 0.0f;
01481         mtx[1][0] = 0.0f, mtx[1][1] = 1.0f, mtx[1][2] = 0.0f, mtx[1][3] = 0.0f;
01482         mtx[2][0] = 0.0f, mtx[2][1] = 0.0f, mtx[2][2] = 1.0f, mtx[2][3] = 0.0f;
01483         mtx[3][0] = 0.0f, mtx[3][1] = 0.0f, mtx[3][2] = 0.0f, mtx[3][3] = 1.0f;
01484 }
01485 
01486 inline void Matrix4::toAxes(Vector3 &x, Vector3 &y, Vector3 &z) const
01487 {
01488         x.set(mtx[0][0], mtx[0][1], mtx[0][2]);
01489         y.set(mtx[1][0], mtx[1][1], mtx[1][2]);
01490         z.set(mtx[2][0], mtx[2][1], mtx[2][2]);
01491 }
01492 
01493 inline void Matrix4::toAxesTransposed(Vector3 &x, Vector3 &y, Vector3 &z) const
01494 {
01495         x.set(mtx[0][0], mtx[1][0], mtx[2][0]);
01496         y.set(mtx[0][1], mtx[1][1], mtx[2][1]);
01497         z.set(mtx[0][2], mtx[1][2], mtx[2][2]);
01498 }
01499 
01500 inline Matrix4 Matrix4::transpose() const
01501 {
01502         Matrix4 tmp;
01503 
01504         tmp[0][0] = mtx[0][0], tmp[0][1] = mtx[1][0], tmp[0][2] = mtx[2][0], tmp[0][3] = mtx[3][0];
01505         tmp[1][0] = mtx[0][1], tmp[1][1] = mtx[1][1], tmp[1][2] = mtx[2][1], tmp[1][3] = mtx[3][1];
01506         tmp[2][0] = mtx[0][2], tmp[2][1] = mtx[1][2], tmp[2][2] = mtx[2][2], tmp[2][3] = mtx[3][2];
01507         tmp[3][0] = mtx[0][3], tmp[3][1] = mtx[1][3], tmp[3][2] = mtx[2][3], tmp[3][3] = mtx[3][3];
01508 
01509         return tmp;
01510 }
01511 
01512 const inline float * Matrix4::getRaw() const
01513 {
01514         return &(mtx[0][0]);
01515 }
01516 
01517 inline float * Matrix4::getRawWritable()
01518 {
01519         return &(mtx[0][0]);
01520 }
01521 
01522 //-----------------------------------------------------------------------------
01531 class Quaternion
01532 {
01533         friend Quaternion operator*(float lhs, const Quaternion &rhs);
01534 
01535 public:
01536         static const Quaternion IDENTITY;
01537 
01538         float w, x, y, z;
01539 
01540         static Quaternion slerp(const Quaternion &a, const Quaternion &b, float t);
01541 
01542         Quaternion() {}
01543         Quaternion(float w_, float x_, float y_, float z_);
01544         Quaternion(float headDegrees, float pitchDegrees, float rollDegrees);
01545         Quaternion(const Vector3 &axis, float degrees);
01546         explicit Quaternion(const Matrix3 &m);
01547         explicit Quaternion(const Matrix4 &m);
01548         ~Quaternion() {}
01549 
01550         bool operator==(const Quaternion &rhs) const;
01551         bool operator!=(const Quaternion &rhs) const;
01552 
01553         Quaternion &operator+=(const Quaternion &rhs);
01554         Quaternion &operator-=(const Quaternion &rhs);
01555         Quaternion &operator*=(const Quaternion &rhs);
01556         Quaternion &operator*=(float scalar);
01557         Quaternion &operator/=(float scalar);
01558 
01559         Quaternion operator+(const Quaternion &rhs) const;
01560         Quaternion operator-(const Quaternion &rhs) const;
01561         Quaternion operator*(const Quaternion &rhs) const;
01562         Quaternion operator*(float scalar) const;
01563         Quaternion operator/(float scalar) const;
01564 
01565         Quaternion conjugate() const;
01566         void fromAxisAngle(const Vector3 &axis, float degrees);
01567         void fromHeadPitchRoll(float headDegrees, float pitchDegrees, float rollDegrees);
01568         void fromMatrix(const Matrix3 &m);
01569         void fromMatrix(const Matrix4 &m);
01570         void identity();
01571         Quaternion inverse() const;
01572         float magnitude() const;
01573         void normalize();
01574         void set(float w_, float x_, float y_, float z_);
01575         void toAxisAngle(Vector3 &axis, float &degrees) const;
01576         void toHeadPitchRoll(float &headDegrees, float &pitchDegrees, float &rollDegrees) const;
01577         Matrix3 toMatrix3() const;
01578         Matrix4 toMatrix4() const;
01579 };
01580 
01581 inline Quaternion operator*(float lhs, const Quaternion &rhs)
01582 {
01583         return rhs * lhs;
01584 }
01585 
01586 inline Quaternion::Quaternion(float w_, float x_, float y_, float z_)
01587 : w(w_), x(x_), y(y_), z(z_) {}
01588 
01589 inline Quaternion::Quaternion(float headDegrees, float pitchDegrees, float rollDegrees)
01590 {
01591         fromHeadPitchRoll(headDegrees, pitchDegrees, rollDegrees);
01592 }
01593 
01594 inline Quaternion::Quaternion(const Vector3 &axis, float degrees)
01595 {
01596         fromAxisAngle(axis, degrees);
01597 }
01598 
01599 inline Quaternion::Quaternion(const Matrix3 &m)
01600 {
01601         fromMatrix(m);
01602 }
01603 
01604 inline Quaternion::Quaternion(const Matrix4 &m)
01605 {
01606         fromMatrix(m);
01607 }
01608 
01609 inline bool Quaternion::operator==(const Quaternion &rhs) const
01610 {
01611         return Math::closeEnough(w, rhs.w) && Math::closeEnough(x, rhs.x)
01612                 && Math::closeEnough(y, rhs.y) && Math::closeEnough(z, rhs.z);
01613 }
01614 
01615 inline bool Quaternion::operator!=(const Quaternion &rhs) const
01616 {
01617         return !(*this == rhs);
01618 }
01619 
01620 inline Quaternion &Quaternion::operator+=(const Quaternion &rhs)
01621 {
01622         w += rhs.w, x += rhs.x, y += rhs.y, z += rhs.z;
01623         return *this;
01624 }
01625 
01626 inline Quaternion &Quaternion::operator-=(const Quaternion &rhs)
01627 {
01628         w -= rhs.w, x -= rhs.x, y -= rhs.y, z -= rhs.z;
01629         return *this;
01630 }
01631 
01632 inline Quaternion &Quaternion::operator*=(const Quaternion &rhs)
01633 {
01634         // Multiply so that rotations are applied in a left to right order.
01635         Quaternion tmp(
01636                 (w * rhs.w) - (x * rhs.x) - (y * rhs.y) - (z * rhs.z),
01637                 (w * rhs.x) + (x * rhs.w) - (y * rhs.z) + (z * rhs.y),
01638                 (w * rhs.y) + (x * rhs.z) + (y * rhs.w) - (z * rhs.x),
01639                 (w * rhs.z) - (x * rhs.y) + (y * rhs.x) + (z * rhs.w));
01640 
01641         /*
01642         // Multiply so that rotations are applied in a right to left order.
01643         Quaternion tmp(
01644         (w * rhs.w) - (x * rhs.x) - (y * rhs.y) - (z * rhs.z),
01645         (w * rhs.x) + (x * rhs.w) + (y * rhs.z) - (z * rhs.y),
01646         (w * rhs.y) - (x * rhs.z) + (y * rhs.w) + (z * rhs.x),
01647         (w * rhs.z) + (x * rhs.y) - (y * rhs.x) + (z * rhs.w));
01648         */
01649 
01650         *this = tmp;
01651         return *this;
01652 }
01653 
01654 inline Quaternion &Quaternion::operator*=(float scalar)
01655 {
01656         w *= scalar, x *= scalar, y *= scalar, z *= scalar;
01657         return *this;
01658 }
01659 
01660 inline Quaternion &Quaternion::operator/=(float scalar)
01661 {
01662         w /= scalar, x /= scalar, y /= scalar, z /= scalar;
01663         return *this;
01664 }
01665 
01666 inline Quaternion Quaternion::operator+(const Quaternion &rhs) const
01667 {
01668         Quaternion tmp(*this);
01669         tmp += rhs;
01670         return tmp;
01671 }
01672 
01673 inline Quaternion Quaternion::operator-(const Quaternion &rhs) const
01674 {
01675         Quaternion tmp(*this);
01676         tmp -= rhs;
01677         return tmp;
01678 }
01679 
01680 inline Quaternion Quaternion::operator*(const Quaternion &rhs) const
01681 {
01682         Quaternion tmp(*this);
01683         tmp *= rhs;
01684         return tmp;
01685 }
01686 
01687 inline Quaternion Quaternion::operator*(float scalar) const
01688 {
01689         Quaternion tmp(*this);
01690         tmp *= scalar;
01691         return tmp;
01692 }
01693 
01694 inline Quaternion Quaternion::operator/(float scalar) const
01695 {
01696         Quaternion tmp(*this);
01697         tmp /= scalar;
01698         return tmp;
01699 }
01700 
01701 inline Quaternion Quaternion::conjugate() const
01702 {
01703         Quaternion tmp(w, -x, -y, -z);
01704         return tmp;
01705 }
01706 
01707 inline void Quaternion::fromAxisAngle(const Vector3 &axis, float degrees)
01708 {
01709         float halfTheta = Math::degreesToRadians(degrees) * 0.5f;
01710         float s = sinf(halfTheta);
01711         w = cosf(halfTheta), x = axis.x * s, y = axis.y * s, z = axis.z * s;
01712 }
01713 
01714 inline void Quaternion::fromHeadPitchRoll(float headDegrees, float pitchDegrees, float rollDegrees)
01715 {
01716         Matrix3 m;
01717         m.fromHeadPitchRoll(headDegrees, pitchDegrees, rollDegrees);
01718         fromMatrix(m);
01719 }
01720 
01721 inline void Quaternion::identity()
01722 {
01723         w = 1.0f, x = y = z = 0.0f;
01724 }
01725 
01726 inline Quaternion Quaternion::inverse() const
01727 {
01728         float invMag = 1.0f / magnitude();
01729         return conjugate() * invMag;
01730 }
01731 
01732 inline float Quaternion::magnitude() const
01733 {
01734         return sqrtf(w * w + x * x + y * y + z * z);
01735 }
01736 
01737 inline void Quaternion::normalize()
01738 {
01739         float invMag = 1.0f / magnitude();
01740         w *= invMag, x *= invMag, y *= invMag, z *= invMag;
01741 }
01742 
01743 inline void Quaternion::set(float w_, float x_, float y_, float z_)
01744 {
01745         w = w_, x = x_, y = y_, z = z_;
01746 }
01747 
01748 inline void Quaternion::toHeadPitchRoll(float &headDegrees, float &pitchDegrees, float &rollDegrees) const
01749 {
01750         Matrix3 m = toMatrix3();
01751         m.toHeadPitchRoll(headDegrees, pitchDegrees, rollDegrees);
01752 }
01753 
01754 //-----------------------------------------------------------------------------
01755 
01769 class MatrixStack
01770 {
01771 public:
01772         enum Error
01773         {
01774                 ERROR_OK,
01775                 ERROR_INVALID_VALUE,
01776                 ERROR_MATRIX_STACK_OVERFLOW,
01777                 ERROR_MATRIX_STACK_UNDERFLOW
01778         };
01779 
01780         static const int DEFAULT_MAX_STACK_DEPTH = 32;
01781 
01782         MatrixStack();
01783         MatrixStack(unsigned int maxDepth);
01784         ~MatrixStack();
01785 
01786         unsigned int currentDepth() const;
01787         const Matrix4 &currentMatrix() const;
01788         unsigned int maxDepth() const;
01789         Error lastError() const;
01790         void loadIdentity();
01791         void loadMatrix(const Matrix4 &m);
01792         void multMatrix(const Matrix4 &m);
01793         void popMatrix();
01794         void pushMatrix();
01795 
01796 private:
01797         void init(unsigned int maxDepth);
01798 
01799         Matrix4 *m_pStack;
01800         unsigned int m_depth;
01801         unsigned int m_maxDepth;
01802         Error m_lastError;
01803 };
01804 
01805 //-----------------------------------------------------------------------------
01806 
01807 #endif

Generado el Miércoles, 15 de Septiembre de 2010 14:56:31 para CGALib por  doxygen 1.7.1