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
gl_matrix.cpp
Go to the documentation of this file.
1 /*
2  * Vega Strike
3  * Copyright (C) 2001-2002 Daniel Horn & Alan Shieh
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 #include "gl_globals.h"
22 #include "gfxlib.h"
23 #include "gfx/vec.h"
24 #include <stdio.h>
25 //typedef float GLdouble;
26 #include <math.h>
27 #include <string.h>
28 #include <assert.h>
29 //#include "vegastrike.h"
30 #include "gfx/matrix.h"
31 #include "vs_globals.h"
32 #ifdef WIN32
33 #ifndef NOMINMAX
34 #define NOMINMAX
35 #endif //tells VCC not to generate min/max macros
36 #include <windows.h>
37 #ifndef M_PI
38 # define M_PI 3.14159265358979323846 /* pi */
39 #endif
40 #endif
41 #include "gl_matrix.h"
42 #include "vs_globals.h"
43 
44 using namespace GFXMatrices; //causes problems with g_game
45 
46 void getInverseProjection( float* &inv )
47 {
48  inv = invprojection;
49 }
50 
52 {
53  return /*invprojection[11]* */ invprojection[0]; //invprojection[15];//should be?? c/d == invproj[15]
54 }
55 
57 {
58  return /*invprojection[11]* */ invprojection[5]; //invprojection[15];//should be?? c/d == invproj[15]
59 }
60 
61 void MatrixToDoubles( double t[], const Matrix &m )
62 {
63  t[0] = m.r[0]; //possible performance hit?!?!
64  t[1] = m.r[1];
65  t[2] = m.r[2];
66  t[3] = 0;
67  t[4] = m.r[3];
68  t[5] = m.r[4];
69  t[6] = m.r[5];
70  t[7] = 0;
71  t[8] = m.r[6];
72  t[9] = m.r[7];
73  t[10] = m.r[8];
74  t[11] = 0;
75  t[12] = (m.p.i);
76  t[13] = (m.p.j);
77  t[14] = (m.p.k);
78  t[15] = 1;
79 }
80 
81 inline void ViewToModel()
82 {
83  double t[16];
84  t[0] = model.r[0]*GFX_SCALE; //possible performance hit?!?!
85  t[1] = model.r[1]*GFX_SCALE;
86  t[2] = model.r[2]*GFX_SCALE;
87  t[3] = 0;
88  t[4] = model.r[3]*GFX_SCALE;
89  t[5] = model.r[4]*GFX_SCALE;
90  t[6] = model.r[5]*GFX_SCALE;
91  t[7] = 0;
92  t[8] = model.r[6]*GFX_SCALE;
93  t[9] = model.r[7]*GFX_SCALE;
94  t[10] = model.r[8]*GFX_SCALE;
95  t[11] = 0;
96  t[12] = (model.p.i-view.p.i)*GFX_SCALE;
97  t[13] = (model.p.j-view.p.j)*GFX_SCALE;
98  t[14] = (model.p.k-view.p.k)*GFX_SCALE;
99  t[15] = 1;
100  //MatrixToDoubles (t,model);
101  glMatrixMode( GL_MODELVIEW );
102  glLoadMatrixd( t );
103 }
104 
105 static void IdentityFloat( float id[] )
106 {
107  id[0] = id[5] = id[10] = id[15] = 1;
108  id[1] = id[2] = id[3] = id[4] = id[6] = id[7] = id[8] = id[9] = id[11] = id[12] = id[13] = id[14] = 0;
109 }
110 
111 void MultFloatMatrix( float dest[], const float m1[], const Matrix &m2 )
112 {
113  dest[0] = m1[0]*m2.r[0]+m1[4]*m2.r[1]+m1[8]*m2.r[2];
114  dest[1] = m1[1]*m2.r[0]+m1[5]*m2.r[1]+m1[9]*m2.r[2];
115  dest[2] = m1[2]*m2.r[0]+m1[6]*m2.r[1]+m1[10]*m2.r[2];
116  dest[3] = m1[3]*m2.r[0]+m1[7]*m2.r[1]+m1[11]*m2.r[2];
117 
118  dest[4] = m1[0]*m2.r[3]+m1[4]*m2.r[4]+m1[8]*m2.r[5];
119  dest[5] = m1[1]*m2.r[3]+m1[5]*m2.r[4]+m1[9]*m2.r[5];
120  dest[6] = m1[2]*m2.r[3]+m1[6]*m2.r[4]+m1[10]*m2.r[5];
121  dest[7] = m1[3]*m2.r[3]+m1[7]*m2.r[4]+m1[11]*m2.r[5];
122 
123  dest[8] = m1[0]*m2.r[6]+m1[4]*m2.r[7]+m1[8]*m2.r[8];
124  dest[9] = m1[1]*m2.r[6]+m1[5]*m2.r[7]+m1[9]*m2.r[8];
125  dest[10] = m1[2]*m2.r[6]+m1[6]*m2.r[7]+m1[10]*m2.r[8];
126  dest[11] = m1[3]*m2.r[6]+m1[7]*m2.r[7]+m1[11]*m2.r[8];
127 
128  dest[12] = m1[0]*m2.p.i+m1[4]*m2.p.j+m1[8]*m2.p.k+m1[12];
129  dest[13] = m1[1]*m2.p.i+m1[5]*m2.p.j+m1[9]*m2.p.k+m1[13];
130  dest[14] = m1[2]*m2.p.i+m1[6]*m2.p.j+m1[10]*m2.p.k+m1[14];
131  dest[15] = m1[3]*m2.p.i+m1[7]*m2.p.j+m1[11]*m2.p.k+m1[15];
132 }
133 
134 static void RotateFloatMatrix( float dest[], const float m1[], const Matrix &m2 )
135 {
136  dest[0] = (m1[0]*m2.r[0]+m1[4]*m2.r[1]+m1[8]*m2.r[2]);
137  dest[1] = (m1[1]*m2.r[0]+m1[5]*m2.r[1]+m1[9]*m2.r[2]);
138  dest[2] = (m1[2]*m2.r[0]+m1[6]*m2.r[1]+m1[10]*m2.r[2]);
139  dest[3] = (m1[3]*m2.r[0]+m1[7]*m2.r[1]+m1[11]*m2.r[2]);
140 
141  dest[4] = (m1[0]*m2.r[3]+m1[4]*m2.r[4]+m1[8]*m2.r[5]);
142  dest[5] = (m1[1]*m2.r[3]+m1[5]*m2.r[4]+m1[9]*m2.r[5]);
143  dest[6] = (m1[2]*m2.r[3]+m1[6]*m2.r[4]+m1[10]*m2.r[5]);
144  dest[7] = (m1[3]*m2.r[3]+m1[7]*m2.r[4]+m1[11]*m2.r[5]);
145 
146  dest[8] = (m1[0]*m2.r[6]+m1[4]*m2.r[7]+m1[8]*m2.r[8]);
147  dest[9] = (m1[1]*m2.r[6]+m1[5]*m2.r[7]+m1[9]*m2.r[8]);
148  dest[10] = (m1[2]*m2.r[6]+m1[6]*m2.r[7]+m1[10]*m2.r[8]);
149  dest[11] = (m1[3]*m2.r[6]+m1[7]*m2.r[7]+m1[11]*m2.r[8]);
150 
151  dest[12] = m1[12];
152  dest[13] = m1[13];
153  dest[14] = m1[14];
154  dest[15] = m1[15];
155 }
156 
158 {
159  float t[16];
161  glMatrixMode( GL_PROJECTION );
162  glLoadMatrixf( t );
163 }
164 
165 void /*GLDRVAPI*/ GFXTranslateView( const QVector &a )
166 {
167  view.p += TransformNormal( view, a );
168  //glPopMatrix();
169  //glLoadIdentity();
170  //glTranslatef(-view[12],-view[13],-view[14]);
171  //glPushMatrix();
172  ViewToModel();
173 }
174 
175 void /*GFXDRVAPI*/ GFXTranslateModel( const QVector &a )
176 {
177  model.p += TransformNormal( model, a );
178  ViewToModel();
179 }
180 
181 void /*GFXDRVAPI*/ GFXTranslateProjection( const Vector &a )
182 {
183  projection[12] += a.i*projection[0]+a.j*projection[4]+a.k*projection[8];
184  projection[13] += a.i*projection[1]+a.j*projection[5]+a.k*projection[9];
185  projection[14] += a.i*projection[2]+a.j*projection[6]+a.k*projection[10];
187 }
188 
189 void /*GFXDRVAPI*/ GFXMultMatrixModel( const Matrix &matrix )
190 {
191  Matrix t;
192  MultMatrix( t, model, matrix );
193  CopyMatrix( model, t );
194  ViewToModel();
195 }
196 
197 //Matrix *mm = model;
198 //Matrix *vv = view;
199 
200 void GFXLoadMatrixView( const Matrix &matrix )
201 {
202  CopyMatrix( view, matrix );
203  ViewToModel();
205 }
206 
207 void /*GFXDRVAPI*/ GFXLoadMatrixModel( const Matrix &matrix )
208 {
209  CopyMatrix( model, matrix );
210  ViewToModel();
211 }
212 
213 void /*GFXDRVAPI*/ GFXLoadMatrixProjection( const float matrix[16] )
214 {
215  memcpy( projection, matrix, 16*sizeof (float) );
217 }
218 
219 void /*GFXDRVAPI*/ GFXViewPort( int minx, int miny, int maxx, int maxy )
220 {
221  glViewport( minx, miny, maxx, maxy );
222 }
223 
224 void /*GFXDRVAPI*/ GFXCenterCamera( bool Enter )
225 {
226  static QVector tmp;
227  if (Enter) {
228  tmp = view.p;
229  view.p.Set( 0, 0, 0 );
230  glMatrixMode( GL_MODELVIEW );
231  glLoadIdentity();
232  } else {
233  view.p = tmp;
235  }
236 }
237 
239 {
240  glMatrixMode( GL_MODELVIEW );
241  glLoadIdentity();
242  glMatrixMode( GL_PROJECTION );
243  glLoadIdentity();
244 }
245 
246 void GFXHudMode( const bool Enter )
247 {
248  if (Enter) {
249  glMatrixMode( GL_MODELVIEW );
250  glPushMatrix();
251  glLoadIdentity();
252  glMatrixMode( GL_PROJECTION );
253  glPushMatrix();
254  glLoadIdentity();
255  } else {
256  glMatrixMode( GL_PROJECTION );
257  glPopMatrix();
258  glMatrixMode( GL_MODELVIEW );
259  glPopMatrix();
260  }
261 }
262 
263 void /*GFXDRVAPI*/ GFXLoadIdentity( const MATRIXMODE mode )
264 {
265  switch (mode)
266  {
267  case MODEL:
268  Identity( model );
269  glMatrixMode( GL_MODELVIEW );
270  //glLoadMatrixf(transview);
271  glLoadIdentity();
272  glTranslated( -view.p.i*GFX_SCALE, -view.p.j*GFX_SCALE, -view.p.k*GFX_SCALE );
273  glScalef( GFX_SCALE, GFX_SCALE, GFX_SCALE );
274  break;
275  case PROJECTION:
278  break;
279  case VIEW:
280  Identity( view );
281  ViewToModel();
282  glMatrixMode( GL_PROJECTION );
283  glLoadMatrixf( projection );
284  break;
285  }
286 }
287 
288 void /*GFXDRVAPI*/ GFXGetMatrixView( Matrix &matrix )
289 {
290  CopyMatrix( matrix, view );
291 }
292 void /*GFXDRVAPI*/ GFXGetMatrixModel( Matrix &matrix )
293 {
294  CopyMatrix( matrix, model );
295 }
296 
297 static void gl_Frustum( float left, float right, float bottom, float top, float nearval, float farval )
298 {
299  GFXGetFrustumVars( false, &left, &right, &bottom, &top, &nearval, &farval );
300  GFXFrustum( projection, invprojection, left, right, bottom, top, nearval, farval );
301 }
302 
303 void GFXFrustum( float *m, float *i, float left, float right, float bottom, float top, float nearval, float farval )
304 {
305  GLfloat x, y, a, b, c, d;
306  x = ( ( (float) 2.0 )*nearval )/(right-left);
307  y = ( ( (float) 2.0 )*nearval )/(top-bottom);
308  a = (right+left)/(right-left);
309  b = (top+bottom)/(top-bottom);
310  //If farval == 0, we'll build an infinite-farplane projection matrix.
311  if (farval == 0) {
312  c = -1.0;
313  d = -1.99*nearval; //-2*nearval, but using exactly -2 might create artifacts
314  } else {
315  c = -(farval+nearval)/(farval-nearval);
316  d = -( ( (float) 2.0 )*farval*nearval )/(farval-nearval);
317  }
318 #define M( row, col ) m[col*4+row]
319  M( 0, 0 ) = x;
320  M( 0, 1 ) = 0.0F;
321  M( 0, 2 ) = a;
322  M( 0, 3 ) = 0.0F;
323  M( 1, 0 ) = 0.0F;
324  M( 1, 1 ) = y;
325  M( 1, 2 ) = b;
326  M( 1, 3 ) = 0.0F;
327  M( 2, 0 ) = 0.0F;
328  M( 2, 1 ) = 0.0F;
329  M( 2, 2 ) = c;
330  M( 2, 3 ) = d;
331  M( 3, 0 ) = 0.0F;
332  M( 3, 1 ) = 0.0F;
333  M( 3, 2 ) = -1.0F;
334  M( 3, 3 ) = 0.0F;
335 #undef M
336 #define M( row, col ) i[col*4+row]
337  M( 0, 0 ) = 1./x;
338  M( 0, 1 ) = 0.0F;
339  M( 0, 2 ) = 0.0F;
340  M( 0, 3 ) = a/x;
341  M( 1, 0 ) = 0.0F;
342  M( 1, 1 ) = 1./y;
343  M( 1, 2 ) = 0.0F;
344  M( 1, 3 ) = b/y;
345  M( 2, 0 ) = 0.0F;
346  M( 2, 1 ) = 0.0F;
347  M( 2, 2 ) = 0.0F;
348  M( 2, 3 ) = -1.0F;
349  M( 3, 0 ) = 0.0F;
350  M( 3, 1 ) = 0.0F;
351  M( 3, 2 ) = 1.F/d;
352  M( 3, 3 ) = (float) c/d;
353 #undef M
354 }
355 
356 void /*GFXDRVAPI*/ GFXPerspective( float fov, float aspect, float znear, float zfar, float cockpit_offset )
357 {
358  znear *= GFX_SCALE;
359  zfar *= GFX_SCALE;
360  cockpit_offset *= GFX_SCALE;
361  //gluPerspective (fov,aspect,znear,zfar);
362 
363  float xmin, xmax, ymin, ymax;
364 
365  ymax = znear*tanf( fov*M_PI/( (float) 360.0 ) ); //78.0 --> 4.7046
366 
367  ymin = -ymax; //-4.7046
368 
369  xmin = (ymin-cockpit_offset/2)*aspect; //-6.2571
370  xmax = (ymax+cockpit_offset/2)*aspect; //6.2571
371  ymin -= cockpit_offset;
372  gl_Frustum( xmin, xmax, ymin, ymax, znear, zfar );
374 }
375 
376 void /*GFXDRVAPI*/ GFXParallel( float left, float right, float bottom, float top, float nearval, float farval )
377 {
378  float *m = projection, x, y, z, tx, ty, tz;
379  x = 2.0/(right-left);
380  y = 2.0/(top-bottom);
381  z = -2.0/(farval-nearval);
382  tx = -(right+left)/(right-left);
383  ty = -(top+bottom)/(top-bottom);
384  tz = -(farval+nearval)/(farval-nearval);
385 
386 #define M( row, col ) m[col*4+row]
387  M( 0, 0 ) = x;
388  M( 0, 1 ) = 0.0F;
389  M( 0, 2 ) = 0.0F;
390  M( 0, 3 ) = tx;
391  M( 1, 0 ) = 0.0F;
392  M( 1, 1 ) = y;
393  M( 1, 2 ) = 0.0F;
394  M( 1, 3 ) = ty;
395  M( 2, 0 ) = 0.0F;
396  M( 2, 1 ) = 0.0F;
397  M( 2, 2 ) = z;
398  M( 2, 3 ) = tz;
399  M( 3, 0 ) = 0.0F;
400  M( 3, 1 ) = 0.0F;
401  M( 3, 2 ) = 0.0F;
402  M( 3, 3 ) = 1.0F;
403 #undef M
405  GFXGetFrustumVars( false, &left, &right, &bottom, &top, &nearval, &farval );
406 }
407 
408 static void LookAtHelper( float eyex,
409  float eyey,
410  float eyez,
411  double centerx,
412  double centery,
413  double centerz,
414  float upx,
415  float upy,
416  float upz )
417 {
418  //Matrix m;
419  double x[3], y[3], z[3];
420  double mag;
421 
422  /* Make rotation matrix */
423 
424  /* Z vector */
425  z[0] = eyex;
426  z[1] = eyey;
427  z[2] = eyez;
428  mag = sqrtf( z[0]*z[0]+z[1]*z[1]+z[2]*z[2] );
429  if (mag) {
430  /* mpichler, 19950515 */
431  z[0] /= mag;
432  z[1] /= mag;
433  z[2] /= mag;
434  }
435  /* Y vector */
436  y[0] = upx;
437  y[1] = upy;
438  y[2] = upz;
439 
440  /* X vector = Y cross Z */
441  //x[0] = z[1]*y[2] - z[2]*y[1];
442  //x[1] = -z[0]*y[2] + z[2]*y[0];
443  //x[2] = z[0]*y[1] - z[1]*y[0];
444  x[0] = y[1]*z[2]-y[2]*z[1];
445  x[1] = -y[0]*z[2]+y[2]*z[0];
446  x[2] = y[0]*z[1]-y[1]*z[0];
447 
448  /* Recompute Y = Z cross X */
449  //y[0] = x[1]*z[2] - x[2]*z[1];
450  //y[1] = -x[0]*z[2] + x[2]*z[0];
451  //y[2] = x[0]*z[1] - x[1]*z[0];
452  y[0] = z[1]*x[2]-z[2]*x[1];
453  y[1] = -z[0]*x[2]+z[2]*x[0];
454  y[2] = z[0]*x[1]-z[1]*x[0];
455 
456  /* mpichler, 19950515 */
457  /* cross product gives area of parallelogram, which is < 1.0 for
458  * non-perpendicular unit-length vectors; so normalize x, y here
459  */
460 
461  mag = sqrtf( x[0]*x[0]+x[1]*x[1]+x[2]*x[2] );
462  if (mag) {
463  x[0] /= mag;
464  x[1] /= mag;
465  x[2] /= mag;
466  }
467  mag = sqrtf( y[0]*y[0]+y[1]*y[1]+y[2]*y[2] );
468  if (mag) {
469  y[0] /= mag;
470  y[1] /= mag;
471  y[2] /= mag;
472  }
473 #define M( row, col ) view.r[col*3+row]
474  M( 0, 0 ) = x[0];
475  M( 0, 1 ) = x[1];
476  M( 0, 2 ) = x[2]; //M(0,3) = 0.0;
477  M( 1, 0 ) = y[0];
478  M( 1, 1 ) = y[1];
479  M( 1, 2 ) = y[2]; //M(1,3) = 0.0;
480  M( 2, 0 ) = z[0];
481  M( 2, 1 ) = z[1];
482  M( 2, 2 ) = z[2]; //M(2,3) = 0.0;
483 #undef M
484  //M(3,0) = 0.0; M(3,1) = 0.0; M(3,2) = 0.0; M(3,3) = 1.0;
485 
486  //Matrix tm;
487  //Identity(tm);
488  view.p.i = centerx+eyex;
489  view.p.j = centery+eyey;
490  view.p.k = centerz+eyez;
491  //CopyMatrix (view,m);
492  //MultMatrix(view, m, tm);
493 }
494 
495 void /*GFXDRVAPI*/ GFXLookAt( Vector eye, QVector center, Vector up )
496 {
497  LookAtHelper( eye.i, eye.j, eye.k, center.i, center.j, center.k, up.i, up.j, up.k );
499 }
500 
501 #ifdef SELF_TEST
502 int main()
503 {
504  float m1[16];
505  double m2[16];
506  Matrix m3[16];
507  float res[16];
508 
509  return 0;
510 }
511 
512 #endif
513 
514 #if 0
515 void GFXMultMatrixView( const &Matrix )
516 {
517  const int MULTMATRIXVIEWNOTIMPLEMENTED = 0;
518  assert( MULTMATRIXVIEWNOTIMPLEMENTED );
519  MultMatrix( t, view, matrix );
520  CopyMatrix( view, t );
522  glMatrixMode( GL_MODELVIEW );
523  //glPopMatrix();
524  //glLoadIdentity();
525  //glTranslatef(-centerx,-centery,-centerz);
526  //glPushMatrix();
527  ViewToModel( true );
528  glLoadMatrixf( model );
529  ViewToModel( false );
530 }
531 #endif
532 
533 #if 0
534 LOOKATHELPER under MultMatrix( view, m, tm );
535 /***
536  * float dis = sqrtf(upx*upx+upy*upy);
537  * Identity (tm);
538  * if (eyez-centerz > 0) {
539  * upx = -upx;
540  * }
541  * #define M(row,col) tm[col*4+row]
542  * M(0,0) = upy/dis;
543  * M(0,1) = -upx/dis;
544  * M(1,1) = upy/dis;
545  * M(1,0) = upx/dis;
546  * M(2,2) = 1.0;
547  * M(3,3) = 1.0;
548  * #undef M
549  ***/ //old hack to twiddle the texture in the xy plane
550 
551 #ifdef NV_CUBE_MAP
552 //FIXME--ADD CAMERA MATRICES
553 //the texture matrix must be used to rotate the texgen-computed
554 //reflection or normal vector texture coordinates to match the orinetation
555 //of the cube map. Teh rotation can be computed based on two vectors
556 //1) the direction vector from the cube map center to the eye position
557 //and 2 the cube map orientation in world coordinates.
558 //the axis is the cross product of these two vectors...teh angle is arcsin
559 //of the dot of these two vectors
560 GFXActiveTexture( 1 );
561 glMatrixMode( GL_TEXTURE );
562 glLoadIdentity();
563 #error
564 
565 //Vector (centerx,centery,centerz).Cross (Vector (1,0,0)); DID NOT TRANSFORM THE ORIENTATION VECTOR TO REVERSE CAMERASPACE
566 Vector axis( centerx, centery, centerz );
567 Vector cubemapincamspace( eyex+centerx, eyey+centery, eyez+centerz );
568 cubemapincamspace.Normalize();
569 axis.Normalize();
570 //float theta = arcsinf (Vector (centerx,centery,centerz).Normalize().Dot (Vector (1,0,0))); DID NOT TRANSFORM THE ORIENTATION VECTOR TO REVERSE CAMERASPACE
571 float theta = asinf( axis.Dot( cubemapincamspace ) );
572 axis = axis.Cross( axis.Cross( cubemapincamspace ) );
573 glRotatef( theta, axis.i, axis.j, axis.k );
574 //ok do matrix math to rotate by theta on axis those ..
575 GFXActiveTexture( 0 );
576 
577 #else
578 /* glTranslatef(.5f,.5f,.4994f);
579  * glMultMatrixf(tm);
580  * glTranslatef(-.5f,-.5f,-.4994f);
581  */
582 #endif
583 #endif
584