Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

Matrix.cpp

Go to the documentation of this file.
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 // Used with MilkShape
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 }

Generated on Sun Jun 5 15:47:04 2005 for Defacto by  doxygen 1.4.3