00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __MATH__H__
00013 #define __MATH__H__
00014
00015 #include <wx/string.h>
00016 #include <sstream>
00017 #include <memory.h>
00018 #include <cmath>
00019 #include <iostream>
00020 #include <iomanip>
00021 #include "common.h"
00022
00024 struct vector2
00025 {
00026 union
00027 {
00028 struct
00029 {
00031 float x, y;
00032 };
00034 float _v[2];
00035 };
00036
00038 vector2(float _x = 0, float _y = 0) : x(_x), y(_y) {}
00040 vector2(const float * v) : x(v[0]), y(v[1]) {}
00042 vector2(const vector2 & v) : x(v.x), y(v.y) {}
00044 bool operator!=(const vector2 & v) const
00045 {
00046 return (x != v.x) || ( y != v.y);
00047 }
00049 bool operator<(const vector2 & v) const
00050 {
00051 return (x < v.x) || ((x == v.x) && ( y < v.y));
00052 }
00053
00054 };
00055
00056
00058 struct vector3
00059 {
00060 union
00061 {
00062 struct
00063 {
00065 float x, y, z;
00066 };
00068 float _v[3];
00069 };
00070
00072 vector3(float _x = 0, float _y = 0, float _z = 0) : x(_x), y(_y), z(_z) {}
00074 vector3(const float * v) : x(v[0]), y(v[1]), z(v[2]) {}
00076 vector3(const vector3 & v) : x(v.x), y(v.y), z(v.z) {}
00077
00079 vector3 & operator=(const vector3 & v)
00080 {
00081 x = v.x;
00082 y = v.y;
00083 z = v.z;
00084 return *this;
00085 }
00086
00088 float operator[](unsigned i) const
00089 {
00090 return _v[i];
00091 }
00092
00094 vector3 operator-(const vector3 & v) const
00095 {
00096 return vector3(x-v.x, y-v.y, z-v.z);
00097 }
00098
00100 vector3 operator-() const
00101 {
00102 return vector3(-x, -y, -z);
00103 }
00104
00106 vector3 operator+(const vector3 & v) const
00107 {
00108 return vector3(x+v.x, y+v.y, z+v.z);
00109 }
00110
00112 vector3 operator*(float f) const
00113 {
00114 return vector3(f*x, f*y, f*z);
00115 }
00116
00118 friend vector3 operator*(float f, const vector3 & v)
00119 {
00120 return vector3(f*v.x, f*v.y, f*v.z);
00121 }
00122
00124 vector3 operator/(float f) const
00125 {
00126 float div = 1.0f/f;
00127 return operator*(div);
00128 }
00129
00131 friend vector3 operator/(float f, const vector3 & v)
00132 {
00133 float div = 1.0f/f;
00134 return v*div;
00135 }
00136
00138 vector3 & operator+=(const vector3 & v)
00139 {
00140 x += v.x;
00141 y += v.y;
00142 z += v.z;
00143 return *this;
00144 }
00145
00147 vector3 & operator-=(const vector3 & v)
00148 {
00149 x -= v.x;
00150 y -= v.y;
00151 z -= v.z;
00152 return *this;
00153 }
00154
00156 vector3 & operator*=(float f)
00157 {
00158 x *= f;
00159 y *= f;
00160 z *= f;
00161 return *this;
00162 }
00163
00165 vector3 & operator/=(float f)
00166 {
00167 x /= f;
00168 y /= f;
00169 z /= f;
00170 return *this;
00171 }
00172
00174 bool operator==(const vector3 & v) const
00175 {
00176 return (x == v.x) && ( y == v.y) && (z == v.z);
00177 }
00178
00180 bool operator!=(const vector3 & v) const
00181 {
00182 return (x != v.x) || ( y != v.y) || (z != v.z);
00183 }
00184
00186 bool operator<(const vector3 & v) const
00187 {
00188 return (x < v.x) || ((x == v.x) && ( y < v.y)) || ((x == v.x) && ( y == v.y) && (z < v.z));
00189 }
00190
00192 float Dot(const vector3 & v) const
00193 {
00194 return x * v.x + y * v.y + z * v.z;
00195 }
00196
00198 vector3 Cross(const vector3 & v) const
00199 {
00200 return vector3(y*v.z-z*v.y,z*v.x-x*v.z,x*v.y-y*v.x);
00201 }
00202
00204 vector3 Normalize() const
00205 {
00206 float a = 1.0f/Length();
00207 return operator*(a);
00208 }
00209
00211 float LengthSq() const
00212 {
00213 return x*x + y*y + z*z;
00214 }
00215
00217 float Length() const
00218 {
00219 return sqrtf(x*x + y*y + z*z);
00220 }
00221
00223 wxString ToString() const
00224 {
00225 return wxString(wxT("(")) << x << wxT(", ") << y << wxT(", ") << z << wxT(")");
00226 }
00227
00229 friend std::ostream & operator<<(std::ostream & os, const vector3 & v)
00230 {
00231 return os << "(" << v.x << ", " << v.y << ", " << v.z << ")";
00232 }
00233
00235 vector3 * Clone() const
00236 {
00237 return new vector3(*this);
00238 }
00239
00240 friend float Distance(const vector3 &a, const vector3 &b) {
00241 return (a-b).Length();
00242 }
00243 friend float SqrDistance(const vector3 &a, const vector3 &b) {
00244 return (a-b).LengthSq();
00245 }
00246
00247 };
00248
00249
00251 struct vector4
00252 {
00253 union
00254 {
00255 struct
00256 {
00258 float x, y, z, w;
00259 };
00261 float _v[4];
00262 };
00263
00265 vector4(float _x = 0, float _y = 0, float _z = 0, float _w = 1) : x(_x), y(_y), z(_z), w(_w) {}
00267 vector4(const float * v) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
00269 vector4(const vector4 & v) : x(v.x), y(v.y), z(v.z), w(v.w) {}
00271 vector4(const vector3 & v, float _w) : x(v.x), y(v.y), z(v.z), w(_w) {}
00272
00274 vector4 & operator=(const vector4 & v)
00275 {
00276 x = v.x;
00277 y = v.y;
00278 z = v.z;
00279 w = v.w;
00280 return *this;
00281 }
00282
00284 float operator[](unsigned i) const
00285 {
00286 return _v[i];
00287 }
00288
00290 vector4 operator*(float f) const
00291 {
00292 return vector4(f*x, f*y, f*z, f*w);
00293 }
00294
00296 friend vector4 operator*(float f, const vector4 & v)
00297 {
00298 return vector4(f*v.x, f*v.y, f*v.z, f*v.w);
00299 }
00300
00302 vector4 & operator*=(float f)
00303 {
00304 x *= f;
00305 y *= f;
00306 z *= f;
00307 w *= f;
00308 return *this;
00309 }
00310
00312 bool operator==(const vector4 & v) const
00313 {
00314 return (x == v.x) && ( y == v.y) && (z == v.z) && (w == v.w);
00315 }
00316
00318 bool operator!=(const vector4 & v) const
00319 {
00320 return (x != v.x) || ( y != v.y) || (z != v.z) || (w != v.w);
00321 }
00322
00324 wxString ToString() const
00325 {
00326 return wxString(wxT("(")) << x << wxT(", ") << y << wxT(", ") << z << wxT(", ") << w << wxT(")");
00327 }
00328
00330 friend std::ostream & operator<<(std::ostream & os, const vector4 & v)
00331 {
00332 return os << "(" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ")";
00333 }
00334
00336 vector4 * Clone() const
00337 {
00338 return new vector4(*this);
00339 }
00340 };
00341
00342
00344 struct plane
00345 {
00346 union
00347 {
00348 struct
00349 {
00351 float a, b, c, d;
00352 };
00354 float _p[4];
00355 };
00356
00358 plane(float _a = 0, float _b = 0, float _c = 0, float _d = 0) : a(_a), b(_b), c(_c), d(_d) {}
00359
00361 plane(const plane & p) : a(p.a), b(p.b), c(p.c), d(p.d) {}
00362
00364 plane & operator=(const plane & p)
00365 {
00366 a = p.a;
00367 b = p.b;
00368 c = p.c;
00369 d = p.d;
00370 return *this;
00371 }
00372
00374 plane Normalize() const
00375 {
00376 float imag = 1.0f / sqrtf(a*a + b*b + c*c);
00377 return plane(a * imag, b * imag, c * imag, d * imag);
00378 }
00379
00381 static plane FromPointNorm(const vector3 & point, const vector3 & normal)
00382 {
00383 return plane(normal.x, normal.y, normal.z, -normal.Dot(point));
00384 }
00385
00387 static plane FromPoints(const vector3 & p1, const vector3 & p2, const vector3 & p3)
00388 {
00389 vector3 v1 = p2 - p1;
00390 vector3 v2 = p3 - p1;
00391 vector3 n = v1.Cross(v2);
00392 return FromPointNorm(p1, n.Normalize());
00393 }
00394
00396 float DotCoord(const vector3 & p) const
00397 {
00398 return a * p.x + b * p.y + c * p.z + d;
00399 }
00400
00402 wxString ToString() const
00403 {
00404 return wxString(wxT("(")) << a << wxT(", ") << b << wxT(", ") << c << wxT(", ") << d << wxT(")");
00405 }
00406
00408 friend std::ostream & operator<<(std::ostream & os, const plane & p)
00409 {
00410 return os << "(" << p.a << ", " << p.b << ", " << p.c << ", " << p.d << ")";
00411 }
00412
00414 plane * Clone() const
00415 {
00416 return new plane(*this);
00417 }
00418 };
00419
00420
00422 struct matrix
00423 {
00424 union
00425 {
00426 struct
00427 {
00429 float _m11, _m12, _m13, _m14,
00430 _m21, _m22, _m23, _m24,
00431 _m31, _m32, _m33, _m34,
00432 _m41, _m42, _m43, _m44;
00433 };
00435 float _m[16];
00436 };
00437
00439 matrix()
00440 {
00441 memset(_m, 0, sizeof(_m));
00442 _m11 = _m22 = _m33 = _m44 = 1;
00443 }
00444
00446 matrix(float _11, float _12, float _13, float _14,
00447 float _21, float _22, float _23, float _24,
00448 float _31, float _32, float _33, float _34,
00449 float _41, float _42, float _43, float _44)
00450 :_m11(_11), _m12(_12), _m13(_13), _m14(_14),
00451 _m21(_21), _m22(_22), _m23(_23), _m24(_24),
00452 _m31(_31), _m32(_32), _m33(_33), _m34(_34),
00453 _m41(_41), _m42(_42), _m43(_43), _m44(_44) {}
00454
00456 matrix(const float * m)
00457 {
00458 for (int i = 0; i < 16; i++)
00459 _m[i] = m[i];
00460 }
00461
00463 matrix(const matrix & m)
00464 {
00465 for (int i = 0; i < 16; i++)
00466 _m[i] = m._m[i];
00467 }
00468
00470 matrix & operator=(const matrix & mat)
00471 {
00472 for (int i = 0; i < 16; i++)
00473 _m[i] = mat._m[i];
00474 return *this;
00475 }
00476
00478 matrix operator+(const matrix & c) const
00479 {
00480 matrix ret;
00481 float * r = ret._m;
00482 const float * m1 = _m;
00483 const float * m2 = c._m;
00484 for (int i = 0; i < 16; i++)
00485 *r++ = *m1++ + *m2++;
00486 return ret;
00487 }
00488
00490 matrix & operator+=(const matrix & c)
00491 {
00492 float * m1 = _m;
00493 const float * m2 = c._m;
00494 for (int i = 0; i < 16; i++)
00495 *m1++ += *m2++;
00496 return *this;
00497 }
00498
00500 matrix operator-(const matrix & c) const
00501 {
00502 matrix ret;
00503 float * r = ret._m;
00504 const float * m1 = _m;
00505 const float * m2 = c._m;
00506 for (int i = 0; i < 16; i++)
00507 *r++ = *m1++ - *m2++;
00508 return ret;
00509 }
00510
00512 matrix & operator-=(const matrix & c)
00513 {
00514 float * m1 = _m;
00515 const float * m2 = c._m;
00516 for (int i = 0; i < 16; i++)
00517 *m1++ -= *m2++;
00518 return *this;
00519 }
00520
00522 matrix operator*(const matrix & c) const
00523 {
00524 matrix ret;
00525 ret._m11 = _m11*c._m11+_m12*c._m21+_m13*c._m31+_m14*c._m41;
00526 ret._m12 = _m11*c._m12+_m12*c._m22+_m13*c._m32+_m14*c._m42;
00527 ret._m13 = _m11*c._m13+_m12*c._m23+_m13*c._m33+_m14*c._m43;
00528 ret._m14 = _m11*c._m14+_m12*c._m24+_m13*c._m34+_m14*c._m44;
00529 ret._m21 = _m21*c._m11+_m22*c._m21+_m23*c._m31+_m24*c._m41;
00530 ret._m22 = _m21*c._m12+_m22*c._m22+_m23*c._m32+_m24*c._m42;
00531 ret._m23 = _m21*c._m13+_m22*c._m23+_m23*c._m33+_m24*c._m43;
00532 ret._m24 = _m21*c._m14+_m22*c._m24+_m23*c._m34+_m24*c._m44;
00533 ret._m31 = _m31*c._m11+_m32*c._m21+_m33*c._m31+_m34*c._m41;
00534 ret._m32 = _m31*c._m12+_m32*c._m22+_m33*c._m32+_m34*c._m42;
00535 ret._m33 = _m31*c._m13+_m32*c._m23+_m33*c._m33+_m34*c._m43;
00536 ret._m34 = _m31*c._m14+_m32*c._m24+_m33*c._m34+_m34*c._m44;
00537 ret._m41 = _m41*c._m11+_m42*c._m21+_m43*c._m31+_m44*c._m41;
00538 ret._m42 = _m41*c._m12+_m42*c._m22+_m43*c._m32+_m44*c._m42;
00539 ret._m43 = _m41*c._m13+_m42*c._m23+_m43*c._m33+_m44*c._m43;
00540 ret._m44 = _m41*c._m14+_m42*c._m24+_m43*c._m34+_m44*c._m44;
00541 return ret;
00542 }
00543
00545 matrix operator*(float f) const
00546 {
00547 return matrix( f*_m11, f*_m12, f*_m13, f*_m14,
00548 f*_m21, f*_m22, f*_m23, f*_m24,
00549 f*_m31, f*_m32, f*_m33, f*_m34,
00550 f*_m41, f*_m42, f*_m43, f*_m44 );
00551 }
00552
00554 friend matrix operator*(float f, const matrix & m)
00555 {
00556 return matrix( f*m._m11, f*m._m12, f*m._m13, f*m._m14,
00557 f*m._m21, f*m._m22, f*m._m23, f*m._m24,
00558 f*m._m31, f*m._m32, f*m._m33, f*m._m34,
00559 f*m._m41, f*m._m42, f*m._m43, f*m._m44 );
00560 }
00561
00563 matrix & operator*=(const matrix & m)
00564 {
00565 operator=(*this * m);
00566 return *this;
00567 }
00568
00570 matrix & operator*=(float f)
00571 {
00572 for (int i = 0; i < 16; i++)
00573 _m[i] *= f;
00574 return *this;
00575 }
00576
00578 bool operator==(const matrix & m) const
00579 {
00580 for (int i=0; i<16; i++)
00581 if (_m[i]!=m._m[i])
00582 return false;
00583 return true;
00584 }
00585
00587 bool IsUnit() const
00588 {
00589 for (int i=0; i<4; i++)
00590 for (int j=0; j<4; j++)
00591 if (_m[i*4+j]!=((i==j)?1:0))
00592 return false;
00593 return true;
00594 }
00595
00597 vector3 ExtractTranslation() const
00598 {
00599 return vector3(_m41, _m42, _m43);
00600 }
00601
00603 matrix ExtractRotation() const
00604 {
00605 matrix mat(_m);
00606 mat._m41 = mat._m42 = mat._m43 = mat._m14 = mat._m24 = mat._m34 = 0;
00607 mat._m44 = 1;
00608 return mat;
00609 }
00610
00612 vector3 TransformCoord(const vector3 & v) const
00613 {
00614 vector3 ret;
00615 ret.x = v.x * _m11 + v.y * _m21 + v.z * _m31 + _m41;
00616 ret.y = v.x * _m12 + v.y * _m22 + v.z * _m32 + _m42;
00617 ret.z = v.x * _m13 + v.y * _m23 + v.z * _m33 + _m43;
00618
00619
00620
00621 return ret;
00622 }
00623
00625 vector3 TransformNormal(const vector3 & v) const
00626 {
00627 vector3 ret;
00628 ret.x = v.x * _m11 + v.y * _m21 + v.z * _m31;
00629 ret.y = v.x * _m12 + v.y * _m22 + v.z * _m32;
00630 ret.z = v.x * _m13 + v.y * _m23 + v.z * _m33;
00631 return ret;
00632 }
00633
00635 matrix Inverse() const
00636 {
00637 matrix ret;
00638
00639 ret._m[0] = _m[0];
00640 ret._m[1] = _m[4];
00641 ret._m[2] = _m[8];
00642 ret._m[4] = _m[1];
00643 ret._m[5] = _m[5];
00644 ret._m[6] = _m[9];
00645 ret._m[8] = _m[2];
00646 ret._m[9] = _m[6];
00647 ret._m[10] = _m[10];
00648
00649 ret._m[12] = ret._m[0]*-_m[12]+ret._m[4]*-_m[13]+ret._m[8]*-_m[14];
00650 ret._m[13] = ret._m[1]*-_m[12]+ret._m[5]*-_m[13]+ret._m[9]*-_m[14];
00651 ret._m[14] = ret._m[2]*-_m[12]+ret._m[6]*-_m[13]+ret._m[10]*-_m[14];
00652
00653 ret._m[3] = 0.0f;
00654 ret._m[7] = 0.0f;
00655 ret._m[11] = 0.0f;
00656 ret._m[15] = 1.0f;
00657
00658 return ret;
00659 }
00660
00662 float Det3x3() const
00663 {
00664 return _m11*_m22*_m33 + _m12*_m23*_m31
00665 + _m13*_m21*_m32 - _m13*_m22*_m31
00666 - _m11*_m23*_m32 - _m12*_m21*_m33;
00667 }
00668
00672 bool InvertThisPrecise()
00673 {
00674 int indxc[4],indxr[4],ipiv[4];
00675 int i,icol,irow,j,k,l,ll,n;
00676 float big,dum,pivinv,temp;
00677
00678 icol = irow = 0;
00679
00680 n = 4;
00681
00682 for ( j = 0 ; j < n ; j++)
00683 ipiv[j] = 0;
00684 for ( i = 0; i < n; i++)
00685 {
00686 big = 0.0;
00687 for (j = 0 ; j < n ; j++)
00688 if (ipiv[j] != 1)
00689 for ( k = 0 ; k<n ; k++)
00690 {
00691 if (ipiv[k] == 0)
00692 {
00693 if (fabs(_m[4*k+j]) >= big)
00694 {
00695 big = fabs(_m[4*k+j]);
00696 irow = j;
00697 icol = k;
00698 }
00699 }
00700 else
00701 if (ipiv[k] > 1)
00702 return false;
00703 }
00704 ++(ipiv[icol]);
00705 if (irow != icol)
00706 {
00707 for ( l = 0 ; l<n ; l++)
00708 {
00709 temp = _m[4*l+icol];
00710 _m[4*l+icol] = _m[4*l+irow];
00711 _m[4*l+irow] = temp;
00712 }
00713 }
00714 indxr[i] = irow;
00715 indxc[i] = icol;
00716 if (_m[4*icol+icol] == 0.0)
00717 return false;
00718
00719 pivinv = 1.0f / _m[4*icol+icol];
00720 _m[4*icol+icol] = 1.0 ;
00721 for ( l = 0 ; l<n ; l++)
00722 _m[4*l+icol] = _m[4*l+icol] * pivinv ;
00723 for (ll = 0 ; ll < n ; ll++)
00724 if (ll != icol)
00725 {
00726 dum = _m[4*icol+ll];
00727 _m[4*icol+ll] = 0.0;
00728 for ( l = 0 ; l<n ; l++)
00729 _m[4*l+ll] = _m[4*l+ll] - _m[4*l+icol] * dum ;
00730 }
00731 }
00732 for ( l = n; l--; )
00733 {
00734 if (indxr[l] != indxc[l])
00735 for ( k = 0; k<n ; k++)
00736 {
00737 temp = _m[4*indxr[l]+k];
00738 _m[4*indxr[l]+k] = _m[4*indxc[l]+k];
00739 _m[4*indxc[l]+k] = temp;
00740 }
00741 }
00742 return true;
00743 }
00744
00746 matrix Transpose() const
00747 {
00748 matrix mat;
00749 for (int i = 0; i < 4; i++)
00750 for (int j = 0; j < 4; j++)
00751 mat._m[4*j+i] = _m[4*i+j];
00752 return mat;
00753 }
00754
00757 matrix & Translate(const vector3 & v)
00758 {
00759 *this *= Translation(v);
00760 return *this;
00761 }
00762
00764 matrix & Scale(const vector3 & v)
00765 {
00766 _m11 *= v.x;
00767 _m22 *= v.y;
00768 _m33 *= v.z;
00769 return *this;
00770 }
00771
00774
00775
00776 void ToEuler(float &x, float &y, float &z) const
00777 {
00778 x=-atan2(_m23, _m33);
00779 y=asin(-_m13);
00780 z=-atan2(_m12, _m11);
00781 }
00782
00785
00786
00787 void ToAxisAngle(vector3 &axis, float &angle) const
00788 {
00789 float epsilon = 0.01f;
00790 float epsilon2 = 0.1f;
00791
00792
00793
00794 if ((fabs(_m12-_m21)<EPSILON) && (fabs(_m13-_m31)<EPSILON) && (fabs(_m23-_m32)<EPSILON)) {
00795
00796
00797
00798 if ((fabs(_m12+_m21) < epsilon2) && (fabs(_m13+_m31) < epsilon2) && (fabs(_m23+_m32) < epsilon2) && (fabs(_m11+_m22+_m33-3) < epsilon2)) {
00799
00800 axis=vector3(0, 1, 0);
00801 angle=0;
00802 }
00803
00804 angle = 3.14159f;
00805 float xx = (_m11+1)/2;
00806 float yy = (_m22+1)/2;
00807 float zz = (_m33+1)/2;
00808 float xy = (_m12+_m21)/4;
00809 float xz = (_m13+_m31)/4;
00810 float yz = (_m23+_m32)/4;
00811 if ((xx > yy) && (xx > zz)) {
00812 if (xx< epsilon) {
00813 axis=vector3(0.0f, 0.7071f, 0.7071f);
00814 } else {
00815 xx=sqrt(xx);
00816 axis=vector3(xx, xy/xx, xz/xx);
00817 }
00818 } else if (yy > zz) {
00819 if (yy< epsilon) {
00820 axis=vector3(0.7071f, 0.0f, 0.7071f);
00821 } else {
00822 yy=sqrt(yy);
00823 axis=vector3(xy/yy, yy, yz/yy);
00824 }
00825 } else {
00826 if (zz< epsilon) {
00827 axis=vector3(0.7071f, 0.7071f, 0.0f);
00828 } else {
00829 zz = sqrt(zz);
00830 axis=vector3(xz/zz, yz/zz, zz);
00831 }
00832 }
00833 return;
00834 }
00835
00836
00837
00838
00839
00840 angle = acos(( _m11 + _m22 + _m33 - 1)/2);
00841 axis=vector3(_m32 - _m23, _m13 - _m31, _m21 - _m12).Normalize();
00842 }
00843
00845 static matrix ScaleMat(const vector3 & v)
00846 {
00847 matrix ret;
00848 ret._m11 = v.x;
00849 ret._m22 = v.y;
00850 ret._m33 = v.z;
00851 return ret;
00852 }
00853
00855 static matrix Translation(const vector3 & v)
00856 {
00857 matrix mat;
00858 mat._m41 = v.x;
00859 mat._m42 = v.y;
00860 mat._m43 = v.z;
00861 return mat;
00862 }
00863
00865 static matrix RotationX(float angle)
00866 {
00867 matrix M;
00868 float Cosine = cos(angle);
00869 float Sine = sin(angle);
00870 M._m22 = Cosine;
00871 M._m23 = -Sine;
00872 M._m32 = Sine;
00873 M._m33 = Cosine;
00874 return M;
00875 }
00876
00878 static matrix RotationY(float angle)
00879 {
00880 matrix M;
00881 float Cosine = cos(angle);
00882 float Sine = sin(angle);
00883 M._m11 = Cosine;
00884 M._m13 = -Sine;
00885 M._m31 = Sine;
00886 M._m33 = Cosine;
00887 return M;
00888 }
00889
00891 static matrix RotationZ(float angle)
00892 {
00893 matrix M;
00894 float Cosine = cos(angle);
00895 float Sine = sin(angle);
00896 M._m11 = Cosine;
00897 M._m12 = -Sine;
00898 M._m21 = Sine;
00899 M._m22 = Cosine;
00900 return M;
00901 }
00902
00907 static matrix RotationYPR(float Yaw, float Pitch, float Roll)
00908 {
00909 matrix M;
00910 float ch = cos(Yaw);
00911 float sh = sin(Yaw);
00912 float cp = cos(Pitch);
00913 float sp = sin(Pitch);
00914 float cr = cos(Roll);
00915 float sr = sin(Roll);
00916
00917 M._m11 = ch * cr + sh * sp * sr;
00918 M._m12 = -ch * sr + sh * sp * cr;
00919 M._m13 = sh * cp;
00920 M._m21 = sr * cp;
00921 M._m22 = cr * cp;
00922 M._m23 = -sp;
00923 M._m31 = -sh * cr - ch * sp * sr;
00924 M._m32 = sr * sh + ch * sp * cr;
00925 M._m33 = ch * cp;
00926
00927 return M;
00928 }
00929
00933 static matrix RotationAxis(const vector3 & axis, float angle)
00934 {
00935 matrix M;
00936 float cosine = cos(angle);
00937 float sine = sin(angle);
00938 float one_minus_cosine = 1 - cosine;
00939
00940 M._m11 = axis.x * axis.x + (1.0f - axis.x * axis.x) * cosine;
00941 M._m21 = axis.x * axis.y * one_minus_cosine + axis.z * sine;
00942 M._m31 = axis.x * axis.z * one_minus_cosine - axis.y * sine;
00943 M._m41 = 0;
00944
00945 M._m12 = axis.x * axis.y * one_minus_cosine - axis.z * sine;
00946 M._m22 = axis.y * axis.y + (1.0f - axis.y * axis.y) * cosine;
00947 M._m32 = axis.y * axis.z * one_minus_cosine + axis.x * sine;
00948 M._m42 = 0;
00949
00950 M._m13 = axis.x * axis.z * one_minus_cosine + axis.y * sine;
00951 M._m23 = axis.y * axis.z * one_minus_cosine - axis.x * sine;
00952 M._m33 = axis.z * axis.z + (1.0f - axis.z * axis.z) * cosine;
00953 M._m43 = 0;
00954
00955 M._m14 = 0;
00956 M._m24 = 0;
00957 M._m34 = 0;
00958 M._m44 = 1;
00959
00960 return M;
00961 }
00962
00963
00965 static matrix RotationVectors(const vector3 & vecStart, const vector3 & vecTo)
00966 {
00967 vector3 vec = vecStart.Cross(vecTo);
00968
00969 if (vec.Length() > 1e-6f)
00970 {
00971
00972 float angle = acos(vecStart.Dot(vecTo));
00973
00974 vec = vec.Normalize();
00975 return RotationAxis(vec, angle);
00976 }
00977
00978
00979 matrix ret;
00980 if (vecStart.Dot(vecTo) < 0.0f)
00981 ret *= -1.0f;
00982
00983 return ret;
00984 }
00985
00987 wxString ToString() const
00988 {
00989 wxString str;
00990 for (int i = 0; i < 4; i++)
00991 {
00992 for (int j = 0; j < 4; j++)
00993 {
00994 str.Append(wxString::Format(wxT("%.2f "), _m[4*i+j]));
00995 }
00996 str << wxT("\n");
00997 }
00998 return str;
00999 }
01000
01002 friend std::ostream & operator<<(std::ostream & os, const matrix & M)
01003 {
01004 for (int i = 0; i < 4; i++)
01005 {
01006 for (int j = 0; j < 4; j++)
01007 {
01008 os << std::setprecision(4) << std::setw(10) << M._m[4*i+j] << " ";
01009 }
01010 os << '\n';
01011 }
01012 return os;
01013 }
01014
01016 matrix * Clone() const
01017 {
01018 return new matrix(*this);
01019 }
01020 };
01021
01022
01024 struct Ray
01025 {
01026 public:
01028 vector3 origin;
01030 vector3 direction;
01031
01033 Ray(vector3 & orig, vector3 & dir)
01034 {
01035 origin = orig;
01036 direction = dir;
01037 }
01039 Ray(const Ray & ray) : origin(ray.origin), direction(ray.direction)
01040 {
01041 }
01042
01044 float GetIntersectionDist(const plane & pln) const
01045 {
01046 return -pln.DotCoord(origin) / direction.Dot(vector3(pln._p));
01047 }
01048
01050 vector3 GetIntersection(const plane & pln) const
01051 {
01052 return origin + direction * GetIntersectionDist(pln);
01053 }
01054
01056
01057 bool IntersectsTri(const vector3 & v0, const vector3 & v1, const vector3 & v2, float * dist = (float *)NULL) const
01058 {
01059 #define MOLLER_RAY_TRI_INTERSECTION 1
01060 #if !MOLLER_RAY_TRI_INTERSECTION
01061
01062 const vector3 edge1 = v1 - v0;
01063 const vector3 edge2 = v2 - v0;
01064
01065
01066 vector3 pvec = direction.Cross(edge2);
01067
01068
01069 const float det = fabsf( edge1.Dot(pvec) );
01070
01071
01072 const vector3 tvec = origin - v0;
01073
01074
01075 const float u = tvec.Dot(pvec);
01076 if ( u < 0 || u > det )
01077 return false;
01078
01079
01080
01081 const float v = direction.Dot( tvec.Cross(edge1) );
01082 if ( v < 0 || u + v > det )
01083 return false;
01084
01085 float intDist = GetIntersectionDist(plane::FromPoints(v0, v1, v2));
01086 if (intDist < 0)
01087 return false;
01088 else if (dist)
01089 *dist = intDist;
01090
01091 return true;
01092 #else
01093 const float threshold = 1e-6f;
01094 const vector3 e1 = v0 - v1;
01095 const vector3 e2 = v2 - v1;
01096 const vector3 dir = direction;
01097 const vector3 p = dir.Cross(e2);
01098 float det = e1.Dot(p);
01099 const vector3 w0 = origin - v1;
01100 const float u = w0.Dot(p);
01101 const vector3 q = w0.Cross(e1);
01102 const float v = dir.Dot(q);
01103
01104
01105 if (det > threshold) {
01106 if (u < 0.0f || u > det)
01107 return false;
01108 if (v < 0.0f || u + v > det)
01109 return false;
01110 }
01111 else
01112 if (det < -threshold)
01113 {
01114 if (u > 0.0 || u < det)
01115 return false;
01116 if (v > 0.0 || u + v < det)
01117 return false;
01118 } else
01119 return false;
01120
01121 float t = e2.Dot(q) / det;
01122
01123 if (t < 0.0f)
01124 return false;
01125
01126 if (dist)
01127 *dist = t;
01128 return true;
01129 #endif
01130
01131 }
01132
01134 Ray * Clone() const
01135 {
01136 return new Ray(*this);
01137 }
01138 };
01139
01140 struct Triangle
01141 {
01142 vector3 v1;
01143 vector3 v2;
01144 vector3 v3;
01145
01147 Triangle() {}
01148
01150 Triangle(const vector3 &_v1, const vector3 &_v2, const vector3 &_v3) : v1(_v1), v2(_v2), v3(_v3) {}
01151
01153 Triangle & operator=(const Triangle & tr)
01154 {
01155 v1 = tr.v1;
01156 v2 = tr.v2;
01157 v3 = tr.v3;
01158 return *this;
01159 }
01160
01162 vector3 operator[](unsigned i) const
01163 {
01164 if (i == 0)
01165 return v1;
01166 else if (i == 1)
01167 return v2;
01168 else if (i == 2)
01169 return v3;
01170
01171 return vector3();
01172 }
01173
01174 vector3 GetCenter()
01175 {
01176 return (v1 + v2 + v3) / 3.0f;
01177 }
01178 };
01179
01181 inline vector3 CrossProd(const vector3 & a, const vector3 & b)
01182 {
01183 return a.Cross(b);
01184 }
01185
01186 inline vector3 Normalize(const vector3 &a)
01187 {
01188 vector3 b = a;
01189 return b.Normalize();
01190 }
01191
01192 #endif