00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SALT_MATRIX_H
00023 #define SALT_MATRIX_H
00024
00025
00026
00027
00028
00029 #include "defines.h"
00030 #include "vector.h"
00031 #include <memory.h>
00032
00033 namespace salt
00034 {
00035 #if 0
00036 }
00037 #endif
00038
00042 class Matrix
00043 {
00044 public:
00046 float m[16];
00047
00049 f_inline Matrix(){}
00050
00052 f_inline Matrix(float *newMatrix) { memcpy(m, newMatrix, sizeof(float)*16); }
00053
00055 f_inline Matrix(const Matrix &newMatrix) { memcpy(m, newMatrix.m, sizeof(float)*16); }
00056
00058 f_inline Matrix(Matrix *newMatrix) { memcpy(m, newMatrix->m, sizeof(float)*16); }
00059
00061 f_inline Matrix(float m00, float m01, float m02, float m03,
00062 float m10, float m11, float m12, float m13,
00063 float m20, float m21, float m22, float m23,
00064 float m30, float m31, float m32, float m33);
00065
00067 f_inline void Identity() { memcpy(m, mIdentity, sizeof(float)*16); }
00068
00070 static float* GetIdentity() { return mIdentity; }
00071
00073 f_inline void RotationX(float inAngle);
00074
00076 f_inline void RotationY(float inAngle);
00077
00079 f_inline void RotationZ(float inAngle);
00080
00082 f_inline void Translation(const Vector3f &inVector);
00083
00085 f_inline void Scale(const Vector3f & inVector);
00086
00090 void LookAt(const Vector3f & inEye, const Vector3f & inDirection, const Vector3f & inUp);
00091
00093 void Dump() const;
00094
00096 f_inline void Set(float m00, float m01, float m02, float m03,
00097 float m10, float m11, float m12, float m13,
00098 float m20, float m21, float m22, float m23,
00099 float m30, float m31, float m32, float m33);
00100
00102 f_inline const Matrix & RotateX(float inAngle);
00103
00105 f_inline const Matrix & RotateY(float inAngle);
00106
00108 f_inline const Matrix & RotateZ(float inAngle);
00109
00111 f_inline const Matrix & Translate(const Vector3f & inVector);
00112
00114 f_inline const Vector3f & Right() const { return *(const Vector3f*) &El(0, 0); }
00115
00117 f_inline Vector3f & Right() { return *(Vector3f*) &El(0, 0); }
00118
00120 f_inline const Vector3f & Up() const { return *(const Vector3f*) &El(0, 1); }
00121
00123 f_inline Vector3f & Up() { return *(Vector3f*) &El(0, 1); }
00124
00126 f_inline const Vector3f & Forward() const { return *(const Vector3f*) &El(0, 2); }
00127
00129 f_inline Vector3f & Forward() { return *(Vector3f*) &El(0, 2); }
00130
00132 f_inline const Vector3f & Pos() const { return *(const Vector3f*) &El(0, 3); }
00133
00135 f_inline Vector3f & Pos() { return *(Vector3f*) &El(0, 3); }
00136
00138 bool IsEqual(const Matrix& matrix) const;
00139
00141 f_inline void InvertRotationMatrix();
00142
00144 f_inline Vector3f Transform(const Vector3f & inVector) const;
00145
00147 f_inline Vector3f Rotate(const Vector3f & inVector) const;
00148
00150 f_inline Vector3f InverseRotate(const Vector3f & inVector) const;
00151
00152
00154 void CalcAttenuationNoRotation(const Vector3f &pos, float radius);
00155
00157 void CalcAttenuationWithRotation(const Matrix &lightWorldMatrix, float radius);
00158
00160 void CalcInfiniteProjection(float width, float height, float fov, float zNear);
00161
00163 void CalcInfiniteFrustum(float left, float right, float bottom, float top, float zNear);
00164
00166 void CalcSpotLight(const Matrix &lightWorldTransform, float fov, float width, float height, float zNear);
00167
00168
00169
00171 f_inline const Matrix operator*(const Matrix &inRHS) const;
00172
00174 f_inline const Matrix & operator*=(const Matrix &inRHS);
00175
00177 f_inline const Vector3f operator*(const Vector3f &inRHS) const;
00178
00180 f_inline const Vector3f operator*(const Vector2f &inRHS) const;
00181
00182
00183
00185 f_inline float& operator() (int inRow, int inColumn) { return El(inRow, inColumn); }
00186
00188 f_inline const float& operator() (int inRow, int inColumn) const { return El(inRow, inColumn); }
00189
00190 protected:
00192 f_inline float& El(int inRow, int inColumn) { return m[inColumn*4 + inRow]; }
00193
00195 f_inline const float& El(int inRow, int inColumn) const { return m[inColumn*4 + inRow]; }
00196
00197 private:
00199 static float mIdentity[16];
00200 };
00201
00202 f_inline Matrix::Matrix(float m00, float m01, float m02, float m03,
00203 float m10, float m11, float m12, float m13,
00204 float m20, float m21, float m22, float m23,
00205 float m30, float m31, float m32, float m33)
00206 {
00207 m[0] = m00; m[4] = m01; m[8] = m02; m[12] = m03;
00208 m[1] = m10; m[5] = m11; m[9] = m12; m[13] = m13;
00209 m[2] = m20; m[6] = m21; m[10]= m22; m[14] = m23;
00210 m[3] = m30; m[7] = m31; m[11]= m32; m[15] = m33;
00211 }
00212
00213 f_inline void Matrix::RotationX(float inAngle)
00214 {
00215 float c=gCos(inAngle), s=gSin(inAngle);
00216
00217
00218 Identity();
00219 El(1, 1) = c;
00220 El(2, 1) = s;
00221 El(1, 2) = -s;
00222 El(2, 2) = c;
00223 }
00224
00225 f_inline void Matrix::RotationY(float inAngle)
00226 {
00227 float c=gCos(inAngle), s=gSin(inAngle);
00228
00229
00230 Identity();
00231 El(0, 0) = c;
00232 El(2, 0) = -s;
00233 El(0, 2) = s;
00234 El(2, 2) = c;
00235 }
00236
00237 f_inline void Matrix::RotationZ(float inAngle)
00238 {
00239 float c=gCos(inAngle), s=gSin(inAngle);
00240
00241
00242 Identity();
00243 El(0, 0) = c;
00244 El(1, 0) = s;
00245 El(0, 1) = -s;
00246 El(1, 1) = c;
00247 }
00248
00249 f_inline void Matrix::Translation(const Vector3f & inVector)
00250 {
00251
00252 Identity();
00253 El(0, 3) = inVector.x();
00254 El(1, 3) = inVector.y();
00255 El(2, 3) = inVector.z();
00256 }
00257
00258 f_inline void Matrix::Scale(const Vector3f & inVector)
00259 {
00260
00261 Identity();
00262 El(0, 0) = inVector.x();
00263 El(1, 1) = inVector.y();
00264 El(2, 2) = inVector.z();
00265 }
00266
00267 f_inline void Matrix::Set(float m00, float m01, float m02, float m03,
00268 float m10, float m11, float m12, float m13,
00269 float m20, float m21, float m22, float m23,
00270 float m30, float m31, float m32, float m33)
00271 {
00272 m[0] = m00; m[4] = m01; m[8] = m02; m[12] = m03;
00273 m[1] = m10; m[5] = m11; m[9] = m12; m[13] = m13;
00274 m[2] = m20; m[6] = m21; m[10]= m22; m[14] = m23;
00275 m[3] = m30; m[7] = m31; m[11]= m32; m[15] = m33;
00276 }
00277
00278
00279
00280 f_inline const Matrix & Matrix::RotateX(float inAngle)
00281 {
00282 float c=gCos(inAngle), s=gSin(inAngle);
00283
00284
00285 float m01 = c*El(0,1) + s*El(0,2);
00286 float m11 = c*El(1,1) + s*El(1,2);
00287 float m21 = c*El(2,1) + s*El(2,2);
00288 float m31 = c*El(3,1) + s*El(3,2);
00289 float m02 =-s*El(0,1) + c*El(0,2);
00290 float m12 =-s*El(1,1) + c*El(1,2);
00291 float m22 =-s*El(2,1) + c*El(2,2);
00292 float m32 =-s*El(3,1) + c*El(3,2);
00293
00294
00295 El(0,1) = m01;
00296 El(1,1) = m11;
00297 El(2,1) = m21;
00298 El(3,1) = m31;
00299 El(0,2) = m02;
00300 El(1,2) = m12;
00301 El(2,2) = m22;
00302 El(3,2) = m32;
00303
00304 return (*this);
00305 }
00306
00307
00308 f_inline const Matrix & Matrix::RotateY(float inAngle)
00309 {
00310 float c=gCos(inAngle), s=gSin(inAngle);
00311
00312
00313 float m00 = c*El(0,0) - s*El(0,2);
00314 float m10 = c*El(1,0) - s*El(1,2);
00315 float m20 = c*El(2,0) - s*El(2,2);
00316 float m30 = c*El(3,0) - s*El(3,2);
00317 float m02 = s*El(0,0) + c*El(0,2);
00318 float m12 = s*El(1,0) + c*El(1,2);
00319 float m22 = s*El(2,0) + c*El(2,2);
00320 float m32 = s*El(3,0) + c*El(3,2);
00321
00322
00323 El(0,0) = m00;
00324 El(1,0) = m10;
00325 El(2,0) = m20;
00326 El(3,0) = m30;
00327 El(0,2) = m02;
00328 El(1,2) = m12;
00329 El(2,2) = m22;
00330 El(3,2) = m32;
00331
00332 return (*this);
00333 }
00334
00335
00336 f_inline const Matrix & Matrix::RotateZ(float inAngle)
00337 {
00338 float c=gCos(inAngle), s=gSin(inAngle);
00339
00340
00341 float m00 = c*El(0,0) + s*El(0,1);
00342 float m10 = c*El(1,0) + s*El(1,1);
00343 float m20 = c*El(2,0) + s*El(2,1);
00344 float m30 = c*El(3,0) + s*El(3,1);
00345 float m01 =-s*El(0,0) + c*El(0,1);
00346 float m11 =-s*El(1,0) + c*El(1,1);
00347 float m21 =-s*El(2,0) + c*El(2,1);
00348 float m31 =-s*El(3,0) + c*El(3,1);
00349
00350
00351 El(0,0) = m00;
00352 El(1,0) = m10;
00353 El(2,0) = m20;
00354 El(3,0) = m30;
00355 El(0,1) = m01;
00356 El(1,1) = m11;
00357 El(2,1) = m21;
00358 El(3,1) = m31;
00359
00360 return (*this);
00361 }
00362
00363
00364 f_inline const Matrix & Matrix::Translate(const Vector3f & inVector)
00365 {
00366 float x = inVector.x(), y = inVector.y(), z = inVector.z();
00367
00368
00369 El(0,3) = x*m[0] + y*m[4] + z*m[8] + m[12];
00370 El(1,3) = x*m[1] + y*m[5] + z*m[9] + m[13];
00371 El(2,3) = x*m[2] + y*m[6] + z*m[10]+ m[14];
00372
00373 return (*this);
00374 }
00375
00376 f_inline void Matrix::InvertRotationMatrix()
00377 {
00378
00379 gSwap(El(0, 1), El(1, 0));
00380 gSwap(El(0, 2), El(2, 0));
00381 gSwap(El(1, 2), El(2, 1));
00382
00383
00384 Pos() = -Rotate(Pos());
00385 }
00386
00387
00388 f_inline Vector3f Matrix::Transform(const Vector3f & inVector) const
00389 {
00390 float x = inVector.x(), y = inVector.y(), z = inVector.z();
00391
00392 return Vector3f( x*m[0] + y*m[4] + z*m[8] + m[12],
00393 x*m[1] + y*m[5] + z*m[9] + m[13],
00394 x*m[2] + y*m[6] + z*m[10]+ m[14]);
00395 }
00396
00397
00398 f_inline Vector3f Matrix::Rotate(const Vector3f & inVector) const
00399 {
00400 float x = inVector.x(), y = inVector.y(), z = inVector.z();
00401 return Vector3f( x*m[0] + y*m[4] + z*m[8],
00402 x*m[1] + y*m[5] + z*m[9],
00403 x*m[2] + y*m[6] + z*m[10]);
00404 }
00405
00406
00407 f_inline Vector3f Matrix::InverseRotate(const Vector3f & inVector) const
00408 {
00409 float x = inVector.x(), y = inVector.y(), z = inVector.z();
00410 return Vector3f(x*m[0] + y*m[1] + z*m[2],
00411 x*m[4] + y*m[5] + z*m[6],
00412 x*m[8] + y*m[9] + z*m[10]);
00413 }
00414
00415
00416 f_inline const Matrix Matrix::operator*(const Matrix & inRHS) const
00417 {
00418 Matrix r;
00419
00420 for (int i=0; i<4; i++)
00421 for (int j=0; j<4; j++)
00422 r(i,j) = El(i,0)*inRHS(0,j)+El(i,1)*inRHS(1,j)+El(i,2)*inRHS(2,j)+El(i,3)*inRHS(3,j);
00423
00424 return r;
00425 }
00426
00427
00428 f_inline const Vector3f Matrix::operator*(const Vector3f &inRHS) const
00429 {
00430 float x = inRHS.x(), y = inRHS.y(), z = inRHS.z();
00431
00432 return Vector3f(x*m[0] + y*m[4] + z*m[8] + m[12],
00433 x*m[1] + y*m[5] + z*m[9] + m[13],
00434 x*m[2] + y*m[6] + z*m[10]+ m[14]);
00435 }
00436
00437
00438 f_inline const Vector3f Matrix::operator*(const Vector2f &inRHS) const
00439 {
00440 float x = inRHS.x(), y = inRHS.y();
00441
00442 return Vector3f(x*m[0] + y*m[4] + m[12],
00443 x*m[1] + y*m[5] + m[13],
00444 x*m[2] + y*m[6] + m[14]);
00445 }
00446
00447 f_inline const Matrix & Matrix::operator*=(const Matrix &inRHS)
00448 {
00449 *this = *this * inRHS;
00450 return *this;
00451 }
00452
00453 }
00454
00455 #endif // SALT_MATRIX_H