00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _BASE_MATRIX4_
00026 #define _BASE_MATRIX4_
00027
00028 #include <iostream>
00029
00030 #include <base/base>
00031 #include <base/Object>
00032 #include <base/consts>
00033 #include <base/Vector3>
00034 #include <base/Point3>
00035 #include <base/Vector4>
00036 #include <base/Matrix3>
00037
00038 #ifdef USE_OSG
00039 #include <osg/Matrix>
00040 #endif
00041
00042
00043 #define MATRIX4_ACCESS(r,c) (4*(c-1)+r-1)
00044
00045
00046 namespace base {
00047
00048 class Matrix4;
00049
00050
00051
00052
00053 struct M4V4mul {
00054 const Matrix4& m;
00055 const Vector4& v;
00056
00057 M4V4mul(const Matrix4& mm, const Vector4& vv) : m(mm), v(vv) {}
00058
00059 operator Vector4() const;
00060 };
00061
00062 struct M4V4mulV4add {
00063 const Matrix4& m;
00064 const Vector4& v;
00065 const Vector4& v2;
00066
00067 M4V4mulV4add(const M4V4mul& mv, const Vector4& vv) : m(mv.m), v(mv.v), v2(vv) {}
00068
00069 operator Vector4() const;
00070 };
00071
00072
00073
00074
00075
00076
00077 class Matrix4
00078 {
00079
00080 public:
00081 Matrix4() { setIdentity(); }
00082 Matrix4(const Matrix4& m) { this->operator=(m); }
00083 Matrix4(const Matrix3& m)
00084 {
00085 e(1,1)=m.e(1,1); e(1,2)=m.e(1,2); e(1,3)=m.e(1,3); e(1,4)=0;
00086 e(2,1)=m.e(2,1); e(2,2)=m.e(2,2); e(2,3)=m.e(2,3); e(2,4)=0;
00087 e(3,1)=m.e(3,1); e(3,2)=m.e(3,2); e(3,3)=m.e(3,3); e(3,4)=0;
00088 e(4,1) = e(4,2) = e(4,3) = 0; e(4,4) = 1;
00089 }
00090 explicit Matrix4(const Real& s) { setDiag(s); }
00091 Matrix4(Real e11, Real e12, Real e13, Real e14,
00092 Real e21, Real e22, Real e23, Real e24,
00093 Real e31, Real e32, Real e33, Real e34,
00094 Real e41, Real e42, Real e43, Real e44)
00095 {
00096 e(1,1)=e11; e(1,2)=e12; e(1,3)=e13; e(1,4)=e14;
00097 e(2,1)=e21; e(2,2)=e22; e(2,3)=e23; e(2,4)=e24;
00098 e(3,1)=e31; e(3,2)=e32; e(3,3)=e33; e(3,4)=e34;
00099 e(4,1)=e41; e(4,2)=e42; e(4,3)=e43; e(4,4)=e44;
00100 }
00101 Matrix4(const Matrix3& orientation, const Point3& translation)
00102 {
00103 const Matrix3& m(orientation);
00104 e(1,1)=m.e(1,1); e(1,2)=m.e(1,2); e(1,3)=m.e(1,3); e(1,4)=translation.x;
00105 e(2,1)=m.e(2,1); e(2,2)=m.e(2,2); e(2,3)=m.e(2,3); e(2,4)=translation.y;
00106 e(3,1)=m.e(3,1); e(3,2)=m.e(3,2); e(3,3)=m.e(3,3); e(3,4)=translation.z;
00107 e(4,1) = e(4,2) = e(4,3) = 0; e(4,4) = 1;
00108 }
00109
00110
00111 #ifdef USE_OSG
00112 Matrix4(const osg::Matrix& matrix)
00113 {
00114 #ifdef OSG_USE_DOUBLE_MATRICES
00115 typedef double osgreal;
00116 #else
00117 typedef float osgreal;
00118 #endif
00119
00120 const osgreal* mat = matrix.ptr();
00121 for(Int e=0; e<16; e++)
00122 m[e] = mat[e];
00123 }
00124 #endif
00125 ~Matrix4() {}
00126
00127
00128 Matrix4& setIdentity() throw()
00129 {
00130 setDiag(Real(1)); return *this;
00131 }
00132
00133 Matrix4& setZero() throw()
00134 {
00135 setDiag(Real(0)); return *this;
00136 }
00137
00138
00139 Real& e(Int row, Int col) throw()
00140 {
00141 Assertm( !((row < 1) || (row > 4) || (col < 1) || (col > 4)), "matrix row and col within bounds (debug only check)");
00142 return m[MATRIX4_ACCESS(row,col)];
00143 }
00144
00145 const Real& e(Int row, Int col) const throw()
00146 {
00147 Assertm( !((row < 1) || (row > 4) || (col < 1) || (col > 4)), "matrix row and col within bounds (debug only check)");
00148 return m[MATRIX4_ACCESS(row,col)];
00149 }
00150
00151 Real& at(Int row, Int col) throw(std::out_of_range)
00152 {
00153 if ((row < 1) || (row > 4) || (col < 1) || (col > 4))
00154 throw std::out_of_range(Exception("matrix row or col out of bounds"));
00155
00156 return m[MATRIX4_ACCESS(row,col)];
00157 }
00158
00159 const Real& at(Int row, Int col) const throw(std::out_of_range)
00160 {
00161 if ((row < 1) || (row > 4) || (col < 1) || (col > 4))
00162 throw std::out_of_range(Exception("matrix row or col out of bounds"));
00163
00164 return m[MATRIX4_ACCESS(row,col)];
00165 }
00166
00167 Real& operator()(Int row, Int col) throw()
00168 {
00169 #ifdef DEBUG
00170 return at(row,col);
00171 #else
00172 return e(row,col);
00173 #endif
00174 }
00175
00176 const Real& operator()(Int row, Int col) const throw()
00177 {
00178 #ifdef DEBUG
00179 return at(row,col);
00180 #else
00181 return e(row,col);
00182 #endif
00183 }
00184
00185
00186 Vector4 row(Int row) const
00187 { return Vector4(e(row,1),e(row,2),e(row,3),e(row,4)); }
00188
00189 Vector4 column(Int col) const
00190 { return Vector4(e(1,col),e(2,col),e(3,col),e(4,col)); }
00191
00192 void setRow(Int row, const Vector3& r) throw()
00193 { e(row,1)=r.x; e(row,2)=r.y; e(row,3)=r.z; }
00194
00195 void setRow(Int row, const Vector4& r) throw()
00196 { e(row,1)=r.x; e(row,2)=r.y; e(row,3)=r.z; e(row,4)=r.w; }
00197
00198 void setColumn(Int col, const Vector3& c) throw()
00199 { e(1,col)=c.x; e(2,col)=c.y; e(3,col)=c.z; }
00200
00201 void setColumn(Int col, const Vector4& c) throw()
00202 { e(1,col)=c.x; e(2,col)=c.y; e(3,col)=c.z; e(4,col)=c.w; }
00203
00204 void swapColumns(Int col1, Int col2) throw(std::out_of_range)
00205 {
00206 if ((col1 < 1) || (col1 > 4) || (col2 < 1) || (col2 > 4))
00207 throw std::out_of_range(Exception("matrix col out of bounds"));
00208
00209 Vector4 tmp(column(col1));
00210 setColumn(col1,column(col2));
00211 setColumn(col2,tmp);
00212 }
00213
00214 void swapRows(Int row1, Int row2) throw(std::out_of_range)
00215 {
00216 if ((row1 < 1) || (row1 > 4) || (row2 < 1) || (row2 > 4))
00217 throw std::out_of_range(Exception("matrix row out of bounds"));
00218
00219 Vector4 tmp(row(row1));
00220 setRow(row1,row(row2));
00221 setRow(row2,tmp);
00222 }
00223
00224
00225 Vector4 operator[](Int r) const
00226 { return row(r); }
00227
00228
00229 int index(Int row, Int col) const throw()
00230 { return MATRIX4_ACCESS(row,col); }
00231
00232 Matrix4& operator=(const Matrix4& src) throw()
00233 {
00234 if (&src != this)
00235 for(int i=0; i<16; i++)
00236 m[i] = src.m[i];
00237 return *this;
00238 }
00239
00240
00241 bool operator==(const Matrix4& m1) const throw()
00242 {
00243 for(int i=0; i<16; i++)
00244 if (m1.m[i]!=m[i]) return false;
00245 return true;
00246 }
00247
00248 bool equals(const Matrix4& m1, Real epsilon = consts::epsilon) const throw()
00249 {
00250 for(int i=0; i<16; i++)
00251 if (!base::equals(m1.m[i],m[i],epsilon)) return false;
00252 return true;
00253 }
00254
00255
00256 void setToTranslation(const Vector3& trans);
00257 void setTranslationComponent(const Vector3& trans);
00258 Vector3 getTranslationComponent() const { return Vector3(e(1,4),e(2,4),e(3,4)); }
00259 void setRotationAboutZ(Real angle);
00260
00261 Matrix4& transpose();
00262 Matrix4& invert();
00263 Matrix4& negate() throw();
00264
00265
00266
00267 void decomposeLUP(Matrix4& L, Matrix4& U, Vector4& Pi) const;
00268
00269
00270 Vector4 solve(const Vector4& b) const;
00271
00272
00273 Matrix4& operator*=(const Matrix4& m2);
00274 Matrix4& operator+=(const Matrix4& m2);
00275 Matrix4& operator-=(const Matrix4& m2);
00276 Matrix4& operator*=(const Real& s);
00277 Matrix4& operator/=(const Real& s);
00278
00279 operator Matrix3() const;
00280 #ifdef USE_OSG
00281 operator osg::Matrix() const;
00282 #endif
00283
00284 const Real* c_array() const { return m; }
00285 Real* c_array() { return m; }
00286
00287
00288 static Vector4 solveLUP(const Matrix4& L, const Matrix4& U, const Vector4& Pi, const Vector4& b);
00289
00290 static void decomposeLUP(const Matrix4& A, Matrix4& L, Matrix4& U, Vector4& Pi)
00291 { A.decomposeLUP(L,U,Pi); }
00292
00293
00294 static Vector4 matrixMulVector(const Matrix4& m, const Vector4& v);
00295 static Vector4 matrixMulVectorAddVector(const Matrix4& m, const Vector4& v, const Vector4& v2);
00296 static Vector4 matrixMulVector(const Matrix4& m, const Vector3& v);
00297
00298 void serialize(Serializer& s);
00299
00300 private:
00301 Real m[16];
00302
00303 void setDiag(const Real& d)
00304 {
00305 m[0] = d;
00306 m[1] = Real(0);
00307 m[2] = Real(0);
00308 m[3] = Real(0);
00309 m[4] = Real(0);
00310 m[5] = d;
00311 m[6] = Real(0);
00312 m[7] = Real(0);
00313 m[8] = Real(0);
00314 m[9] = Real(0);
00315 m[10] = d;
00316 m[11] = Real(0);
00317 m[12] = Real(0);
00318 m[13] = Real(0);
00319 m[14] = Real(0);
00320 m[15] = d;
00321 }
00322
00323 };
00324
00325
00326
00327
00328
00329 inline Matrix4 operator*(const Matrix4& m1, const Matrix4& m2)
00330 { Matrix4 r(m1); return r *= m2; }
00331
00332 inline Matrix4 operator+(const Matrix4& m1, const Matrix4& m2)
00333 { Matrix4 r(m1); return r += m2; }
00334
00335 inline Matrix4 operator-(const Matrix4& m1, const Matrix4& m2)
00336 { Matrix4 r(m1); return r -= m2; }
00337
00338 inline Matrix4 operator-(const Matrix4& m1)
00339 { Matrix4 r(m1); return r.negate(); }
00340
00341 inline Matrix4 operator*(const Matrix4& m1, const Real& s)
00342 { Matrix4 r(m1); return r *= s; }
00343
00344 inline Matrix4 operator*(const Real& s, const Matrix4& m1)
00345 { Matrix4 r(m1); return r *= s; }
00346
00347 inline Matrix4 operator/(const Matrix4& m1, const Real& s)
00348 { Matrix4 r(m1); return r /= s; }
00349
00350
00351 inline Vector3 operator*(const Matrix4& m1, const Vector3& v)
00352 { Vector4 r(Matrix4::matrixMulVector(m1,v)); return Vector3(r.x,r.y,r.z); }
00353
00354 inline Matrix4 transpose(const Matrix4& m)
00355 { Matrix4 r(m); return r.transpose(); }
00356
00357 inline Matrix4 inverse(const Matrix4& m)
00358 { Matrix4 r(m); return r.invert(); }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 inline M4V4mulV4add operator+(const M4V4mul& mv, const Vector4& vv)
00369 { return M4V4mulV4add(mv,vv); }
00370
00371 inline M4V4mul operator*(const Matrix4& mm, const Vector4& vv)
00372 { return M4V4mul(mm,vv); }
00373
00374 inline M4V4mul::operator Vector4() const
00375 { return Matrix4::matrixMulVector(m,v); }
00376
00377 inline M4V4mulV4add::operator Vector4() const
00378 { return Matrix4::matrixMulVectorAddVector(m,v,v2); }
00379
00380
00381 std::ostream& operator<<(std::ostream& out, const Matrix4& m);
00382
00383
00384 }
00385
00386 #endif
00387