Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
•All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
matrix.h
Go to the documentation of this file.
1 /*
2  * Vega Strike
3  * Copyright (C) 2001-2002 Alan Shieh Rewritten by Daniel Horn for Double precision
4  *
5  * http://vegastrike.sourceforge.net/
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 #ifndef _MATRIX_H
22 #define _MATRIX_H
23 
24 #include "vec.h"
25 #include "endianness.h"
26 class Matrix
27 {
28 private:
29  float operator[]( int i );
30 public:
31  float r[9];
33 
34  inline Matrix() : p( 0, 0, 0 )
35  {
36  r[0] = r[1] = r[2] = r[3] = r[4] = r[5] = r[6] = r[7] = r[8] = 0;
37  }
38 
39 //Convert the matrix into network byte order
40  void netswap()
41  {
42  for (int i = 0; i < 9; i++)
43  r[i] = VSSwapHostFloatToLittle( r[i] );
44  p.netswap();
45  }
46  inline Vector getR() const
47  {
48  return Vector( r[6], r[7], r[8] );
49  }
50  inline Vector getQ() const
51  {
52  return Vector( r[3], r[4], r[5] );
53  }
54  inline Vector getP() const
55  {
56  return Vector( r[0], r[1], r[2] );
57  }
58  inline Matrix( float r0, float r1, float r2, float r3, float r4, float r5, float r6, float r7, float r8, QVector pos )
59  {
60  r[0] = r0;
61  r[1] = r1;
62  r[2] = r2;
63  r[3] = r3;
64  r[4] = r4;
65  r[5] = r5;
66  r[6] = r6;
67  r[7] = r7;
68  r[8] = r8;
69  p = pos;
70  }
71  inline void InvertRotationInto( Matrix &result ) const
72  {
73  result.r[0] = r[0];
74  result.r[1] = r[3];
75  result.r[2] = r[6];
76  result.r[3] = r[1];
77  result.r[4] = r[4];
78  result.r[5] = r[7];
79  result.r[6] = r[2];
80  result.r[7] = r[5];
81  result.r[8] = r[8];
82  }
83  inline Matrix( const Vector &v1, const Vector &v2, const Vector &v3 ) : p( 0, 0, 0 )
84  {
85  this->r[0] = v1.i;
86  this->r[1] = v1.j;
87  this->r[2] = v1.k;
88 
89  this->r[3] = v2.i;
90  this->r[4] = v2.j;
91  this->r[5] = v2.k;
92 
93  this->r[6] = v3.i;
94  this->r[7] = v3.j;
95  this->r[8] = v3.k;
96  }
97  inline Matrix( const Vector &v1, const Vector &v2, const Vector &v3, const QVector &pos );
98  inline Matrix operator*( const Matrix &m2 ) const;
99 };
100 
101 const Matrix identity_matrix( 1, 0, 0,
102  0, 1, 0,
103  0, 0, 1,
104  QVector( 0, 0, 0 ) );
105 
108 inline void ScaleMatrix( Matrix &matrix, const Vector &scale )
109 {
110  matrix.r[0] *= scale.i;
111  matrix.r[1] *= scale.i;
112  matrix.r[2] *= scale.i;
113  matrix.r[3] *= scale.j;
114  matrix.r[4] *= scale.j;
115  matrix.r[5] *= scale.j;
116  matrix.r[6] *= scale.k;
117  matrix.r[7] *= scale.k;
118  matrix.r[8] *= scale.k;
119 }
120 
121 inline void VectorAndPositionToMatrix( Matrix &matrix, const Vector &v1, const Vector &v2, const Vector &v3, const QVector &pos )
122 {
123  matrix.r[0] = v1.i;
124  matrix.r[1] = v1.j;
125  matrix.r[2] = v1.k;
126 
127  matrix.r[3] = v2.i;
128  matrix.r[4] = v2.j;
129  matrix.r[5] = v2.k;
130 
131  matrix.r[6] = v3.i;
132  matrix.r[7] = v3.j;
133  matrix.r[8] = v3.k;
134  matrix.p = pos;
135 }
136 inline Matrix::Matrix( const Vector &v1, const Vector &v2, const Vector &v3, const QVector &pos )
137 {
138  VectorAndPositionToMatrix( *this, v1, v2, v3, pos );
139 }
140 
143 inline void Zero( Matrix &matrix )
144 {
145  matrix.r[0] = 0;
146  matrix.r[1] = 0;
147  matrix.r[2] = 0;
148  matrix.r[3] = 0;
149 
150  matrix.r[4] = 0;
151  matrix.r[5] = 0;
152  matrix.r[6] = 0;
153  matrix.r[7] = 0;
154 
155  matrix.r[8] = 0;
156  matrix.p.Set( 0, 0, 0 );
157 }
160 inline void Identity( Matrix &matrix )
161 {
162  matrix.r[0] = 1;
163  matrix.r[1] = 0;
164  matrix.r[2] = 0;
165  matrix.r[3] = 0;
166  matrix.r[4] = 1;
167  matrix.r[5] = 0;
168  matrix.r[6] = 0;
169  matrix.r[7] = 0;
170  matrix.r[8] = 1;
171  matrix.p.Set( 0, 0, 0 );
172 }
176 inline void RotateAxisAngle( Matrix &tmp, const Vector &axis, const float angle )
177 {
178  float c = cosf( angle );
179  float s = sinf( angle );
180 #define M( a, b ) (tmp.r[b*3+a])
181  M( 0, 0 ) = axis.i*axis.i*(1-c)+c;
182  M( 0, 1 ) = axis.i*axis.j*(1-c)-axis.k*s;
183  M( 0, 2 ) = axis.i*axis.k*(1-c)+axis.j*s;
184  //M(0,3)=0;
185  M( 1, 0 ) = axis.j*axis.i*(1-c)+axis.k*s;
186  M( 1, 1 ) = axis.j*axis.j*(1-c)+c;
187  M( 1, 2 ) = axis.j*axis.k*(1-c)-axis.i*s;
188  //M(1,3)=0;
189  M( 2, 0 ) = axis.i*axis.k*(1-c)-axis.j*s;
190  M( 2, 1 ) = axis.j*axis.k*(1-c)+axis.i*s;
191  M( 2, 2 ) = axis.k*axis.k*(1-c)+c;
192  //M(2,3)=0;
193 #undef M
194  tmp.p.Set( 0, 0, 0 );
195 }
196 
197 inline void Translate( Matrix &matrix, const QVector &v )
198 {
199  matrix.r[0] = 1;
200  matrix.r[1] = 0;
201  matrix.r[2] = 0;
202  matrix.r[3] = 0;
203  matrix.r[4] = 1;
204  matrix.r[5] = 0;
205  matrix.r[6] = 0;
206  matrix.r[7] = 0;
207  matrix.r[8] = 1;
208  matrix.p = v;
209 }
210 
214 inline void MultMatrix( Matrix &dest, const Matrix &m1, const Matrix &m2 )
215 {
216  dest.r[0] = m1.r[0]*m2.r[0]+m1.r[3]*m2.r[1]+m1.r[6]*m2.r[2];
217  dest.r[1] = m1.r[1]*m2.r[0]+m1.r[4]*m2.r[1]+m1.r[7]*m2.r[2];
218  dest.r[2] = m1.r[2]*m2.r[0]+m1.r[5]*m2.r[1]+m1.r[8]*m2.r[2];
219 
220  dest.r[3] = m1.r[0]*m2.r[3]+m1.r[3]*m2.r[4]+m1.r[6]*m2.r[5];
221  dest.r[4] = m1.r[1]*m2.r[3]+m1.r[4]*m2.r[4]+m1.r[7]*m2.r[5];
222  dest.r[5] = m1.r[2]*m2.r[3]+m1.r[5]*m2.r[4]+m1.r[8]*m2.r[5];
223 
224  dest.r[6] = m1.r[0]*m2.r[6]+m1.r[3]*m2.r[7]+m1.r[6]*m2.r[8];
225  dest.r[7] = m1.r[1]*m2.r[6]+m1.r[4]*m2.r[7]+m1.r[7]*m2.r[8];
226  dest.r[8] = m1.r[2]*m2.r[6]+m1.r[5]*m2.r[7]+m1.r[8]*m2.r[8];
227 
228  dest.p.i = m1.r[0]*m2.p.i+m1.r[3]*m2.p.j+m1.r[6]*m2.p.k+m1.p.i;
229  dest.p.j = m1.r[1]*m2.p.i+m1.r[4]*m2.p.j+m1.r[7]*m2.p.k+m1.p.j;
230  dest.p.k = m1.r[2]*m2.p.i+m1.r[5]*m2.p.j+m1.r[8]*m2.p.k+m1.p.k;
231 }
232 
233 inline Matrix Matrix::operator*( const Matrix &m2 ) const
234 {
235  Matrix res;
236  MultMatrix( res, *this, m2 );
237  return res;
238 }
239 
243 inline void CopyMatrix( Matrix &dest, const Matrix &source )
244 {
245  dest = source;
246 }
250 inline QVector Transform( const Matrix &t, const QVector &v )
251 {
252  return QVector( t.p.i+v.i*t.r[0]+v.j*t.r[3]+v.k*t.r[6],
253  t.p.j+v.i*t.r[1]+v.j*t.r[4]+v.k*t.r[7],
254  t.p.k+v.i*t.r[2]+v.j*t.r[5]+v.k*t.r[8] );
255 }
256 inline Vector Transform( const Matrix &t, const Vector &v )
257 {
258  return Vector( t.p.i+v.i*t.r[0]+v.j*t.r[3]+v.k*t.r[6],
259  t.p.j+v.i*t.r[1]+v.j*t.r[4]+v.k*t.r[7],
260  t.p.k+v.i*t.r[2]+v.j*t.r[5]+v.k*t.r[8] );
261 }
262 inline const QVector QVector::Transform( const class Matrix &m1 ) const
263 {
264  return ::Transform( m1, *this );
265 }
266 inline const Vector Vector::Transform( const class Matrix &m1 ) const
267 {
268  QVector ret = ::Transform( m1, QVector( i, j, k ) );
269  return Vector( ret.i, ret.j, ret.k );
270 }
271 
272 //these vectors are going to be just normals...
273 inline Vector InvTransformNormal( const Matrix &t, const Vector &v )
274 {
275 #define M( A, B ) (t.r[B*3+A])
276  return Vector( v.i*M( 0, 0 )+v.j*M( 1, 0 )+v.k*M( 2, 0 ),
277  v.i*M( 0, 1 )+v.j*M( 1, 1 )+v.k*M( 2, 1 ),
278  v.i*M( 0, 2 )+v.j*M( 1, 2 )+v.k*M( 2, 2 ) );
279 
280 #undef M
281 }
282 inline QVector InvTransformNormal( const Matrix &t, const QVector &v )
283 {
284 #define M( A, B ) (t.r[B*3+A])
285  return QVector( v.i*M( 0, 0 )+v.j*M( 1, 0 )+v.k*M( 2, 0 ),
286  v.i*M( 0, 1 )+v.j*M( 1, 1 )+v.k*M( 2, 1 ),
287  v.i*M( 0, 2 )+v.j*M( 1, 2 )+v.k*M( 2, 2 ) );
288 
289 #undef M
290 }
291 
292 inline QVector InvTransform( const Matrix &t, const QVector &v )
293 {
294  return InvTransformNormal( t, QVector( v.i-t.p.i, v.j-t.p.j, v.k-t.p.k ) );
295 }
296 inline Vector InvTransform( const Matrix &t, const Vector &v )
297 {
298  return InvTransformNormal( t, QVector( v.i-t.p.i, v.j-t.p.j, v.k-t.p.k ) ).Cast();
299 }
300 
301 inline Vector TransformNormal( const Matrix &t, const Vector &v )
302 {
303  return Vector( v.i*t.r[0]+v.j*t.r[3]+v.k*t.r[6],
304  v.i*t.r[1]+v.j*t.r[4]+v.k*t.r[7],
305  v.i*t.r[2]+v.j*t.r[5]+v.k*t.r[8] );
306 }
307 inline QVector TransformNormal( const Matrix &t, const QVector &v )
308 {
309  return QVector( v.i*t.r[0]+v.j*t.r[3]+v.k*t.r[6],
310  v.i*t.r[1]+v.j*t.r[4]+v.k*t.r[7],
311  v.i*t.r[2]+v.j*t.r[5]+v.k*t.r[8] );
312 }
313 
314 int invert( float b[], float a[] );
315 
316 inline void MatrixToVectors( const Matrix &m, Vector &p, Vector &q, Vector &r, QVector &c )
317 {
318  p.Set( m.r[0], m.r[1], m.r[2] );
319  q.Set( m.r[3], m.r[4], m.r[5] );
320  r.Set( m.r[6], m.r[7], m.r[8] );
321  c = m.p;
322 }
323 
324 inline QVector InvScaleTransform( const Matrix &trans, QVector pos )
325 {
326  pos = pos-trans.p;
327 #define a (trans.r[0])
328 #define b (trans.r[3])
329 #define c (trans.r[6])
330 #define d (trans.r[1])
331 #define e (trans.r[4])
332 #define f (trans.r[7])
333 #define g (trans.r[2])
334 #define h (trans.r[5])
335 #define i (trans.r[8])
336  double factor = 1.0F/(-c*e*g+b*f*g+c*d*h-a*f*h-b*d*i+a*e*i);
337  return QVector( pos.Dot( QVector( e*i-f*h, c*h-b*i,
338  b*f-c*e ) ),
339  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;
340 
341 #undef a
342 #undef b
343 #undef c
344 #undef d
345 #undef e
346 #undef f
347 #undef g
348 #undef h
349 #undef i
350 }
351 inline void InvertMatrix( Matrix &o, const Matrix &trans )
352 {
353 #define a (trans.r[0])
354 #define b (trans.r[3])
355 #define c (trans.r[6])
356 #define d (trans.r[1])
357 #define e (trans.r[4])
358 #define f (trans.r[7])
359 #define g (trans.r[2])
360 #define h (trans.r[5])
361 #define i (trans.r[8])
362  float factor = 1.0F/(-c*e*g+b*f*g+c*d*h-a*f*h-b*d*i+a*e*i);
363  o.r[0] = factor*(e*i-f*h);
364  o.r[3] = factor*(c*h-b*i);
365  o.r[6] = factor*(b*f-c*e);
366  o.r[1] = factor*(f*g-d*i);
367  o.r[4] = factor*(a*i-c*g);
368  o.r[7] = factor*(c*d-a*f);
369  o.r[2] = factor*(d*h-e*g);
370  o.r[5] = factor*(b*g-a*h);
371  o.r[8] = factor*(a*e-b*d);
372 #undef a
373 #undef b
374 #undef c
375 #undef d
376 #undef e
377 #undef f
378 #undef g
379 #undef h
380 #undef i
381  o.p = TransformNormal( o, QVector( -trans.p ) );
382 }
383 
384 inline void Rotate( Matrix &tmp, const Vector &axis, float angle )
385 {
386  double c = cos( angle );
387  double s = sin( angle );
388 //Row, COl
389 #define M( a, b ) (tmp.r[b*3+a])
390  M( 0, 0 ) = axis.i*axis.i*(1-c)+c;
391  M( 0, 1 ) = axis.i*axis.j*(1-c)-axis.k*s;
392  M( 0, 2 ) = axis.i*axis.k*(1-c)+axis.j*s;
393  //M(0,3)=0;
394  M( 1, 0 ) = axis.j*axis.i*(1-c)+axis.k*s;
395  M( 1, 1 ) = axis.j*axis.j*(1-c)+c;
396  M( 1, 2 ) = axis.j*axis.k*(1-c)-axis.i*s;
397  //M(1,3)=0;
398  M( 2, 0 ) = axis.i*axis.k*(1-c)-axis.j*s;
399  M( 2, 1 ) = axis.j*axis.k*(1-c)+axis.i*s;
400  M( 2, 2 ) = axis.k*axis.k*(1-c)+c;
401  //M(2,3)=0;
402 #undef M
403  tmp.p.Set( 0, 0, 0 );
404 }
406 {
410  DrawContext( const Matrix &a, GFXVertexList *vl ) : m( a )
411  , vlist( vl ) {}
412 };
413 
414 #endif
415