Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/vs-enhencements/src/lib/graphics/importer/bsp/bsp_manager.cc @ 10670

Last change on this file since 10670 was 10670, checked in by nicolasc, 17 years ago

moved "ship attributes" to world entity
electronic and shield widget not yet working

File size: 58.6 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.