00001
00007 #include "Matrix.h"
00008
00009 Mat4::Mat4() {
00010 for (int i=0; i<16; i++) m[i] = 0.0f;
00011 }
00012
00013 Mat4::Mat4(float val) {
00014 for (int i=0; i<16; i++) m[i] = val;
00015 }
00016
00017 Mat4::Mat4(float mat[]) {
00018 for (int i=0; i<16; i++) m[i] = mat[i];
00019 }
00020
00021 void Mat4::loadIdentity() {
00022 for (unsigned int i=0; i<16; i++) {
00023 m[i] = ((i & 3) == (i >> 2));
00024 }
00025 }
00026
00027 void Mat4::loadRotateX(const float angle) {
00028 float cosA = cosf(angle);
00029 float sinA = sinf(angle);
00030
00031 m[0] = cosA;
00032 m[1] = 0;
00033 m[2] = sinA;
00034 m[3] = 0;
00035
00036 m[4] = 0;
00037 m[5] = 1;
00038 m[6] = 0;
00039 m[7] = 0;
00040
00041 m[8] = -sinA;
00042 m[9] = 0;
00043 m[10] = cosA;
00044 m[11] = 0;
00045
00046 m[12] = 0;
00047 m[13] = 0;
00048 m[14] = 0;
00049 m[15] = 1;
00050 }
00051
00052 void Mat4::loadRotateY(const float angle) {
00053 float cosA = cosf(angle);
00054 float sinA = sinf(angle);
00055
00056 m[0] = 1;
00057 m[1] = 0;
00058 m[2] = 0;
00059 m[3] = 0;
00060
00061 m[4] = 0;
00062 m[5] = cosA;
00063 m[6] = sinA;
00064 m[7] = 0;
00065
00066 m[8] = 0;
00067 m[9] = -sinA;
00068 m[10] = cosA;
00069 m[11] = 0;
00070
00071 m[12] = 0;
00072 m[13] = 0;
00073 m[14] = 0;
00074 m[15] = 1;
00075 }
00076
00077 void Mat4::loadRotateZ(const float angle) {
00078 float cosA = cosf(angle);
00079 float sinA = sinf(angle);
00080
00081 m[0] = cosA;
00082 m[1] = sinA;
00083 m[2] = 0;
00084 m[3] = 0;
00085
00086 m[4] = -sinA;
00087 m[5] = cosA;
00088 m[6] = 0;
00089 m[7] = 0;
00090
00091 m[8] = 0;
00092 m[9] = 0;
00093 m[10] = 1;
00094 m[11] = 0;
00095
00096 m[12] = 0;
00097 m[13] = 0;
00098 m[14] = 0;
00099 m[15] = 1;
00100 }
00101
00102 void Mat4::loadRotateXY(const float angleX, const float angleY) {
00103 float cosX = cosf(angleX);
00104 float sinX = sinf(angleX);
00105
00106 float cosY = cosf(angleY);
00107 float sinY = sinf(angleY);
00108
00109 m[0] = cosY;
00110 m[1] = -sinX*sinY;
00111 m[2] = cosX*sinY;
00112 m[3] = 0;
00113
00114 m[4] = 0;
00115 m[5] = cosX;
00116 m[6] = sinX;
00117 m[7] = 0;
00118
00119 m[8] = -sinY;
00120 m[9] = -sinX*cosY;
00121 m[10] = cosX*cosY;
00122 m[11] = 0;
00123
00124 m[12] = 0;
00125 m[13] = 0;
00126 m[14] = 0;
00127 m[15] = 1;
00128 }
00129
00130 void Mat4::loadRotateZXY(const float angleX, const float angleY, const float angleZ) {
00131 float cosX = cosf(angleX);
00132 float sinX = sinf(angleX);
00133
00134 float cosY = cosf(angleY);
00135 float sinY = sinf(angleY);
00136
00137 float cosZ = cosf(angleZ);
00138 float sinZ = sinf(angleZ);
00139
00140 m[0] = cosY * cosZ + sinX * sinY * sinZ;
00141 m[1] = cosY * sinZ - sinX * sinY * cosZ;
00142 m[2] = cosX * sinY;
00143 m[3] = 0;
00144
00145 m[4] = -cosX * sinZ;
00146 m[5] = cosX * cosZ;
00147 m[6] = sinX;
00148 m[7] = 0;
00149
00150 m[8] = sinX * cosY * sinZ - sinY * cosZ;
00151 m[9] = -sinY * sinZ - sinX * cosY * cosZ;
00152 m[10] = cosX * cosY;
00153 m[11] = 0;
00154
00155 m[12] = 0;
00156 m[13] = 0;
00157 m[14] = 0;
00158 m[15] = 1;
00159 }
00160
00161 void Mat4::loadRotate(const Vec3 &v, const float angle) {
00162 float cosA = cosf(angle);
00163 float sinA = sinf(angle);
00164
00165 m[0] = v.x * v.x * (1 - cosA) + cosA;
00166 m[1] = v.x * v.y * (cosA - 1) + v.z * sinA;
00167 m[2] = v.x * v.z * (1 - cosA) + v.y * sinA;
00168 m[3] = 0;
00169 m[4] = v.x * v.y * (cosA - 1) - v.z * sinA;
00170 m[5] = v.y * v.y * (1 - cosA) + cosA;
00171 m[6] = v.y * v.z * (cosA - 1) + v.x * sinA;
00172 m[7] = 0;
00173 m[8] = v.x * v.z * (1 - cosA) - v.y * sinA;
00174 m[9] = v.y * v.z * (cosA - 1) - v.x * sinA;
00175 m[10] = v.z * v.z * (1 - cosA) + cosA;
00176 m[11] = 0;
00177 m[12] = 0;
00178 m[13] = 0;
00179 m[14] = 0;
00180 m[15] = 1;
00181 }
00182
00183 void Mat4::loadProjectionMatrix(float fov, float aspect, float zNear, float zFar) {
00184 float w, h;
00185
00186 w = tanf(0.5f *fov);
00187 h = w*aspect;
00188
00189 m[0] = 1.0f / w;
00190 m[1] = 0;
00191 m[2] = 0;
00192 m[3] = 0;
00193
00194 m[4] = 0;
00195 m[5] = 1.0f / h;
00196 m[6] = 0;
00197 m[7] = 0;
00198
00199 m[8] = 0;
00200 m[9] = 0;
00201 m[10] = (zFar + zNear) / (zFar - zNear);
00202 m[11] = 1;
00203
00204 m[12] = 0;
00205 m[13] = 0;
00206 m[14] = -(2 * zFar * zNear) / (zFar - zNear);
00207 m[15] = 0;
00208 }
00209
00210 void Mat4::translate(const Vec3 &v) {
00211 m[12] += (v.x * m[0] + v.y * m[4] + v.z * m[8]);
00212 m[13] += (v.x * m[1] + v.y * m[5] + v.z * m[9]);
00213 m[14] += (v.x * m[2] + v.y * m[6] + v.z * m[10]);
00214 m[15] += (v.x * m[3] + v.y * m[7] + v.z * m[11]);
00215 }
00216
00217 void Mat4::setTranslate(const Vec3 &v) {
00218 m[12] = v.x;
00219 m[13] = v.y;
00220 m[14] = v.z;
00221 }
00222
00223 Vec3 Mat4::translateVec(const Vec3 &v) {
00224 Vec3 vec;
00225 vec.x = v.x + m[12];
00226 vec.y = v.y + m[13];
00227 vec.z = v.z + m[14];
00228
00229 return vec;
00230 }
00231
00232 void Mat4::scale(const float sx, const float sy, const float sz) {
00233 m[0] *= sx; m[1] *= sx; m[2] *= sx; m[3] *= sx;
00234 m[4] *= sy; m[5] *= sy; m[6] *= sy; m[7] *= sy;
00235 m[8] *= sz; m[9] *= sz; m[10] *= sz; m[11] *= sz;
00236 }
00237
00238 Vec3 Mat4::rotateVec(const Vec3 &v) {
00239 Vec3 vec;
00240 vec.x = v.x * m[0] + v.y * m[4] + v.z * m[8];
00241 vec.y = v.x * m[1] + v.y * m[5] + v.z * m[9];
00242 vec.y = v.x * m[2] + v.y * m[6] + v.z * m[10];
00243
00244 return vec;
00245 }
00246
00247 void Mat4::rotateX(const float angle) {
00248 Mat4 temp;
00249
00250 temp.loadRotateX(angle);
00251 (*this) *= temp;
00252 }
00253
00254 void Mat4::rotateY(const float angle) {
00255 Mat4 temp;
00256
00257 temp.loadRotateY(angle);
00258 (*this) *= temp;
00259 }
00260
00261 void Mat4::rotateZ(const float angle) {
00262 Mat4 temp;
00263
00264 temp.loadRotateZ(angle);
00265 (*this) *= temp;
00266 }
00267
00268 void Mat4::rotateXY(const float angleX, const float angleY) {
00269 Mat4 temp;
00270
00271 temp.loadRotateXY(angleX, angleY);
00272 (*this) *= temp;
00273 }
00274
00275 void Mat4::rotateZXY(const float angleX, const float angleY, const float angleZ) {
00276 Mat4 temp;
00277
00278 temp.loadRotateZXY(angleX, angleY, angleZ);
00279 (*this) *= temp;
00280 }
00281
00282 void Mat4::rotate(const Vec3 &v, const float angle) {
00283 Mat4 temp;
00284
00285 temp.loadRotate(v, angle);
00286 (*this) *= temp;
00287 }
00288
00289 void Mat4::transpose() {
00290 float temp;
00291
00292 temp = m[4];
00293 m[4] = m[1];
00294 m[1] = temp;
00295
00296 temp = m[8];
00297 m[8] = m[2];
00298 m[2] = temp;
00299
00300 temp = m[12];
00301 m[12] = m[3];
00302 m[3] = temp;
00303
00304 temp = m[9];
00305 m[9] = m[6];
00306 m[6] = temp;
00307
00308 temp = m[13];
00309 m[13] = m[7];
00310 m[7] = temp;
00311
00312 temp = m[14];
00313 m[14] = m[11];
00314 m[11] = temp;
00315 }
00316
00317 Mat4 Mat4::operator + (const Mat4 &v) {
00318 Mat4 mat;
00319 for (unsigned int i = 0; i < 16; i++){
00320 mat.m[i] = m[i] + v.m[i];
00321 }
00322 return mat;
00323 }
00324
00325 Mat4 Mat4::operator + (const float s) {
00326 Mat4 mat;
00327 for (unsigned int i = 0; i < 16; i++){
00328 mat.m[i] = m[i] + s;
00329 }
00330 return mat;
00331 }
00332
00333 Mat4 Mat4::operator - (const Mat4 &v) {
00334 Mat4 mat;
00335 for (unsigned int i = 0; i < 16; i++){
00336 mat.m[i] = m[i] - v.m[i];
00337 }
00338 return mat;
00339 }
00340
00341 Mat4 Mat4::operator - (const float s) {
00342 Mat4 mat;
00343 for (unsigned int i = 0; i < 16; i++){
00344 mat.m[i] = m[i] - s;
00345 }
00346 return mat;
00347 }
00348
00349 Mat4 Mat4::operator - () {
00350 Mat4 mat;
00351 for (unsigned int i = 0; i < 16; i++){
00352 mat.m[i] = -m[i];
00353 }
00354 return mat;
00355 }
00356
00357 void Mat4::operator += (const Mat4 &v) {
00358 for (unsigned int i = 0; i < 16; i++){
00359 m[i] += v.m[i];
00360 }
00361 }
00362
00363 void Mat4::operator -= (const Mat4 &v) {
00364 for (unsigned int i = 0; i < 16; i++){
00365 m[i] -= v.m[i];
00366 }
00367 }
00368
00369 void Mat4::operator += (const float s) {
00370 for (unsigned int i = 0; i < 16; i++){
00371 m[i] += s;
00372 }
00373 }
00374
00375 void Mat4::operator -= (const float s) {
00376 for (unsigned int i = 0; i < 16; i++){
00377 m[i] -= s;
00378 }
00379 }
00380
00381
00382 Mat4 Mat4::operator * (const Mat4 &v) {
00383 Mat4 mat;
00384 unsigned int i,us,vs;
00385
00386 for (i = 0; i < 16; i++){
00387 us = (i & 0x3);
00388 vs = (i & 0xC);
00389
00390 mat.m[i] = m[us ] * v.m[vs ] +
00391 m[us + 4] * v.m[vs + 1] +
00392 m[us + 8] * v.m[vs + 2] +
00393 m[us + 12] * v.m[vs + 3];
00394 }
00395 return mat;
00396 }
00397
00398 Mat4 Mat4::operator * (const float s) {
00399 Mat4 mat;
00400 unsigned int i;
00401
00402 for (i = 0; i < 16; i++){
00403 mat.m[i] = m[i] * s;
00404 }
00405 return mat;
00406 }
00407
00408 void Mat4::operator *= (const float s) {
00409 for (unsigned int i=0; i<16; i++) {
00410 m[i] *= s;
00411 }
00412 }
00413
00414 void Mat4::operator *= (const Mat4 &v) {
00415 unsigned int i, us, vs;
00416 float nm[16];
00417
00418 for (i = 0; i < 16; i++){
00419 us = (i & 0x3);
00420 vs = (i & 0xC);
00421
00422 nm[i] = m[us ] * v.m[vs ] +
00423 m[us + 4] * v.m[vs + 1] +
00424 m[us + 8] * v.m[vs + 2] +
00425 m[us + 12] * v.m[vs + 3];
00426 }
00427 for (i = 0; i < 16; i++){
00428 m[i] = nm[i];
00429 }
00430 }
00431
00432 Vec3 Mat4::operator * (const Vec3 &v) {
00433 return Vec3(
00434 m[0] * v.x + m[4] * v.y + m[8] * v.z,
00435 m[1] * v.x + m[5] * v.y + m[9] * v.z,
00436 m[2] * v.x + m[6] * v.y + m[10] * v.z);
00437 }
00438
00439 Vec4 Mat4::operator * (const Vec4 &v) {
00440 return Vec4(
00441 m[0] * v.x + m[4] * v.y + m[8] * v.z + m[12],
00442 m[1] * v.x + m[5] * v.y + m[9] * v.z + m[13],
00443 m[2] * v.x + m[6] * v.y + m[10] * v.z + m[14],
00444 m[3] * v.x + m[7] * v.y + m[11] * v.z + m[15]);
00445 }
00446
00447 Mat4 Mat4::operator / (const float d) {
00448 Mat4 mat;
00449 unsigned int i;
00450
00451 for (i = 0; i < 16; i++){
00452 mat.m[i] = m[i] / d;
00453 }
00454 return mat;
00455 }
00456
00457 void Mat4::operator /= (const float s) {
00458 for (unsigned int i=0; i<16; i++) {
00459 m[i] /= s;
00460 }
00461 }
00462
00463 Mat4 Mat4::operator ! () {
00464 Mat4 mat;
00465 unsigned int i,j,k;
00466 float temp, newMat[4][8];
00467
00468 for (k = i = 0; i < 4; i++){
00469 for (j = 0; j < 4; j++){
00470 newMat[j][i] = m[k];
00471 newMat[i][j + 4] = (i == j);
00472 k++;
00473 }
00474 }
00475
00476
00477 for (i = 0; i < 4; i++){
00478 if (newMat[i][i] == 0){
00479 j = 0;
00480 do {
00481 j++;
00482 } while (newMat[j][i] == 0);
00483
00484 for (k = i; k < 8; k++){
00485 temp = newMat[j][k];
00486 newMat[j][k] = newMat[i][k];
00487 newMat[i][k] = temp;
00488 }
00489 }
00490
00491 for (j = i+1; j < 8; j++){
00492 newMat[i][j] /= newMat[i][i];
00493 }
00494
00495 for (j = 0; j < 4; j++){
00496 if (j != i){
00497 for (k = i+1; k < 8; k++){
00498 newMat[j][k] -= newMat[j][i] * newMat[i][k];
00499 }
00500 }
00501 }
00502 }
00503
00504 for (k = 0, i = 4; i < 8; i++){
00505 for (j = 0; j < 4; j++){
00506 mat.m[k] = newMat[j][i];
00507 k++;
00508 }
00509 }
00510
00511 return mat;
00512 }
00513
00514
00515
00516
00517 void Mat4::postMultiply(const Mat4 &matrix) {
00518 float newMatrix[16];
00519 const float *m1 = m, *m2 = matrix.m;
00520
00521 newMatrix[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2];
00522 newMatrix[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2];
00523 newMatrix[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2];
00524 newMatrix[3] = 0;
00525
00526 newMatrix[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6];
00527 newMatrix[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6];
00528 newMatrix[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6];
00529 newMatrix[7] = 0;
00530
00531 newMatrix[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10];
00532 newMatrix[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10];
00533 newMatrix[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10];
00534 newMatrix[11] = 0;
00535
00536 newMatrix[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12];
00537 newMatrix[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13];
00538 newMatrix[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14];
00539 newMatrix[15] = 1;
00540
00541 set( newMatrix );
00542 }
00543
00544 void Mat4::setTranslation(const float *translation) {
00545 m[12] = translation[0];
00546 m[13] = translation[1];
00547 m[14] = translation[2];
00548 }
00549
00550 void Mat4::setInverseTranslation(const float *translation) {
00551 m[12] = -translation[0];
00552 m[13] = -translation[1];
00553 m[14] = -translation[2];
00554 }
00555
00556 void Mat4::setRotationRadians(const float *angles) {
00557 double cr = cos( angles[0] );
00558 double sr = sin( angles[0] );
00559 double cp = cos( angles[1] );
00560 double sp = sin( angles[1] );
00561 double cy = cos( angles[2] );
00562 double sy = sin( angles[2] );
00563
00564 m[0] = ( float )( cp*cy );
00565 m[1] = ( float )( cp*sy );
00566 m[2] = ( float )( -sp );
00567
00568 double srsp = sr*sp;
00569 double crsp = cr*sp;
00570
00571 m[4] = ( float )( srsp*cy-cr*sy );
00572 m[5] = ( float )( srsp*sy+cr*cy );
00573 m[6] = ( float )( sr*cp );
00574
00575 m[8] = ( float )( crsp*cy+sr*sy );
00576 m[9] = ( float )( crsp*sy-sr*cy );
00577 m[10] = ( float )( cr*cp );
00578 }