00001 #ifndef __VECMATH_MATRIX3_HPP
00002 #define __VECMATH_MATRIX3_HPP
00003
00004 #include <vecmath/Export>
00005 template <class Type> class VECMATH_EXPORT _Matrix3;
00006
00007 #ifndef __VECMATH_VECTOR3_HPP
00008 #include <vecmath/_Vector3.h>
00009 #endif
00010
00011 #ifndef __VECMATH_VECTOR4_HPP
00012 #include <vecmath/_Vector4.h>
00013 #endif
00014
00015 #ifndef __VECMATH_QUAT4_HPP
00016 #include <vecmath/_Quat4.h>
00017 #endif
00018
00019
00020
00021
00022
00023
00024
00025 #define DEBUGMATRIX3(d)
00026
00027
00028
00029
00030 template <class Type> class VECMATH_EXPORT _Matrix3 {
00031 public:
00032 static const Type EPS;
00033 static const Type ERR_EPS;
00034
00035 Type m00, m01, m02,
00036 m10, m11, m12,
00037 m20, m21, m22;
00038
00039 _Matrix3<Type>() {}
00040
00041 _Matrix3<Type>(Type s) {
00042 set(s);
00043 DEBUGMATRIX3(cout << "_Matrix3 constructor scale " << endl << *this << endl);
00044 }
00045
00046
00047
00048 explicit _Matrix3<Type>(Type m00 , Type m01 = 0, Type m02 = 0,
00049 Type m10 = 0, Type m11 = 0, Type m12 = 0,
00050 Type m20 = 0, Type m21 = 0, Type m22 = 0) {
00051 set(m00, m01, m02,
00052 m10, m11, m12,
00053 m20, m21, m22);
00054 DEBUGMATRIX3(cout << "_Matrix3 constructor R9 " << endl << *this << endl);
00055 }
00056
00057 _Matrix3<Type>(const _Matrix3<double>& m) {
00058 set(m);
00059 DEBUGMATRIX3(cout << "_Matrix3 constructor &double " << endl << *this << endl);
00060 }
00061
00062 _Matrix3<Type>(const _Matrix3<float>& m) {
00063 set(m);
00064 DEBUGMATRIX3(cout << "_Matrix3 constructor &float " << endl << *this << endl);
00065 }
00066
00067 _Matrix3<Type>(const Type v[9]) {
00068 set(v);
00069 DEBUGMATRIX3(cout << "_Matrix3 constructor t[9] " << endl << *this << endl);
00070 }
00071
00072 #if 0
00073
00074 _Matrix3<Type>(const _AxisAngle4<double>& a) {
00075 set(a);
00076 DEBUGMATRIX3(cout << "_Matrix3 constructor &AxisAngle4d " << endl << *this << endl);
00077 }
00078
00079 _Matrix3<Type>(const _AxisAngle4<float>& a) {
00080 set(a);
00081 DEBUGMATRIX3(cout << "_Matrix3 constructor &AxisAngle4f " << endl << *this << endl);
00082 }
00083 #endif
00084
00085 void add(Type d);
00086 void add(Type d, const _Matrix3<Type>& m);
00087 void add(const _Matrix3<Type>& m);
00088 void add(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00089
00090 static void compute_svd(double ad[], double ad1[], double ad2[], bool flag);
00091
00092 Type determinant(void) const {
00093 return determinant3x3(m00, m01, m02, m10, m11, m12, m20, m21, m22);
00094 }
00095
00096 bool epsilonEquals(const _Matrix3<Type>& m, Type d) const;
00097 bool equals(const _Matrix3<Type>& m) const;
00098 void getColumn(int column, _Vector3<Type>& v) const;
00099 void getColumn(int column, Type ad[]) const;
00100 Type getElement(int row, int column) const;
00101 void getRow(int row, _Vector3<Type>& v) const;
00102 void getRow(int row, Type ad[3]) const;
00103
00104 void get(float ad[9]) const {
00105 ad[0] = m00;
00106 ad[1] = m01;
00107 ad[2] = m02;
00108 ad[3] = m10;
00109 ad[4] = m11;
00110 ad[5] = m12;
00111 ad[6] = m20;
00112 ad[7] = m21;
00113 ad[8] = m22;
00114 }
00115
00116 void get(double ad[9]) const {
00117 ad[0] = m00;
00118 ad[1] = m01;
00119 ad[2] = m02;
00120 ad[3] = m10;
00121 ad[4] = m11;
00122 ad[5] = m12;
00123 ad[6] = m20;
00124 ad[7] = m21;
00125 ad[8] = m22;
00126 }
00127
00128 Type getScale() const {
00129 double tmp_scale[3];
00130 double tmp_rot[9];
00131 getScaleRotate(tmp_scale, tmp_rot);
00132 return Math::max3(tmp_scale);
00133 }
00134
00135 void getScaleRotate(double ad[3], double ad1[9]) const {
00136 double tmp[9];
00137
00138 get(tmp);
00139 compute_svd(tmp, ad, ad1, false);
00140 }
00141
00142 void invert() {
00143 invert(*this);
00144 }
00145
00146 void invert(const _Matrix3<Type>& m);
00147
00148 void mul(Type d);
00149 void mul(Type d, const _Matrix3<Type>& m);
00150
00151 void mul(const _Matrix3<Type>& m) {
00152 mul(*this, m);
00153 }
00154
00155 void mul(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00156
00157 void mulNormalize(const _Matrix3<Type>& m) {
00158 mulNormalize(*this, m);
00159 }
00160
00161 void mulNormalize(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00162 void mulTransposeBoth(const _Matrix3<Type> m, const _Matrix3<Type>& m1);
00163 void mulTransposeLeft(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00164 void mulTransposeRight(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00165
00166 void negate() {
00167 negate(*this);
00168 }
00169
00170 void negate(const _Matrix3<Type>& m);
00171 void normalize();
00172 void normalize(const _Matrix3<Type>& m);
00173
00174 void normalizeCP() {
00175 normalizeCP(*this);
00176 }
00177
00178 void normalizeCP(const _Matrix3<Type>& m);
00179 void rotX(Type angle);
00180 void rotY(Type angle);
00181 void rotZ(Type angle);
00182
00183 void set(Type mm00, Type mm01, Type mm02,
00184 Type mm10, Type mm11, Type mm12,
00185 Type mm20, Type mm21, Type mm22) {
00186 m00 = mm00, m01 = mm01, m02 = mm02;
00187 m10 = mm10, m11 = mm11, m12 = mm12;
00188 m20 = mm20, m21 = mm21, m22 = mm22;
00189 }
00190
00191 void set(Type d) {
00192 set(d , 0.0, 0.0,
00193 0.0, d, 0.0,
00194 0.0, 0.0, d);
00195 }
00196
00197 #if 0
00198 void set(const _AxisAngle4<double>& aa) {
00199 setAxisAngle(aa.x, aa.y, aa.z, aa.angle);
00200 }
00201
00202 void set(const _AxisAngle4<float>& aa) {
00203 setAxisAngle(aa.x, aa.y, aa.z, aa.angle);
00204 }
00205 #endif
00206
00207 public:
00208 void set(const _Matrix3<double>& m) {
00209 set(m.m00, m.m01, m.m02,
00210 m.m10, m.m11, m.m12,
00211 m.m20, m.m21, m.m22);
00212 }
00213
00214 void set(const _Matrix3<float>& m) {
00215 set(m.m00, m.m01, m.m02,
00216 m.m10, m.m11, m.m12,
00217 m.m20, m.m21, m.m22);
00218 }
00219
00220 #if 0
00221
00222 void set(const _Matrix4<double>& m) {
00223 set(m.m00, m.m01, m.m02,
00224 m.m10, m.m11, m.m12,
00225 m.m20, m.m21, m.m22);
00226 }
00227
00228
00229 void set(const _Matrix4<float>& m) {
00230 set(m.m00, m.m01, m.m02,
00231 m.m10, m.m11, m.m12,
00232 m.m20, m.m21, m.m22);
00233 }
00234 #endif
00235
00236 void set(const _Quat4<double>& q) {
00237 setQuat(q.x, q.y, q.z, q.w);
00238 }
00239
00240 void set(const _Quat4<float>& q) {
00241 setQuat(q.x, q.y, q.z, q.w);
00242 }
00243
00244 void set(const double at[9]) {
00245 set(at[0], at[1], at[2],
00246 at[3], at[4], at[5],
00247 at[6], at[7], at[8]);
00248 }
00249
00250 void set(const float at[9]) {
00251 set(at[0], at[1], at[2],
00252 at[3], at[4], at[5],
00253 at[6], at[7], at[8]);
00254 }
00255
00256 void setColumn(int column, Type x, Type y, Type z) {
00257 switch (column) {
00258 case 0:
00259 m00 = x;
00260 m10 = y;
00261 m20 = z;
00262 break;
00263 case 1:
00264 m01 = x;
00265 m11 = y;
00266 m21 = z;
00267 break;
00268 case 2:
00269 m02 = x;
00270 m12 = y;
00271 m22 = z;
00272 break;
00273 default:
00274 break;
00275 }
00276 }
00277
00278 void setColumn(int column, const _Vector3<Type>& at) {
00279 switch(column) {
00280 case 0:
00281 m00 = at.x;
00282 m10 = at.y;
00283 m20 = at.z;
00284 break;
00285 case 1:
00286 m01 = at.x;
00287 m11 = at.y;
00288 m21 = at.z;
00289 break;
00290 case 2:
00291 m02 = at.x;
00292 m12 = at.y;
00293 m22 = at.z;
00294 break;
00295 default:
00296 break;
00297 }
00298 }
00299
00300 void setColumn(int column, const Type v[3]) {
00301 switch(column) {
00302 case 0:
00303 m00 = v[0];
00304 m10 = v[1];
00305 m20 = v[2];
00306 break;
00307 case 1:
00308 m01 = v[0];
00309 m11 = v[1];
00310 m21 = v[2];
00311 break;
00312 case 2:
00313 m02 = v[0];
00314 m12 = v[1];
00315 m22 = v[2];
00316 break;
00317 default:
00318 break;
00319 }
00320 }
00321
00322 void setElement(int row, int column, Type value) {
00323 switch(row) {
00324 case 0:
00325 switch(column) {
00326 case 0: m00 = value; break;
00327 case 1: m01 = value; break;
00328 case 2: m02 = value; break;
00329 }
00330 break;
00331 case 1:
00332 switch(column) {
00333 case 0: m10 = value; break;
00334 case 1: m11 = value; break;
00335 case 2: m12 = value; break;
00336 }
00337 break;
00338 case 2:
00339 switch(column) {
00340 case 0: m20 = value; break;
00341 case 1: m21 = value; break;
00342 case 2: m22 = value; break;
00343 }
00344 break;
00345 }
00346 }
00347
00348 void setIdentity() {
00349 set(1.0);
00350 }
00351
00352 void setRow(int row, Type x, Type y, Type z);
00353 void setRow(int row, const _Vector3<Type>& v);
00354 void setRow(int row, const Type v[]);
00355
00356 void setScale(Type d) {
00357 double tmp_scale[3];
00358 double tmp_rot[9];
00359 getScaleRotate(tmp_scale, tmp_rot);
00360 set(tmp_rot[0] * d, tmp_rot[1] * d, tmp_rot[2] * d,
00361 tmp_rot[3] * d, tmp_rot[4] * d, tmp_rot[5] * d,
00362 tmp_rot[6] * d, tmp_rot[7] * d, tmp_rot[8] * d);
00363 }
00364
00365 void setZero() {
00366 set(0.0);
00367 }
00368
00369 void sub(const _Matrix3<Type>& m);
00370 void sub(const _Matrix3<Type>& m, const _Matrix3<Type>& m1);
00371
00372
00373 void set(const _Vector3<Type>& v) {
00374 set(v.x, 0.0, 0.0,
00375 0.0, v.y, 0.0,
00376 0.0, 0.0, v.z);
00377 }
00378
00379
00380 void swapRow(int row1, int row2) {
00381 if (row1 > row2)
00382 Math::swap(row1, row2);
00383 else if (row1 == row2)
00384 return;
00385
00386 if (row1 < row2) {
00387 if (row1 == 0) {
00388 if (row2 == 1) {
00389 Math::swap(m00, m10);
00390 Math::swap(m01, m11);
00391 Math::swap(m02, m12);
00392 } else {
00393 Math::swap(m00, m20);
00394 Math::swap(m01, m21);
00395 Math::swap(m02, m22);
00396 }
00397 } else {
00398 Math::swap(m10, m20);
00399 Math::swap(m11, m21);
00400 Math::swap(m12, m22);
00401 }
00402 }
00403 }
00404
00405
00406 void swapColumn(int col1, int col2) {
00407 if (col1 > col2)
00408 Math::swap(col1, col2);
00409 else if (col1 == col2)
00410 return;
00411
00412 if (col1 < col2) {
00413 if (col1 == 0) {
00414 if (col2 == 1) {
00415 Math::swap(m00, m01);
00416 Math::swap(m10, m11);
00417 Math::swap(m20, m21);
00418 } else {
00419 Math::swap(m00, m02);
00420 Math::swap(m10, m12);
00421 Math::swap(m20, m22);
00422 }
00423 } else {
00424 Math::swap(m01, m02);
00425 Math::swap(m11, m12);
00426 Math::swap(m21, m22);
00427 }
00428 }
00429 }
00430
00431
00432
00433
00434
00435 void transform(_Tuple3<Type>& t) const {
00436 transform(t, t);
00437 }
00438
00439 void transform(const _Tuple3<Type>& t, _Tuple3<Type>& t1) const;
00440
00441 void transpose(void) {
00442 Math::swap(m10, m01);
00443 Math::swap(m20, m02);
00444 Math::swap(m12, m21);
00445 }
00446
00447 void transpose(const _Matrix3<Type>& m);
00448
00449 operator const Type * () const {
00450 return &m00;
00451 }
00452
00453 Type& operator ()(int row, int column) const {
00454 return (Type &)(*((operator const Type *()) + row * 3 + column));
00455
00456 }
00457
00458
00459
00460
00461 static Type determinant2x2(Type a, Type b, Type c, Type d) {
00462 return a * d - b * c;
00463 }
00464
00465 static Type determinant3x3(Type a1, Type a2, Type a3,
00466 Type b1, Type b2, Type b3,
00467 Type c1, Type c2, Type c3) {
00468 return (a1 * determinant2x2(b2, b3, c2, c3) -
00469 b1 * determinant2x2(a2, a3, c2, c3) +
00470 c1 * determinant2x2(a2, a3, b2, b3));
00471 }
00472
00473 private:
00474 void setAxisAngle(Type x, Type y, Type z, Type angle);
00475 void setQuat(Type x, Type y, Type z, Type w);
00476 };
00477
00478 #endif