00001 #ifndef _MATRIX_H_
00002 #define _MATRIX_H_
00003
00004 #include<vector>
00005 #include<iostream>
00006 #include"fv_inc.h"
00007 #include"Vec3D.h"
00008 #include"Homogenous.h"
00009 #include"MathHelper.h"
00010
00011 namespace FemViewer {
00012 using namespace fvmath;
00013
00014 template<typename T> class Matrix;
00015
00016 template<typename T>
00017 std::ostream& operator << (std::ostream& strm,const Matrix<T>& mt);
00018
00019 template<typename T = float>
00020 class Matrix {
00021 public:
00022 static Matrix Identity;
00023 private:
00024 bool isIdentity;
00025 public:
00026
00027
00028
00029
00030
00031
00032
00033 std::vector<T> matrix;
00034
00035
00036 Matrix()
00037 {
00038 SetIdentity();
00039 }
00040
00041 Matrix(T v) : matrix(16,v)
00042 { }
00043
00044
00045 Matrix(const Matrix<T> &Tr) : matrix(Tr.matrix)
00046 { }
00047
00048
00049 Matrix& operator = (const Matrix<T> &Tr)
00050 {
00051 if (this != &Tr)
00052 matrix = Tr.matrix;
00053 return *this;
00054 }
00055
00056 bool IsIdentity() const { return isIdentity; }
00057 void SetIdentity()
00058 {
00059 matrix.resize(16, 0);
00060 matrix[0] = matrix[5] = matrix[10] = matrix[15] = T(1);
00061 isIdentity = true;
00062 }
00063
00064 T& operator [](size_t idx) { return matrix[idx]; }
00065 const T& operator [](size_t idx) const { return matrix[idx]; }
00066
00067
00068 Matrix operator + (const Matrix<T> &Tr) const
00069 {
00070 Matrix result(*this);
00071 for(size_t i = 0; i < 16; i++)
00072 result.matrix[i] += Tr.matrix[i];
00073 return result;
00074 }
00075
00076
00077 Matrix operator - (const Matrix<T> &Tr) const
00078 {
00079 Matrix result(*this);
00080 for(size_t i = 0; i < 16; i++)
00081 result.matrix[i] -= Tr.matrix[i];
00082 return result;
00083 }
00084
00085
00086 Matrix operator * (const Matrix<T>& Tr) const
00087 {
00088 Matrix result;
00089 result.matrix[0] = matrix[0]*Tr.matrix[0] + matrix[4]*Tr.matrix[1] + matrix[8]*Tr.matrix[2] + matrix[12]*Tr.matrix[3];
00090 result.matrix[1] = matrix[1]*Tr.matrix[0] + matrix[5]*Tr.matrix[1] + matrix[9]*Tr.matrix[2] + matrix[13]*Tr.matrix[3];
00091 result.matrix[2] = matrix[2]*Tr.matrix[0] + matrix[6]*Tr.matrix[1] + matrix[10]*Tr.matrix[2] + matrix[14]*Tr.matrix[3];
00092 result.matrix[3] = matrix[3]*Tr.matrix[0] + matrix[7]*Tr.matrix[1] + matrix[11]*Tr.matrix[2] + matrix[15]*Tr.matrix[3];
00093
00094 result.matrix[4] = matrix[0]*Tr.matrix[4] + matrix[4]*Tr.matrix[5] + matrix[8]*Tr.matrix[6] + matrix[12]*Tr.matrix[7];
00095 result.matrix[5] = matrix[1]*Tr.matrix[4] + matrix[5]*Tr.matrix[5] + matrix[9]*Tr.matrix[6] + matrix[13]*Tr.matrix[7];
00096 result.matrix[6] = matrix[2]*Tr.matrix[4] + matrix[6]*Tr.matrix[5] + matrix[10]*Tr.matrix[6] + matrix[14]*Tr.matrix[7];
00097 result.matrix[7] = matrix[3]*Tr.matrix[4] + matrix[7]*Tr.matrix[5] + matrix[11]*Tr.matrix[6] + matrix[15]*Tr.matrix[7];
00098
00099 result.matrix[8] = matrix[0]*Tr.matrix[8] + matrix[4]*Tr.matrix[9] + matrix[8]*Tr.matrix[10] + matrix[12]*Tr.matrix[11];
00100 result.matrix[9] = matrix[1]*Tr.matrix[8] + matrix[5]*Tr.matrix[9] + matrix[9]*Tr.matrix[10] + matrix[13]*Tr.matrix[11];
00101 result.matrix[10] = matrix[2]*Tr.matrix[8] + matrix[6]*Tr.matrix[9] + matrix[10]*Tr.matrix[10] + matrix[14]*Tr.matrix[11];
00102 result.matrix[11] = matrix[3]*Tr.matrix[8] + matrix[7]*Tr.matrix[9] + matrix[11]*Tr.matrix[10] + matrix[15]*Tr.matrix[11];
00103
00104 result.matrix[12] = matrix[0]*Tr.matrix[12] + matrix[4]*Tr.matrix[13] + matrix[8]*Tr.matrix[14] + matrix[12]*Tr.matrix[15];
00105 result.matrix[13] = matrix[1]*Tr.matrix[12] + matrix[5]*Tr.matrix[13] + matrix[9]*Tr.matrix[14] + matrix[13]*Tr.matrix[15];
00106 result.matrix[14] = matrix[2]*Tr.matrix[12] + matrix[6]*Tr.matrix[13] + matrix[10]*Tr.matrix[14] + matrix[14]*Tr.matrix[15];
00107 result.matrix[15] = matrix[3]*Tr.matrix[12] + matrix[7]*Tr.matrix[13] + matrix[11]*Tr.matrix[14] + matrix[15]*Tr.matrix[15];
00108
00109 return result;
00110 }
00111
00112
00113 Matrix& operator += (const Matrix<T> &Tr)
00114 {
00115 for(size_t i = 0; i < 16; i++)
00116 matrix[i] += Tr.matrix[i];
00117 return *this;
00118 }
00119
00120
00121 Matrix& operator -= (const Matrix<T> &Tr)
00122 {
00123 for(size_t i = 0; i < 16; i++)
00124 matrix[i] -= Tr.matrix[i];
00125 return *this;
00126 }
00127
00128
00129 Matrix& operator *= (T constant)
00130 {
00131 for(size_t i = 0; i < 16; i++)
00132 matrix[i] *= constant;
00133 return *this;
00134 }
00135
00136
00137 Matrix& operator /= (T constant)
00138 {
00139 for(size_t i = 0; i < 16; i++)
00140 matrix[i] /= constant;
00141 return *this;
00142 }
00143
00144
00145 Vec3D operator * (const Vec3D& dc) const
00146 {
00147 float w = matrix[3] * dc[0] + matrix[7] * dc[1] + matrix[11] * dc[2] + matrix[15];
00148
00149
00150 return Vec3D(
00151 (matrix[0] * dc[0] + matrix[4] * dc[1] + matrix[ 8] * dc[2] + matrix[12]) / w,
00152 (matrix[1] * dc[0] + matrix[5] * dc[1] + matrix[ 9] * dc[2] + matrix[13]) / w,
00153 (matrix[2] * dc[0] + matrix[6] * dc[1] + matrix[10] * dc[2] + matrix[14]) / w);
00154 }
00155
00156 CVec3<T> operator * (const Vec3<T>& dc) const
00157 {
00158 T w = this->matrix[3] * dc.x + this->matrix[7] * dc.y + this->matrix[11] * dc.z + this->matrix[15];
00159 T inv_w = 1 / w;
00160
00161
00162 return CVec3<T>(
00163 (this->matrix[0] * dc.x + this->matrix[4] * dc.y + this->matrix[ 8] * dc.z + this->matrix[12]) * inv_w,
00164 (this->matrix[1] * dc.x + this->matrix[5] * dc.y + this->matrix[ 9] * dc.z + this->matrix[13]) * inv_w,
00165 (this->matrix[2] * dc.x + this->matrix[6] * dc.y + this->matrix[10] * dc.z + this->matrix[14]) * inv_w);
00166 }
00167
00168
00169 Homogenous operator * (const Homogenous &hc) const
00170 {
00171 float w = matrix[3] * hc.x + matrix[7] * hc.y + matrix[11] * hc.z + matrix[15];
00172
00173
00174 return Homogenous(
00175 (matrix[0] * hc.x + matrix[4] * hc.y + matrix[ 8] * hc.z + matrix[12]) / w,
00176 (matrix[1] * hc.x + matrix[5] * hc.y + matrix[ 9] * hc.z + matrix[13]) / w,
00177 (matrix[2] * hc.x + matrix[6] * hc.y + matrix[10] * hc.z + matrix[14]) / w);
00178 }
00179
00180
00181 void make3x3(T* out) const
00182 {
00183 int i(0);
00184 do {
00185 if (i == 3 || i == 7) i++;
00186 *out++ = matrix[i++];
00187 } while (i<11);
00188 }
00189
00190 void LoadIdentity()
00191 {
00192 for (size_t i = 0; i < 16; i++)
00193 matrix[i] = (i % 5) ? 0.0f : 1.0f;
00194 }
00195
00196 void LoadNullMatrix()
00197 {
00198 for (size_t i = 0; i < 16; i++)
00199 matrix[i] = 0.0f;
00200 }
00201
00202 void SetScalefactors(const T& sx, const T&sy, const T& sz)
00203 {
00204 matrix[0] = sx;
00205 matrix[5] = sy;
00206 matrix[10] = sz;
00207 }
00208
00209 void SetTransformationFactors(const Vec3<T>& coef)
00210 {
00211 matrix[12] = coef.x;
00212 matrix[13] = coef.y;
00213 matrix[14] = coef.z;
00214 }
00215
00216
00217 bool IsSingular() const;
00218
00219
00220 void Apply() const
00221 {
00222 glMultMatrixf(&matrix[0]);
00223 }
00224
00225
00226 virtual ~Matrix()
00227 {
00228 matrix.clear();
00229 }
00230
00231
00232 void rotateAbout(const float *coord, const float angle);
00233
00234
00235 void scale(const Vec3D& vec);
00236
00237
00238 void translate(const Vec3D& vec);
00239
00240
00241 Matrix Invers() const;
00242
00243 static Matrix LookAt(const fvmath::Vec3<T>& eye,
00244 const fvmath::Vec3<T>& center,
00245 const fvmath::Vec3<T>& up)
00246 {
00247 fvmath::CVec3<T> d = center - eye;
00248 Normalize(d);
00249 fvmath::CVec3<T> u(up);
00250 Normalize(u);
00251 fvmath::CVec3<T> s = d * u;
00252 u = s * d;
00253
00254
00255
00256 Matrix<T> Result;
00257 Result[0] = s.x;
00258 Result[4] = s.y;
00259 Result[8] = s.z;
00260 Result[1] = u.x;
00261 Result[5] = u.y;
00262 Result[9] = u.z;
00263 Result[2] =-d.x;
00264 Result[6] =-d.y;
00265 Result[10] =-d.z;
00266 Result[12] =-Dot(s, eye);
00267 Result[13] =-Dot(u, eye);
00268 Result[14] = Dot(d, eye);
00269
00270 return Result;
00271 }
00272
00273
00274 friend std::ostream& operator << <>(std::ostream& strm,const Matrix& mt);
00275 };
00276
00277 template<typename T>
00278 Matrix<T> Matrix<T>::Identity;
00279
00280
00281 template<typename T>
00282 inline Matrix<T> operator * (T lhs, const Matrix<T> &rhs)
00283 {
00284
00285 Matrix<T> result(rhs);
00286 for(typename std::vector<T>::iterator i = result.matrix.begin(); i < result.matrix.end(); i++)
00287 *i *= lhs;
00288 return result;
00289 }
00290
00291
00292 template<typename T>
00293 inline Matrix<T> operator * (const Matrix<T> &lhs, T rhs)
00294 {
00295 Matrix<T> result(lhs);
00296 for(typename std::vector<T>::iterator i = result.matrix.begin(); i < result.matrix.end(); i++)
00297 *i *= rhs;
00298 return result;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 template<typename T>
00313 inline std::istream& operator >> (std::istream& lhs, Matrix<T>& transformation)
00314 {
00315 lhs >> transformation.matrix[0];
00316 for(size_t i = 1; i < 16; i++)
00317 lhs >> transformation.matrix[i];
00318 return lhs;
00319 }
00320
00321 template<typename T>
00322 std::ostream & operator << (std::ostream& strm,const Matrix<T>& mt)
00323 {
00324 strm << "matrix: \n"
00325 << "m[0] = "<< mt.matrix[0] << " m[4] = " << mt.matrix[4] << " m[ 8] = " << mt.matrix[ 8] << " m[12] = " << mt.matrix[12] << std::endl
00326 << "m[1] = "<< mt.matrix[1] << " m[5] = " << mt.matrix[5] << " m[ 9] = " << mt.matrix[ 9] << " m[13] = " << mt.matrix[13] << std::endl
00327 << "m[2] = "<< mt.matrix[2] << " m[6] = " << mt.matrix[6] << " m[10] = " << mt.matrix[10] << " m[14] = " << mt.matrix[14] << std::endl
00328 << "m[3] = "<< mt.matrix[3] << " m[7] = " << mt.matrix[7] << " m[11] = " << mt.matrix[11] << " m[15] = " << mt.matrix[15] << std::endl;
00329 return strm;
00330 }
00331
00332
00333 typedef Matrix<float> Matrixf;
00334 typedef Matrix<double> Matrixd;
00335
00336 }
00337 #endif