00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __SP_DIMENSION_MATRIX4_H__
00009 #define __SP_DIMENSION_MATRIX4_H__
00010
00011
00012 #include "Base/spStandard.hpp"
00013 #include "Base/spMath.hpp"
00014 #include "Base/spDimensionOBB.hpp"
00015
00016 #include <string.h>
00017
00018
00019 namespace sp
00020 {
00021 namespace dim
00022 {
00023
00024
00025 template <typename T> class matrix3;
00026 template <typename T> class matrix2;
00027
00028 enum EMatrixTypes
00029 {
00030 MATRIX_PROJECTION = 0,
00031 MATRIX_VIEW,
00032 MATRIX_WORLD,
00033 MATRIX_TEXTURE,
00034 MATRIX_COLOR,
00035
00036 MATRIX_COUNT
00037 };
00038
00040 enum EMatrixCoordinateSystmes
00041 {
00042 MATRIX_LEFTHANDED,
00043 MATRIX_RIGHTHANDED
00044 };
00045
00058 template <typename T> class matrix4
00059 {
00060
00061 public:
00062
00063 matrix4()
00064 {
00065 reset();
00066 }
00067 matrix4(const T (&Other)[16])
00068 {
00069 *this = Other;
00070 }
00071 matrix4(const matrix4<T> &Other)
00072 {
00073 *this = Other;
00074 }
00075 matrix4(const matrix3<T> &Other);
00076 matrix4(const obbox3d<T> &Box)
00077 {
00078 M[0] = Box.Axis.X.X * Box.HalfSize.X;
00079 M[1] = Box.Axis.X.Y * Box.HalfSize.X;
00080 M[2] = Box.Axis.X.Z * Box.HalfSize.X;
00081 M[3] = 0;
00082
00083 M[4] = Box.Axis.Y.X * Box.HalfSize.Y;
00084 M[5] = Box.Axis.Y.Y * Box.HalfSize.Y;
00085 M[6] = Box.Axis.Y.Z * Box.HalfSize.Y;
00086 M[7] = 0;
00087
00088 M[ 8] = Box.Axis.Z.X * Box.HalfSize.Z;
00089 M[ 9] = Box.Axis.Z.Y * Box.HalfSize.Z;
00090 M[10] = Box.Axis.Z.Z * Box.HalfSize.Z;
00091 M[11] = 0;
00092
00093 M[12] = Box.Center.X;
00094 M[13] = Box.Center.Y;
00095 M[14] = Box.Center.Z;
00096 M[15] = 1;
00097 }
00098 matrix4(
00099 T m1n1, T m2n1, T m3n1, T m4n1,
00100 T m1n2, T m2n2, T m3n2, T m4n2,
00101 T m1n3, T m2n3, T m3n3, T m4n3,
00102 T m1n4, T m2n4, T m3n4, T m4n4)
00103 {
00104 M[0] = m1n1; M[4] = m2n1; M[ 8] = m3n1; M[12] = m4n1;
00105 M[1] = m1n2; M[5] = m2n2; M[ 9] = m3n2; M[13] = m4n2;
00106 M[2] = m1n3; M[6] = m2n3; M[10] = m3n3; M[14] = m4n3;
00107 M[3] = m1n4; M[7] = m2n4; M[11] = m3n4; M[15] = m4n4;
00108 }
00109 matrix4(
00110 const vector4d<T> &XDirection,
00111 const vector4d<T> &YDirection,
00112 const vector4d<T> &ZDirection,
00113 const vector4d<T> &Position)
00114 {
00115 M[0] = XDirection.X; M[4] = YDirection.X; M[ 8] = ZDirection.X; M[12] = Position.X;
00116 M[1] = XDirection.Y; M[5] = YDirection.Y; M[ 9] = ZDirection.Y; M[13] = Position.Y;
00117 M[2] = XDirection.Z; M[6] = YDirection.Z; M[10] = ZDirection.Z; M[14] = Position.Z;
00118 M[3] = XDirection.W; M[7] = YDirection.W; M[11] = ZDirection.W; M[15] = Position.W;
00119 }
00120 ~matrix4()
00121 {
00122 }
00123
00124
00125
00131 inline const T operator () (u32 row, u32 col) const
00132 {
00133 return row < 4 && col < 4 ? M[(row << 2) + col] : (T)0;
00134 }
00135 inline T& operator () (u32 row, u32 col)
00136 {
00137 return M[(row << 2) + col];
00138 }
00139
00141 inline const T operator [] (u32 i) const
00142 {
00143 return i < 16 ? M[i] : (T)0;
00144 }
00145 inline T& operator [] (u32 i)
00146 {
00147 return M[i];
00148 }
00149
00150 inline bool operator == (const matrix4<T> &Other)
00151 {
00152 for (s32 i = 0; i < 16; ++i)
00153 {
00154 if (M[i] != Other.M[i])
00155 return false;
00156 }
00157 return true;
00158 }
00159 inline bool operator != (const matrix4<T> &Other)
00160 {
00161 for (s32 i = 0; i < 16; ++i)
00162 {
00163 if (M[i] != Other.M[i])
00164 return true;
00165 }
00166 return false;
00167 }
00168
00169 inline matrix4<T>& operator = (const T (&Other)[16])
00170 {
00171 M[0] = Other[0]; M[4] = Other[4]; M[ 8] = Other[ 8]; M[12] = Other[12];
00172 M[1] = Other[1]; M[5] = Other[5]; M[ 9] = Other[ 9]; M[13] = Other[13];
00173 M[2] = Other[2]; M[6] = Other[6]; M[10] = Other[10]; M[14] = Other[14];
00174 M[3] = Other[3]; M[7] = Other[7]; M[11] = Other[11]; M[15] = Other[15];
00175 return *this;
00176 }
00177 inline matrix4<T>& operator = (const matrix4<T> &Other)
00178 {
00179 M[0] = Other[0]; M[4] = Other[4]; M[ 8] = Other[ 8]; M[12] = Other[12];
00180 M[1] = Other[1]; M[5] = Other[5]; M[ 9] = Other[ 9]; M[13] = Other[13];
00181 M[2] = Other[2]; M[6] = Other[6]; M[10] = Other[10]; M[14] = Other[14];
00182 M[3] = Other[3]; M[7] = Other[7]; M[11] = Other[11]; M[15] = Other[15];
00183 return *this;
00184 }
00185 inline matrix4<T>& operator = (T Scalar)
00186 {
00187 memset(M, Scalar, sizeof(M));
00188 return *this;
00189 }
00190
00191 inline matrix4<T> operator + (const matrix4<T> &mltMatrix) const
00192 {
00193 matrix4<T> Other;
00194
00195 Other[0] = M[0] + mltMatrix[0]; Other[4] = M[4] + mltMatrix[4]; Other[ 8] = M[ 8] + mltMatrix[ 8]; Other[12] = M[12] + mltMatrix[12];
00196 Other[1] = M[1] + mltMatrix[1]; Other[5] = M[5] + mltMatrix[5]; Other[ 9] = M[ 9] + mltMatrix[ 9]; Other[13] = M[13] + mltMatrix[13];
00197 Other[2] = M[2] + mltMatrix[2]; Other[6] = M[6] + mltMatrix[6]; Other[10] = M[10] + mltMatrix[10]; Other[14] = M[14] + mltMatrix[14];
00198 Other[3] = M[3] + mltMatrix[3]; Other[7] = M[7] + mltMatrix[7]; Other[11] = M[11] + mltMatrix[11]; Other[15] = M[15] + mltMatrix[15];
00199
00200 return Other;
00201 }
00202
00203 inline matrix4<T>& operator += (const matrix4<T> &mltMatrix)
00204 {
00205 M[0] += mltMatrix[0]; M[4] += mltMatrix[4]; M[ 8] += mltMatrix[ 8]; M[12] += mltMatrix[12];
00206 M[1] += mltMatrix[1]; M[5] += mltMatrix[5]; M[ 9] += mltMatrix[ 9]; M[13] += mltMatrix[13];
00207 M[2] += mltMatrix[2]; M[6] += mltMatrix[6]; M[10] += mltMatrix[10]; M[14] += mltMatrix[14];
00208 M[3] += mltMatrix[3]; M[7] += mltMatrix[7]; M[11] += mltMatrix[11]; M[15] += mltMatrix[15];
00209 return *this;
00210 }
00211
00212 inline matrix4<T> operator - (const matrix4<T> &mltMatrix) const
00213 {
00214 matrix4<T> Other;
00215 Other[0] = M[0] - mltMatrix[0]; Other[4] = M[4] - mltMatrix[4]; Other[ 8] = M[ 8] - mltMatrix[ 8]; Other[12] = M[12] - mltMatrix[12];
00216 Other[1] = M[1] - mltMatrix[1]; Other[5] = M[5] - mltMatrix[5]; Other[ 9] = M[ 9] - mltMatrix[ 9]; Other[13] = M[13] - mltMatrix[13];
00217 Other[2] = M[2] - mltMatrix[2]; Other[6] = M[6] - mltMatrix[6]; Other[10] = M[10] - mltMatrix[10]; Other[14] = M[14] - mltMatrix[14];
00218 Other[3] = M[3] - mltMatrix[3]; Other[7] = M[7] - mltMatrix[7]; Other[11] = M[11] - mltMatrix[11]; Other[15] = M[15] - mltMatrix[15];
00219 return Other;
00220 }
00221 inline matrix4<T>& operator -= (const matrix4<T> &mltMatrix)
00222 {
00223 M[0] -= mltMatrix[0]; M[4] -= mltMatrix[4]; M[ 8] -= mltMatrix[ 8]; M[12] -= mltMatrix[12];
00224 M[1] -= mltMatrix[1]; M[5] -= mltMatrix[5]; M[ 9] -= mltMatrix[ 9]; M[13] -= mltMatrix[13];
00225 M[2] -= mltMatrix[2]; M[6] -= mltMatrix[6]; M[10] -= mltMatrix[10]; M[14] -= mltMatrix[14];
00226 M[3] -= mltMatrix[3]; M[7] -= mltMatrix[7]; M[11] -= mltMatrix[11]; M[15] -= mltMatrix[15];
00227 return *this;
00228 }
00229
00230 inline matrix4<T> operator * (const matrix4<T> &mltMatrix) const
00231 {
00232 matrix4<T> m3;
00233 const T* m1 = M;
00234 const T* m2 = mltMatrix.M;
00235
00236 m3[ 0] = m1[0]*m2[ 0] + m1[4]*m2[ 1] + m1[ 8]*m2[ 2] + m1[12]*m2[ 3];
00237 m3[ 1] = m1[1]*m2[ 0] + m1[5]*m2[ 1] + m1[ 9]*m2[ 2] + m1[13]*m2[ 3];
00238 m3[ 2] = m1[2]*m2[ 0] + m1[6]*m2[ 1] + m1[10]*m2[ 2] + m1[14]*m2[ 3];
00239 m3[ 3] = m1[3]*m2[ 0] + m1[7]*m2[ 1] + m1[11]*m2[ 2] + m1[15]*m2[ 3];
00240
00241 m3[ 4] = m1[0]*m2[ 4] + m1[4]*m2[ 5] + m1[ 8]*m2[ 6] + m1[12]*m2[ 7];
00242 m3[ 5] = m1[1]*m2[ 4] + m1[5]*m2[ 5] + m1[ 9]*m2[ 6] + m1[13]*m2[ 7];
00243 m3[ 6] = m1[2]*m2[ 4] + m1[6]*m2[ 5] + m1[10]*m2[ 6] + m1[14]*m2[ 7];
00244 m3[ 7] = m1[3]*m2[ 4] + m1[7]*m2[ 5] + m1[11]*m2[ 6] + m1[15]*m2[ 7];
00245
00246 m3[ 8] = m1[0]*m2[ 8] + m1[4]*m2[ 9] + m1[ 8]*m2[10] + m1[12]*m2[11];
00247 m3[ 9] = m1[1]*m2[ 8] + m1[5]*m2[ 9] + m1[ 9]*m2[10] + m1[13]*m2[11];
00248 m3[10] = m1[2]*m2[ 8] + m1[6]*m2[ 9] + m1[10]*m2[10] + m1[14]*m2[11];
00249 m3[11] = m1[3]*m2[ 8] + m1[7]*m2[ 9] + m1[11]*m2[10] + m1[15]*m2[11];
00250
00251 m3[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[ 8]*m2[14] + m1[12]*m2[15];
00252 m3[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[ 9]*m2[14] + m1[13]*m2[15];
00253 m3[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15];
00254 m3[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
00255
00256 return m3;
00257 }
00258
00259 inline matrix4<T> operator * (T Scalar) const
00260 {
00261 matrix4<T> Other;
00262
00263 Other[0] = M[0]*Scalar; Other[4] = M[4]*Scalar; Other[ 8] = M[ 8]*Scalar; Other[12] = M[12]*Scalar;
00264 Other[1] = M[1]*Scalar; Other[5] = M[5]*Scalar; Other[ 9] = M[ 9]*Scalar; Other[13] = M[13]*Scalar;
00265 Other[2] = M[2]*Scalar; Other[6] = M[6]*Scalar; Other[10] = M[10]*Scalar; Other[14] = M[14]*Scalar;
00266 Other[3] = M[3]*Scalar; Other[7] = M[7]*Scalar; Other[11] = M[11]*Scalar; Other[15] = M[15]*Scalar;
00267
00268 return Other;
00269 }
00270
00271 inline matrix4<T>& operator *= (const matrix4<T> &mltMatrix)
00272 {
00273 T m1[16];
00274 memcpy(m1, M, sizeof(M));
00275 const T* m2 = mltMatrix.M;
00276
00277 M[ 0] = m1[0]*m2[ 0] + m1[4]*m2[ 1] + m1[ 8]*m2[ 2] + m1[12]*m2[ 3];
00278 M[ 1] = m1[1]*m2[ 0] + m1[5]*m2[ 1] + m1[ 9]*m2[ 2] + m1[13]*m2[ 3];
00279 M[ 2] = m1[2]*m2[ 0] + m1[6]*m2[ 1] + m1[10]*m2[ 2] + m1[14]*m2[ 3];
00280 M[ 3] = m1[3]*m2[ 0] + m1[7]*m2[ 1] + m1[11]*m2[ 2] + m1[15]*m2[ 3];
00281
00282 M[ 4] = m1[0]*m2[ 4] + m1[4]*m2[ 5] + m1[ 8]*m2[ 6] + m1[12]*m2[ 7];
00283 M[ 5] = m1[1]*m2[ 4] + m1[5]*m2[ 5] + m1[ 9]*m2[ 6] + m1[13]*m2[ 7];
00284 M[ 6] = m1[2]*m2[ 4] + m1[6]*m2[ 5] + m1[10]*m2[ 6] + m1[14]*m2[ 7];
00285 M[ 7] = m1[3]*m2[ 4] + m1[7]*m2[ 5] + m1[11]*m2[ 6] + m1[15]*m2[ 7];
00286
00287 M[ 8] = m1[0]*m2[ 8] + m1[4]*m2[ 9] + m1[ 8]*m2[10] + m1[12]*m2[11];
00288 M[ 9] = m1[1]*m2[ 8] + m1[5]*m2[ 9] + m1[ 9]*m2[10] + m1[13]*m2[11];
00289 M[10] = m1[2]*m2[ 8] + m1[6]*m2[ 9] + m1[10]*m2[10] + m1[14]*m2[11];
00290 M[11] = m1[3]*m2[ 8] + m1[7]*m2[ 9] + m1[11]*m2[10] + m1[15]*m2[11];
00291
00292 M[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[ 8]*m2[14] + m1[12]*m2[15];
00293 M[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[ 9]*m2[14] + m1[13]*m2[15];
00294 M[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15];
00295 M[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
00296
00297 return *this;
00298 }
00299
00300 inline matrix4<T>& operator *= (T Scalar)
00301 {
00302 M[0] *= Scalar; M[4] *= Scalar; M[ 8] *= Scalar; M[12] *= Scalar;
00303 M[1] *= Scalar; M[5] *= Scalar; M[ 9] *= Scalar; M[13] *= Scalar;
00304 M[2] *= Scalar; M[6] *= Scalar; M[10] *= Scalar; M[14] *= Scalar;
00305 M[3] *= Scalar; M[7] *= Scalar; M[11] *= Scalar; M[15] *= Scalar;
00306 return *this;
00307 }
00308
00309 inline vector3d<T> operator * (const vector3d<T> &Vector) const
00310 {
00311 return vector3d<T>(
00312 Vector.X*M[0] + Vector.Y*M[4] + Vector.Z*M[ 8] + M[12],
00313 Vector.X*M[1] + Vector.Y*M[5] + Vector.Z*M[ 9] + M[13],
00314 Vector.X*M[2] + Vector.Y*M[6] + Vector.Z*M[10] + M[14]
00315 );
00316 }
00317
00318 inline point2d<T> operator * (const point2d<T> &Vector) const
00319 {
00320 return point2d<T>(
00321 Vector.X*M[0] + Vector.Y*M[4] + M[12],
00322 Vector.X*M[1] + Vector.Y*M[5] + M[13]
00323 );
00324 }
00325
00326 inline triangle3d<T> operator * (const triangle3d<T> &Triangle) const
00327 {
00328 return triangle3d<T>(
00329 *this * Triangle.PointA,
00330 *this * Triangle.PointB,
00331 *this * Triangle.PointC
00332 );
00333 }
00334
00335 inline triangle3d<T> operator * (const triangle3d<T, vector3d<T>*> &Triangle) const
00336 {
00337 return triangle3d<T>(
00338 *this * (*Triangle.PointA),
00339 *this * (*Triangle.PointB),
00340 *this * (*Triangle.PointC)
00341 );
00342 }
00343
00344 inline plane3d<T> operator * (const plane3d<T> &Plane) const
00345 {
00346 const vector3d<T> Member(*this * Plane.getMemberPoint());
00347 const matrix4<T> TransposedInverse(getInverse().getTransposed());
00348 const vector3d<T> Normal(TransposedInverse * Plane.Normal);
00349
00350 return plane3d<T>(Normal, Normal.dot(Member));
00351 }
00352
00353 inline obbox3d<T> operator * (const obbox3d<T> &Box) const
00354 {
00355 return obbox3d<T>(
00356 *this * Box.Center,
00357 vecRotate(Box.Axis.X), vecRotate(Box.Axis.Y), vecRotate(Box.Axis.Z)
00358 );
00359 }
00360
00361 inline line3d<T> operator * (const line3d<T> &Line) const
00362 {
00363 return line3d<T>(*this * Line.Start, *this * Line.End);
00364 }
00365
00366
00367
00369 inline point2d<T> vecRotate(const point2d<T> &Vector) const
00370 {
00371 return point2d<T>(
00372 Vector.X*M[0] + Vector.Y*M[4],
00373 Vector.X*M[1] + Vector.Y*M[5]
00374 );
00375 }
00376
00378 inline point2d<T> vecRotateInverse(const point2d<T> &Vector) const
00379 {
00380 return point2d<T>(
00381 Vector.X*M[0] + Vector.Y*M[1],
00382 Vector.X*M[4] + Vector.Y*M[5]
00383 );
00384 }
00385
00387 inline vector3d<T> vecRotate(const vector3d<T> &Vector) const
00388 {
00389 return vector3d<T>(
00390 Vector.X*M[0] + Vector.Y*M[4] + Vector.Z*M[ 8],
00391 Vector.X*M[1] + Vector.Y*M[5] + Vector.Z*M[ 9],
00392 Vector.X*M[2] + Vector.Y*M[6] + Vector.Z*M[10]
00393 );
00394 }
00395
00397 inline vector3d<T> vecRotateInverse(const vector3d<T> &Vector) const
00398 {
00399 return vector3d<T>(
00400 Vector.X*M[0] + Vector.Y*M[1] + Vector.Z*M[ 2],
00401 Vector.X*M[4] + Vector.Y*M[5] + Vector.Z*M[ 6],
00402 Vector.X*M[8] + Vector.Y*M[9] + Vector.Z*M[10]
00403 );
00404 }
00405
00407 inline void clear()
00408 {
00409 memset(M, 0, sizeof(M));
00410 }
00411
00421 inline matrix4<T>& reset()
00422 {
00423 M[0] = 1; M[4] = 0; M[ 8] = 0; M[12] = 0;
00424 M[1] = 0; M[5] = 1; M[ 9] = 0; M[13] = 0;
00425 M[2] = 0; M[6] = 0; M[10] = 1; M[14] = 0;
00426 M[3] = 0; M[7] = 0; M[11] = 0; M[15] = 1;
00427 return *this;
00428 }
00429
00439 inline matrix4<T>& reset(const vector3d<T> &InitPosition, const vector3d<T> &InitScale = T(1))
00440 {
00441 M[0] = InitScale.X; M[4] = 0; M[ 8] = 0; M[12] = InitPosition.X;
00442 M[1] = 0; M[5] = InitScale.Y; M[ 9] = 0; M[13] = InitPosition.Y;
00443 M[2] = 0; M[6] = 0; M[10] = InitScale.Z; M[14] = InitPosition.Z;
00444 M[3] = 0; M[7] = 0; M[11] = 0; M[15] = 1;
00445 return *this;
00446 }
00447
00449 inline void multiplySingleMatrix(const T (&Other)[4])
00450 {
00451 T Result[4];
00452
00453 Result[0] = M[0]*Other[0] + M[4]*Other[1] + M[ 8]*Other[2] + M[12]*Other[3];
00454 Result[1] = M[1]*Other[0] + M[5]*Other[1] + M[ 9]*Other[2] + M[13]*Other[3];
00455 Result[2] = M[2]*Other[0] + M[6]*Other[1] + M[10]*Other[2] + M[14]*Other[3];
00456 Result[3] = M[3]*Other[0] + M[7]*Other[1] + M[11]*Other[2] + M[15]*Other[3];
00457
00458 Other[0] = Result[0]; Other[1] = Result[1]; Other[2] = Result[2]; Other[3] = Result[3];
00459 }
00460
00461 inline void matrixLookAt(const vector3d<T> &Position, const vector3d<T> &LookAt, const vector3d<T> &upVector)
00462 {
00463 vector3d<T> ZAxis = LookAt - Position;
00464 ZAxis.normalize();
00465
00466 vector3d<T> XAxis = upVector.cross(ZAxis);
00467 XAxis.normalize();
00468
00469 vector3d<T> YAxis = ZAxis.cross(XAxis);
00470
00471 M[0] = XAxis.X; M[4] = XAxis.Y; M[ 8] = XAxis.Z; M[12] = -XAxis.dot(Position);
00472 M[1] = YAxis.X; M[5] = YAxis.Y; M[ 9] = YAxis.Z; M[13] = -YAxis.dot(Position);
00473 M[2] = ZAxis.X; M[6] = ZAxis.Y; M[10] = ZAxis.Z; M[14] = -ZAxis.dot(Position);
00474 M[3] = 0; M[7] = 0; M[11] = 0; M[15] = 1;
00475 }
00476
00477 inline bool getInverse(matrix4<T> &InverseMat) const
00478 {
00479 const matrix4<T> &m = *this;
00480
00481 T d = (
00482 (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) -
00483 (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) +
00484 (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1)) +
00485 (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) -
00486 (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) +
00487 (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0))
00488 );
00489
00490 if (d == T(0))
00491 return false;
00492
00493 d = T(1) / d;
00494
00495 InverseMat(0, 0) = d * ( m(1, 1) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) + m(1, 2) * (m(2, 3) * m(3, 1) - m(2, 1) * m(3, 3)) + m(1, 3) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1)) );
00496 InverseMat(0, 1) = d * ( m(2, 1) * (m(0, 2) * m(3, 3) - m(0, 3) * m(3, 2)) + m(2, 2) * (m(0, 3) * m(3, 1) - m(0, 1) * m(3, 3)) + m(2, 3) * (m(0, 1) * m(3, 2) - m(0, 2) * m(3, 1)) );
00497 InverseMat(0, 2) = d * ( m(3, 1) * (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) + m(3, 2) * (m(0, 3) * m(1, 1) - m(0, 1) * m(1, 3)) + m(3, 3) * (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)) );
00498 InverseMat(0, 3) = d * ( m(0, 1) * (m(1, 3) * m(2, 2) - m(1, 2) * m(2, 3)) + m(0, 2) * (m(1, 1) * m(2, 3) - m(1, 3) * m(2, 1)) + m(0, 3) * (m(1, 2) * m(2, 1) - m(1, 1) * m(2, 2)) );
00499 InverseMat(1, 0) = d * ( m(1, 2) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) + m(1, 3) * (m(2, 2) * m(3, 0) - m(2, 0) * m(3, 2)) + m(1, 0) * (m(2, 3) * m(3, 2) - m(2, 2) * m(3, 3)) );
00500 InverseMat(1, 1) = d * ( m(2, 2) * (m(0, 0) * m(3, 3) - m(0, 3) * m(3, 0)) + m(2, 3) * (m(0, 2) * m(3, 0) - m(0, 0) * m(3, 2)) + m(2, 0) * (m(0, 3) * m(3, 2) - m(0, 2) * m(3, 3)) );
00501 InverseMat(1, 2) = d * ( m(3, 2) * (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) + m(3, 3) * (m(0, 2) * m(1, 0) - m(0, 0) * m(1, 2)) + m(3, 0) * (m(0, 3) * m(1, 2) - m(0, 2) * m(1, 3)) );
00502 InverseMat(1, 3) = d * ( m(0, 2) * (m(1, 3) * m(2, 0) - m(1, 0) * m(2, 3)) + m(0, 3) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) + m(0, 0) * (m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2)) );
00503 InverseMat(2, 0) = d * ( m(1, 3) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0)) + m(1, 0) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) + m(1, 1) * (m(2, 3) * m(3, 0) - m(2, 0) * m(3, 3)) );
00504 InverseMat(2, 1) = d * ( m(2, 3) * (m(0, 0) * m(3, 1) - m(0, 1) * m(3, 0)) + m(2, 0) * (m(0, 1) * m(3, 3) - m(0, 3) * m(3, 1)) + m(2, 1) * (m(0, 3) * m(3, 0) - m(0, 0) * m(3, 3)) );
00505 InverseMat(2, 2) = d * ( m(3, 3) * (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) + m(3, 0) * (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) + m(3, 1) * (m(0, 3) * m(1, 0) - m(0, 0) * m(1, 3)) );
00506 InverseMat(2, 3) = d * ( m(0, 3) * (m(1, 1) * m(2, 0) - m(1, 0) * m(2, 1)) + m(0, 0) * (m(1, 3) * m(2, 1) - m(1, 1) * m(2, 3)) + m(0, 1) * (m(1, 0) * m(2, 3) - m(1, 3) * m(2, 0)) );
00507 InverseMat(3, 0) = d * ( m(1, 0) * (m(2, 2) * m(3, 1) - m(2, 1) * m(3, 2)) + m(1, 1) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) + m(1, 2) * (m(2, 1) * m(3, 0) - m(2, 0) * m(3, 1)) );
00508 InverseMat(3, 1) = d * ( m(2, 0) * (m(0, 2) * m(3, 1) - m(0, 1) * m(3, 2)) + m(2, 1) * (m(0, 0) * m(3, 2) - m(0, 2) * m(3, 0)) + m(2, 2) * (m(0, 1) * m(3, 0) - m(0, 0) * m(3, 1)) );
00509 InverseMat(3, 2) = d * ( m(3, 0) * (m(0, 2) * m(1, 1) - m(0, 1) * m(1, 2)) + m(3, 1) * (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) + m(3, 2) * (m(0, 1) * m(1, 0) - m(0, 0) * m(1, 1)) );
00510 InverseMat(3, 3) = d * ( m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)) + m(0, 1) * (m(1, 2) * m(2, 0) - m(1, 0) * m(2, 2)) + m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0)) );
00511
00512 return true;
00513 }
00514
00515 inline bool setInverse()
00516 {
00517 matrix4<T> Matrix;
00518
00519 if (getInverse(Matrix))
00520 {
00521 *this = Matrix;
00522 return true;
00523 }
00524
00525 return false;
00526 }
00527
00528 inline matrix4<T> getInverse() const
00529 {
00530 matrix4<T> Mat;
00531 getInverse(Mat);
00532 return Mat;
00533 }
00534
00535
00536
00537
00538
00539
00540
00541 inline matrix4<T>& translate(const vector3d<T> &Vector)
00542 {
00543 matrix4<T> Other;
00544
00545 Other[12] = Vector.X;
00546 Other[13] = Vector.Y;
00547 Other[14] = Vector.Z;
00548
00549 return *this *= Other;
00550 }
00551
00552
00553
00554
00555
00556
00557
00558 inline matrix4<T>& scale(const vector3d<T> &Vector)
00559 {
00560 matrix4<T> Other;
00561
00562 Other[ 0] = Vector.X;
00563 Other[ 5] = Vector.Y;
00564 Other[10] = Vector.Z;
00565
00566 return *this *= Other;
00567 }
00568
00569
00570
00571
00572
00573
00574
00575 inline matrix4<T>& rotate(const T Angle, vector3d<T> Rotation)
00576 {
00577 matrix4<T> Other;
00578
00579
00580 Rotation.normalize();
00581
00582
00583 T x = Rotation.X;
00584 T y = Rotation.Y;
00585 T z = Rotation.Z;
00586 T c = math::Cos(Angle);
00587 T s = math::Sin(Angle);
00588 T cc = static_cast<T>(1) - c;
00589
00590
00591 Other[0] = x*x*cc + c; Other[4] = x*y*cc - z*s; Other[ 8] = x*z*cc + y*s; Other[12] = 0;
00592 Other[1] = y*x*cc + z*s; Other[5] = y*y*cc + c; Other[ 9] = y*z*cc - x*s; Other[13] = 0;
00593 Other[2] = x*z*cc - y*s; Other[6] = y*z*cc + x*s; Other[10] = z*z*cc + c; Other[14] = 0;
00594 Other[3] = 0; Other[7] = 0; Other[11] = 0; Other[15] = 1;
00595
00596 return *this *= Other;
00597 }
00598
00599 inline matrix4<T>& rotateX(const T Angle)
00600 {
00601 matrix4<T> Other;
00602
00603 const T c = math::Cos(Angle);
00604 const T s = math::Sin(Angle);
00605
00606
00607 Other[0] = 1; Other[4] = 0; Other[ 8] = 0; Other[12] = 0;
00608 Other[1] = 0; Other[5] = c; Other[ 9] = -s; Other[13] = 0;
00609 Other[2] = 0; Other[6] = s; Other[10] = c; Other[14] = 0;
00610 Other[3] = 0; Other[7] = 0; Other[11] = 0; Other[15] = 1;
00611
00612 return *this *= Other;
00613 }
00614
00615 inline matrix4<T>& rotateY(const T Angle)
00616 {
00617 matrix4<T> Other;
00618
00619 const T c = math::Cos(Angle);
00620 const T s = math::Sin(Angle);
00621
00622
00623 Other[0] = c; Other[4] = 0; Other[ 8] = s; Other[12] = 0;
00624 Other[1] = 0; Other[5] = 1; Other[ 9] = 0; Other[13] = 0;
00625 Other[2] = -s; Other[6] = 0; Other[10] = c; Other[14] = 0;
00626 Other[3] = 0; Other[7] = 0; Other[11] = 0; Other[15] = 1;
00627
00628 return *this *= Other;
00629 }
00630
00631 inline matrix4<T>& rotateZ(const T Angle)
00632 {
00633 matrix4<T> Other;
00634
00635 const T c = math::Cos(Angle);
00636 const T s = math::Sin(Angle);
00637
00638
00639 Other[0] = c; Other[4] = -s; Other[ 8] = 0; Other[12] = 0;
00640 Other[1] = s; Other[5] = c; Other[ 9] = 0; Other[13] = 0;
00641 Other[2] = 0; Other[6] = 0; Other[10] = 1; Other[14] = 0;
00642 Other[3] = 0; Other[7] = 0; Other[11] = 0; Other[15] = 1;
00643
00644 return *this *= Other;
00645 }
00646
00647 inline void rotateYXZ(const vector3df &Rotation)
00648 {
00649 rotateY(Rotation.Y);
00650 rotateX(Rotation.X);
00651 rotateZ(Rotation.Z);
00652 }
00653
00654 inline void rotateZXY(const vector3df &Rotation)
00655 {
00656 rotateZ(Rotation.Z);
00657 rotateX(Rotation.X);
00658 rotateY(Rotation.Y);
00659 }
00660
00661 inline void setRotation(vector3d<T> Rotation, bool UseDegrees = true)
00662 {
00663 if (UseDegrees)
00664 Rotation = Rotation * math::DEG;
00665
00666
00667 const T cx = cos(Rotation.X);
00668 const T sx = sin(Rotation.X);
00669 const T cy = cos(Rotation.Y);
00670 const T sy = sin(Rotation.Y);
00671 const T cz = cos(Rotation.Z);
00672 const T sz = sin(Rotation.Z);
00673
00674 const T sxy = sx*sy;
00675 const T cxy = cx*sy;
00676
00677
00678 M[ 0] = cy*cz;
00679 M[ 1] = cy*sz;
00680 M[ 2] = -sy;
00681
00682 M[ 4] = sxy*cz - cx*sz;
00683 M[ 5] = sxy*sz + cx*cz;
00684 M[ 6] = sx*cy;
00685
00686 M[ 8] = cxy*cz + sx*sz;
00687 M[ 9] = cxy*sz - sx*cz;
00688 M[10] = cx*cy;
00689 }
00690
00691 inline void setInverseRotation(vector3df Rotation, bool UseDegrees = true)
00692 {
00693 if (UseDegrees)
00694 Rotation = Rotation * static_cast<T>(M_PI / 180.0);
00695
00696
00697 const T cx = cos(Rotation.X);
00698 const T sx = sin(Rotation.X);
00699 const T cy = cos(Rotation.Y);
00700 const T sy = sin(Rotation.Y);
00701 const T cz = cos(Rotation.Z);
00702 const T sz = sin(Rotation.Z);
00703
00704 const T sxy = sx*sy;
00705 const T cxy = cx*sy;
00706
00707
00708 M[ 0] = cy*cz;
00709 M[ 4] = cy*sz;
00710 M[ 8] = -sy;
00711
00712 M[ 1] = sxy*cz - cx*sz;
00713 M[ 5] = sxy*sz + cx*cz;
00714 M[ 9] = sx*cy;
00715
00716 M[ 2] = cxy*cz + sx*sz;
00717 M[ 6] = cxy*sz - sx*cz;
00718 M[10] = cx*cy;
00719 }
00720
00721 inline void setTextureRotation(const T &Degree)
00722 {
00723
00724 const T c = math::Cos(Degree);
00725 const T s = math::Sin(Degree);
00726
00727 M[0] = c;
00728 M[1] = s;
00729 M[2] = static_cast<T>(-0.5 * ( c + s) + 0.5);
00730
00731 M[4] = -s;
00732 M[5] = c;
00733 M[6] = static_cast<T>(-0.5 * (-s + c) + 0.5);
00734 }
00735
00736
00737
00738
00739
00740
00741 inline void setPerspectiveLH(T FieldOfView, T Aspect, T Near, T Far)
00742 {
00743 const T h = static_cast<T>(1.0 / tan((FieldOfView * math::DEG64) / T(2)));
00744 const T w = h / Aspect;
00745
00746 const T dif = Far - Near;
00747
00748 M[ 0] = w;
00749 M[ 1] = 0;
00750 M[ 2] = 0;
00751 M[ 3] = 0;
00752
00753 M[ 4] = 0;
00754 M[ 5] = h;
00755 M[ 6] = 0;
00756 M[ 7] = 0;
00757
00758 M[ 8] = 0;
00759 M[ 9] = 0;
00760 M[10] = Far/dif;
00761
00762 M[11] = 1;
00763
00764 M[12] = 0;
00765 M[13] = 0;
00766 M[14] = (-Near*Far)/dif;
00767
00768 M[15] = 0;
00769 }
00770
00771 inline void setPerspectiveRH(T FieldOfView, T Aspect, T Near, T Far)
00772 {
00773 const T h = static_cast<T>(1.0 / tan((FieldOfView * math::DEG64) / T(2)));
00774 const T w = h / Aspect;
00775
00776 const T dif = Near - Far;
00777
00778 M[ 0] = w;
00779 M[ 1] = 0;
00780 M[ 2] = 0;
00781 M[ 3] = 0;
00782
00783 M[ 4] = 0;
00784 M[ 5] = h;
00785 M[ 6] = 0;
00786 M[ 7] = 0;
00787
00788 M[ 8] = 0;
00789 M[ 9] = 0;
00790 M[10] = Far/dif;
00791
00792 M[11] = -1;
00793
00794 M[12] = 0;
00795 M[13] = 0;
00796 M[14] = Near*Far/dif;
00797
00798 M[15] = 0;
00799 }
00800
00801 inline void setOrthoLH(T Left, T Right, T Top, T Bottom, T Near, T Far)
00802 {
00803 M[ 0] = T(2)/(Right - Left);
00804 M[ 1] = 0;
00805 M[ 2] = 0;
00806 M[ 3] = 0;
00807
00808 M[ 4] = 0;
00809 M[ 5] = T(2)/(Bottom - Top);
00810 M[ 6] = 0;
00811 M[ 7] = 0;
00812
00813 M[ 8] = 0;
00814 M[ 9] = 0;
00815 M[10] = T(1)/(Far - Near);
00816 M[11] = 0;
00817
00818 M[12] = 0;
00819 M[13] = 0;
00820 M[14] = -Near/(Far - Near);
00821
00822 M[15] = 1;
00823 }
00824
00825 inline void setOrthoRH(T Left, T Right, T Top, T Bottom, T Near, T Far)
00826 {
00827 M[ 0] = T(2)/(Right - Left);
00828 M[ 1] = 0;
00829 M[ 2] = 0;
00830 M[ 3] = 0;
00831
00832 M[ 4] = 0;
00833 M[ 5] = T(2)/(Bottom - Top);
00834 M[ 6] = 0;
00835 M[ 7] = 0;
00836
00837 M[ 8] = 0;
00838 M[ 9] = 0;
00839 M[10] = T(1)/(Near - Far);
00840 M[11] = 0;
00841
00842 M[12] = 0;
00843 M[13] = 0;
00844 M[14] = Near/(Near - Far);
00845
00846 M[15] = 1;
00847 }
00848
00849 inline void make2Dimensional(s32 Width, s32 Height, s32 ScreenWidth, s32 ScreenHeight)
00850 {
00851 reset();
00852 scale(
00853 vector3d<T>(static_cast<T>(1.0 / (Width/2)), static_cast<T>(1.0 / (Height/2)), 1)
00854 );
00855 translate(
00856 vector3d<T>(static_cast<T>(-ScreenWidth/2), static_cast<T>(-ScreenHeight/2), 0)
00857 );
00858 }
00859
00860 inline void makeViewport(const rect2di &Viewport, const f32 DepthScale = 1.0f)
00861 {
00862 const T Width = static_cast<T>( ( Viewport.Right - Viewport.Left - 0.75 ) / 2 );
00863 const T Height = static_cast<T>( ( Viewport.Bottom - Viewport.Top - 0.75 ) / 2 );
00864
00865 const T PosX = static_cast<T>( -0.5f + ( Viewport.Left + Viewport.Right ) / 2 );
00866 const T PosY = static_cast<T>( -0.5f + ( Viewport.Top + Viewport.Bottom ) / 2 );
00867
00868 M[ 0] = Width;
00869 M[ 1] = 0;
00870 M[ 2] = 0;
00871 M[ 3] = 0;
00872
00873 M[ 4] = 0;
00874 M[ 5] = -Height;
00875 M[ 6] = 0;
00876 M[ 7] = 0;
00877
00878 M[ 8] = 0;
00879 M[ 9] = 0;
00880 M[10] = DepthScale;
00881 M[11] = 0;
00882
00883 M[12] = PosX;
00884 M[13] = PosY;
00885 M[14] = 0;
00886 M[15] = 0;
00887 }
00888
00889
00890
00891 vector4d<T> getRow(s32 Position) const
00892 {
00893 switch (Position)
00894 {
00895 case 0:
00896 return vector4d<T>(M[0], M[4], M[ 8], M[12]);
00897 case 1:
00898 return vector4d<T>(M[1], M[5], M[ 9], M[13]);
00899 case 2:
00900 return vector4d<T>(M[2], M[6], M[10], M[14]);
00901 case 3:
00902 return vector4d<T>(M[3], M[7], M[11], M[15]);
00903 }
00904 return vector4d<T>();
00905 }
00906
00907 void setRow(s32 Position, const vector4d<T> &Vec)
00908 {
00909 switch (Position)
00910 {
00911 case 0:
00912 M[0] = Vec.X, M[4] = Vec.Y, M[ 8] = Vec.Z, M[12] = Vec.W;
00913 break;
00914 case 1:
00915 M[1] = Vec.X, M[5] = Vec.Y, M[ 9] = Vec.Z, M[13] = Vec.W;
00916 break;
00917 case 2:
00918 M[2] = Vec.X, M[6] = Vec.Y, M[10] = Vec.Z, M[14] = Vec.W;
00919 break;
00920 case 3:
00921 M[3] = Vec.X, M[7] = Vec.Y, M[11] = Vec.Z, M[15] = Vec.W;
00922 break;
00923 }
00924 }
00925
00926 vector4d<T> getColumn(s32 Position) const
00927 {
00928 switch (Position)
00929 {
00930 case 0:
00931 return vector4d<T>(M[ 0], M[ 1], M[ 2], M[ 3]);
00932 case 1:
00933 return vector4d<T>(M[ 4], M[ 5], M[ 6], M[ 7]);
00934 case 2:
00935 return vector4d<T>(M[ 8], M[ 9], M[10], M[11]);
00936 case 3:
00937 return vector4d<T>(M[12], M[13], M[14], M[15]);
00938 }
00939 return vector4d<T>();
00940 }
00941
00942 void setColumn(s32 Position, const vector4d<T> &Vec)
00943 {
00944 switch (Position)
00945 {
00946 case 0:
00947 M[ 0] = Vec.X, M[ 1] = Vec.Y, M[ 2] = Vec.Z, M[ 3] = Vec.W;
00948 break;
00949 case 1:
00950 M[ 4] = Vec.X, M[ 5] = Vec.Y, M[ 6] = Vec.Z, M[ 7] = Vec.W;
00951 break;
00952 case 2:
00953 M[ 8] = Vec.X, M[ 9] = Vec.Y, M[10] = Vec.Z, M[11] = Vec.W;
00954 break;
00955 case 3:
00956 M[12] = Vec.X, M[13] = Vec.Y, M[14] = Vec.Z, M[15] = Vec.W;
00957 break;
00958 }
00959 }
00960
00961 inline void setPosition(const vector3d<T> &Position)
00962 {
00963 M[12] = Position.X; M[13] = Position.Y; M[14] = Position.Z;
00964 }
00965 inline vector3d<T> getPosition() const
00966 {
00967 return vector3d<T>(M[12], M[13], M[14]);
00968 }
00969
00970
00971 void setScale(const vector3d<T> &Scale)
00972 {
00973 vector3d<T> XAxis(M[0], M[1], M[ 2]);
00974 vector3d<T> YAxis(M[4], M[5], M[ 6]);
00975 vector3d<T> ZAxis(M[8], M[9], M[10]);
00976
00977 XAxis.setLength(Scale.X);
00978 YAxis.setLength(Scale.Y);
00979 ZAxis.setLength(Scale.Z);
00980
00981 M[0] = XAxis.X, M[1] = XAxis.Y, M[ 2] = XAxis.Z;
00982 M[4] = YAxis.X, M[5] = YAxis.Y, M[ 6] = YAxis.Z;
00983 M[8] = ZAxis.X, M[9] = ZAxis.Y, M[10] = ZAxis.Z;
00984 }
00986 vector3d<T> getScale() const
00987 {
00988 if (math::Equal(M[1], 0.0f) && math::Equal(M[2], 0.0f) &&
00989 math::Equal(M[4], 0.0f) && math::Equal(M[6], 0.0f) &&
00990 math::Equal(M[8], 0.0f) && math::Equal(M[9], 0.0f))
00991 {
00992 return vector3d<T>(M[0], M[5], M[10]);
00993 }
00994
00995 return vector3d<T>(
00996 sqrtf(M[0]*M[0] + M[1]*M[1] + M[ 2]*M[ 2]),
00997 sqrtf(M[4]*M[4] + M[5]*M[5] + M[ 6]*M[ 6]),
00998 sqrtf(M[8]*M[8] + M[9]*M[9] + M[10]*M[10])
00999 );
01000 }
01001
01002 vector3d<T> getRotation() const
01003 {
01004 const matrix4<T> &Mat = *this;
01005 const vector3d<T> Scale = getScale();
01006 const vector3d<T> InvScale = vector3d<T>(T(1)/Scale.X, T(1)/Scale.Y, T(1)/Scale.Z);
01007
01008 T X, Y, Z, rotx, roty, C;
01009
01010 Y = -asin(Mat[2]*InvScale.X);
01011 C = cos(Y);
01012 Y *= static_cast<T>(math::RAD64);
01013
01014 if (!math::Equal(C, T(0)))
01015 {
01016 C = T(1) / C;
01017 rotx = Mat[10] * C * InvScale.Z;
01018 roty = Mat[6] * C * InvScale.Y;
01019 X = atan2(roty, rotx) * static_cast<T>(math::RAD64);
01020 rotx = Mat[0] * C * InvScale.X;
01021 roty = Mat[1] * C * InvScale.X;
01022 Z = atan2(roty, rotx) * static_cast<T>(math::RAD64);
01023 }
01024 else
01025 {
01026 X = T(0);
01027 rotx = Mat[5] * InvScale.Y;
01028 roty = -Mat[4] * InvScale.Y;
01029 Z = atan2(roty, rotx) * static_cast<T>(math::RAD64);
01030 }
01031
01032 if (X < 0) X += 360;
01033 if (Y < 0) Y += 360;
01034 if (Z < 0) Z += 360;
01035
01036 return vector3d<T>(X, Y, Z);
01037 }
01038
01039 matrix4<T> getRotationMatrix() const
01040 {
01041 matrix4<T> Matrix(
01042 M[0], M[4], M[ 8], 0,
01043 M[1], M[5], M[ 9], 0,
01044 M[2], M[6], M[10], 0,
01045 0, 0, 0, 1
01046 );
01047
01048 const vector3d<T> Scale(getScale());
01049 Matrix.scale(dim::vector3d<T>(1) / Scale);
01050
01051 return Matrix;
01052 }
01053
01054 matrix4<T> getPositionMatrix() const
01055 {
01056 return matrix4<T>(
01057 1, 0, 0, M[12],
01058 0, 1, 0, M[13],
01059 0, 0, 1, M[14],
01060 0, 0, 0, 1
01061 );
01062 }
01063
01064 inline matrix4<T> getPositionScaleMatrix() const
01065 {
01066 const vector3d<T> Scale(getScale());
01067 return matrix4<T>(
01068 Scale.X, 0, 0, M[12],
01069 0, Scale.Y, 0, M[13],
01070 0, 0, Scale.Z, M[14],
01071 0, 0, 0, 1
01072 );
01073 }
01074
01075 inline matrix4<T> getPositionRotationMatrix() const
01076 {
01077 const dim::vector3d<T> Scale(getScale());
01078
01079 matrix4<T> Matrix(*this);
01080 Matrix.scale(dim::vector3d<T>(1) / Scale);
01081
01082 return Matrix;
01083 }
01084
01085 inline matrix4<T> getTransposed() const
01086 {
01087 matrix4<T> Mat;
01088 getTransposed(Mat);
01089 return Mat;
01090 }
01091
01092 inline void getTransposed(matrix4<T> &Other) const
01093 {
01094 Other[0] = M[ 0]; Other[4] = M[ 1]; Other[ 8] = M[ 2]; Other[12] = M[ 3];
01095 Other[1] = M[ 4]; Other[5] = M[ 5]; Other[ 9] = M[ 6]; Other[13] = M[ 7];
01096 Other[2] = M[ 8]; Other[6] = M[ 9]; Other[10] = M[10]; Other[14] = M[11];
01097 Other[3] = M[12]; Other[7] = M[13]; Other[11] = M[14]; Other[15] = M[15];
01098 }
01099
01100 inline matrix4<T> getTextureMatrix() const
01101 {
01102 matrix4<T> Mat;
01103
01104 Mat[ 0] = M[ 0]; Mat[ 1] = M[ 1]; Mat[ 2] = M[ 3];
01105 Mat[ 4] = M[ 4]; Mat[ 5] = M[ 5]; Mat[ 6] = M[ 7];
01106 Mat[ 8] = M[12]; Mat[ 9] = M[13]; Mat[10] = M[15];
01107
01108 return Mat;
01109 }
01110
01111 inline matrix4<T> interpolate(const matrix4<T> &Other, f32 seek) const
01112 {
01113 matrix4<T> Mat;
01114
01115 for (s32 i = 0; i < 16; ++i)
01116 Mat.M[i] = M[i] + (Other.M[i] - M[i]) * seek;
01117
01118 return Mat;
01119 }
01120
01121 inline bool isIdentity() const
01122 {
01123 for (s32 i = 0, j; i < 4; ++i)
01124 {
01125 for (j = 0; j < 4; ++j)
01126 {
01127 if ( ( i != j && !math::Equal((*this)(i, j), 0.0f) ) ||
01128 ( i == j && !math::Equal((*this)(i, j), 1.0f) ) )
01129 {
01130 return false;
01131 }
01132 }
01133 }
01134
01135 return true;
01136 }
01137
01138 inline bool equal(const matrix4<T> &Other) const
01139 {
01140 for (s32 i = 0; i < 16; ++i)
01141 {
01142 if (math::Equal(M[i], Other.M[i]))
01143 return false;
01144 }
01145 return true;
01146 }
01147
01148 inline const T* getArray() const
01149 {
01150 return M;
01151 }
01152 inline T* getArray()
01153 {
01154 return M;
01155 }
01156
01157 inline matrix3<T> get3x3() const
01158 {
01159 return matrix3<T>(
01160 M[0], M[4], M[ 8],
01161 M[1], M[5], M[ 9],
01162 M[2], M[6], M[10]
01163 );
01164 }
01165 inline matrix2<T> get2x2() const
01166 {
01167 return matrix2<T>(
01168 M[0], M[4],
01169 M[1], M[5]
01170 );
01171 }
01172
01173 template <typename B> inline matrix4<B> cast() const
01174 {
01175 matrix4<B> Other;
01176
01177 for (u32 i = 0; i < 16; ++i)
01178 Other[i] = static_cast<B>(M[i]);
01179
01180 return Other;
01181 }
01182
01183
01184
01185 static vector3d<T> getProjection(
01186 const vector3d<T> ObjectPosition, const rect2di &Viewport,
01187 const matrix4<T> &ProjectionMatrix, const matrix4<T> &ModelviewMatrix)
01188 {
01189 T v[4] = { ObjectPosition.X, ObjectPosition.Y, ObjectPosition.Z, 1 };
01190
01191 matrix4<T>(ProjectionMatrix * ModelviewMatrix).multiplySingleMatrix(v);
01192
01193 return vector3d<T>(
01194 Viewport.Left + Viewport.Right * (v[0] + 1) / 2,
01195 Viewport.Top + Viewport.Bottom * (v[1] + 1) / 2,
01196 (v[2] + 1) / 2
01197 );
01198 }
01199
01200
01201
01203 T M[16];
01204
01205
01206
01207 static const matrix4<T> IDENTITY;
01208
01209 };
01210
01211 typedef matrix4<f32> matrix4f;
01212 typedef matrix4<f64> matrix4d;
01213
01214 template <typename T> const matrix4<T> matrix4<T>::IDENTITY;
01215
01216
01217
01218
01219
01220
01221 template <typename T> inline matrix4<T> getRotationMatrix(const matrix4<T> &Mat)
01222 {
01223 return matrix4<T>(
01224 Mat[0], Mat[4], Mat[ 8], 0,
01225 Mat[1], Mat[5], Mat[ 9], 0,
01226 Mat[2], Mat[6], Mat[10], 0,
01227 0, 0, 0, 1
01228 );
01229 }
01230 template <typename T> inline matrix4<T> getScaleMatrix(matrix4<T> Mat)
01231 {
01232 Mat.setPosition(0);
01233
01234 vector3df Rot(Mat.getRotation());
01235 Mat.matrixRotateYXZ(-Rot);
01236
01237 return Mat;
01238 }
01239
01240 template <typename T> inline matrix4<T> getRotationMatrix(const vector3d<T> &Rotation)
01241 {
01242 matrix4<T> Mat;
01243 Mat.setRotation(Rotation);
01244 return Mat;
01245 }
01246
01247 template <typename T> inline matrix4<T> getPositionMatrix(const vector3d<T> &Position)
01248 {
01249 matrix4<T> Mat;
01250 Mat.setPosition(Position);
01251 return Mat;
01252 }
01253
01254 template <typename T> inline matrix4<T> getScaleMatrix(const vector3d<T> &Scale)
01255 {
01256 matrix4<T> Mat;
01257 Mat.setScale(Scale);
01258 return Mat;
01259 }
01260
01261 template <typename T> inline matrix4<T> getDirectionMatrix(const vector3d<T> From, const vector3d<T> To)
01262 {
01263
01264 T w = To.X - From.X;
01265 T h = To.Y - From.Y;
01266 T dx = math::getDistance(From, To);
01267 T dy = math::getDistance(dim::point2df(From.X, From.Z), dim::point2df(To.X, To.Z));
01268 T rx = 0;
01269 T ry = 0;
01270
01271
01272 if (!math::Equal(From.Y, To.Y))
01273 rx = math::ASin(h/dx);
01274
01275 if (!math::Equal(From.X, To.X))
01276 ry = -math::ASin(w/dy);
01277
01278 if (From.Z < To.Z)
01279 ry = T(180) - ry;
01280
01281
01282 matrix4<T> Mat;
01283 Mat.translate(From);
01284 Mat.rotateY(ry);
01285 Mat.rotateX(rx);
01286
01287 return Mat;
01288 }
01289
01290
01291 }
01292
01293 }
01294
01295
01296 #endif
01297
01298
01299
01300