00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #if !defined(MATHS_H)
00024 #define MATHS_H
00025
00026 #include <cmath>
00027 #include <cstdlib>
00028
00029
00030
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
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
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
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
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
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
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
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 °rees) 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
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
01643
01644
01645
01646
01647
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 ¤tMatrix() 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