Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

matrix.h

Go to the documentation of this file.
00001 /*
00002  * Vega Strike
00003  * Copyright (C) 2001-2002 Alan Shieh Rewritten by Daniel Horn for Double precision
00004  *
00005  * http://vegastrike.sourceforge.net/
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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         //                M(0,3)=0;
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         //                M(1,3)=0;
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         //                M(2,3)=0;
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 //these vectors are going to be just normals...
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 //Row, COl
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         //          M(0,3)=0;
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         //                M(1,3)=0;
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         //                M(2,3)=0;
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

Generated on Mon Jul 7 21:13:44 2003 for Ethereal by doxygen1.2.15