Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/cleanup/src/lib/graphics/importer/bsp/bsp_manager.cc

Last change on this file was 10618, checked in by bknecht, 18 years ago

merged cleanup into trunk (only improvements)

File size: 58.5 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2006 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: bottac@ee.ethz.ch
13
14   Inspired by:
15   Rendering Q3 Maps by Morgan McGuire                  http://graphics.cs.brown.edu/games/quake/quake3.html
16   Unofficial Quake 3 Map Specs by Kekoa Proudfoot      http://graphics.stanford.edu/~kekoa/q3/
17
18   Collision detection adapted from:
19   Quake 3 Collision Detection by Nathan Ostgard        http://www.devmaster.net/articles/quake3collision/
20*/
21
22
23#include "limits.h"
24#include "vector.h"
25#include "bsp_file.h"
26#include "bsp_manager.h"
27#include "bsp_tree_leaf.h"
28#include "p_node.h"
29#include "state.h"
30#include "debug.h"
31#include "material.h"
32#include "tools/camera.h"
33#include "vertex_array_model.h"
34#include "world_entities/player.h"
35#include "world_entities/playable.h"
36
37// STL Containers
38#include <vector>
39#include <deque>
40#include "movie_player.h"
41
42#include "world_entity.h"
43
44#include "util/loading/resource_manager.h"
45#include "util/loading/load_param.h"
46#include "util/loading/factory.h"
47
48#include "aabb.h"
49#include "cr_engine.h"
50#include "collision_tube.h"
51
52
53//CREATE_FACTORY( BspManager, CL_BSP_MODEL);
54
55BspManager::BspManager(WorldEntity* parent)
56{
57
58  this->lastTex = -1;
59  this->parent = parent;
60  /*// open a BSP file
61  this->bspFile = new BspFile();
62  this->bspFile->scale = 0.4f;
63  this->bspFile->read(ResourceManager::getFullName("test.bsp").c_str());
64  this->bspFile->build_tree();
65  this->root  = this->bspFile->get_root();
66  this->alreadyVisible = new bool [this->bspFile->numFaces];
67  */
68
69}
70
71
72/*
73BspManager::BspManager(const TiXmlElement* root)
74{
75
76
77  if( root != NULL)
78    this->loadParams(root);
79
80  CDEngine::getInstance()->setBSPModel(this);
81} */
82
83BspManager::~BspManager()
84{
85  if(this->bspFile)
86    delete this->bspFile;
87}
88
89int BspManager::load(const char* fileName, float scale)
90{
91  // open a BSP file
92
93
94  this->bspFile = new BspFile();
95  this->bspFile->scale =  scale;
96  if(this->bspFile->read(Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName).c_str()) == -1)
97    return -1;
98
99  this->bspFile->build_tree();
100  this->root  = this->bspFile->get_root();
101  this->alreadyVisible = new bool [this->bspFile->numFaces];
102
103  this->outputFraction = 1.0f;
104
105  return 0;
106}
107
108
109/*
110BspManager::BspManager(const char* fileName, float scale)
111{
112  // open a BSP file
113  this->bspFile = new BspFile();
114  this->bspFile->scale =  scale;
115  this->bspFile->read(fileName);
116  this->bspFile->build_tree();
117  this->root  = this->bspFile->get_root();
118  this->alreadyVisible = new bool [this->bspFile->numFaces];
119
120  CDEngine::getInstance()->setBSPModel(this);
121}
122*/
123
124const void BspManager::tick(float time)
125{
126
127  if(!this->bspFile->MovieMaterials.empty()) {
128    ::std::vector<MoviePlayer *>::iterator it = this->bspFile->MovieMaterials.begin() ;
129    while(it != this->bspFile->MovieMaterials.end()) {
130      (*it)->tick(time);
131      it++;
132    }
133    //this->bspFile->MovieMaterials.front()->tick(time );
134
135
136  }
137
138}
139const void BspManager::draw()
140{
141
142  /*
143  this->drawDebugCube(&this->out);
144  this->out1 = this->out;
145  this->out2 = this->out;
146  if(this->collPlane != NULL) {
147    this->out1.x += this->collPlane->x*5.0;
148    this->out1.y += this->collPlane->y*5.0;
149    this->out1.z += this->collPlane->z*5.0;
150
151    this->out2.x += this->collPlane->x*10.0;
152    this->out2.y += this->collPlane->y*10.0;
153    this->out2.z += this->collPlane->z*10.0;
154  }
155  this->drawDebugCube(&this->out1);
156  this->drawDebugCube(&this->out2);
157
158  */
159
160
161  // Draw Debug Terrain
162  /*
163  this->bspFile->Materials[0]->select();
164  for(int i = 0; i <  this->bspFile->numPatches ; i++)
165        {
166                this->bspFile->VertexArrayModels[i]->draw();
167
168        }
169  */
170
171
172  this->lastTex = -1;
173  // erase alreadyVisible
174  for(int i = 0; i < this->bspFile->numFaces; i++) this->alreadyVisible[i] = false;
175  float tmp = 0;
176  //this->opal.clear();
177  //this->trasparent.clear();
178  // Find all visible faces...
179
180  this->cam = State::getCamera()->getAbsCoor() ;
181  //this->ship = State::getCameraTargetNode()->getAbsCoor();
182
183
184
185
186
187  this->viewDir=    State::getCamera()->getAbsDirX();
188  float d = (cam.x*viewDir.x + cam.y*viewDir.y + cam.z * viewDir.z);
189
190  BspTreeNode*  ActLeaf = this->getLeaf(this->bspFile->root, &ship);
191  int viscluster = -1;
192  viscluster =((leaf*)(this->bspFile->leaves))[ ActLeaf->leafIndex].cluster; // get the players cluster (viscluster)
193
194
195
196
197  // this->checkCollision(this->root, &this->cam);   //!< Test Collision Detection
198
199
200  this->outputStartsOut = true;
201  this->outputAllSolid = false;
202  this->outputFraction = 1.0f;
203
204  if ( viscluster < 0  || ((int *)(this->bspFile->header))[35] == 0 )  //!< if (sizeof(Visdata) == 0)
205  {
206
207
208
209    // Iterate through all Leafs
210    for(int i = 0; i <  this->bspFile->numLeafs   ; i++ )
211    {
212      // cluster =  (this->bspFile->leaves)[i].cluster;
213      leaf& curLeaf = (this->bspFile->leaves)[i];
214      if(curLeaf.cluster<0) continue;
215
216      /** Do Frustum culling and draw 'em all **/
217
218      Vector dir = State::getCameraNode()->getAbsDirX();
219
220      float dist =  dir.x*this->cam.x +dir.y*this->cam.y +dir.z*this->cam.z;
221      //if(dist < 0) dist = -dist;
222      const float dMins = dir.x*(float)curLeaf.mins[0] +dir.y*(float)curLeaf.mins[1] +dir.z*(float)curLeaf.mins[2] - dist ;
223      const float dMaxs = dir.x*(float)curLeaf.maxs[0] +dir.y*(float)curLeaf.maxs[1] +dir.z*(float)curLeaf.maxs[2] - dist ;
224
225      if(dMins < -300.0 && dMaxs < -300.0) {
226        continue;
227      }
228      if( (this->cam - Vector(curLeaf.mins[0],curLeaf.mins[1], curLeaf.mins[2])).len() > 2000  && (this->cam - Vector(curLeaf.maxs[0],curLeaf.maxs[1], curLeaf.maxs[2])).len() > 2000) {
229        continue;
230      }
231
232
233      // Iterate through all faces
234      for (int j = 0; j < curLeaf.n_leaffaces ; ++j) {
235        const int g = (j +  curLeaf.leafface);
236        const int f = ((int *)this->bspFile->leafFaces)[g];
237        if (f >=0 && !this->isAlreadyVisible(f)) {
238          this->alreadyVisible[f] = true;
239          addFace(f); // "visibleFaces.append(f)"
240        }
241      }
242
243
244
245
246    } //for
247  } else {
248
249
250    unsigned int v;
251    unsigned char  visSet;
252
253    // Iterate through all Leafs
254
255    for(int i = 0; i <  this->bspFile->numLeafs   ; ++i ) {
256      leaf& camLeaf =  (this->bspFile->leaves)[ActLeaf->leafIndex] ;
257      leaf& curLeaf =  (this->bspFile->leaves)[i] ;
258      int& cluster =  curLeaf.cluster;
259
260      if(cluster < 0) continue;
261      v = ((viscluster *  ( ((int *)this->bspFile->visData)[1]) ) + (cluster / 8));
262      visSet =((char*) (this->bspFile->visData))[v + 8];
263
264      // gets bit of visSet
265      if( ((visSet) & (1 << (cluster &  7))) != 0 ) {
266
267        // Frustum culling
268
269        Vector dir;
270        dir.x = State::getCameraNode()->getAbsDirX().x;
271        dir.y =  State::getCameraNode()->getAbsDirX().y;
272        dir.z =  State::getCameraNode()->getAbsDirX().z;
273        const float dist =  dir.x*this->cam.x +dir.y*this->cam.y +dir.z*this->cam.z;
274        //if(dist < 0) dist = -dist;
275        const float dMins = dir.x*(float)curLeaf.mins[0] +dir.y*(float)curLeaf.mins[1] +dir.z*(float)curLeaf.mins[2] - dist;
276        const float dMaxs = dir.x*(float)curLeaf.maxs[0] +dir.y*(float)curLeaf.maxs[1] +dir.z*(float)curLeaf.maxs[2] - dist;
277
278        if(dMins < -70.0 && dMaxs < -70.0) {
279          continue;
280        }
281
282
283        // Iterate through all faces
284        for (int j = 0; j < curLeaf.n_leaffaces ; ++j) {
285          const int g = (j +  curLeaf.leafface);
286          const int f = ((int *)this->bspFile->leafFaces)[g];
287
288          if (!this->isAlreadyVisible(f) && f>=0) {
289            this->addFace(f);
290            this->alreadyVisible[f] = true;
291          }
292
293        }
294
295      }// if
296
297    }//for
298
299  }//else
300
301
302  // now sort the transparent faces in the right order
303  if (this->sortTransparency == 1) {
304      int size = this->trasparent.size();
305     
306      // bubble sort
307      bool hasSwapped = true;
308      Vector v1, v2;
309
310      // initialize distance array
311      float * distToPlayer = new float [size];
312      for (int i = 0; i < size; i++)
313      {
314          face& fac1 =  (this->bspFile->faces)[this->trasparent[i]];
315//          face& fac2 =  (this->bspFile->faces)[this->trasparent[i+1]];
316
317          // get center of face 1
318          const BspVertex* curVertex = (BspVertex *) this->bspFile->vertice;
319
320          if (this->sortTransparencyMore == 1)
321          {
322              // assign the values of the vertices
323              float maxDist = 0;
324              float curDist = 0;
325              int maxVert = fac1.vertex;
326              for (int v = 0; v < fac1.n_vertexes; v++)
327              {
328                    v1(curVertex[fac1.vertex + v].position[0], curVertex[fac1.vertex + v].position[1], curVertex[fac1.vertex + v].position[2]);
329                    curDist = (this->cam - v1).len();
330                    if (curDist > maxDist)
331                    {
332                        maxDist = curDist;
333                        maxVert = fac1.vertex + v;
334                    }
335              }
336              v1(curVertex[maxVert].position[0], curVertex[maxVert].position[1], curVertex[maxVert].position[2]);
337          }
338          else
339          {
340              v1(curVertex[fac1.vertex].position[0], curVertex[fac1.vertex].position[1], curVertex[fac1.vertex].position[2]);
341          }
342
343          // relativly to observer
344          v1 = this->cam - v1;
345
346          // save in array
347          distToPlayer[i] = v1.len();
348      }
349
350      while( hasSwapped)
351      {
352        hasSwapped = false;
353
354        for( int i = 0; i < size - 1; i++)
355        {
356/*
357          // sorting test
358          face& fac1 =  (this->bspFile->faces)[this->trasparent[i]];
359          face& fac2 =  (this->bspFile->faces)[this->trasparent[i+1]];
360
361          // get center of face 1
362          const BspVertex* curVertex = (BspVertex *) this->bspFile->vertice;
363         
364          if (this->sortTransparencyMore == 1)
365          {
366              // assign the values of the vertices
367              float maxDist = 0;
368              float curDist = 0;
369              int maxVert = fac1.vertex;
370              for (int v = 0; v < fac1.n_vertexes; v++)
371              {
372                    v1(curVertex[fac1.vertex + v].position[0], curVertex[fac1.vertex + v].position[1], curVertex[fac1.vertex + v].position[2]);
373                    curDist = (this->cam - v1).len();
374                    if (curDist > maxDist)
375                    {
376                        maxDist = curDist;
377                        maxVert = fac1.vertex + v;
378                    }
379              }
380              v1(curVertex[maxVert].position[0], curVertex[maxVert].position[1], curVertex[maxVert].position[2]);
381
382              maxDist = 0;
383              curDist = 0;
384              maxVert = fac1.vertex;
385              for (int v = 0; v < fac2.n_vertexes; v++)
386              {
387                    v2(curVertex[fac2.vertex + v].position[0], curVertex[fac2.vertex + v].position[1], curVertex[fac2.vertex + v].position[2]);
388                    curDist = (this->cam - v2).len();
389                    if (curDist > maxDist)
390                    {
391                        maxDist = curDist;
392                        maxVert = fac2.vertex + v;
393                    }
394              }
395              v2(curVertex[maxVert].position[0], curVertex[maxVert].position[1], curVertex[maxVert].position[2]);
396          }
397          else
398          {
399              v1(curVertex[fac1.vertex].position[0], curVertex[fac1.vertex].position[1], curVertex[fac1.vertex].position[2]);
400              v2(curVertex[fac2.vertex].position[0], curVertex[fac2.vertex].position[1], curVertex[fac2.vertex].position[2]);
401          }
402
403          // relativly to observer
404          v1 = this->cam - v1;
405          v2 = this->cam - v2;
406
407
408*/
409          // swap if necessary
410//          if( v1.len() - v2.len() > 1)
411          if( distToPlayer[i] - distToPlayer[i+1] > 1)
412          {
413            // swap elements
414            float tmp1 = distToPlayer[i+1];
415            distToPlayer[i+1] = distToPlayer[i];
416            distToPlayer[i] = tmp1;
417           
418            int tmp2 = this->trasparent[i+1];
419            this->trasparent[i+1] = this->trasparent[i];
420            this->trasparent[i] = tmp2;
421
422            //printf( "has swapped: %d\n", i );
423
424            //v1.debug();
425            //v2.debug();
426            hasSwapped = true;
427          }
428        }
429      }
430      //printf("hasSwapped == false\n");
431  }
432
433
434  // draw all solid faces
435  while(!this->opal.empty()) {
436    this->draw_face(this->opal.back()); // front()
437    this->opal.pop_back();              // pop_back()
438  }
439
440  // draw all transparent faces
441  while(!this->trasparent.empty()) {
442    this->draw_face(this->trasparent.back());
443    this->trasparent.pop_back();
444  }
445  //glEnable(GL_TEXTURE_2D);
446  glActiveTextureARB(GL_TEXTURE1_ARB);
447  glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap);
448
449
450
451}//draw
452
453
454
455void BspManager::draw_face(int curface)
456{
457  face& curFace =  (this->bspFile->faces)[curface];
458  const BspVertex* curVertex = (BspVertex *) this->bspFile->vertice;
459  int stride = sizeof(BspVertex);  // sizeof(Vertex)
460  int offset    = curFace.vertex;
461  if (curFace.effect != -1) return;
462  // PRINTF(0)("BSP Manager: ");
463  // PRINTF(0)("BSP Manager: type: %i  \n", curFace.texture);
464
465  //  if(  curFace.texture < 0 ) return;
466  if(curFace.type == 2) {
467    this->draw_patch( &curFace);
468    return;
469  }
470  // if(curFace.type != 1) return;
471  if((char*)(this->bspFile->textures)[curFace.texture*72]== 0) return;
472
473  if(this->lastTex != curFace.texture) {
474    if(this->bspFile->Materials[curFace.texture].animated) {
475      // glBlendFunc(GL_ZERO,GL_ONE);
476
477
478
479      if(this->bspFile->Materials[curFace.texture].aviMat->getStatus() == 2) this->bspFile->Materials[curFace.texture].aviMat->start(0);
480      //this->bspFile->Materials[curFace.texture].aviMat->tick(0.005);
481      int n =  this->bspFile->Materials[curFace.texture].aviMat->getTexture();
482      glActiveTextureARB(GL_TEXTURE0_ARB);
483      glBindTexture(GL_TEXTURE_2D, n );
484      this->lastTex = curFace.texture;
485
486    } else {
487      this->bspFile->Materials[curFace.texture].mat->select();
488      this->lastTex = curFace.texture;
489    }
490  }
491
492  if(curFace.lm_index < 0) {
493    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
494    glActiveTextureARB(GL_TEXTURE1_ARB);
495    glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap );
496    glEnable(GL_TEXTURE_2D);
497  } else {
498    // glEnable(GL_BLEND);
499    //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
500    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
501    glActiveTextureARB(GL_TEXTURE1_ARB);
502    glBindTexture(GL_TEXTURE_2D, this->bspFile->glLightMapTextures[curFace.lm_index]);
503    glEnable(GL_TEXTURE_2D);
504    //  glDisable(GL_BLEND);
505  }
506
507  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
508
509  // glColor4f(3.0,3.0,3.0,1.0);
510  glEnableClientState(GL_VERTEX_ARRAY );
511  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
512  glEnableClientState(GL_NORMAL_ARRAY );
513  //  glEnableClientState(GL_COLOR_ARRAY);
514
515
516  glVertexPointer(3, GL_FLOAT, stride, &(curVertex[offset].position[0]));
517
518  glClientActiveTextureARB(GL_TEXTURE0_ARB);
519  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[0]));
520  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
521
522  glClientActiveTextureARB(GL_TEXTURE1_ARB);
523  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[1]));
524  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
525
526
527  glNormalPointer( GL_FLOAT, stride, &(curVertex[offset].normal[0]));
528  // glColorPointer(4, GL_BYTE, stride, &(curVertex[offset].color[0]));
529  glDrawElements(GL_TRIANGLES, curFace.n_meshverts,
530                 GL_UNSIGNED_INT, &(((meshvert *)this->bspFile->meshverts) [curFace.meshvert]));
531
532  glDisableClientState(GL_TEXTURE0_ARB);
533  glDisableClientState(GL_TEXTURE1_ARB);
534  glDisableClientState(GL_VERTEX_ARRAY );
535  glDisableClientState(GL_TEXTURE_COORD_ARRAY );
536  glDisableClientState(GL_NORMAL_ARRAY );
537  // glDisableClientState(GL_COLOR_ARRAY);
538
539}
540
541
542void BspManager::draw_debug_face(int curface)
543{
544  face& curFace =  (this->bspFile->faces)[curface];
545  const BspVertex* curVertex = (BspVertex *) this->bspFile->vertice;
546  int stride = 44;  // sizeof(Vertex)
547  int offset    = curFace.vertex;
548
549  // PRINTF(0)("BSP Manager: ");
550  // PRINTF(0)("BSP Manager: type: %i  \n", curFace.texture);
551
552  //  if(  curFace.texture < 0 ) return;
553  if(curFace.type == 2) {
554    this->draw_patch( &curFace);
555    return;
556  }
557  if(curFace.type == 3) return;
558  // if(this->bspFile->Materials[curFace.texture] != NULL)
559
560  this->bspFile->Materials[2].mat->select();
561  this->lastTex = 2;
562
563  glEnableClientState(GL_VERTEX_ARRAY );
564  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
565  glEnableClientState(GL_NORMAL_ARRAY );
566  //glEnableClientState(GL_COLOR_ARRAY);
567  // glEnableClientState(GL_VERTEX_ARRAY );
568  glClientActiveTextureARB(GL_TEXTURE0_ARB);
569  glVertexPointer(3, GL_FLOAT, stride, &(curVertex[offset].position[0]));
570  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
571  // glClientActiveTextureARB(GL_TEXTURE0_ARB);
572  glClientActiveTextureARB(GL_TEXTURE1_ARB);
573  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[0]));
574  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
575  // glClientActiveTextureARB(GL_TEXTURE1_ARB);
576  // glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[1]));
577  //glEnableClientState(GL_NORMAL_ARRAY );
578
579  glNormalPointer( GL_FLOAT, stride, &(curVertex[offset].normal[0]));
580  //  glColorPointer(4, GL_BYTE, stride, &(curVertex[offset].color[0]));
581  glDrawElements(GL_TRIANGLES, curFace.n_meshverts,
582                 GL_UNSIGNED_INT, &(((meshvert *)this->bspFile->meshverts) [curFace.meshvert]));
583
584}
585
586void BspManager::draw_patch(face* Face)
587{
588  if(this->lastTex != Face->texture) {
589    this->bspFile->Materials[Face->texture].mat->select();
590    this->lastTex = Face->texture;
591  }
592  if (Face->effect != -1) return;
593
594
595  if(Face->lm_index < 0) {
596    glActiveTextureARB(GL_TEXTURE1_ARB);
597    glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap);
598    glEnable(GL_TEXTURE_2D);
599  } else {
600    glActiveTextureARB(GL_TEXTURE1_ARB);
601    glBindTexture(GL_TEXTURE_2D, this->bspFile->glLightMapTextures[Face->lm_index]);
602    glEnable(GL_TEXTURE_2D);
603  }
604  //glColor4f(3.0,3.0,3.0,1.0);
605
606  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
607  glEnable( GL_AUTO_NORMAL);
608  glEnableClientState(GL_VERTEX_ARRAY );
609  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
610  for(int i = Face->n_meshverts -1; i >=0   ; i--) {
611    //glFrontFace(GL_CW);
612    //PRINTF(0)("BSP Manager: Face->size[0]: %i . \n", Face->size[0]);
613
614
615    //glEnableClientState(GL_NORMAL_ARRAY );
616
617    glVertexPointer(3, GL_FLOAT,44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).position[0]));
618
619
620    glClientActiveTextureARB(GL_TEXTURE0_ARB);
621    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
622    glTexCoordPointer(2, GL_FLOAT, 44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).texcoord[0][0]));
623
624
625
626    glClientActiveTextureARB(GL_TEXTURE1_ARB);
627    glTexCoordPointer(2, GL_FLOAT, 44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).texcoord[1][0]));
628    //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
629
630
631    //  glNormalPointer( GL_FLOAT, 44,&((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).normal[0]) );
632
633
634
635
636    for(int row=6; row>=0; --row) {
637      glDrawElements(GL_TRIANGLE_STRIP, 2*(8), GL_UNSIGNED_INT,
638                     & (     (((GLuint*)  (this->bspFile->patchIndexes))[7*8*2*(Face->meshvert+i)+ row*2*8]  ))  );
639    }
640
641    //glFrontFace(GL_CCW);
642  }
643  glDisableClientState(GL_TEXTURE0_ARB);
644  glDisableClientState(GL_TEXTURE1_ARB);
645  glDisable(GL_AUTO_NORMAL);
646  glDisableClientState(GL_VERTEX_ARRAY );
647  glDisableClientState(GL_TEXTURE_COORD_ARRAY );
648
649
650}
651
652bool BspManager::isAlreadyVisible(int Face)
653{
654  return this->alreadyVisible[Face];
655}
656
657
658BspTreeNode*  BspManager::getLeaf(BspTreeNode* node, Vector* cam)
659{
660  float dist = 0;
661  while(!(node->isLeaf)) {
662    dist = (node->plane.x * this->cam.x + node->plane.y*this->cam.y + node->plane.z*this->cam.z) - node->d;
663    if(dist >= 0.0f) {
664      node = node->left;
665    } else {
666      node = node->right;
667    }
668  }
669  return  node;
670}
671
672void BspManager::checkBrushRay(brush* curBrush)
673{
674  float EPSILON = 0.000001;
675  float startDistance;
676  float endDistance;
677
678  float startFraction = -1.0f;
679  float endFraction = 1.0f;
680  bool startsOut = false;
681  bool endsOut = false;
682
683  Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
684  Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
685
686  for (int i = 0; i < curBrush->n_brushsides; i++) {
687    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
688    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
689
690    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
691    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
692
693    if (startDistance > 0)
694      startsOut = true;
695    if (endDistance > 0)
696      endsOut = true;
697
698    // make sure the trace isn't completely on one side of the brush
699    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
700      return;
701    }
702    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
703      continue;
704    }
705
706    // MMM... BEEFY
707    if (startDistance > endDistance) {   // line is entering into the brush
708      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
709      if (fraction > startFraction)
710        startFraction = fraction;
711      // don't store plane
712      // this->collPlane = &curPlane;
713
714    } else {   // line is leaving the brush
715      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
716      if (fraction < endFraction)
717        endFraction = fraction;
718      // don't store plane
719      //this->collPlane = & curPlane;
720
721    }
722
723  }
724  if (startsOut == false) {
725    this->outputStartsOut = false;
726    if (endsOut == false)
727      this->outputAllSolid = true;
728    return;
729  }
730
731  if (startFraction < endFraction) {
732    if (startFraction > -1.0f && startFraction < outputFraction) {
733      if (startFraction < 0)
734        startFraction = 0;
735      this->outputFraction = startFraction;
736    }
737  }
738
739}
740
741void BspManager::checkBrushRayN(brush* curBrush)
742{
743  float EPSILON = 0.000001;
744  float startDistance;
745  float endDistance;
746
747  float startFraction = -1.0f;
748  float endFraction = 1.0f;
749  bool  startsOut = false;
750  bool  endsOut = false;
751
752  // Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
753  // Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
754
755  for (int i = 0; i < curBrush->n_brushsides; i++) {
756    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
757    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
758
759    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
760    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
761
762    if (startDistance > 0)
763      startsOut = true;
764    if (endDistance > 0)
765      endsOut = true;
766
767    // make sure the trace isn't completely on one side of the brush
768    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
769      return;
770    }
771    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
772      continue;
773    }
774
775    // MMM... BEEFY
776    if (startDistance > endDistance) {   // line is entering into the brush
777      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
778      if (fraction > startFraction)
779        startFraction = fraction;
780      // store plane
781      this->collPlane = &curPlane;
782
783    } else {   // line is leaving the brush
784      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
785      if (fraction < endFraction)
786        endFraction = fraction;
787      // store plane
788      this->collPlane = & curPlane;
789
790    }
791
792  }
793  if (startsOut == false) {
794    this->outputStartsOut = false;
795    if (endsOut == false)
796      this->outputAllSolid = true;
797    return;
798  }
799
800  if (startFraction < endFraction) {
801    if (startFraction > -1.0f && startFraction < outputFraction) {
802      if (startFraction < 0)
803        startFraction = 0;
804      this->outputFraction = startFraction;
805    }
806  }
807
808}
809
810void BspManager::checkBrushRayN(brush* curBrush, Vector& inputStart, Vector& inputEnd)
811{
812  float EPSILON = 0.000001;
813  float startDistance;
814  float endDistance;
815
816  float startFraction = -1.0f;
817  float endFraction = 1.0f;
818  bool  startsOut = false;
819  bool  endsOut = false;
820
821  //Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
822  //Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
823
824  for (int i = 0; i < curBrush->n_brushsides; i++) {
825    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
826    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
827
828    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
829    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
830
831    if (startDistance > 0)
832      startsOut = true;
833    if (endDistance > 0)
834      endsOut = true;
835
836    // make sure the trace isn't completely on one side of the brush
837    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
838      return;
839    }
840    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
841      continue;
842    }
843
844    // MMM... BEEFY
845    if (startDistance > endDistance) {   // line is entering into the brush
846      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
847      if (fraction > startFraction)
848        startFraction = fraction;
849      // store plane
850      this->collPlane = &curPlane;
851
852    } else {   // line is leaving the brush
853      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
854      if (fraction < endFraction)
855        endFraction = fraction;
856      // store plane
857      this->collPlane = & curPlane;
858
859    }
860
861  }
862  if (startsOut == false) {
863    this->outputStartsOut = false;
864    if (endsOut == false)
865      this->outputAllSolid = true;
866    return;
867  }
868
869  if (startFraction < endFraction) {
870    if (startFraction > -1.0f && startFraction < outputFraction) {
871      if (startFraction < 0)
872        startFraction = 0;
873      this->outputFraction = startFraction;
874    }
875  }
876
877}
878
879
880void BspManager::checkCollisionRay(BspTreeNode* node, float startFraction, float endFraction, Vector* start, Vector* end)
881{
882
883
884  float EPSILON = 0.000001;
885  float  endDistance = (end)->x * (node->plane.x) +(end)->y * (node->plane.y) +(end)->z * (node->plane.z)  - node->d;
886  float  startDistance = (start)->x * (node->plane.x)+ (start)->y * (node->plane.y)+ (start)->z * (node->plane.z)- node->d;
887
888
889  if(node->isLeaf) {
890    leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
891    for (int i = 0; i <  curLeaf.n_leafbrushes ; i++) {
892      brush& curBrush = this->bspFile->brushes[((int*)(this->bspFile->leafBrushes))[curLeaf.leafbrush_first+i]];
893      //object *brush = &BSP.brushes[BSP.leafBrushes[leaf->firstLeafBrush + i]];
894      if (curBrush.n_brushsides > 0   &&
895          ((((BspTexture*)(this->bspFile->textures))[curBrush.texture]).contents & 1))
896        // CheckBrush( brush );
897        this->checkBrushRay(&curBrush);
898      if(curBrush.n_brushsides <=0) this->outputAllSolid = true;
899    }
900    return;
901  }
902
903
904  if (startDistance >= 0 && endDistance >= 0)     // A
905  {   // both points are in front of the plane
906    // so check the front child
907    this->checkCollisionRay(node->left,0,0,start,end);
908  } else if (startDistance < 0 && endDistance < 0)  // B
909  {   // both points are behind the plane
910    // so check the back child
911    this->checkCollisionRay(node->right,0,0,start,end);
912  } else                                            // C
913  {   // the line spans the splitting plane
914    int side;
915    float fraction1, fraction2, middleFraction;
916    Vector middle;
917
918    // STEP 1: split the segment into two
919    if (startDistance < endDistance) {
920      side = 1; // back
921      float inverseDistance = 1.0f / (startDistance - endDistance);
922      fraction1 = (startDistance + EPSILON) * inverseDistance;
923      fraction2 = (startDistance + EPSILON) * inverseDistance;
924    } else if (endDistance < startDistance) {
925      side = 0; // front(start)->x * (node->plane.x)+
926      float inverseDistance = 1.0f / (startDistance - endDistance);
927      fraction1 = (startDistance + EPSILON) * inverseDistance;
928      fraction2 = (startDistance - EPSILON) * inverseDistance;
929    } else {
930      side = 0; // front
931      fraction1 = 1.0f;
932      fraction2 = 0.0f;
933    }
934
935    // STEP 2: make sure the numbers are valid
936    if (fraction1 < 0.0f) fraction1 = 0.0f;
937    else if (fraction1 > 1.0f) fraction1 = 1.0f;
938    if (fraction2 < 0.0f) fraction2 = 0.0f;
939    else if (fraction2 > 1.0f) fraction2 = 1.0f;
940
941    // STEP 3: calculate the middle point for the first side
942    middleFraction = startFraction +
943                     (endFraction - startFraction) * fraction1;
944
945    middle.x = start->x + fraction1 * (end->x - start->x);
946    middle.y = start->y + fraction1 * (end->y - start->y);
947    middle.z = start->z + fraction1 * (end->z - start->z);
948
949    // STEP 4: check the first side
950    //CheckNode( node->children[side], startFraction, middleFraction, start, middle );
951    if(side == 0) this->checkCollisionRay(node->left,startFraction, middleFraction, start, &middle );
952
953    else this->checkCollisionRay(node->right,startFraction, middleFraction,
954                                   start, &middle );
955
956    // STEP 5: calculate the middle point for the second side
957    middleFraction = startFraction +
958                     (endFraction - startFraction) * fraction2;
959
960    middle.x = start->x + fraction2 * (end->x - start->x);
961    middle.y = start->y + fraction2 * (end->y - start->y);
962    middle.z = start->z + fraction2 * (end->z - start->z);
963
964    // STEP 6: check the second side
965    if(side == 1)this->checkCollisionRay(node->left,middleFraction, endFraction, &middle, end);
966
967    else this->checkCollisionRay(node->right,middleFraction, endFraction,&middle, end );
968
969
970  }
971
972}
973
974
975
976void BspManager::checkCollisionRayN(BspTreeNode* node, float startFraction, float endFraction, Vector* start, Vector* end)
977{
978
979
980  float EPSILON = 0.000001;
981
982  float endDistance = end->dot(node->plane) - node->d;
983  float startDistance = start->dot(node->plane) - node->d;
984 
985  if( node->isLeaf) {
986    leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
987    for (int i = 0; i <  curLeaf.n_leafbrushes ; i++) {
988      brush& curBrush = this->bspFile->brushes[((int*)(this->bspFile->leafBrushes))[curLeaf.leafbrush_first+i]];
989      //object *brush = &BSP.brushes[BSP.leafBrushes[leaf->firstLeafBrush + i]];
990      if (curBrush.n_brushsides > 0   &&
991          ((((BspTexture*)(this->bspFile->textures))[curBrush.texture]).contents & 1))
992        // CheckBrush( brush );
993        this->checkBrushRayN(&curBrush);
994      if(curBrush.n_brushsides <=0) this->outputAllSolid = true;
995    }
996
997    return;
998  }
999
1000  //TODO valgrind complains about uninitialised value here
1001  if (startDistance >= 0 && endDistance >= 0)     // A
1002  {   // both points are in front of the plane
1003    // so check the front child
1004    this->checkCollisionRayN(node->left,0,0,start,end);
1005  } else if (startDistance < 0 && endDistance < 0)  // B
1006  {   // both points are behind the plane
1007    // so check the back child
1008    this->checkCollisionRayN(node->right,0,0,start,end);
1009  } else                                            // C
1010  {   // the line spans the splitting plane
1011    int side;
1012    float fraction1, fraction2, middleFraction;
1013    Vector middle;
1014
1015    // STEP 1: split the segment into two
1016    if (startDistance < endDistance) {
1017      side = 1; // back
1018      float inverseDistance = 1.0f / (startDistance - endDistance);
1019      fraction1 = (startDistance + EPSILON) * inverseDistance;
1020      fraction2 = (startDistance + EPSILON) * inverseDistance;
1021    } else if (endDistance < startDistance) {
1022      side = 0; // front(start)->x * (node->plane.x)+
1023      float inverseDistance = 1.0f / (startDistance - endDistance);
1024      fraction1 = (startDistance + EPSILON) * inverseDistance;
1025      fraction2 = (startDistance - EPSILON) * inverseDistance;
1026    } else {
1027      side = 0; // front
1028      fraction1 = 1.0f;
1029      fraction2 = 0.0f;
1030    }
1031
1032    // STEP 2: make sure the numbers are valid
1033    if (fraction1 < 0.0f) fraction1 = 0.0f;
1034    else if (fraction1 > 1.0f) fraction1 = 1.0f;
1035    if (fraction2 < 0.0f) fraction2 = 0.0f;
1036    else if (fraction2 > 1.0f) fraction2 = 1.0f;
1037
1038    // STEP 3: calculate the middle point for the first side
1039    middleFraction = startFraction + (endFraction - startFraction) * fraction1;
1040    middle = (*start) + ((*end) - (*start)) * fraction1;
1041
1042
1043    // STEP 4: check the first side
1044    //CheckNode( node->children[side], startFraction, middleFraction, start, middle );
1045    if(side == 0) this->checkCollisionRayN(node->left,startFraction, middleFraction, start, &middle );
1046
1047    else this->checkCollisionRayN(node->right,startFraction, middleFraction,
1048                                    start, &middle );
1049
1050    // STEP 5: calculate the middle point for the second side
1051    middleFraction = startFraction + (endFraction - startFraction) * fraction2;
1052    middle = (*start) + ((*end) - (*start)) * fraction2;
1053
1054    // STEP 6: check the second side
1055    if(side == 1)this->checkCollisionRayN(node->left,middleFraction, endFraction, &middle, end);
1056
1057    else this->checkCollisionRayN(node->right,middleFraction, endFraction,&middle, end );
1058
1059
1060  }
1061
1062}
1063
1064float BspManager::checkPatchAltitude(BspTreeNode* node)
1065{
1066  leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
1067  for(int i = 0; i < curLeaf.n_leaffaces ; i++) {}
1068  return 10.0f;
1069}
1070
1071void BspManager::checkCollisionBox(void)
1072{}
1073
1074
1075void BspManager::TraceBox( Vector& inputStart, Vector& inputEnd,
1076                           Vector& inputMins, Vector& inputMaxs )
1077{
1078  if (inputMins.x == 0 && inputMins.y == 0 && inputMins.z == 0 &&
1079      inputMaxs.x == 0 && inputMaxs.y == 0 && inputMaxs.z == 0) {   // the user called TraceBox, but this is actually a ray
1080    //!> FIXME TraceRay( inputStart, inputEnd );
1081  } else {   // setup for a box
1082    //traceType = TT_BOX;
1083    this->traceMins = inputMins;
1084    this->traceMaxs = inputMaxs;
1085    this->traceExtents.x = -traceMins.x > traceMaxs.x ?
1086                           -traceMins.x : traceMaxs.x;
1087    this->traceExtents.y = -traceMins.y > traceMaxs.y ?
1088                           -traceMins.y : traceMaxs.y;
1089    this->traceExtents.z = -traceMins.z > traceMaxs.z ?
1090                           -traceMins.z : traceMaxs.z;
1091    //!> FIXME Trace( inputStart, inputEnd );
1092  }
1093}
1094
1095void BspManager::checkCollision(WorldEntity* worldEntity)
1096{
1097
1098  // Init  Collision Detection
1099  this->outputStartsOut = true;
1100  this->outputAllSolid = false;
1101  this->outputFraction = 1.0f;
1102
1103  this->checkCollisionX(worldEntity);
1104  this->checkCollisionZ(worldEntity);
1105
1106  if(!(this->checkCollisionY(worldEntity)))
1107  this->checkCollisionWay(worldEntity);
1108
1109
1110#if 0
1111  // Retrieve Bounding box
1112  AABB* box = worldEntity->getModelAABB();
1113
1114
1115  Vector forwardDir = Vector(0.0,0.0,1.0);
1116  Vector upDir = Vector(0.0,1.0,0.0);
1117  Vector position = worldEntity->getAbsCoor();
1118
1119  bool SolidFlag = false;
1120  bool collision = false;
1121  Vector position1 = position;
1122  Vector position2 = position + Vector(0.0,1.0,0.0);
1123  Vector position3 = position;
1124  Vector position4 = position + Vector(0.0,1.0,0.0);
1125  Vector dest = worldEntity->getAbsCoor() - upDir*40.0f; //
1126  Vector dest1 = position + forwardDir*4.0f;
1127  Vector dest2 = position2 + forwardDir*4.0;
1128  Vector dest3 = position + forwardDir*4.0f;
1129  Vector dest4 = position2 + forwardDir*4.0;
1130  dest = position - Vector(0.0, 40.0,0.0);
1131  Vector out = dest;
1132  Vector out1;
1133  Vector out2;
1134
1135
1136  plane* testPlane;
1137
1138  bool xCollision = false;
1139  bool zCollision = false;
1140
1141
1142  float height = 40;
1143
1144
1145  if( box != NULL) {
1146    position = worldEntity->getAbsCoor() +  box->center; // + Vector(0.0, 1.0, 0.0) * box->halfLength[1] * 1.0f;
1147    dest     = worldEntity->getAbsCoor() +  box->center - Vector(0.0, 1.0, 0.0) * (box->halfLength[1] + BSP_Y_OFFSET) *   100;
1148
1149    Vector dirX =  worldEntity->getAbsDirX(); dirX.y = 0.0f; dirX.normalize();
1150
1151    //position1 = worldEntity->getAbsCoor() +  box->center - dirX * (box->halfLength[0]  + BSP_X_OFFSET);
1152    dest1     = worldEntity->getAbsCoor() +  box->center + dirX * (box->halfLength[0]  + BSP_X_OFFSET);
1153    dest2     = worldEntity->getAbsCoor() -  box->center + dirX * (box->halfLength[0]  + BSP_X_OFFSET);
1154
1155    Vector dirZ =  worldEntity->getAbsDirZ(); dirX.y = 0.0f; dirZ.normalize();
1156    //position2 = worldEntity->getAbsCoor() +  box->center - dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
1157    dest3     = worldEntity->getAbsCoor() +  box->center + dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
1158    dest4     = worldEntity->getAbsCoor() -  box->center + dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
1159  } else {
1160    // Init positions and destinations to anything useful!
1161
1162  }
1163
1164
1165
1166  // 1st Ray: Y RAY
1167  this->inputStart =  position;
1168  this->inputEnd =   dest;
1169  this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &dest );
1170
1171
1172  //
1173  if(!this->outputStartsOut ) {
1174    this->collPlane = new plane;
1175    this->collPlane->x = 0.0f;
1176    this->collPlane->y = 0.0f;
1177    this->collPlane->z = 0.0f;
1178    collision = true;
1179  } else {
1180
1181    if( this->outputFraction == 1.0f) {
1182      if(this->outputAllSolid ) {
1183        this->collPlane = new plane;
1184        this->collPlane->x = 0.0f;
1185        this->collPlane->y = 0.0f;
1186        this->collPlane->z = 0.0f;
1187        collision = true;
1188        SolidFlag = true;
1189      } else
1190        collision = false;
1191
1192
1193      out = dest;
1194
1195    } else {
1196      collision = true;
1197      out.x = position.x + (dest.x -position.x) * this->outputFraction;
1198      out.y = position.y + (dest.y -position.y) * this->outputFraction;
1199      out.z = position.z + (dest.z -position.z) * this->outputFraction;
1200
1201      Vector out3 = out + Vector(height*this->collPlane->x,height*this->collPlane->y,height*this->collPlane->z);
1202      this->out = out;
1203    }
1204  }
1205    testPlane = this->collPlane;
1206
1207
1208  bool xCollisionNeg = false;
1209  bool zCollisionNeg = false;
1210
1211
1212
1213    // 2nd Collision Detection X-RAY
1214    this->outputStartsOut = true;
1215    this->outputAllSolid = false;
1216    this->outputFraction = 1.0f;
1217    this->inputStart =  position1;
1218    this->inputEnd =   dest1;
1219    this->checkCollisionRayN(this->root,0.0f,1.0f, &position1, &dest1 );
1220
1221    if(this->outputFraction < 1.0f) {
1222      out.x = dest1.x + (dest1.x -position1.x) * this->outputFraction;
1223      dest1 = position1 + (dest1 -position1) * this->outputFraction;
1224      xCollision = true;
1225      testPlane = this->collPlane;
1226    }
1227    if(this->outputAllSolid ) {
1228
1229      this->collPlane = new plane;
1230      this->collPlane->x = 0.0f;
1231      this->collPlane->y = 0.0f;
1232      this->collPlane->z = 0.0f;
1233      testPlane = this->collPlane;
1234      SolidFlag = true;
1235      xCollision = true;
1236    }
1237    //out.z = this->outputFraction;
1238
1239
1240
1241      // 3rd Collision Detection Z-RAY
1242      this->outputStartsOut = true;
1243      this->outputAllSolid = false;
1244      this->outputFraction = 1.0f;
1245      this->inputStart =  position2;
1246      this->inputEnd =   dest2;
1247
1248      this->checkCollisionRayN(this->root,0.0f,1.0f, &position2, &dest2 );
1249      //out.x = this->outputFraction;
1250
1251      if(this->outputFraction < 1.0f ) {
1252        out.z = out.z = dest2.z + (dest2.z -position2.z) * this->outputFraction;
1253        dest2 = position2 + (dest2 -position2) * this->outputFraction;
1254        zCollision = true;
1255        testPlane = this->collPlane;
1256
1257      }
1258      if(this->outputAllSolid ) {
1259        this->collPlane = new plane;
1260        this->collPlane->x = 0.0f;
1261        this->collPlane->y = 0.0f;
1262        this->collPlane->z = 0.0f;
1263        testPlane = this->collPlane;
1264
1265        SolidFlag = true;
1266        zCollision = true;
1267      }
1268
1269
1270  // Return the normal here: Normal's stored in this->collPlane;
1271  if( collision) {
1272    worldEntity->registerCollision(COLLISION_TYPE_AXIS_Y , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z), out, SolidFlag);
1273}
1274  if(xCollision) {
1275    worldEntity->registerCollision(COLLISION_TYPE_AXIS_X , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z),dest1 , SolidFlag);
1276  }
1277
1278  if(zCollision) {
1279    worldEntity->registerCollision(COLLISION_TYPE_AXIS_Z , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z), dest2 , SolidFlag);
1280  }
1281#endif
1282
1283}
1284
1285
1286
1287/**
1288 * check the collision in the x direction (forward, backward)
1289 */
1290bool BspManager::checkCollisionX(WorldEntity* entity)
1291{
1292  // Retrieve Bounding box
1293  AABB* box = entity->getModelAABB();
1294
1295
1296  plane*            testPlane          = NULL;  //!< the collision test plane
1297
1298  Vector            forward;                    //!< left collision ray
1299  Vector            backward;                   //!< right collision ray
1300  Vector            collPos;                    //!< the collision position
1301
1302  bool              xCollisionForward  = false; //!< flag true if right collision
1303  bool              xCollisionBackward = false; //!< flag true if left collision
1304  bool              SolidFlag          = false; //!< flag set true if solid
1305
1306  Vector            position;                   //!< current position of the entity
1307  Vector            dirX;                       //!< direction x
1308
1309  position = entity->getAbsCoor();
1310  dirX =  entity->getAbsDirX(); dirX.y = 0.0f; dirX.normalize();
1311
1312  // calculate the rays
1313  if( box != NULL)
1314  {
1315    forward  = entity->getAbsCoor() +  box->center + dirX * (box->halfLength[0]  + BSP_X_OFFSET);
1316    backward = entity->getAbsCoor() +  box->center - dirX * (box->halfLength[0]  + BSP_X_OFFSET);
1317  }
1318  else
1319  {
1320    forward  = position + dirX * 4.0f;
1321    backward = position + Vector(0.0, 1.0, 0.0) + dirX * 4.0;
1322  }
1323
1324
1325  /*   X Ray forward  */
1326  // init some member variables before collision check
1327  this->outputStartsOut = true;
1328  this->outputAllSolid = false;
1329  this->outputFraction = 1.0f;
1330  this->inputStart =  position;
1331  this->inputEnd =   forward;
1332  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &forward );
1333
1334  // collision occured
1335  if( this->outputFraction < 1.0f)
1336  {
1337    collPos = position + (forward - position) * this->outputFraction;
1338    xCollisionForward = true;
1339    testPlane = this->collPlane;
1340  }
1341  if(this->outputAllSolid )
1342  {
1343    this->collPlane = new plane;
1344    this->collPlane->x = 0.0f;
1345    this->collPlane->y = 0.0f;
1346    this->collPlane->z = 0.0f;
1347    testPlane = this->collPlane;
1348    SolidFlag = true;
1349    xCollisionForward = true;
1350  }
1351
1352  // collision registration
1353  if( xCollisionForward)
1354  {
1355    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X ,
1356                              entity, this->parent,
1357                              Vector(testPlane->x, testPlane->y, testPlane->z),
1358                              collPos,
1359                              SolidFlag);
1360  }
1361
1362
1363
1364  /*   X Ray backward  */
1365  // init some member variables before collision check
1366  this->outputStartsOut = true;
1367  this->outputAllSolid = false;
1368  this->outputFraction = 1.0f;
1369  this->inputStart =  position;
1370  this->inputEnd =   backward;
1371  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &backward );
1372
1373  // collision occured
1374  if( this->outputFraction < 1.0f)
1375  {
1376    collPos = position + (backward - position) * this->outputFraction;
1377    xCollisionBackward = true;
1378    testPlane = this->collPlane;
1379  }
1380  if( this->outputAllSolid)
1381  {
1382    this->collPlane = new plane;
1383    this->collPlane->x = 0.0f;
1384    this->collPlane->y = 0.0f;
1385    this->collPlane->z = 0.0f;
1386    testPlane = this->collPlane;
1387    SolidFlag = true;
1388    xCollisionBackward = true;
1389  }
1390
1391  // collision registration
1392  if( xCollisionBackward)
1393  {
1394    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X_NEG,
1395                              entity, this->parent,
1396                              Vector(testPlane->x, testPlane->y, testPlane->z),
1397                              collPos,
1398                              SolidFlag);
1399  }
1400
1401 return (xCollisionBackward || xCollisionForward);
1402}
1403
1404
1405/**
1406 * check the collision in the z direction (up, down)
1407 */
1408bool BspManager::checkCollisionY(WorldEntity* entity)
1409{
1410
1411  // Retrieve Bounding box
1412  AABB* box = entity->getModelAABB();
1413
1414
1415  plane*            testPlane          = NULL;  //!< the collision test plane
1416
1417  Vector            up;                         //!< up collision ray
1418  Vector            down;                       //!< down collision ray
1419  Vector            collPos;                    //!< the collision position
1420
1421  bool              yCollisionUp       = false; //!< flag true if right collision
1422  bool              yCollisionDown     = false; //!< flag true if left collision
1423  bool              SolidFlag          = false; //!< flag set true if solid
1424
1425  Vector            position;                   //!< current position of the entity
1426  Vector            dirY;                       //!< direction x
1427
1428  position = entity->getAbsCoor();
1429  collPos = position;
1430  dirY =  Vector(0.0, 1.0, 0.0);
1431
1432  // calculate the rays
1433  if( box != NULL)
1434  {
1435    up   = position +  box->center + dirY * (box->halfLength[1]/*  + BSP_Y_OFFSET*/);
1436    down = position +  box->center - dirY * (box->halfLength[1]  + BSP_Y_OFFSET);
1437  }
1438  else
1439  {
1440    up   = position + dirY * 4.0f;
1441    down = position + Vector(0.0, 1.0, 0.0) + dirY * 4.0;
1442  }
1443
1444
1445
1446
1447  /*   Y Ray up */
1448  // init some member variables before collision check
1449  this->inputStart = position;
1450  this->inputEnd   = up;
1451  this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &up );
1452
1453  if( !this->outputStartsOut )
1454  {
1455    this->collPlane = new plane;
1456    this->collPlane->x = 0.0f;
1457    this->collPlane->y = 0.0f;
1458    this->collPlane->z = 0.0f;
1459    yCollisionUp = true;
1460  }
1461  else
1462  {
1463    if( this->outputFraction == 1.0f)
1464    {
1465      if( this->outputAllSolid )
1466      {
1467        this->collPlane = new plane;
1468        this->collPlane->x = 0.0f;
1469        this->collPlane->y = 0.0f;
1470        this->collPlane->z = 0.0f;
1471        yCollisionUp = true;
1472        SolidFlag = true;
1473      }
1474      else
1475      {
1476        yCollisionUp = false;
1477        collPos = up;
1478      }
1479    }
1480    else
1481    {
1482      yCollisionUp = true;
1483      collPos = position + (up - position) * this->outputFraction;
1484      this->out = collPos;        // why this????
1485    }
1486  }
1487  testPlane = this->collPlane;
1488
1489  // collision registration
1490  if( yCollisionUp)
1491  {
1492    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y,
1493                              entity, this->parent,
1494                              Vector(testPlane->x, testPlane->y, testPlane->z),
1495                              collPos, SolidFlag);
1496  }
1497
1498
1499
1500
1501  /*   Y Ray down */
1502  // init some member variables before collision check
1503  this->inputStart = position;
1504  this->inputEnd   = down;
1505  this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &down );
1506
1507  if( !this->outputStartsOut )
1508  {
1509    this->collPlane = new plane;
1510    this->collPlane->x = 0.0f;
1511    this->collPlane->y = 0.0f;
1512    this->collPlane->z = 0.0f;
1513    yCollisionDown = true;
1514  }
1515  else
1516  {
1517    if( this->outputFraction == 1.0f) // No collision Detected
1518    {
1519      if( this->outputAllSolid )
1520      {
1521        this->collPlane = new plane;
1522        this->collPlane->x = 0.0f;
1523        this->collPlane->y = 0.0f;
1524        this->collPlane->z = 0.0f;
1525        yCollisionDown = true;
1526        SolidFlag = true;
1527      }
1528      else      // No collision happened
1529      {
1530        yCollisionDown = false;
1531        collPos = down;
1532      }
1533    }
1534    else           // A collision has happended
1535    {
1536      yCollisionDown = true;
1537      collPos = position + (down - position) * this->outputFraction;
1538    }
1539  }
1540  testPlane = this->collPlane;
1541
1542  // collision registration
1543  if( yCollisionDown)
1544  {
1545    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG ,
1546                              entity, this->parent,
1547                              Vector(testPlane->x, testPlane->y, testPlane->z),
1548                              collPos, SolidFlag);
1549  }
1550
1551 return (yCollisionUp || yCollisionDown);
1552}
1553
1554
1555
1556
1557/**
1558 * check the collision in the z direction (left, right)
1559 */
1560bool BspManager::checkCollisionZ(WorldEntity* entity)
1561{
1562  // Retrieve Bounding box
1563  AABB* box = entity->getModelAABB();
1564
1565
1566  plane*            testPlane          = NULL;  //!< the collision test plane
1567
1568  Vector            right;                      //!< right collision ray
1569  Vector            left;                       //!< left collision ray
1570  Vector            collPos;                    //!< the collision position
1571
1572  bool              zCollisionRight    = false; //!< flag true if right collision
1573  bool              zCollisionLeft     = false; //!< flag true if left collision
1574  bool              SolidFlag          = false; //!< flag set true if solid
1575
1576  Vector            position;                   //!< current position of the entity
1577  Vector            dirZ;                       //!< direction x
1578
1579  position = entity->getAbsCoor();
1580  dirZ =  entity->getAbsDirZ(); dirZ.y = 0.0f; dirZ.normalize();
1581
1582  // calculate the rays
1583  if( box != NULL)
1584  {
1585    right = entity->getAbsCoor() +  box->center + dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
1586    left  = entity->getAbsCoor() +  box->center - dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
1587  }
1588  else
1589  {
1590    right = position + dirZ * 4.0f;
1591    left  = position + Vector(0.0, 1.0, 0.0) + dirZ * 4.0;
1592  }
1593
1594
1595  /*   Z Ray right */
1596  // init some member variables before collision check
1597  this->outputStartsOut = true;
1598  this->outputAllSolid = false;
1599  this->outputFraction = 1.0f;
1600  this->inputStart =  position;
1601  this->inputEnd =   right;
1602  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &right );
1603
1604
1605  // collision occured
1606  if( this->outputFraction < 1.0f )
1607  {
1608    collPos = position + (right - position) * this->outputFraction;
1609    zCollisionRight = true;
1610    testPlane = this->collPlane;
1611  }
1612  if(this->outputAllSolid )
1613  {
1614    this->collPlane = new plane;
1615    this->collPlane->x = 0.0f;
1616    this->collPlane->y = 0.0f;
1617    this->collPlane->z = 0.0f;
1618    testPlane = this->collPlane;
1619
1620    SolidFlag = true;
1621    zCollisionRight = true;
1622  }
1623
1624
1625  if( zCollisionRight) {
1626    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z ,
1627                              entity, this->parent,
1628                              Vector(testPlane->x, testPlane->y, testPlane->z),
1629                              collPos , SolidFlag);
1630  }
1631
1632
1633
1634  /*   Z Ray left */
1635  // init some member variables before collision check
1636  this->outputStartsOut = true;
1637  this->outputAllSolid = false;
1638  this->outputFraction = 1.0f;
1639  this->inputStart =  position;
1640  this->inputEnd =    left;
1641  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &left);
1642
1643
1644  // collision occured
1645  if( this->outputFraction < 1.0f )
1646  {
1647    collPos = position + (left - position) * this->outputFraction;
1648    zCollisionLeft = true;
1649    testPlane = this->collPlane;
1650  }
1651  if(this->outputAllSolid )
1652  {
1653    this->collPlane = new plane;
1654    this->collPlane->x = 0.0f;
1655    this->collPlane->y = 0.0f;
1656    this->collPlane->z = 0.0f;
1657    testPlane = this->collPlane;
1658
1659    SolidFlag = true;
1660    zCollisionLeft = true;
1661  }
1662
1663
1664  if( zCollisionLeft) {
1665    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z_NEG ,
1666                               entity, this->parent,
1667                               Vector(testPlane->x, testPlane->y, testPlane->z),
1668                               collPos , SolidFlag);
1669  }
1670
1671 return (zCollisionLeft || zCollisionRight);
1672
1673}
1674
1675
1676
1677
1678/**
1679 * check wether a collision occured on the way from the last position to the current position
1680 */
1681bool BspManager::checkCollisionWay(WorldEntity* entity)
1682{
1683
1684
1685 
1686  plane*            testPlane          = NULL;  //!< the collision test plane
1687  Vector            to;
1688  Vector            collPos;                    //!< the collision position
1689
1690  bool              yCollisionUp       = false; //!< flag true if right collision
1691  bool              SolidFlag          = false; //!< flag set true if solid
1692
1693  Vector            from;                   //!< current position of the entity
1694  Vector            dirY;                       //!< direction x
1695
1696  from = entity->getLastAbsCoor();
1697  to    = entity->getAbsCoor();
1698  collPos = from;
1699  dirY =  Vector(0.0, 1.0, 0.0);
1700
1701
1702
1703
1704  /*   Y Ray up */
1705  // init some member variables before collision check
1706  this->inputStart = from;
1707  this->inputEnd   = to;
1708  this->checkCollisionRayN(this->root,0.0f,1.0f, &from, &to );
1709
1710  if( !this->outputStartsOut )
1711  {
1712    this->collPlane = new plane;
1713    this->collPlane->x = 0.0f;
1714    this->collPlane->y = 0.0f;
1715    this->collPlane->z = 0.0f;
1716    yCollisionUp = true;
1717  }
1718  else
1719  {
1720    if( this->outputFraction == 1.0f)
1721    {
1722      if( this->outputAllSolid )
1723      {
1724        this->collPlane = new plane;
1725        this->collPlane->x = 0.0f;
1726        this->collPlane->y = 0.0f;
1727        this->collPlane->z = 0.0f;
1728        yCollisionUp = true;
1729        SolidFlag = true;
1730      }
1731      else
1732      {
1733        yCollisionUp = false;
1734        collPos = to;
1735      }
1736    }
1737    else
1738    {
1739      yCollisionUp = true;
1740      collPos = from + (to - from) * this->outputFraction;
1741      this->out = collPos;        // why this????
1742    }
1743  }
1744  testPlane = this->collPlane;
1745
1746  // collision registration
1747  if( yCollisionUp)
1748  {
1749    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_WAY,
1750                              entity, this->parent,
1751                              Vector(testPlane->x, testPlane->y, testPlane->z),
1752                              collPos, SolidFlag);
1753  }
1754
1755 return yCollisionUp;
1756
1757}
1758
1759
1760
1761
1762void  BspManager::checkCollision(BspTreeNode* node, Vector* cam)
1763{
1764  Vector next = this->cam;
1765  next.x =   (State::getCameraTargetNode()->getLastAbsCoor()).x ;
1766  next.y =   (State::getCameraTargetNode()->getLastAbsCoor()).y ;
1767  next.z =   (State::getCameraTargetNode()->getLastAbsCoor()).z ;
1768
1769  float dist = 0;
1770  if(!(node->isLeaf)) {
1771    dist = (node->plane.x * this->cam.x + node->plane.y*this->cam.y + node->plane.z*this->cam.z) - node->d;
1772    if(dist > 4.0f) {
1773      checkCollision(node->left,cam);
1774      return;
1775    }
1776    if(dist < -4.0f) {
1777      checkCollision(node->right,cam);
1778      return;
1779    }
1780    if(dist<=4.0f && dist >= -4.0f) {
1781      checkCollision(node->left,cam);
1782      checkCollision(node->right,cam);
1783      return;
1784    }
1785    return;
1786  } else {
1787
1788    leaf& camLeaf =  ((leaf *)(this->bspFile->leaves))[(node->leafIndex ) ];
1789
1790    if (camLeaf.cluster < 0) {
1791      this->drawDebugCube(&this->cam);
1792      this->drawDebugCube(&next);
1793      // State::getPlayer()->getPlayable()->setRelCoor(-100,-100,-100);
1794      //State::getPlayer()->getPlayable()->collidesWith(NULL, State::getCameraTargetNode()->getLastAbsCoor());
1795    }
1796
1797
1798    /*
1799        for(int i = 0; i < camLeaf.n_leafbrushes && i < 10; i++ )
1800        {
1801                brush& curBrush = ((brush*)(this->bspFile->brushes))[(camLeaf.leafbrush_first +i)%this->bspFile->numLeafBrushes];
1802                if(curBrush.n_brushsides < 0) return;
1803                for(int j = 0; j < curBrush.n_brushsides; j++)
1804                {
1805                float dist = -0.1;
1806                brushside& curBrushSide = ((brushside*)(this->bspFile->brushSides))[(curBrush.brushside +j)%this->bspFile->numBrushSides];
1807                plane&      testPlane = ((plane*)(this->bspFile->planes))[curBrushSide.plane % this->bspFile->numPlanes];
1808                dist = testPlane.x * this->cam.x +  testPlane.y * this->cam.y  +  testPlane.z * this->cam.z   -testPlane.d ;
1809
1810                if(dist < -0.01f) dist = -1.0f *dist;
1811                if(dist < 1.0f){
1812                                this->drawDebugCube(&this->cam);
1813                                return;
1814                              }
1815                }
1816
1817        } */
1818
1819  }
1820  return;
1821}
1822
1823void BspManager::drawDebugCube(Vector* cam)
1824{
1825  glBegin(GL_QUADS);
1826
1827  // Bottom Face.  Red, 75% opaque, magnified texture
1828
1829  glNormal3f( 0.0f, -1.0f, 0.0f); // Needed for lighting
1830  glColor4f(0.9,0.2,0.2,.75); // Basic polygon color
1831
1832  glTexCoord2f(0.800f, 0.800f); glVertex3f(cam->x-1.0f, cam->y-1.0f,cam->z -1.0f);
1833  glTexCoord2f(0.200f, 0.800f); glVertex3f(cam->x+1.0f, cam->y-1.0f,cam->z -1.0f);
1834  glTexCoord2f(0.200f, 0.200f); glVertex3f(cam->x+ 1.0f,cam->y -1.0f,cam->z +  1.0f);
1835  glTexCoord2f(0.800f, 0.200f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z + 1.0f);
1836
1837
1838  // Top face; offset.  White, 50% opaque.
1839
1840  glNormal3f( 0.0f, 1.0f, 0.0f);  glColor4f(0.5,0.5,0.5,.5);
1841
1842  glTexCoord2f(0.005f, 1.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.0f);
1843  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
1844  glTexCoord2f(1.995f, 0.005f); glVertex3f(cam->x+ 1.0f,  cam->y+1.0f,  cam->z +1.0f);
1845  glTexCoord2f(1.995f, 1.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z -1.0f);
1846
1847
1848  // Far face.  Green, 50% opaque, non-uniform texture cooridinates.
1849
1850  glNormal3f( 0.0f, 0.0f,-1.0f);  glColor4f(0.2,0.9,0.2,.5);
1851
1852  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z -1.3f);
1853  glTexCoord2f(2.995f, 2.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.3f);
1854  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x+ 1.0f,cam->y+  1.0f, cam->z -1.3f);
1855  glTexCoord2f(0.005f, 0.005f); glVertex3f( cam->x+1.0f,cam->y -1.0f, cam->z -1.3f);
1856
1857
1858  // Right face.  Blue; 25% opaque
1859
1860  glNormal3f( 1.0f, 0.0f, 0.0f);  glColor4f(0.2,0.2,0.9,.25);
1861
1862  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y -1.0f, cam->z -1.0f);
1863  glTexCoord2f(0.995f, 0.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z -1.0f);
1864  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z + 1.0f);
1865  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y-1.0f,  cam->z +1.0f);
1866
1867
1868  // Front face; offset.  Multi-colored, 50% opaque.
1869
1870  glNormal3f( 0.0f, 0.0f, 1.0f);
1871
1872  glColor4f( 0.9f, 0.2f, 0.2f, 0.5f);
1873  glTexCoord2f( 0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f,  cam->z +1.0f);
1874  glColor4f( 0.2f, 0.9f, 0.2f, 0.5f);
1875  glTexCoord2f( 0.995f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y-1.0f,  cam->z +1.0f);
1876  glColor4f( 0.2f, 0.2f, 0.9f, 0.5f);
1877  glTexCoord2f( 0.995f, 0.995f); glVertex3f( cam->x+1.0f,  cam->y+1.0f,  cam->z +1.0f);
1878  glColor4f( 0.1f, 0.1f, 0.1f, 0.5f);
1879  glTexCoord2f( 0.005f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
1880
1881
1882  // Left Face; offset.  Yellow, varying levels of opaque.
1883
1884  glNormal3f(-1.0f, 0.0f, 0.0f);
1885
1886  glColor4f(0.9,0.9,0.2,0.0);
1887  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z -1.0f);
1888  glColor4f(0.9,0.9,0.2,0.66);
1889  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x-1.0f,cam->y -1.0f,  cam->z +1.0f);
1890  glColor4f(0.9,0.9,0.2,1.0);
1891  glTexCoord2f(0.995f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
1892  glColor4f(0.9,0.9,0.2,0.33);
1893  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.0f);
1894
1895  glEnd();
1896}
1897
1898void BspManager::addFace(int f)
1899{
1900  face& curFace =  ((face *)(this->bspFile->faces))[f];
1901  if(this->bspFile->Materials[curFace.texture].alpha) this->trasparent.push_back(f);
1902  else this->opal.push_back(f);
1903}
Note: See TracBrowser for help on using the repository browser.