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_clip.cpp
Go to the documentation of this file.
1 #include "gfxlib.h"
2 #include "gfx/matrix.h"
3 #include "gl_matrix.h"
4 #include "lin_time.h"
5 #include <stdio.h>
6 using namespace GFXMatrices; //causes problems with g_game
7 double BoxFrust[6][4];
8 double frust[6][4];
9 
10 float /*GFXDRVAPI*/ GFXSphereInFrustum( const QVector &Cnt, float radius )
11 {
12  return GFXSphereInFrustum( frust, Cnt, radius );
13 }
15 {
16  return GFXBoxInFrustum( BoxFrust, min, max );
17 }
19 {
20  return GFXBoxInFrustum( frust, min, max );
21 }
22 
23 CLIPSTATE /*GFXDRVAPI*/ GFXSpherePartiallyInFrustum( const Vector &Cnt, float radius )
24 {
25  return GFXSpherePartiallyInFrustum( BoxFrust, Cnt, radius );
26 }
27 CLIPSTATE /*GFXDRVAPI*/ GFXTransformedSpherePartiallyInFrustum( const Vector &Cnt, float radius )
28 {
29  return GFXSpherePartiallyInFrustum( frust, Cnt, radius );
30 }
31 
32 CLIPSTATE /*GFXDRVAPI*/ GFXSpherePartiallyInFrustum( double f[6][4], const Vector &Cnt, const float radius )
33 {
34  int p;
35  float d;
37  for (p = 0; p < 6; p++) {
38  //does not evaluate for yon
39  d = f[p][0]*Cnt.i+f[p][1]*Cnt.j+f[p][2]*Cnt.k+f[p][3];
40  if (d <= -radius)
41  return GFX_NOT_VISIBLE;
42  else if (d <= radius)
43  retval = GFX_PARTIALLY_VISIBLE;
44  }
45  return retval;
46 }
47 
48 CLIPSTATE GFXBoxInFrustum( double f[6][4], const Vector &min, const Vector &max )
49 {
50  //Doesn't do a perfect test for NOT_VISIBLE. Just checks to
51  //see if all box vertices are outside at least one frustum
52  //plane. Some pathological boxes could return SOME_CLIP even
53  //though they're really fully outside the frustum. But that
54  //won't hurt us too much if it isn't a common case; the
55  //contents will just be culled/clipped at a later stage in the
56  //pipeline.
57 
58  //Check each vertex of the box against the view frustum, and compute
59  //bit codes for whether the point is outside each plane.
60  int OrCodes = 0, AndCodes = ~0;
61  for (int i = 0; i < 8; i++) {
62  Vector v( min.i, min.j, min.k );
63  if (i&1) v.i = (max.i);
64  if (i&2) v.j = (max.j);
65  if (i&4) v.k = (max.k);
66  //Now check against the frustum planes.
67  int Code = 0;
68  int Bit = 1;
69  for (int j = 0; j < 6; j++, Bit <<= 1)
70  if (v.i*f[j][0]+v.j*f[j][1]+v.k*f[j][2]+f[j][3] < 0)
71  //The point is outside this plane.
72  Code |= Bit;
73  OrCodes |= Code;
74  AndCodes &= Code;
75  }
76  //Based on bit-codes, return culling results.
77  if (OrCodes == 0)
78  //The box is completely within the frustum.
79  return GFX_TOTALLY_VISIBLE;
80  else if (AndCodes != 0)
81  //All the points are outside one of the frustum planes.
82  return GFX_NOT_VISIBLE;
83  else
84  return GFX_PARTIALLY_VISIBLE;
85 }
86 
87 void DrawFrustum( double f[6][4] )
88 {
89  GFXColor cols[6] = {
90  GFXColor( 0,
91  0,
92  1 ),
93  GFXColor(
94  0,
95  1,
96  0 ),
97  GFXColor( 1,
98  0,
99  0 ), GFXColor( 1, 1, 0 ), GFXColor( 1,
100  0,
101  1 ),
102  GFXColor( 0,
103  1,
104  1 )
105  };
106  for (unsigned int i = 0; i < 4; i++) {
107  Vector n( f[i][0], f[i][1], f[i][2] );
108  Vector r( 9284, -3259, -1249 );
109  Vector t = n.Cross( r );
110  Vector q = t.Cross( n );
111  t.Normalize();
112  q.Normalize();
113  t = t*10000;
114  q = q*10000;
115  n = n*f[i][3];
116  Vector a = t+n;
117  Vector b = q+n;
118  Vector c = n-t;
119  Vector d = n-q;
120  GFXDisable( LIGHTING );
121  GFXEnable( DEPTHTEST );
123  GFXDisable( TEXTURE0 );
124  GFXBlendMode( ONE, ONE );
125  GFXDisable( TEXTURE1 );
126  GFXColorf( cols[i] );
127  GFXBegin( GFXQUAD );
128  GFXVertexf( a );
129  GFXVertexf( b );
130  GFXVertexf( c );
131  GFXVertexf( d );
132  GFXVertexf( d );
133  GFXVertexf( c );
134  GFXVertexf( b );
135  GFXVertexf( a );
136  GFXEnd();
137  }
138 }
139 
140 float /*GFXDRVAPI*/ GFXSphereInFrustum( double f[6][4], const QVector &Cnt, float radius )
141 {
142  /*
143  * static float lasttime = GetElapsedTime();
144  * if (lasttime!=GetElapsedTime()) {
145  * DrawFrustum (f);
146  * lasttime = GetElapsedTime();
147  * }*/
148  int p;
149  double d;
150  for (p = 0; p < 5; p++) {
151  //does not evaluate for yon
152  d = f[p][0]*Cnt.i+f[p][1]*Cnt.j+f[p][2]*Cnt.k+f[p][3];
153  if (d < 0) {
154  //VSFileSystem::Fprintf (stderr,"cin %f",d);
155  if (d <= -radius)
156  return 0;
157  }
158  }
159  return d;
160 }
161 
162 void GFXGetFrustumVars( bool retr, float *l, float *r, float *b, float *t, float *n, float *f )
163 {
164  static float nnear, ffar, left, right, bot, top; //Visual C++ reserves near and far
165  if (!retr) {
166  nnear = *n;
167  ffar = *f;
168  left = *l;
169  right = *r;
170  bot = *b;
171  top = *t;
172  } else {
173  *l = left;
174  *r = right;
175  *b = bot;
176  *t = top;
177  *n = nnear;
178  *f = ffar;
179  }
180  //VSFileSystem::Fprintf (stderr,"<FUN%f,%f,%f,%f,%f,%f>>",near,far,left,right,bot,top);
181 }
182 
183 void /*GFXDRVAPI*/ GFXGetFrustum( double f[6][4] )
184 {
185  f = frust;
186 }
187 void /*GFXDRVAPI*/ GFXBoxInFrustumModel( const Matrix &model )
188 {
189  Matrix tmp;
190  MultMatrix( tmp, view, model );
192 }
193 void /*GFXDRVAPI*/ GFXCalculateFrustum()
194 {
196 }
197 void WackyMultFloatMatrix( double dest[], const float m1[], const Matrix &m2 )
198 {
199  QVector p( InvTransformNormal( m2, m2.p ) );
200  p = ( TransformNormal( m2, -m2.p ) );
201  //p=m2.p;
202  dest[0] = m1[0]*(double) m2.r[0]+m1[4]*(double) m2.r[1]+m1[8]*(double) m2.r[2];
203  dest[1] = m1[1]*(double) m2.r[0]+m1[5]*(double) m2.r[1]+m1[9]*(double) m2.r[2];
204  dest[2] = m1[2]*(double) m2.r[0]+m1[6]*(double) m2.r[1]+m1[10]*(double) m2.r[2];
205  dest[3] = m1[3]*(double) m2.r[0]+m1[7]*(double) m2.r[1]+m1[11]*(double) m2.r[2];
206 
207  dest[4] = m1[0]*(double) m2.r[3]+m1[4]*(double) m2.r[4]+m1[8]*(double) m2.r[5];
208  dest[5] = m1[1]*(double) m2.r[3]+m1[5]*(double) m2.r[4]+m1[9]*(double) m2.r[5];
209  dest[6] = m1[2]*(double) m2.r[3]+m1[6]*(double) m2.r[4]+m1[10]*(double) m2.r[5];
210  dest[7] = m1[3]*(double) m2.r[3]+m1[7]*(double) m2.r[4]+m1[11]*(double) m2.r[5];
211 
212  dest[8] = m1[0]*(double) m2.r[6]+m1[4]*(double) m2.r[7]+m1[8]*(double) m2.r[8];
213  dest[9] = m1[1]*(double) m2.r[6]+m1[5]*(double) m2.r[7]+m1[9]*(double) m2.r[8];
214  dest[10] = m1[2]*(double) m2.r[6]+m1[6]*(double) m2.r[7]+m1[10]*(double) m2.r[8];
215  dest[11] = m1[3]*(double) m2.r[6]+m1[7]*(double) m2.r[7]+m1[11]*(double) m2.r[8];
216 
217  dest[12] = m1[0]*p.i+m1[4]*p.j+m1[8]*p.k+m1[12];
218  dest[13] = m1[1]*p.i+m1[5]*p.j+m1[9]*p.k+m1[13];
219  dest[14] = m1[2]*p.i+m1[6]*p.j+m1[10]*p.k+m1[14];
220  dest[15] = m1[3]*p.i+m1[7]*p.j+m1[11]*p.k+m1[15];
221 }
222 
223 void /*GFXDRVAPI*/ GFXCalculateFrustum( double frustum[6][4], const Matrix &modl, const float *proj )
224 {
225  double clip[16];
226  WackyMultFloatMatrix( clip, proj, modl );
227  double t;
228  /* Extract the numbers for the RIGHT plane */
229  frustum[0][0] = clip[3]-clip[0];
230  frustum[0][1] = clip[7]-clip[4];
231  frustum[0][2] = clip[11]-clip[8];
232  frustum[0][3] = clip[15]-clip[12];
233 
234  /* Normalize the result */
235  t = sqrt( frustum[0][0]*frustum[0][0]+frustum[0][1]*frustum[0][1]+frustum[0][2]*frustum[0][2] );
236  frustum[0][0] /= t;
237  frustum[0][1] /= t;
238  frustum[0][2] /= t;
239  frustum[0][3] /= t;
240 
241  /* Extract the numbers for the LEFT plane */
242  frustum[1][0] = clip[3]+clip[0];
243  frustum[1][1] = clip[7]+clip[4];
244  frustum[1][2] = clip[11]+clip[8];
245  frustum[1][3] = clip[15]+clip[12];
246 
247  /* Normalize the result */
248  t = sqrt( frustum[1][0]*frustum[1][0]+frustum[1][1]*frustum[1][1]+frustum[1][2]*frustum[1][2] );
249  frustum[1][0] /= t;
250  frustum[1][1] /= t;
251  frustum[1][2] /= t;
252  frustum[1][3] /= t;
253 
254  /* Extract the BOTTOM plane */
255  frustum[2][0] = clip[3]+clip[1];
256  frustum[2][1] = clip[7]+clip[5];
257  frustum[2][2] = clip[11]+clip[9];
258  frustum[2][3] = clip[15]+clip[13];
259 
260  /* Normalize the result */
261  t = sqrt( frustum[2][0]*frustum[2][0]+frustum[2][1]*frustum[2][1]+frustum[2][2]*frustum[2][2] );
262  frustum[2][0] /= t;
263  frustum[2][1] /= t;
264  frustum[2][2] /= t;
265  frustum[2][3] /= t;
266 
267  /* Extract the TOP plane */
268  frustum[3][0] = clip[3]-clip[1];
269  frustum[3][1] = clip[7]-clip[5];
270  frustum[3][2] = clip[11]-clip[9];
271  frustum[3][3] = clip[15]-clip[13];
272 
273  /* Normalize the result */
274  t = sqrt( frustum[3][0]*frustum[3][0]+frustum[3][1]*frustum[3][1]+frustum[3][2]*frustum[3][2] );
275  frustum[3][0] /= t;
276  frustum[3][1] /= t;
277  frustum[3][2] /= t;
278  frustum[3][3] /= t;
279 
280  /* Extract the FAR plane */
281  frustum[5][0] = clip[3]-clip[2];
282  frustum[5][1] = clip[7]-clip[6];
283  frustum[5][2] = clip[11]-clip[10];
284  frustum[5][3] = clip[15]-clip[14];
285 
286  /* Normalize the result */
287  t = sqrt( frustum[5][0]*frustum[5][0]+frustum[5][1]*frustum[5][1]+frustum[5][2]*frustum[5][2] );
288  frustum[5][0] /= t;
289  frustum[5][1] /= t;
290  frustum[5][2] /= t;
291  frustum[5][3] /= t;
292 
293  /* Extract the NEAR plane */
294  frustum[4][0] = clip[3]+clip[2];
295  frustum[4][1] = clip[7]+clip[6];
296  frustum[4][2] = clip[11]+clip[10];
297  frustum[4][3] = clip[15]+clip[14];
298 
299  /* Normalize the result */
300  t = sqrt( frustum[4][0]*frustum[4][0]+frustum[4][1]*frustum[4][1]+frustum[4][2]*frustum[4][2] );
301  frustum[4][0] /= t;
302  frustum[4][1] /= t;
303  frustum[4][2] /= t;
304  frustum[4][3] /= t;
305 }
306 
311 float GFXGetZPerspective( const float z )
312 {
313  /*
314  *
315  * | xs 0 a 0 |[x] [xs + az] [1/xs 0 0 a/xs][x] [x/xs+ aw/xs]
316  * | 0 ys b 0 |[y] = [ys + bz] ^-1 [ 0 1/ys 0 b/ys][y] = [y/ys+ bw/ys]
317  * | 0 0 c d |[z] [cz + dw] [ 0 0 0 -1 ][z] [0 ]
318  * | 0 0 -1 0 |[w] [-z ] [ 0 0 1/d c/d ][w] [z/d + cw/d ]
319  *
320  */
321 
322  float left, right, bottom, top, nearval, farval;
323  GFXGetFrustumVars( true, &left, &right, &bottom, &top, &nearval, &farval );
324 
325  float xs = 2*nearval/(right-left);
326  float a = (right+left)/(right-left);
327 
328  //Compute homogeneus x,w for (1,0,z,0)
329  float hx = xs+z*a;
330  float hw = -z;
331 
332  //Translate into euclidean coordinates and return euclidean x
333  return fabs( hx/hw );
334 }
335 
336 #if 0
337 PROJECTION DOESNt FIT INTO REDUCED MAT
338 /* Extract the numbers for the RIGHT plane */
339  frustum[0][0] = /*clip[ 3]*/ -clip.r[0];
340 frustum[0][1] = /*clip[ 7]*/ -clip.r[3];
341 frustum[0][2] = /*clip[11]*/ -clip.r[6];
342 frustum[0][3] = /*clip[15]*/ 1-clip.p.i;
343 
344 /* Normalize the result */
345 t = sqrt( frustum[0][0]*frustum[0][0]+frustum[0][1]*frustum[0][1]+frustum[0][2]*frustum[0][2] );
346 frustum[0][0] /= t;
347 frustum[0][1] /= t;
348 frustum[0][2] /= t;
349 frustum[0][3] /= t;
350 
351 /* Extract the numbers for the LEFT plane */
352 frustum[1][0] = /*clip[ 3]*/ +clip.r[0];
353 frustum[1][1] = /*clip[ 7]*/ +clip.r[3];
354 frustum[1][2] = /*clip[11]*/ +clip.r[6];
355 frustum[1][3] = /*clip[15]*/ 1+clip.p.i;
356 
357 /* Normalize the result */
358 t = sqrt( frustum[1][0]*frustum[1][0]+frustum[1][1]*frustum[1][1]+frustum[1][2]*frustum[1][2] );
359 frustum[1][0] /= t;
360 frustum[1][1] /= t;
361 frustum[1][2] /= t;
362 frustum[1][3] /= t;
363 
364 /* Extract the BOTTOM plane */
365 frustum[2][0] = /*clip[ 3]*/ +clip.r[1];
366 frustum[2][1] = /*clip[ 7]*/ +clip.r[4];
367 frustum[2][2] = /*clip[11]*/ +clip.r[7];
368 frustum[2][3] = /*clip[15]*/ 1+clip.p.j;
369 
370 /* Normalize the result */
371 t = sqrt( frustum[2][0]*frustum[2][0]+frustum[2][1]*frustum[2][1]+frustum[2][2]*frustum[2][2] );
372 frustum[2][0] /= t;
373 frustum[2][1] /= t;
374 frustum[2][2] /= t;
375 frustum[2][3] /= t;
376 
377 /* Extract the TOP plane */
378 frustum[2][0] = /*clip.r[ 3]*/ -clip.r[1];
379 frustum[2][1] = /*clip[ 7]*/ -clip.r[4];
380 frustum[2][2] = /*clip[11]*/ -clip.r[7];
381 frustum[2][3] = /*clip[15]*/ 1-clip.p.j;
382 
383 /* Normalize the result */
384 t = sqrt( frustum[3][0]*frustum[3][0]+frustum[3][1]*frustum[3][1]+frustum[3][2]*frustum[3][2] );
385 frustum[3][0] /= t;
386 frustum[3][1] /= t;
387 frustum[3][2] /= t;
388 frustum[3][3] /= t;
389 
390 /* Extract the FAR plane */
391 frustum[5][0] = /*clip.r[ 3]*/ -clip.r[2];
392 frustum[5][1] = /*clip[ 7]*/ -clip.r[5];
393 frustum[5][2] = /*clip[11]*/ -clip.r[8];
394 frustum[5][3] = /*clip[15]*/ 1-clip.p.k;
395 
396 /* Normalize the result */
397 t = sqrt( frustum[5][0]*frustum[5][0]+frustum[5][1]*frustum[5][1]+frustum[5][2]*frustum[5][2] );
398 frustum[5][0] /= t;
399 frustum[5][1] /= t;
400 frustum[5][2] /= t;
401 frustum[5][3] /= t;
402 
403 /* Extract the NEAR plane */
404 frustum[4][0] = /*clip[ 3]*/ +clip.r[2];
405 frustum[4][1] = /*clip[ 7]*/ +clip.r[5];
406 frustum[4][2] = /*clip[11]*/ +clip.r[8];
407 frustum[4][3] = /*clip[15]*/ 1+clip.p.k;
408 
409 /* Normalize the result */
410 t = sqrt( frustum[4][0]*frustum[4][0]+frustum[4][1]*frustum[4][1]+frustum[4][2]*frustum[4][2] );
411 frustum[4][0] /= t;
412 frustum[4][1] /= t;
413 frustum[4][2] /= t;
414 frustum[4][3] /= t;
415 
416 #endif
417