00001 #include <math.h>
00002 #include "vuMatrix.h"
00003 #include "vuVector.h"
00004
00005 #define PI_OVER_180 0.01745329251994
00006
00007
00008 vuMatrix::vuMatrix()
00009 {
00010 for(int i=0;i<16;++i)
00011 val[i] = 0.0f;
00012 }
00013
00014
00015 vuMatrix::vuMatrix(const vuMatrix& m)
00016 {
00017 for(int i=0;i<16;++i)
00018 val[i] = m.val[i];
00019 }
00020
00021
00022 vuMatrix::vuMatrix(float v)
00023 {
00024 for(int i=0;i<16;++i)
00025 val[i] = v;
00026 }
00027
00028
00029 vuMatrix::vuMatrix(const float* v)
00030 {
00031 for(int i=0;i<16;++i)
00032 val[i] = v[i];
00033 }
00034
00035
00036 vuMatrix::~vuMatrix()
00037 {
00038 }
00039
00040
00041 vuMatrix& vuMatrix::operator=(const vuMatrix& m)
00042 {
00043 if (this != &m)
00044 {
00045 for(int i=0;i<16;++i)
00046 val[i] = m.val[i];
00047 }
00048 return *this;
00049 }
00050
00051
00052 vuMatrix& vuMatrix::operator=(float v)
00053 {
00054 for(int i=0;i<16;++i)
00055 val[i] = v;
00056 return *this;
00057 }
00058
00059
00060 vuMatrix& vuMatrix::operator=(const float* v)
00061 {
00062 for(int i=0;i<16;++i)
00063 val[i] = v[i];
00064 return *this;
00065 }
00066
00067
00068 vuMatrix& vuMatrix::makeIdentity(void)
00069 {
00070 for(int i=1;i<15;++i)
00071 val[i] = 0.0f;
00072 val[0] = val[5] = val[10] = val[15] = 1.0f;
00073 return *this;
00074 }
00075
00076 vuMatrix& vuMatrix::makeRotate(const vuVector& axis, float a)
00077 {
00078 vuVector axis2;
00079 float s;
00080 float c;
00081
00082 s = (float)sin(a*PI_OVER_180);
00083 c = (float)cos(a*PI_OVER_180);
00084 axis2 = axis.mul(axis);
00085
00086 val[0] = axis2[0]+(1.0f-axis2[0])*c;
00087 val[1] = axis[0]*axis[1]*(1.0f-c)+axis[2]*s;
00088 val[2] = axis[0]*axis[2]*(1.0f-c)-axis[1]*s;
00089 val[3] = 0.0f;
00090
00091 val[4] = axis[0]*axis[1]*(1.0f-c)-axis[2]*s;
00092 val[5] = axis2[1]+(1.0f-axis2[1])*c;
00093 val[6] = axis[1]*axis[2]*(1.0f-c)+axis[0]*s;
00094 val[7] = 0.0f;
00095
00096 val[8] = axis[0]*axis[2]*(1.0f-c)+axis[1]*s;
00097 val[9] = axis[1]*axis[2]*(1.0f-c)-axis[0]*s;
00098 val[10] = axis2[2]+(1.0f-axis2[2])*c;
00099 val[11] = 0.0f;
00100
00101 val[12] = 0.0f;
00102 val[13] = 0.0f;
00103 val[14] = 0.0f;
00104 val[15] = 1.0f;
00105
00106 return *this;
00107 }
00108
00109 vuMatrix& vuMatrix::makeRotateX(float a)
00110 {
00111 makeIdentity();
00112 val[5] = val[10] = (float)cos((double)a*PI_OVER_180);
00113 val[9] = -(val[6] = (float)sin((double)a*PI_OVER_180));
00114 return *this;
00115 }
00116
00117 vuMatrix& vuMatrix::makeRotateY(float a)
00118 {
00119 makeIdentity();
00120 val[0] = val[10] = (float)cos((double)a*PI_OVER_180);
00121 val[2] = -(val[8] = (float)sin((double)a*PI_OVER_180));
00122 return *this;
00123 }
00124
00125 vuMatrix& vuMatrix::makeRotateZ(float a)
00126 {
00127 makeIdentity();
00128 val[0] = val[5] = (float)cos((double)a*PI_OVER_180);
00129 val[4] = -(val[1] = (float)sin((double)a*PI_OVER_180));
00130 return *this;
00131 }
00132
00133 vuMatrix& vuMatrix::makeTranslate(float x, float y, float z)
00134 {
00135 makeIdentity();
00136 val[12] = x;
00137 val[13] = y;
00138 val[14] = z;
00139 return *this;
00140 }
00141
00142 vuMatrix& vuMatrix::makeScale(float x, float y, float z)
00143 {
00144 makeIdentity();
00145 val[0] = x;
00146 val[5] = y;
00147 val[10] = z;
00148 return *this;
00149 }
00150
00151 vuMatrix& vuMatrix::makeShearXY(float s)
00152 {
00153 makeIdentity();
00154 val[1] = s;
00155 return *this;
00156 }
00157
00158 vuMatrix& vuMatrix::makeShearXZ(float s)
00159 {
00160 makeIdentity();
00161 val[2] = s;
00162 return *this;
00163 }
00164
00165 vuMatrix& vuMatrix::makeShearYX(float s)
00166 {
00167 makeIdentity();
00168 val[4] = s;
00169 return *this;
00170 }
00171
00172 vuMatrix& vuMatrix::makeShearYZ(float s)
00173 {
00174 makeIdentity();
00175 val[6] = s;
00176 return *this;
00177 }
00178
00179 vuMatrix& vuMatrix::makeShearZX(float s)
00180 {
00181 makeIdentity();
00182 val[8] = s;
00183 return *this;
00184 }
00185
00186 vuMatrix& vuMatrix::makeShearZY(float s)
00187 {
00188 makeIdentity();
00189 val[9] = s;
00190 return *this;
00191 }
00192
00193 vuMatrix& vuMatrix::makeReflectX(void)
00194 {
00195 makeIdentity();
00196 val[0] = -1.0f;
00197 return *this;
00198 }
00199
00200 vuMatrix& vuMatrix::makeReflectY(void)
00201 {
00202 makeIdentity();
00203 val[5] = -1.0f;
00204 return *this;
00205 }
00206
00207 vuMatrix& vuMatrix::makeReflectZ(void)
00208 {
00209 makeIdentity();
00210 val[10] = -1.0f;
00211 return *this;
00212 }
00213
00214 vuMatrix& vuMatrix::makePerspective(float d)
00215 {
00216 makeIdentity();
00217 val[10] = 0.0f;
00218 val[11] = 1.0f/d;
00219 return *this;
00220 }
00221
00222 vuMatrix& vuMatrix::makePerspectiveKeepZ(float d)
00223 {
00224 makeIdentity();
00225 val[11] = 1.0f/d;
00226 return *this;
00227 }
00228
00229
00230 float* vuMatrix::operator[](unsigned int index)
00231 {
00232 if (index > 3)
00233 throw "vuMatrix: Index out of range.";
00234 return &val[index*4];
00235 }
00236
00237
00238 const float* vuMatrix::operator[](unsigned int index) const
00239 {
00240 if (index > 3)
00241 throw "vuMatrix: Index out of range.";
00242 return &val[index*4];
00243 }
00244
00245
00246 float* vuMatrix::getData(void)
00247 {
00248 return val;
00249 }
00250
00251 float const* vuMatrix::getData(void) const
00252 { return val; }
00253
00254
00255 vuMatrix vuMatrix::invOrtho() const
00256 {
00257 vuMatrix r;
00258 float *vp = r.getData();
00259 vp[0] = val[0]; vp[5] = val[5]; vp[10] = val[10];
00260 vp[3] = val[3]; vp[7] = val[7]; vp[11] = val[11]; vp[15] = 1/val[15];
00261 vp[12] = -val[12]; vp[13] = -val[13]; vp[14] = -val[14];
00262 vp[1] = val[4]; vp[4] = val[1];
00263 vp[2] = val[8]; vp[8] = val[2];
00264 vp[6] = val[9]; vp[9] = val[6];
00265 return r;
00266 }
00267
00268
00269 vuMatrix vuMatrix::operator+(const vuMatrix& m) const
00270 {
00271 vuMatrix r;
00272 for(int i=0;i<16;++i)
00273 r.val[i] = val[i] + m.val[i];
00274 return r;
00275 }
00276
00277
00278 vuMatrix vuMatrix::operator-(const vuMatrix& m) const
00279 {
00280 vuMatrix r;
00281 for(int i=0;i<16;++i)
00282 r.val[i] = val[i] - m.val[i];
00283 return r;
00284 }
00285
00286
00287 vuMatrix vuMatrix::operator*(const vuMatrix& m) const
00288 {
00289 vuMatrix r;
00290 int i, j, k;
00291 for(i=0;i<4;++i)
00292 for(j=0;j<4;++j)
00293 for(k=0;k<4;++k)
00294 r.val[(j<<2)+i] += val[(k<<2)+i] * m.val[(j<<2)+k];
00295 return r;
00296 }
00297
00298
00299 vuVector vuMatrix::operator*(const vuVector& v) const
00300 {
00301 vuVector r;
00302 int i, j;
00303 r[3] = (float)(0.0);
00304 for(i=0;i<4;++i)
00305 for(j=0;j<4;++j)
00306 r.val[i] += val[(j<<2)+i]*v.val[j];
00307 return r;
00308 }
00309
00310
00311 vuMatrix vuMatrix::operator*(float s) const
00312 {
00313 vuMatrix r;
00314 for(int i=0;i<16;++i)
00315 r.val[i] = val[i] * s;
00316 return r;
00317 }
00318
00319
00320 vuMatrix operator*(float s,const vuMatrix& m)
00321 {
00322 vuMatrix r;
00323 for(int i=0;i<16;++i)
00324 r.val[i] = m.val[i] * s;
00325 return r;
00326 }
00327
00328
00329 vuMatrix& vuMatrix::operator+=(const vuMatrix& m)
00330 {
00331 for(int i=0;i<16;++i)
00332 val[i] += m.val[i];
00333 return *this;
00334 }
00335
00336
00337 vuMatrix& vuMatrix::operator-=(const vuMatrix& m)
00338 {
00339 for(int i=0;i<16;++i)
00340 val[i] -= m.val[i];
00341 return *this;
00342 }
00343
00344
00345 vuMatrix& vuMatrix::operator*=(const vuMatrix& m)
00346 {
00347 vuMatrix r;
00348 int i, j, k;
00349 for(i=0;i<4;++i)
00350 for(j=0;j<4;++j)
00351 for(k=0;k<4;++k)
00352 r.val[(j<<2)+i] += val[(k<<2)+i] * m.val[(j<<2)+k];
00353 return (*this=r);
00354 }
00355
00356
00357 vuMatrix& vuMatrix::operator*=(float s)
00358 {
00359 for(int i=0;i<16;++i)
00360 val[i] *= s;
00361 return *this;
00362 }
00363
00364
00365 bool vuMatrix::operator==(const vuMatrix& m) const
00366 {
00367 for(int i=0;i<16;++i)
00368 if (val[i] != m.val[i])
00369 return false;
00370 return true;
00371 }
00372
00373
00374 bool vuMatrix::operator!=(const vuMatrix& m) const
00375 {
00376 return !(operator==(m));
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 vuMatrix vuMatrix::inverse(void)
00388 {
00389 vuMatrix result;
00390
00391
00392 float det = (val[2*4+0] * val[3*4+1] - val[3*4+0] * val[2*4+1]) *
00393 (val[0*4+2] * val[1*4+3] - val[1*4+2] * val[0*4+3]) +
00394
00395 (-1) * (val[2*4+0] * val[3*4+2] - val[3*4+0] * val[2*4+2]) *
00396 (val[0*4+1] * val[1*4+3] - val[1*4+1] * val[0*4+3]) +
00397
00398 (val[2*4+1] * val[3*4+2] - val[3*4+1] * val[2*4+2]) *
00399 (val[0*4+0] * val[1*4+3] - val[1*4+0] * val[0*4+3]) +
00400
00401 (-1) * (val[2*4+1] * val[3*4+3] - val[3*4+1] * val[2*4+3]) *
00402 (val[0*4+0] * val[1*4+2] - val[1*4+0] * val[0*4+2]) +
00403
00404 (val[2*4+0] * val[3*4+3] - val[3*4+0] * val[2*4+3]) *
00405 (val[0*4+1] * val[1*4+2] - val[1*4+1] * val[0*4+2]) +
00406
00407 (val[2*4+2] * val[3*4+3] - val[3*4+2] * val[2*4+3]) *
00408 (val[0*4+0] * val[1*4+1] - val[1*4+0] * val[0*4+1]);
00409
00410 result.val[0] = (val[1*4+1] * val[2*4+2] * val[3*4+3] + val[1*4+2] * val[2*4+3] * val[3*4+1] +
00411 val[1*4+3] * val[2*4+1] * val[3*4+2] - val[3*4+1] * val[2*4+2] * val[1*4+3] -
00412 val[3*4+2] * val[2*4+3] * val[1*4+1] - val[3*4+3] * val[2*4+1] * val[1*4+2])
00413 / det;
00414 result.val[1] = -(val[0*4+1] * val[2*4+2] * val[3*4+3] + val[0*4+2] * val[2*4+3] * val[3*4+1] +
00415 val[0*4+3] * val[2*4+1] * val[3*4+2] - val[3*4+1] * val[2*4+2] * val[0*4+3] -
00416 val[3*4+2] * val[2*4+3] * val[0*4+1] - val[3*4+3] * val[2*4+1] * val[0*4+2])
00417 / det;
00418 result.val[2] = (val[0*4+1] * val[1*4+2] * val[3*4+3] + val[0*4+2] * val[1*4+3] * val[3*4+1] +
00419 val[0*4+3] * val[1*4+1] * val[3*4+2] - val[3*4+1] * val[1*4+2] * val[0*4+3] -
00420 val[3*4+2] * val[1*4+3] * val[0*4+1] - val[3*4+3] * val[1*4+1] * val[0*4+2])
00421 / det;
00422 result.val[3] = -(val[0*4+1] * val[1*4+2] * val[2*4+3] + val[0*4+2] * val[1*4+3] * val[2*4+1] +
00423 val[0*4+3] * val[1*4+1] * val[2*4+2] - val[2*4+1] * val[1*4+2] * val[0*4+3] -
00424 val[2*4+2] * val[1*4+3] * val[0*4+1] - val[2*4+3] * val[1*4+1] * val[0*4+2])
00425 / det;
00426
00427
00428 result.val[4] = -(val[1*4+0] * val[2*4+2] * val[3*4+3] + val[1*4+2] * val[2*4+3] * val[3*4+0] +
00429 val[1*4+3] * val[2*4+0] * val[3*4+2] - val[3*4+0] * val[2*4+2] * val[1*4+3] -
00430 val[3*4+2] * val[2*4+3] * val[1*4+0] - val[3*4+3] * val[2*4+0] * val[1*4+2])
00431 / det;
00432 result.val[5] = (val[0*4+0] * val[2*4+2] * val[3*4+3] + val[0*4+2] * val[2*4+3] * val[3*4+0] +
00433 val[0*4+3] * val[2*4+0] * val[3*4+2] - val[3*4+0] * val[2*4+2] * val[0*4+3] -
00434 val[3*4+2] * val[2*4+3] * val[0*4+0] - val[3*4+3] * val[2*4+0] * val[0*4+2])
00435 / det;
00436 result.val[6] = -(val[0*4+0] * val[1*4+2] * val[3*4+3] + val[0*4+2] * val[1*4+3] * val[3*4+0] +
00437 val[0*4+3] * val[1*4+0] * val[3*4+2] - val[3*4+0] * val[1*4+2] * val[0*4+3] -
00438 val[3*4+2] * val[1*4+3] * val[0*4+0] - val[3*4+3] * val[1*4+0] * val[0*4+2])
00439 / det;
00440 result.val[7] = (val[0*4+0] * val[1*4+2] * val[2*4+3] + val[0*4+2] * val[1*4+3] * val[2*4+0] +
00441 val[0*4+3] * val[1*4+0] * val[2*4+2] - val[2*4+0] * val[1*4+2] * val[0*4+3] -
00442 val[2*4+2] * val[1*4+3] * val[0*4+0] - val[2*4+3] * val[1*4+0] * val[0*4+2])
00443 / det;
00444
00445
00446
00447 result.val[8] = (val[1*4+0] * val[2*4+1] * val[3*4+3] + val[1*4+1] * val[2*4+3] * val[3*4+0] +
00448 val[1*4+3] * val[2*4+0] * val[3*4+1] - val[3*4+0] * val[2*4+1] * val[1*4+3] -
00449 val[3*4+1] * val[2*4+3] * val[1*4+0] - val[3*4+3] * val[2*4+0] * val[1*4+1])
00450 / det;
00451 result.val[9] = -(val[0*4+0] * val[2*4+1] * val[3*4+3] + val[0*4+1] * val[2*4+3] * val[3*4+0] +
00452 val[0*4+3] * val[2*4+0] * val[3*4+1] - val[3*4+0] * val[2*4+1] * val[0*4+3] -
00453 val[3*4+1] * val[2*4+3] * val[0*4+0] - val[3*4+3] * val[2*4+0] * val[0*4+1])
00454 / det;
00455 result.val[10] = (val[0*4+0] * val[1*4+1] * val[3*4+3] + val[0*4+1] * val[1*4+3] * val[3*4+0] +
00456 val[0*4+3] * val[1*4+0] * val[3*4+1] - val[3*4+0] * val[1*4+1] * val[0*4+3] -
00457 val[3*4+1] * val[1*4+3] * val[0*4+0] - val[3*4+3] * val[1*4+0] * val[0*4+1])
00458 / det;
00459 result.val[11] = -(val[0*4+0] * val[1*4+1] * val[2*4+3] + val[0*4+1] * val[1*4+3] * val[2*4+0] +
00460 val[0*4+3] * val[1*4+0] * val[2*4+1] - val[2*4+0] * val[1*4+1] * val[0*4+3] -
00461 val[2*4+1] * val[1*4+3] * val[0*4+0] - val[2*4+3] * val[1*4+0] * val[0*4+1])
00462 / det;
00463
00464
00465
00466
00467 result.val[12] =-(val[1*4+0] * val[2*4+1] * val[3*4+2] + val[1*4+1] * val[2*4+2] * val[3*4+0] +
00468 val[1*4+2] * val[2*4+0] * val[3*4+1] - val[3*4+0] * val[2*4+1] * val[1*4+2] -
00469 val[3*4+1] * val[2*4+2] * val[1*4+0] - val[3*4+2] * val[2*4+0] * val[1*4+1])
00470 / det;
00471 result.val[13] = (val[0*4+0] * val[2*4+1] * val[3*4+2] + val[0*4+1] * val[2*4+2] * val[3*4+0] +
00472 val[0*4+2] * val[2*4+0] * val[3*4+1] - val[3*4+0] * val[2*4+1] * val[0*4+2] -
00473 val[3*4+1] * val[2*4+2] * val[0*4+0] - val[3*4+2] * val[2*4+0] * val[0*4+1])
00474 / det;
00475 result.val[14] = -(val[0*4+0] * val[1*4+1] * val[3*4+2] + val[0*4+1] * val[1*4+2] * val[3*4+0] +
00476 val[0*4+2] * val[1*4+0] * val[3*4+1] - val[3*4+0] * val[1*4+1] * val[0*4+2] -
00477 val[3*4+1] * val[1*4+2] * val[0*4+0] - val[3*4+2] * val[1*4+0] * val[0*4+1])
00478 / det;
00479 result.val[15] = (val[0*4+0] * val[1*4+1] * val[2*4+2] + val[0*4+1] * val[1*4+2] * val[2*4+0] +
00480 val[0*4+2] * val[1*4+0] * val[2*4+1] - val[2*4+0] * val[1*4+1] * val[0*4+2] -
00481 val[2*4+1] * val[1*4+2] * val[0*4+0] - val[2*4+2] * val[1*4+0] * val[0*4+1])
00482 / det;
00483
00484 return result;
00485 }
00486
00487
00488
00489
00490 void swap(float& a, float& b)
00491 {
00492 float temp = a;
00493 a = b;
00494 b = temp;
00495 }
00496
00497 void vuMatrix::invertRotationMatrix()
00498
00499
00500 {
00501 swap((val[1]), (val[4]));
00502 swap((val[2]), (val[8]));
00503 swap((val[6]), (val[9]));
00504 }