00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _MATRIX_H
00022 #define _MATRIX_H
00023
00024 #include "vec.h"
00025 class Matrix {
00026 private:
00027 float operator [] (int i);
00028 public:
00029 float r[9];
00030 QVector position;
00031 Matrix() {}
00032 QVector& pos(){return position;}
00033 const QVector& pos()const{return position;}
00034 Vector getR() const{return Vector (r[6],r[7],r[8]);}
00035 Vector getQ() const{return Vector (r[3],r[4],r[5]);}
00036 Vector getP() const{return Vector (r[0],r[1],r[2]);}
00037 Matrix (float r0, float r1, float r2, float r3, float r4, float r5, float r6, float r7, float r8, QVector pos) {
00038 r[0]=r0;
00039 r[1]=r1;
00040 r[2]=r2;
00041 r[3]=r3;
00042 r[4]=r4;
00043 r[5]=r5;
00044 r[6]=r6;
00045 r[7]=r7;
00046 r[8]=r8;
00047 position=pos;
00048 }
00049 Matrix(const Vector &v1, const Vector &v2, const Vector &v3):position(0,0,0) {
00050 this->r[0] = v1.i;
00051 this->r[1] = v1.j;
00052 this->r[2] = v1.k;
00053
00054 this->r[3] = v2.i;
00055 this->r[4] = v2.j;
00056 this->r[5] = v2.k;
00057
00058 this->r[6] = v3.i;
00059 this->r[7] = v3.j;
00060 this->r[8] = v3.k;
00061 }
00062 Matrix (const Vector &v1, const Vector & v2, const Vector & v3, const QVector & pos);
00063 Matrix operator * (const Matrix &m2) const;
00064 };
00065
00066 const Matrix identity_matrix (1,0,0,
00067 0,1,0,
00068 0,0,1,
00069 QVector(0,0,0));
00070
00073 inline void ScaleMatrix(Matrix &matrix, const Vector &scale) {
00074 matrix.r[0]*=scale.i;
00075 matrix.r[1]*=scale.i;
00076 matrix.r[2]*=scale.i;
00077 matrix.r[3]*=scale.j;
00078 matrix.r[4]*=scale.j;
00079 matrix.r[5]*=scale.j;
00080 matrix.r[6]*=scale.k;
00081 matrix.r[7]*=scale.k;
00082 matrix.r[8]*=scale.k;
00083 }
00084
00085 inline void VectorAndPositionToMatrix(Matrix &matrix, const Vector &v1, const Vector &v2, const Vector &v3, const QVector &pos) {
00086
00087 matrix.r[0] = v1.i;
00088 matrix.r[1] = v1.j;
00089 matrix.r[2] = v1.k;
00090
00091 matrix.r[3] = v2.i;
00092 matrix.r[4] = v2.j;
00093 matrix.r[5] = v2.k;
00094
00095 matrix.r[6] = v3.i;
00096 matrix.r[7] = v3.j;
00097 matrix.r[8] = v3.k;
00098 matrix.position = pos;
00099 }
00100 inline Matrix::Matrix (const Vector & v1, const Vector & v2, const Vector & v3, const QVector &pos) {
00101 VectorAndPositionToMatrix(*this, v1, v2, v3, pos);
00102 }
00103
00106 inline void Zero(Matrix & matrix)
00107 {
00108 matrix.r[0] = 0;
00109 matrix.r[1] = 0;
00110 matrix.r[2] = 0;
00111 matrix.r[3] = 0;
00112
00113 matrix.r[4] = 0;
00114 matrix.r[5] = 0;
00115 matrix.r[6] = 0;
00116 matrix.r[7] = 0;
00117
00118 matrix.r[8] = 0;
00119 matrix.position.Set(0,0,0);
00120 }
00123 inline void Identity(Matrix &matrix)
00124 {
00125 matrix.r[0] = 1;
00126 matrix.r[1] = 0;
00127 matrix.r[2] = 0;
00128 matrix.r[3] = 0;
00129 matrix.r[4] = 1;
00130 matrix.r[5] = 0;
00131 matrix.r[6] = 0;
00132 matrix.r[7] = 0;
00133 matrix.r[8] = 1;
00134 matrix.position.Set(0,0,0);
00135 }
00139 inline void RotateAxisAngle(Matrix & tmp, const Vector &axis, const float angle) {
00140 float c = cosf (angle);
00141 float s = sinf (angle);
00142 #define M(a,b) (tmp.r[b*3+a])
00143 M(0,0)=axis.i*axis.i*(1-c)+c;
00144 M(0,1)=axis.i*axis.j*(1-c)-axis.k*s;
00145 M(0,2)=axis.i*axis.k*(1-c)+axis.j*s;
00146
00147 M(1,0)=axis.j*axis.i*(1-c)+axis.k*s;
00148 M(1,1)=axis.j*axis.j*(1-c)+c;
00149 M(1,2)=axis.j*axis.k*(1-c)-axis.i*s;
00150
00151 M(2,0)=axis.i*axis.k*(1-c)-axis.j*s;
00152 M(2,1)=axis.j*axis.k*(1-c)+axis.i*s;
00153 M(2,2)=axis.k*axis.k*(1-c)+c;
00154
00155 #undef M
00156 tmp.position.Set (0,0,0);
00157 }
00158
00159 inline void Translate(Matrix &matrix, const QVector &v) {
00160 matrix.r[0] = 1;
00161 matrix.r[1] = 0;
00162 matrix.r[2] = 0;
00163 matrix.r[3] = 0;
00164 matrix.r[4] = 1;
00165 matrix.r[5] = 0;
00166 matrix.r[6] = 0;
00167 matrix.r[7] = 0;
00168 matrix.r[8] = 1;
00169 matrix.position=v;
00170 }
00171
00175 inline void MultMatrix(Matrix &dest, const Matrix & m1, const Matrix &m2)
00176 {
00177 dest.r[0] = m1.r[0]*m2.r[0] + m1.r[3]*m2.r[1] + m1.r[6]*m2.r[2];
00178 dest.r[1] = m1.r[1]*m2.r[0] + m1.r[4]*m2.r[1] + m1.r[7]*m2.r[2];
00179 dest.r[2] = m1.r[2]*m2.r[0] + m1.r[5]*m2.r[1] + m1.r[8]*m2.r[2];
00180
00181 dest.r[3] = m1.r[0]*m2.r[3] + m1.r[3]*m2.r[4] + m1.r[6]*m2.r[5];
00182 dest.r[4] = m1.r[1]*m2.r[3] + m1.r[4]*m2.r[4] + m1.r[7]*m2.r[5];
00183 dest.r[5] = m1.r[2]*m2.r[3] + m1.r[5]*m2.r[4] + m1.r[8]*m2.r[5];
00184
00185
00186 dest.r[6] = m1.r[0]*m2.r[6] + m1.r[3]*m2.r[7] + m1.r[6]*m2.r[8];
00187 dest.r[7] = m1.r[1]*m2.r[6] + m1.r[4]*m2.r[7] + m1.r[7]*m2.r[8];
00188 dest.r[8] = m1.r[2]*m2.r[6] + m1.r[5]*m2.r[7] + m1.r[8]*m2.r[8];
00189
00190 dest.position.i = m1.r[0]*m2.position.i + m1.r[3]*m2.position.j + m1.r[6]*m2.position.k + m1.position.i;
00191 dest.position.j = m1.r[1]*m2.position.i + m1.r[4]*m2.position.j + m1.r[7]*m2.position.k + m1.position.j;
00192 dest.position.k = m1.r[2]*m2.position.i + m1.r[5]*m2.position.j + m1.r[8]*m2.position.k + m1.position.k;
00193
00194 }
00195
00196 inline Matrix Matrix::operator * (const Matrix &m2) const{
00197 Matrix res;
00198 MultMatrix (res,*this,m2);
00199 return res;
00200 }
00201
00205 inline void CopyMatrix(Matrix &dest, const Matrix &source) {
00206 dest = source;
00207 }
00211 inline QVector Transform (const Matrix &t, const QVector & v) {
00212 return QVector (t.position.i+v.i*t.r[0]+v.j*t.r[3]+v.k*t.r[6],
00213 t.position.j+v.i*t.r[1]+v.j*t.r[4]+v.k*t.r[7],
00214 t.position.k+v.i*t.r[2]+v.j*t.r[5]+v.k*t.r[8]);
00215 }
00216 inline Vector Transform (const Matrix &t, const Vector & v) {
00217 return Vector (t.position.i+v.i*t.r[0]+v.j*t.r[3]+v.k*t.r[6],
00218 t.position.j+v.i*t.r[1]+v.j*t.r[4]+v.k*t.r[7],
00219 t.position.k+v.i*t.r[2]+v.j*t.r[5]+v.k*t.r[8]);
00220 }
00221 inline const QVector QVector::Transform(const class Matrix &m1) const {
00222 return ::Transform (m1,*this);
00223 }
00224 inline const Vector Vector::Transform(const class Matrix &m1) const {
00225 QVector ret = ::Transform (m1,QVector (i,j,k));
00226 return Vector (ret.i,ret.j,ret.k);
00227 }
00228
00229
00230 inline Vector InvTransformNormal (const Matrix &t, const Vector & v) {
00231
00232 #define M(A,B) t.r[B*3+A]
00233 return Vector(v.i*M(0,0)+v.j*M(1,0)+v.k*M(2,0),
00234 v.i*M(0,1)+v.j*M(1,1)+v.k*M(2,1),
00235 v.i*M(0,2)+v.j*M(1,2)+v.k*M(2,2));
00236 #undef M
00237 }
00238 inline QVector InvTransformNormal (const Matrix &t, const QVector & v) {
00239
00240 #define M(A,B) t.r[B*3+A]
00241 return QVector(v.i*M(0,0)+v.j*M(1,0)+v.k*M(2,0),
00242 v.i*M(0,1)+v.j*M(1,1)+v.k*M(2,1),
00243 v.i*M(0,2)+v.j*M(1,2)+v.k*M(2,2));
00244 #undef M
00245 }
00246
00247 inline QVector InvTransform (const Matrix &t, const QVector & v) {
00248 return InvTransformNormal (t, QVector (v.i-t.position.i, v.j-t.position.j, v.k-t.position.k));
00249 }
00250 inline Vector InvTransform (const Matrix &t, const Vector & v) {
00251 return InvTransformNormal (t, QVector (v.i-t.position.i, v.j-t.position.j, v.k-t.position.k)).Cast();
00252 }
00253
00254 inline Vector TransformNormal (const Matrix &t, const Vector & v) {
00255 return Vector (v.i*t.r[0]+v.j*t.r[3]+v.k*t.r[6],
00256 v.i*t.r[1]+v.j*t.r[4]+v.k*t.r[7],
00257 v.i*t.r[2]+v.j*t.r[5]+v.k*t.r[8]);
00258 }
00259 inline QVector TransformNormal (const Matrix &t, const QVector & v) {
00260 return QVector (v.i*t.r[0]+v.j*t.r[3]+v.k*t.r[6],
00261 v.i*t.r[1]+v.j*t.r[4]+v.k*t.r[7],
00262 v.i*t.r[2]+v.j*t.r[5]+v.k*t.r[8]);
00263 }
00264
00265 int invert (float b[], float a[]);
00266
00267 inline void MatrixToVectors (const Matrix &m,Vector &p,Vector&q,Vector&r, QVector &c) {
00268 p.Set (m.r[0],m.r[1],m.r[2]);
00269 q.Set (m.r[3],m.r[4],m.r[5]);
00270 r.Set (m.r[6],m.r[7],m.r[8]);
00271 c=m.position;
00272 }
00273
00274 inline QVector InvScaleTransform (const Matrix &trans, QVector pos) {
00275 pos = pos - trans.position;
00276 #define a (trans.r[0])
00277 #define b (trans.r[3])
00278 #define c (trans.r[6])
00279 #define d (trans.r[1])
00280 #define e (trans.r[4])
00281 #define f (trans.r[7])
00282 #define g (trans.r[2])
00283 #define h (trans.r[5])
00284 #define i (trans.r[8])
00285 double factor = 1.0F/(-c*e*g+ b*f*g + c*d*h - a*f*h - b*d*i + a*e*i);
00286 return (QVector(pos.Dot (QVector (e*i- f*h,c*h-b*i,b*f-c*e)),pos.Dot (QVector (f*g-d*i,a*i-c*g, c*d-a*f)),pos.Dot (QVector (d*h-e*g, b*g-a*h, a*e-b*d)))*factor);
00287 #undef a
00288 #undef b
00289 #undef c
00290 #undef d
00291 #undef e
00292 #undef f
00293 #undef g
00294 #undef h
00295 #undef i
00296 }
00297 inline void InvertMatrix (Matrix &o, const Matrix &trans) {
00298 #define a (trans.r[0])
00299 #define b (trans.r[3])
00300 #define c (trans.r[6])
00301 #define d (trans.r[1])
00302 #define e (trans.r[4])
00303 #define f (trans.r[7])
00304 #define g (trans.r[2])
00305 #define h (trans.r[5])
00306 #define i (trans.r[8])
00307 float factor = 1.0F/(-c*e*g+ b*f*g + c*d*h - a*f*h - b*d*i + a*e*i);
00308 o.r[0]=factor*(e*i- f*h);
00309 o.r[3]=factor*(c*h-b*i);
00310 o.r[6]=factor*(b*f-c*e);
00311 o.r[1]=factor*(f*g-d*i);
00312 o.r[4]=factor*(a*i-c*g);
00313 o.r[7]=factor*(c*d-a*f);
00314 o.r[2]=factor*(d*h-e*g);
00315 o.r[5]=factor*(b*g-a*h);
00316 o.r[8]=factor*(a*e-b*d);
00317 #undef a
00318 #undef b
00319 #undef c
00320 #undef d
00321 #undef e
00322 #undef f
00323 #undef g
00324 #undef h
00325 #undef i
00326 o.position= TransformNormal (o,QVector (-trans.position));
00327 }
00328
00329 inline void Rotate (Matrix &tmp, const Vector &axis, float angle) {
00330 double c = cos (angle);
00331 double s = sin (angle);
00332
00333 #define M(a,b) (tmp.r[b*3+a])
00334 M(0,0)=axis.i*axis.i*(1-c)+c;
00335 M(0,1)=axis.i*axis.j*(1-c)-axis.k*s;
00336 M(0,2)=axis.i*axis.k*(1-c)+axis.j*s;
00337
00338 M(1,0)=axis.j*axis.i*(1-c)+axis.k*s;
00339 M(1,1)=axis.j*axis.j*(1-c)+c;
00340 M(1,2)=axis.j*axis.k*(1-c)-axis.i*s;
00341
00342 M(2,0)=axis.i*axis.k*(1-c)-axis.j*s;
00343 M(2,1)=axis.j*axis.k*(1-c)+axis.i*s;
00344 M(2,2)=axis.k*axis.k*(1-c)+c;
00345
00346 #undef M
00347 tmp.position.Set(0,0,0);
00348 }
00349 struct DrawContext {
00350 Matrix m;
00351 class GFXVertexList *vlist;
00352 DrawContext() { }
00353 DrawContext(const Matrix &a, GFXVertexList *vl) :m(a),vlist(vl){}
00354 };
00355
00356 #endif