Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/importer/bsp/bsp_manager.cc @ 10761

Last change on this file since 10761 was 10698, checked in by snellen, 18 years ago

merged adm, hud, vs-enhancements : beni's responsible for this commit. blame him!

File size: 59.7 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  if (State::showWireframe())
508  {
509    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
510    glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap );
511    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
512  }
513
514  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
515
516  glEnableClientState(GL_VERTEX_ARRAY );
517  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
518  glEnableClientState(GL_NORMAL_ARRAY );
519  //  glEnableClientState(GL_COLOR_ARRAY);
520
521
522  glVertexPointer(3, GL_FLOAT, stride, &(curVertex[offset].position[0]));
523
524  glClientActiveTextureARB(GL_TEXTURE0_ARB);
525  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[0]));
526  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
527
528  glClientActiveTextureARB(GL_TEXTURE1_ARB);
529  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[1]));
530  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
531
532
533  glNormalPointer( GL_FLOAT, stride, &(curVertex[offset].normal[0]));
534  // glColorPointer(4, GL_BYTE, stride, &(curVertex[offset].color[0]));
535  glDrawElements(GL_TRIANGLES, curFace.n_meshverts,
536                 GL_UNSIGNED_INT, &(((meshvert *)this->bspFile->meshverts) [curFace.meshvert]));
537
538  glDisableClientState(GL_TEXTURE0_ARB);
539  glDisableClientState(GL_TEXTURE1_ARB);
540  glDisableClientState(GL_VERTEX_ARRAY );
541  glDisableClientState(GL_TEXTURE_COORD_ARRAY );
542  glDisableClientState(GL_NORMAL_ARRAY );
543  // glDisableClientState(GL_COLOR_ARRAY);
544 
545  if (State::showWireframe())
546  {
547    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
548    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
549  }
550}
551
552
553void BspManager::draw_debug_face(int curface)
554{
555  face& curFace =  (this->bspFile->faces)[curface];
556  const BspVertex* curVertex = (BspVertex *) this->bspFile->vertice;
557  int stride = 44;  // sizeof(Vertex)
558  int offset    = curFace.vertex;
559
560  // PRINTF(0)("BSP Manager: ");
561  // PRINTF(0)("BSP Manager: type: %i  \n", curFace.texture);
562
563  //  if(  curFace.texture < 0 ) return;
564  if(curFace.type == 2) {
565    this->draw_patch( &curFace);
566    return;
567  }
568  if(curFace.type == 3) return;
569  // if(this->bspFile->Materials[curFace.texture] != NULL)
570
571  this->bspFile->Materials[2].mat->select();
572  this->lastTex = 2;
573
574  glEnableClientState(GL_VERTEX_ARRAY );
575  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
576  glEnableClientState(GL_NORMAL_ARRAY );
577  //glEnableClientState(GL_COLOR_ARRAY);
578  // glEnableClientState(GL_VERTEX_ARRAY );
579  glClientActiveTextureARB(GL_TEXTURE0_ARB);
580  glVertexPointer(3, GL_FLOAT, stride, &(curVertex[offset].position[0]));
581  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
582  // glClientActiveTextureARB(GL_TEXTURE0_ARB);
583  glClientActiveTextureARB(GL_TEXTURE1_ARB);
584  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[0]));
585  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
586  // glClientActiveTextureARB(GL_TEXTURE1_ARB);
587  // glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[1]));
588  //glEnableClientState(GL_NORMAL_ARRAY );
589
590  glNormalPointer( GL_FLOAT, stride, &(curVertex[offset].normal[0]));
591  //  glColorPointer(4, GL_BYTE, stride, &(curVertex[offset].color[0]));
592  glDrawElements(GL_TRIANGLES, curFace.n_meshverts,
593                 GL_UNSIGNED_INT, &(((meshvert *)this->bspFile->meshverts) [curFace.meshvert]));
594
595}
596
597void BspManager::draw_patch(face* Face)
598{
599  if(this->lastTex != Face->texture) {
600    this->bspFile->Materials[Face->texture].mat->select();
601    this->lastTex = Face->texture;
602  }
603  if (Face->effect != -1) return;
604
605  if(Face->lm_index < 0) {
606    glActiveTextureARB(GL_TEXTURE1_ARB);
607    glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap);
608    glEnable(GL_TEXTURE_2D);
609  } else {
610    glActiveTextureARB(GL_TEXTURE1_ARB);
611    glBindTexture(GL_TEXTURE_2D, this->bspFile->glLightMapTextures[Face->lm_index]);
612    glEnable(GL_TEXTURE_2D);
613  }
614 
615  if (State::showWireframe())
616  {
617    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
618    glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap );
619    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
620  }
621
622
623  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
624  glEnable( GL_AUTO_NORMAL);
625  glEnableClientState(GL_VERTEX_ARRAY );
626  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
627  for(int i = Face->n_meshverts -1; i >=0   ; i--) {
628    //glFrontFace(GL_CW);
629    //PRINTF(0)("BSP Manager: Face->size[0]: %i . \n", Face->size[0]);
630
631
632    //glEnableClientState(GL_NORMAL_ARRAY );
633
634    glVertexPointer(3, GL_FLOAT,44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).position[0]));
635
636
637    glClientActiveTextureARB(GL_TEXTURE0_ARB);
638    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
639    glTexCoordPointer(2, GL_FLOAT, 44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).texcoord[0][0]));
640
641
642
643    glClientActiveTextureARB(GL_TEXTURE1_ARB);
644    glTexCoordPointer(2, GL_FLOAT, 44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).texcoord[1][0]));
645    //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
646
647
648    //  glNormalPointer( GL_FLOAT, 44,&((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).normal[0]) );
649
650
651
652
653    for(int row=6; row>=0; --row) {
654      glDrawElements(GL_TRIANGLE_STRIP, 2*(8), GL_UNSIGNED_INT,
655                     & (     (((GLuint*)  (this->bspFile->patchIndexes))[7*8*2*(Face->meshvert+i)+ row*2*8]  ))  );
656    }
657
658    //glFrontFace(GL_CCW);
659  }
660  glDisableClientState(GL_TEXTURE0_ARB);
661  glDisableClientState(GL_TEXTURE1_ARB);
662  glDisable(GL_AUTO_NORMAL);
663  glDisableClientState(GL_VERTEX_ARRAY );
664  glDisableClientState(GL_TEXTURE_COORD_ARRAY );
665 
666  if (State::showWireframe())
667  {
668    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
669    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
670  }
671}
672
673bool BspManager::isAlreadyVisible(int Face)
674{
675  return this->alreadyVisible[Face];
676}
677
678
679BspTreeNode*  BspManager::getLeaf(BspTreeNode* node, Vector* cam)
680{
681  float dist = 0;
682  while(!(node->isLeaf)) {
683    dist = (node->plane.x * this->cam.x + node->plane.y*this->cam.y + node->plane.z*this->cam.z) - node->d;
684    if(dist >= 0.0f) {
685      node = node->left;
686    } else {
687      node = node->right;
688    }
689  }
690  return  node;
691}
692
693void BspManager::checkBrushRay(brush* curBrush)
694{
695  float EPSILON = 0.000001;
696  float startDistance;
697  float endDistance;
698
699  float startFraction = -1.0f;
700  float endFraction = 1.0f;
701  bool startsOut = false;
702  bool endsOut = false;
703
704  Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
705  Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
706
707  for (int i = 0; i < curBrush->n_brushsides; i++) {
708    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
709    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
710
711    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
712    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
713
714    if (startDistance > 0)
715      startsOut = true;
716    if (endDistance > 0)
717      endsOut = true;
718
719    // make sure the trace isn't completely on one side of the brush
720    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
721      return;
722    }
723    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
724      continue;
725    }
726
727    // MMM... BEEFY
728    if (startDistance > endDistance) {   // line is entering into the brush
729      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
730      if (fraction > startFraction)
731        startFraction = fraction;
732      // don't store plane
733      // this->collPlane = &curPlane;
734
735    } else {   // line is leaving the brush
736      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
737      if (fraction < endFraction)
738        endFraction = fraction;
739      // don't store plane
740      //this->collPlane = & curPlane;
741
742    }
743
744  }
745  if (startsOut == false) {
746    this->outputStartsOut = false;
747    if (endsOut == false)
748      this->outputAllSolid = true;
749    return;
750  }
751
752  if (startFraction < endFraction) {
753    if (startFraction > -1.0f && startFraction < outputFraction) {
754      if (startFraction < 0)
755        startFraction = 0;
756      this->outputFraction = startFraction;
757    }
758  }
759
760}
761
762void BspManager::checkBrushRayN(brush* curBrush)
763{
764  float EPSILON = 0.000001;
765  float startDistance;
766  float endDistance;
767
768  float startFraction = -1.0f;
769  float endFraction = 1.0f;
770  bool  startsOut = false;
771  bool  endsOut = false;
772
773  // Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
774  // Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
775
776  for (int i = 0; i < curBrush->n_brushsides; i++) {
777    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
778    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
779
780    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
781    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
782
783    if (startDistance > 0)
784      startsOut = true;
785    if (endDistance > 0)
786      endsOut = true;
787
788    // make sure the trace isn't completely on one side of the brush
789    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
790      return;
791    }
792    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
793      continue;
794    }
795
796    // MMM... BEEFY
797    if (startDistance > endDistance) {   // line is entering into the brush
798      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
799      if (fraction > startFraction)
800        startFraction = fraction;
801      // store plane
802      this->collPlane = &curPlane;
803
804    } else {   // line is leaving the brush
805      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
806      if (fraction < endFraction)
807        endFraction = fraction;
808      // store plane
809      this->collPlane = & curPlane;
810
811    }
812
813  }
814  if (startsOut == false) {
815    this->outputStartsOut = false;
816    if (endsOut == false)
817      this->outputAllSolid = true;
818    return;
819  }
820
821  if (startFraction < endFraction) {
822    if (startFraction > -1.0f && startFraction < outputFraction) {
823      if (startFraction < 0)
824        startFraction = 0;
825      this->outputFraction = startFraction;
826    }
827  }
828
829}
830
831void BspManager::checkBrushRayN(brush* curBrush, Vector& inputStart, Vector& inputEnd)
832{
833  float EPSILON = 0.000001;
834  float startDistance;
835  float endDistance;
836
837  float startFraction = -1.0f;
838  float endFraction = 1.0f;
839  bool  startsOut = false;
840  bool  endsOut = false;
841
842  //Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
843  //Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
844
845  for (int i = 0; i < curBrush->n_brushsides; i++) {
846    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
847    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
848
849    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
850    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
851
852    if (startDistance > 0)
853      startsOut = true;
854    if (endDistance > 0)
855      endsOut = true;
856
857    // make sure the trace isn't completely on one side of the brush
858    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
859      return;
860    }
861    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
862      continue;
863    }
864
865    // MMM... BEEFY
866    if (startDistance > endDistance) {   // line is entering into the brush
867      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
868      if (fraction > startFraction)
869        startFraction = fraction;
870      // store plane
871      this->collPlane = &curPlane;
872
873    } else {   // line is leaving the brush
874      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
875      if (fraction < endFraction)
876        endFraction = fraction;
877      // store plane
878      this->collPlane = & curPlane;
879
880    }
881
882  }
883  if (startsOut == false) {
884    this->outputStartsOut = false;
885    if (endsOut == false)
886      this->outputAllSolid = true;
887    return;
888  }
889
890  if (startFraction < endFraction) {
891    if (startFraction > -1.0f && startFraction < outputFraction) {
892      if (startFraction < 0)
893        startFraction = 0;
894      this->outputFraction = startFraction;
895    }
896  }
897
898}
899
900
901void BspManager::checkCollisionRay(BspTreeNode* node, float startFraction, float endFraction, Vector* start, Vector* end)
902{
903
904
905  float EPSILON = 0.000001;
906  float  endDistance = (end)->x * (node->plane.x) +(end)->y * (node->plane.y) +(end)->z * (node->plane.z)  - node->d;
907  float  startDistance = (start)->x * (node->plane.x)+ (start)->y * (node->plane.y)+ (start)->z * (node->plane.z)- node->d;
908
909
910  if(node->isLeaf) {
911    leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
912    for (int i = 0; i <  curLeaf.n_leafbrushes ; i++) {
913      brush& curBrush = this->bspFile->brushes[((int*)(this->bspFile->leafBrushes))[curLeaf.leafbrush_first+i]];
914      //object *brush = &BSP.brushes[BSP.leafBrushes[leaf->firstLeafBrush + i]];
915      if (curBrush.n_brushsides > 0   &&
916          ((((BspTexture*)(this->bspFile->textures))[curBrush.texture]).contents & 1))
917        // CheckBrush( brush );
918        this->checkBrushRay(&curBrush);
919      if(curBrush.n_brushsides <=0) this->outputAllSolid = true;
920    }
921    return;
922  }
923
924
925  if (startDistance >= 0 && endDistance >= 0)     // A
926  {   // both points are in front of the plane
927    // so check the front child
928    this->checkCollisionRay(node->left,0,0,start,end);
929  } else if (startDistance < 0 && endDistance < 0)  // B
930  {   // both points are behind the plane
931    // so check the back child
932    this->checkCollisionRay(node->right,0,0,start,end);
933  } else                                            // C
934  {   // the line spans the splitting plane
935    int side;
936    float fraction1, fraction2, middleFraction;
937    Vector middle;
938
939    // STEP 1: split the segment into two
940    if (startDistance < endDistance) {
941      side = 1; // back
942      float inverseDistance = 1.0f / (startDistance - endDistance);
943      fraction1 = (startDistance + EPSILON) * inverseDistance;
944      fraction2 = (startDistance + EPSILON) * inverseDistance;
945    } else if (endDistance < startDistance) {
946      side = 0; // front(start)->x * (node->plane.x)+
947      float inverseDistance = 1.0f / (startDistance - endDistance);
948      fraction1 = (startDistance + EPSILON) * inverseDistance;
949      fraction2 = (startDistance - EPSILON) * inverseDistance;
950    } else {
951      side = 0; // front
952      fraction1 = 1.0f;
953      fraction2 = 0.0f;
954    }
955
956    // STEP 2: make sure the numbers are valid
957    if (fraction1 < 0.0f) fraction1 = 0.0f;
958    else if (fraction1 > 1.0f) fraction1 = 1.0f;
959    if (fraction2 < 0.0f) fraction2 = 0.0f;
960    else if (fraction2 > 1.0f) fraction2 = 1.0f;
961
962    // STEP 3: calculate the middle point for the first side
963    middleFraction = startFraction +
964                     (endFraction - startFraction) * fraction1;
965
966    middle.x = start->x + fraction1 * (end->x - start->x);
967    middle.y = start->y + fraction1 * (end->y - start->y);
968    middle.z = start->z + fraction1 * (end->z - start->z);
969
970    // STEP 4: check the first side
971    //CheckNode( node->children[side], startFraction, middleFraction, start, middle );
972    if(side == 0) this->checkCollisionRay(node->left,startFraction, middleFraction, start, &middle );
973
974    else this->checkCollisionRay(node->right,startFraction, middleFraction,
975                                   start, &middle );
976
977    // STEP 5: calculate the middle point for the second side
978    middleFraction = startFraction +
979                     (endFraction - startFraction) * fraction2;
980
981    middle.x = start->x + fraction2 * (end->x - start->x);
982    middle.y = start->y + fraction2 * (end->y - start->y);
983    middle.z = start->z + fraction2 * (end->z - start->z);
984
985    // STEP 6: check the second side
986    if(side == 1)this->checkCollisionRay(node->left,middleFraction, endFraction, &middle, end);
987
988    else this->checkCollisionRay(node->right,middleFraction, endFraction,&middle, end );
989
990
991  }
992
993}
994
995
996
997void BspManager::checkCollisionRayN(BspTreeNode* node, float startFraction, float endFraction, Vector* start, Vector* end)
998{
999
1000
1001  float EPSILON = 0.000001;
1002
1003  float endDistance = end->dot(node->plane) - node->d;
1004  float startDistance = start->dot(node->plane) - node->d;
1005 
1006  if( node->isLeaf) {
1007    leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
1008    for (int i = 0; i <  curLeaf.n_leafbrushes ; i++) {
1009      brush& curBrush = this->bspFile->brushes[((int*)(this->bspFile->leafBrushes))[curLeaf.leafbrush_first+i]];
1010      //object *brush = &BSP.brushes[BSP.leafBrushes[leaf->firstLeafBrush + i]];
1011      if (curBrush.n_brushsides > 0   &&
1012          ((((BspTexture*)(this->bspFile->textures))[curBrush.texture]).contents & 1))
1013        // CheckBrush( brush );
1014        this->checkBrushRayN(&curBrush);
1015      if(curBrush.n_brushsides <=0) this->outputAllSolid = true;
1016    }
1017
1018    return;
1019  }
1020
1021  //TODO valgrind complains about uninitialised value here
1022  if (startDistance >= 0 && endDistance >= 0)     // A
1023  {   // both points are in front of the plane
1024    // so check the front child
1025    this->checkCollisionRayN(node->left,0,0,start,end);
1026  } else if (startDistance < 0 && endDistance < 0)  // B
1027  {   // both points are behind the plane
1028    // so check the back child
1029    this->checkCollisionRayN(node->right,0,0,start,end);
1030  } else                                            // C
1031  {   // the line spans the splitting plane
1032    int side;
1033    float fraction1, fraction2, middleFraction;
1034    Vector middle;
1035
1036    // STEP 1: split the segment into two
1037    if (startDistance < endDistance) {
1038      side = 1; // back
1039      float inverseDistance = 1.0f / (startDistance - endDistance);
1040      fraction1 = (startDistance + EPSILON) * inverseDistance;
1041      fraction2 = (startDistance + EPSILON) * inverseDistance;
1042    } else if (endDistance < startDistance) {
1043      side = 0; // front(start)->x * (node->plane.x)+
1044      float inverseDistance = 1.0f / (startDistance - endDistance);
1045      fraction1 = (startDistance + EPSILON) * inverseDistance;
1046      fraction2 = (startDistance - EPSILON) * inverseDistance;
1047    } else {
1048      side = 0; // front
1049      fraction1 = 1.0f;
1050      fraction2 = 0.0f;
1051    }
1052
1053    // STEP 2: make sure the numbers are valid
1054    if (fraction1 < 0.0f) fraction1 = 0.0f;
1055    else if (fraction1 > 1.0f) fraction1 = 1.0f;
1056    if (fraction2 < 0.0f) fraction2 = 0.0f;
1057    else if (fraction2 > 1.0f) fraction2 = 1.0f;
1058
1059    // STEP 3: calculate the middle point for the first side
1060    middleFraction = startFraction + (endFraction - startFraction) * fraction1;
1061    middle = (*start) + ((*end) - (*start)) * fraction1;
1062
1063
1064    // STEP 4: check the first side
1065    //CheckNode( node->children[side], startFraction, middleFraction, start, middle );
1066    if(side == 0) this->checkCollisionRayN(node->left,startFraction, middleFraction, start, &middle );
1067
1068    else this->checkCollisionRayN(node->right,startFraction, middleFraction,
1069                                    start, &middle );
1070
1071    // STEP 5: calculate the middle point for the second side
1072    middleFraction = startFraction + (endFraction - startFraction) * fraction2;
1073    middle = (*start) + ((*end) - (*start)) * fraction2;
1074
1075    // STEP 6: check the second side
1076    if(side == 1)this->checkCollisionRayN(node->left,middleFraction, endFraction, &middle, end);
1077
1078    else this->checkCollisionRayN(node->right,middleFraction, endFraction,&middle, end );
1079
1080
1081  }
1082
1083}
1084
1085float BspManager::checkPatchAltitude(BspTreeNode* node)
1086{
1087  leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
1088  for(int i = 0; i < curLeaf.n_leaffaces ; i++) {}
1089  return 10.0f;
1090}
1091
1092void BspManager::checkCollisionBox(void)
1093{}
1094
1095
1096void BspManager::TraceBox( Vector& inputStart, Vector& inputEnd,
1097                           Vector& inputMins, Vector& inputMaxs )
1098{
1099  if (inputMins.x == 0 && inputMins.y == 0 && inputMins.z == 0 &&
1100      inputMaxs.x == 0 && inputMaxs.y == 0 && inputMaxs.z == 0) {   // the user called TraceBox, but this is actually a ray
1101    //!> FIXME TraceRay( inputStart, inputEnd );
1102  } else {   // setup for a box
1103    //traceType = TT_BOX;
1104    this->traceMins = inputMins;
1105    this->traceMaxs = inputMaxs;
1106    this->traceExtents.x = -traceMins.x > traceMaxs.x ?
1107                           -traceMins.x : traceMaxs.x;
1108    this->traceExtents.y = -traceMins.y > traceMaxs.y ?
1109                           -traceMins.y : traceMaxs.y;
1110    this->traceExtents.z = -traceMins.z > traceMaxs.z ?
1111                           -traceMins.z : traceMaxs.z;
1112    //!> FIXME Trace( inputStart, inputEnd );
1113  }
1114}
1115
1116void BspManager::checkCollision(WorldEntity* worldEntity)
1117{
1118
1119  // Init  Collision Detection
1120  this->outputStartsOut = true;
1121  this->outputAllSolid = false;
1122  this->outputFraction = 1.0f;
1123
1124  this->checkCollisionX(worldEntity);
1125  this->checkCollisionZ(worldEntity);
1126
1127  if(!(this->checkCollisionY(worldEntity)))
1128  this->checkCollisionWay(worldEntity);
1129
1130
1131#if 0
1132  // Retrieve Bounding box
1133  AABB* box = worldEntity->getModelAABB();
1134
1135
1136  Vector forwardDir = Vector(0.0,0.0,1.0);
1137  Vector upDir = Vector(0.0,1.0,0.0);
1138  Vector position = worldEntity->getAbsCoor();
1139
1140  bool SolidFlag = false;
1141  bool collision = false;
1142  Vector position1 = position;
1143  Vector position2 = position + Vector(0.0,1.0,0.0);
1144  Vector position3 = position;
1145  Vector position4 = position + Vector(0.0,1.0,0.0);
1146  Vector dest = worldEntity->getAbsCoor() - upDir*40.0f; //
1147  Vector dest1 = position + forwardDir*4.0f;
1148  Vector dest2 = position2 + forwardDir*4.0;
1149  Vector dest3 = position + forwardDir*4.0f;
1150  Vector dest4 = position2 + forwardDir*4.0;
1151  dest = position - Vector(0.0, 40.0,0.0);
1152  Vector out = dest;
1153  Vector out1;
1154  Vector out2;
1155
1156
1157  plane* testPlane;
1158
1159  bool xCollision = false;
1160  bool zCollision = false;
1161
1162
1163  float height = 40;
1164
1165
1166  if( box != NULL) {
1167    position = worldEntity->getAbsCoor() +  box->center; // + Vector(0.0, 1.0, 0.0) * box->halfLength[1] * 1.0f;
1168    dest     = worldEntity->getAbsCoor() +  box->center - Vector(0.0, 1.0, 0.0) * (box->halfLength[1] + BSP_Y_OFFSET) *   100;
1169
1170    Vector dirX =  worldEntity->getAbsDirX(); dirX.y = 0.0f; dirX.normalize();
1171
1172    //position1 = worldEntity->getAbsCoor() +  box->center - dirX * (box->halfLength[0]  + BSP_X_OFFSET);
1173    dest1     = worldEntity->getAbsCoor() +  box->center + dirX * (box->halfLength[0]  + BSP_X_OFFSET);
1174    dest2     = worldEntity->getAbsCoor() -  box->center + dirX * (box->halfLength[0]  + BSP_X_OFFSET);
1175
1176    Vector dirZ =  worldEntity->getAbsDirZ(); dirX.y = 0.0f; dirZ.normalize();
1177    //position2 = worldEntity->getAbsCoor() +  box->center - dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
1178    dest3     = worldEntity->getAbsCoor() +  box->center + dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
1179    dest4     = worldEntity->getAbsCoor() -  box->center + dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
1180  } else {
1181    // Init positions and destinations to anything useful!
1182
1183  }
1184
1185
1186
1187  // 1st Ray: Y RAY
1188  this->inputStart =  position;
1189  this->inputEnd =   dest;
1190  this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &dest );
1191
1192
1193  //
1194  if(!this->outputStartsOut ) {
1195    this->collPlane = new plane;
1196    this->collPlane->x = 0.0f;
1197    this->collPlane->y = 0.0f;
1198    this->collPlane->z = 0.0f;
1199    collision = true;
1200  } else {
1201
1202    if( this->outputFraction == 1.0f) {
1203      if(this->outputAllSolid ) {
1204        this->collPlane = new plane;
1205        this->collPlane->x = 0.0f;
1206        this->collPlane->y = 0.0f;
1207        this->collPlane->z = 0.0f;
1208        collision = true;
1209        SolidFlag = true;
1210      } else
1211        collision = false;
1212
1213
1214      out = dest;
1215
1216    } else {
1217      collision = true;
1218      out.x = position.x + (dest.x -position.x) * this->outputFraction;
1219      out.y = position.y + (dest.y -position.y) * this->outputFraction;
1220      out.z = position.z + (dest.z -position.z) * this->outputFraction;
1221
1222      Vector out3 = out + Vector(height*this->collPlane->x,height*this->collPlane->y,height*this->collPlane->z);
1223      this->out = out;
1224    }
1225  }
1226    testPlane = this->collPlane;
1227
1228
1229  bool xCollisionNeg = false;
1230  bool zCollisionNeg = false;
1231
1232
1233
1234    // 2nd Collision Detection X-RAY
1235    this->outputStartsOut = true;
1236    this->outputAllSolid = false;
1237    this->outputFraction = 1.0f;
1238    this->inputStart =  position1;
1239    this->inputEnd =   dest1;
1240    this->checkCollisionRayN(this->root,0.0f,1.0f, &position1, &dest1 );
1241
1242    if(this->outputFraction < 1.0f) {
1243      out.x = dest1.x + (dest1.x -position1.x) * this->outputFraction;
1244      dest1 = position1 + (dest1 -position1) * this->outputFraction;
1245      xCollision = true;
1246      testPlane = this->collPlane;
1247    }
1248    if(this->outputAllSolid ) {
1249
1250      this->collPlane = new plane;
1251      this->collPlane->x = 0.0f;
1252      this->collPlane->y = 0.0f;
1253      this->collPlane->z = 0.0f;
1254      testPlane = this->collPlane;
1255      SolidFlag = true;
1256      xCollision = true;
1257    }
1258    //out.z = this->outputFraction;
1259
1260
1261
1262      // 3rd Collision Detection Z-RAY
1263      this->outputStartsOut = true;
1264      this->outputAllSolid = false;
1265      this->outputFraction = 1.0f;
1266      this->inputStart =  position2;
1267      this->inputEnd =   dest2;
1268
1269      this->checkCollisionRayN(this->root,0.0f,1.0f, &position2, &dest2 );
1270      //out.x = this->outputFraction;
1271
1272      if(this->outputFraction < 1.0f ) {
1273        out.z = out.z = dest2.z + (dest2.z -position2.z) * this->outputFraction;
1274        dest2 = position2 + (dest2 -position2) * this->outputFraction;
1275        zCollision = true;
1276        testPlane = this->collPlane;
1277
1278      }
1279      if(this->outputAllSolid ) {
1280        this->collPlane = new plane;
1281        this->collPlane->x = 0.0f;
1282        this->collPlane->y = 0.0f;
1283        this->collPlane->z = 0.0f;
1284        testPlane = this->collPlane;
1285
1286        SolidFlag = true;
1287        zCollision = true;
1288      }
1289
1290
1291  // Return the normal here: Normal's stored in this->collPlane;
1292  if( collision) {
1293    worldEntity->registerCollision(COLLISION_TYPE_AXIS_Y , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z), out, SolidFlag);
1294}
1295  if(xCollision) {
1296    worldEntity->registerCollision(COLLISION_TYPE_AXIS_X , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z),dest1 , SolidFlag);
1297  }
1298
1299  if(zCollision) {
1300    worldEntity->registerCollision(COLLISION_TYPE_AXIS_Z , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z), dest2 , SolidFlag);
1301  }
1302#endif
1303
1304}
1305
1306
1307
1308/**
1309 * check the collision in the x direction (forward, backward)
1310 */
1311bool BspManager::checkCollisionX(WorldEntity* entity)
1312{
1313  // Retrieve Bounding box
1314  AABB* box = entity->getModelAABB();
1315
1316
1317  plane*            testPlane          = NULL;  //!< the collision test plane
1318
1319  Vector            forward;                    //!< left collision ray
1320  Vector            backward;                   //!< right collision ray
1321  Vector            collPos;                    //!< the collision position
1322
1323  bool              xCollisionForward  = false; //!< flag true if right collision
1324  bool              xCollisionBackward = false; //!< flag true if left collision
1325  bool              SolidFlag          = false; //!< flag set true if solid
1326
1327  Vector            position;                   //!< current position of the entity
1328  Vector            dirX;                       //!< direction x
1329
1330  position = entity->getAbsCoor();
1331  dirX =  entity->getAbsDirX(); dirX.y = 0.0f; dirX.normalize();
1332
1333  // calculate the rays
1334  if( box != NULL)
1335  {
1336    forward  = entity->getAbsCoor() +  box->center + dirX * (box->halfLength[0]  + BSP_X_OFFSET);
1337    backward = entity->getAbsCoor() +  box->center - dirX * (box->halfLength[0]  + BSP_X_OFFSET);
1338  }
1339  else
1340  {
1341    forward  = position + dirX * 4.0f;
1342    backward = position + Vector(0.0, 1.0, 0.0) + dirX * 4.0;
1343  }
1344
1345
1346  /*   X Ray forward  */
1347  // init some member variables before collision check
1348  this->outputStartsOut = true;
1349  this->outputAllSolid = false;
1350  this->outputFraction = 1.0f;
1351  this->inputStart =  position;
1352  this->inputEnd =   forward;
1353  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &forward );
1354
1355  // collision occured
1356  if( this->outputFraction < 1.0f)
1357  {
1358    collPos = position + (forward - position) * this->outputFraction;
1359    xCollisionForward = true;
1360    testPlane = this->collPlane;
1361  }
1362  if(this->outputAllSolid )
1363  {
1364    this->collPlane = new plane;
1365    this->collPlane->x = 0.0f;
1366    this->collPlane->y = 0.0f;
1367    this->collPlane->z = 0.0f;
1368    testPlane = this->collPlane;
1369    SolidFlag = true;
1370    xCollisionForward = true;
1371  }
1372
1373  // collision registration
1374  if( xCollisionForward)
1375  {
1376    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X ,
1377                              entity, this->parent,
1378                              Vector(testPlane->x, testPlane->y, testPlane->z),
1379                              collPos,
1380                              SolidFlag);
1381  }
1382
1383
1384
1385  /*   X Ray backward  */
1386  // init some member variables before collision check
1387  this->outputStartsOut = true;
1388  this->outputAllSolid = false;
1389  this->outputFraction = 1.0f;
1390  this->inputStart =  position;
1391  this->inputEnd =   backward;
1392  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &backward );
1393
1394  // collision occured
1395  if( this->outputFraction < 1.0f)
1396  {
1397    collPos = position + (backward - position) * this->outputFraction;
1398    xCollisionBackward = true;
1399    testPlane = this->collPlane;
1400  }
1401  if( this->outputAllSolid)
1402  {
1403    this->collPlane = new plane;
1404    this->collPlane->x = 0.0f;
1405    this->collPlane->y = 0.0f;
1406    this->collPlane->z = 0.0f;
1407    testPlane = this->collPlane;
1408    SolidFlag = true;
1409    xCollisionBackward = true;
1410  }
1411
1412  // collision registration
1413  if( xCollisionBackward)
1414  {
1415    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X_NEG,
1416                              entity, this->parent,
1417                              Vector(testPlane->x, testPlane->y, testPlane->z),
1418                              collPos,
1419                              SolidFlag);
1420  }
1421
1422 return (xCollisionBackward || xCollisionForward);
1423}
1424
1425
1426/**
1427 * check the collision in the z direction (up, down)
1428 */
1429bool BspManager::checkCollisionY(WorldEntity* entity)
1430{
1431
1432  // Retrieve Bounding box
1433  AABB* box = entity->getModelAABB();
1434
1435
1436  plane*            testPlane          = NULL;  //!< the collision test plane
1437
1438  Vector            up;                         //!< up collision ray
1439  Vector            down;                       //!< down collision ray
1440  Vector            collPos;                    //!< the collision position
1441
1442  bool              yCollisionUp       = false; //!< flag true if right collision
1443  bool              yCollisionDown     = false; //!< flag true if left collision
1444  bool              SolidFlag          = false; //!< flag set true if solid
1445
1446  Vector            position;                   //!< current position of the entity
1447  Vector            dirY;                       //!< direction x
1448
1449  position = entity->getAbsCoor();
1450  collPos = position;
1451  dirY =  Vector(0.0, 1.0, 0.0);
1452
1453  // calculate the rays
1454  if( box != NULL)
1455  {
1456    up   = position +  box->center + dirY * (box->halfLength[1]/*  + BSP_Y_OFFSET*/);
1457    down = position +  box->center - dirY * (box->halfLength[1]  + BSP_Y_OFFSET);
1458  }
1459  else
1460  {
1461    up   = position + dirY * 4.0f;
1462    down = position + Vector(0.0, 1.0, 0.0) + dirY * 4.0;
1463  }
1464
1465
1466
1467
1468  /*   Y Ray up */
1469  // init some member variables before collision check
1470  this->inputStart = position;
1471  this->inputEnd   = up;
1472  this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &up );
1473
1474  if( !this->outputStartsOut )
1475  {
1476    this->collPlane = new plane;
1477    this->collPlane->x = 0.0f;
1478    this->collPlane->y = 0.0f;
1479    this->collPlane->z = 0.0f;
1480    yCollisionUp = true;
1481  }
1482  else
1483  {
1484    if( this->outputFraction == 1.0f)
1485    {
1486      if( this->outputAllSolid )
1487      {
1488        this->collPlane = new plane;
1489        this->collPlane->x = 0.0f;
1490        this->collPlane->y = 0.0f;
1491        this->collPlane->z = 0.0f;
1492        yCollisionUp = true;
1493        SolidFlag = true;
1494      }
1495      else
1496      {
1497        yCollisionUp = false;
1498        collPos = up;
1499      }
1500    }
1501    else
1502    {
1503      yCollisionUp = true;
1504      collPos = position + (up - position) * this->outputFraction;
1505      this->out = collPos;        // why this????
1506    }
1507  }
1508  testPlane = this->collPlane;
1509
1510  // collision registration
1511  if( yCollisionUp)
1512  {
1513    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y,
1514                              entity, this->parent,
1515                              Vector(testPlane->x, testPlane->y, testPlane->z),
1516                              collPos, SolidFlag);
1517  }
1518
1519
1520
1521
1522  /*   Y Ray down */
1523  // init some member variables before collision check
1524  this->inputStart = position;
1525  this->inputEnd   = down;
1526  this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &down );
1527
1528  if( !this->outputStartsOut )
1529  {
1530    this->collPlane = new plane;
1531    this->collPlane->x = 0.0f;
1532    this->collPlane->y = 0.0f;
1533    this->collPlane->z = 0.0f;
1534    yCollisionDown = true;
1535  }
1536  else
1537  {
1538    if( this->outputFraction == 1.0f) // No collision Detected
1539    {
1540      if( this->outputAllSolid )
1541      {
1542        this->collPlane = new plane;
1543        this->collPlane->x = 0.0f;
1544        this->collPlane->y = 0.0f;
1545        this->collPlane->z = 0.0f;
1546        yCollisionDown = true;
1547        SolidFlag = true;
1548      }
1549      else      // No collision happened
1550      {
1551        yCollisionDown = false;
1552        collPos = down;
1553      }
1554    }
1555    else           // A collision has happended
1556    {
1557      yCollisionDown = true;
1558      collPos = position + (down - position) * this->outputFraction;
1559    }
1560  }
1561  testPlane = this->collPlane;
1562
1563  // collision registration
1564  if( yCollisionDown)
1565  {
1566    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG ,
1567                              entity, this->parent,
1568                              Vector(testPlane->x, testPlane->y, testPlane->z),
1569                              collPos, SolidFlag);
1570  }
1571
1572 return (yCollisionUp || yCollisionDown);
1573}
1574
1575
1576
1577
1578/**
1579 * check the collision in the z direction (left, right)
1580 */
1581bool BspManager::checkCollisionZ(WorldEntity* entity)
1582{
1583  // Retrieve Bounding box
1584  AABB* box = entity->getModelAABB();
1585
1586
1587  plane*            testPlane          = NULL;  //!< the collision test plane
1588
1589  Vector            right;                      //!< right collision ray
1590  Vector            left;                       //!< left collision ray
1591  Vector            collPos;                    //!< the collision position
1592
1593  bool              zCollisionRight    = false; //!< flag true if right collision
1594  bool              zCollisionLeft     = false; //!< flag true if left collision
1595  bool              SolidFlag          = false; //!< flag set true if solid
1596
1597  Vector            position;                   //!< current position of the entity
1598  Vector            dirZ;                       //!< direction x
1599
1600  position = entity->getAbsCoor();
1601  dirZ =  entity->getAbsDirZ(); dirZ.y = 0.0f; dirZ.normalize();
1602
1603  // calculate the rays
1604  if( box != NULL)
1605  {
1606    right = entity->getAbsCoor() +  box->center + dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
1607    left  = entity->getAbsCoor() +  box->center - dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
1608  }
1609  else
1610  {
1611    right = position + dirZ * 4.0f;
1612    left  = position + Vector(0.0, 1.0, 0.0) + dirZ * 4.0;
1613  }
1614
1615
1616  /*   Z Ray right */
1617  // init some member variables before collision check
1618  this->outputStartsOut = true;
1619  this->outputAllSolid = false;
1620  this->outputFraction = 1.0f;
1621  this->inputStart =  position;
1622  this->inputEnd =   right;
1623  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &right );
1624
1625
1626  // collision occured
1627  if( this->outputFraction < 1.0f )
1628  {
1629    collPos = position + (right - position) * this->outputFraction;
1630    zCollisionRight = true;
1631    testPlane = this->collPlane;
1632  }
1633  if(this->outputAllSolid )
1634  {
1635    this->collPlane = new plane;
1636    this->collPlane->x = 0.0f;
1637    this->collPlane->y = 0.0f;
1638    this->collPlane->z = 0.0f;
1639    testPlane = this->collPlane;
1640
1641    SolidFlag = true;
1642    zCollisionRight = true;
1643  }
1644
1645
1646  if( zCollisionRight) {
1647    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z ,
1648                              entity, this->parent,
1649                              Vector(testPlane->x, testPlane->y, testPlane->z),
1650                              collPos , SolidFlag);
1651  }
1652
1653
1654
1655  /*   Z Ray left */
1656  // init some member variables before collision check
1657  this->outputStartsOut = true;
1658  this->outputAllSolid = false;
1659  this->outputFraction = 1.0f;
1660  this->inputStart =  position;
1661  this->inputEnd =    left;
1662  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &left);
1663
1664
1665  // collision occured
1666  if( this->outputFraction < 1.0f )
1667  {
1668    collPos = position + (left - position) * this->outputFraction;
1669    zCollisionLeft = true;
1670    testPlane = this->collPlane;
1671  }
1672  if(this->outputAllSolid )
1673  {
1674    this->collPlane = new plane;
1675    this->collPlane->x = 0.0f;
1676    this->collPlane->y = 0.0f;
1677    this->collPlane->z = 0.0f;
1678    testPlane = this->collPlane;
1679
1680    SolidFlag = true;
1681    zCollisionLeft = true;
1682  }
1683
1684
1685  if( zCollisionLeft) {
1686    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z_NEG ,
1687                               entity, this->parent,
1688                               Vector(testPlane->x, testPlane->y, testPlane->z),
1689                               collPos , SolidFlag);
1690  }
1691
1692 return (zCollisionLeft || zCollisionRight);
1693
1694}
1695
1696
1697
1698float BspManager::checkCollisionRay(Vector StartPoint, Vector Direction, float length )
1699{
1700  Direction.normalize(); // Oder besser vor dem Fkt-Aufruf schon normalisieren
1701  this->outputStartsOut = true;
1702  this->outputAllSolid = false;
1703  this->outputFraction = 1.0f;
1704  this->inputStart =  StartPoint;
1705  Vector End =   StartPoint + (Direction)*length;
1706  this->inputEnd =   End;
1707
1708  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &StartPoint, &(End) );
1709
1710  return (this->outputFraction * length);
1711
1712}
1713
1714
1715
1716/**
1717 * check wether a collision occured on the way from the last position to the current position
1718 */
1719bool BspManager::checkCollisionWay(WorldEntity* entity)
1720{
1721
1722
1723 
1724  plane*            testPlane          = NULL;  //!< the collision test plane
1725  Vector            to;
1726  Vector            collPos;                    //!< the collision position
1727
1728  bool              yCollisionUp       = false; //!< flag true if right collision
1729  bool              SolidFlag          = false; //!< flag set true if solid
1730
1731  Vector            from;                   //!< current position of the entity
1732  Vector            dirY;                       //!< direction x
1733
1734  from = entity->getLastAbsCoor();
1735  to    = entity->getAbsCoor();
1736  collPos = from;
1737  dirY =  Vector(0.0, 1.0, 0.0);
1738
1739
1740
1741
1742  /*   Y Ray up */
1743  // init some member variables before collision check
1744  this->inputStart = from;
1745  this->inputEnd   = to;
1746  this->checkCollisionRayN(this->root,0.0f,1.0f, &from, &to );
1747
1748  if( !this->outputStartsOut )
1749  {
1750    this->collPlane = new plane;
1751    this->collPlane->x = 0.0f;
1752    this->collPlane->y = 0.0f;
1753    this->collPlane->z = 0.0f;
1754    yCollisionUp = true;
1755  }
1756  else
1757  {
1758    if( this->outputFraction == 1.0f)
1759    {
1760      if( this->outputAllSolid )
1761      {
1762        this->collPlane = new plane;
1763        this->collPlane->x = 0.0f;
1764        this->collPlane->y = 0.0f;
1765        this->collPlane->z = 0.0f;
1766        yCollisionUp = true;
1767        SolidFlag = true;
1768      }
1769      else
1770      {
1771        yCollisionUp = false;
1772        collPos = to;
1773      }
1774    }
1775    else
1776    {
1777      yCollisionUp = true;
1778      collPos = from + (to - from) * this->outputFraction;
1779      this->out = collPos;        // why this????
1780    }
1781  }
1782  testPlane = this->collPlane;
1783
1784  // collision registration
1785  if( yCollisionUp)
1786  {
1787    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_WAY,
1788                              entity, this->parent,
1789                              Vector(testPlane->x, testPlane->y, testPlane->z),
1790                              collPos, SolidFlag);
1791  }
1792
1793 return yCollisionUp;
1794
1795}
1796
1797
1798
1799
1800void  BspManager::checkCollision(BspTreeNode* node, Vector* cam)
1801{
1802  Vector next = this->cam;
1803  next.x =   (State::getCameraTargetNode()->getLastAbsCoor()).x ;
1804  next.y =   (State::getCameraTargetNode()->getLastAbsCoor()).y ;
1805  next.z =   (State::getCameraTargetNode()->getLastAbsCoor()).z ;
1806
1807  float dist = 0;
1808  if(!(node->isLeaf)) {
1809    dist = (node->plane.x * this->cam.x + node->plane.y*this->cam.y + node->plane.z*this->cam.z) - node->d;
1810    if(dist > 4.0f) {
1811      checkCollision(node->left,cam);
1812      return;
1813    }
1814    if(dist < -4.0f) {
1815      checkCollision(node->right,cam);
1816      return;
1817    }
1818    if(dist<=4.0f && dist >= -4.0f) {
1819      checkCollision(node->left,cam);
1820      checkCollision(node->right,cam);
1821      return;
1822    }
1823    return;
1824  } else {
1825
1826    leaf& camLeaf =  ((leaf *)(this->bspFile->leaves))[(node->leafIndex ) ];
1827
1828    if (camLeaf.cluster < 0) {
1829      this->drawDebugCube(&this->cam);
1830      this->drawDebugCube(&next);
1831      // State::getPlayer()->getPlayable()->setRelCoor(-100,-100,-100);
1832      //State::getPlayer()->getPlayable()->collidesWith(NULL, State::getCameraTargetNode()->getLastAbsCoor());
1833    }
1834
1835
1836    /*
1837        for(int i = 0; i < camLeaf.n_leafbrushes && i < 10; i++ )
1838        {
1839                brush& curBrush = ((brush*)(this->bspFile->brushes))[(camLeaf.leafbrush_first +i)%this->bspFile->numLeafBrushes];
1840                if(curBrush.n_brushsides < 0) return;
1841                for(int j = 0; j < curBrush.n_brushsides; j++)
1842                {
1843                float dist = -0.1;
1844                brushside& curBrushSide = ((brushside*)(this->bspFile->brushSides))[(curBrush.brushside +j)%this->bspFile->numBrushSides];
1845                plane&      testPlane = ((plane*)(this->bspFile->planes))[curBrushSide.plane % this->bspFile->numPlanes];
1846                dist = testPlane.x * this->cam.x +  testPlane.y * this->cam.y  +  testPlane.z * this->cam.z   -testPlane.d ;
1847
1848                if(dist < -0.01f) dist = -1.0f *dist;
1849                if(dist < 1.0f){
1850                                this->drawDebugCube(&this->cam);
1851                                return;
1852                              }
1853                }
1854
1855        } */
1856
1857  }
1858  return;
1859}
1860
1861void BspManager::drawDebugCube(Vector* cam)
1862{
1863  glBegin(GL_QUADS);
1864
1865  // Bottom Face.  Red, 75% opaque, magnified texture
1866
1867  glNormal3f( 0.0f, -1.0f, 0.0f); // Needed for lighting
1868  glColor4f(0.9,0.2,0.2,.75); // Basic polygon color
1869
1870  glTexCoord2f(0.800f, 0.800f); glVertex3f(cam->x-1.0f, cam->y-1.0f,cam->z -1.0f);
1871  glTexCoord2f(0.200f, 0.800f); glVertex3f(cam->x+1.0f, cam->y-1.0f,cam->z -1.0f);
1872  glTexCoord2f(0.200f, 0.200f); glVertex3f(cam->x+ 1.0f,cam->y -1.0f,cam->z +  1.0f);
1873  glTexCoord2f(0.800f, 0.200f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z + 1.0f);
1874
1875
1876  // Top face; offset.  White, 50% opaque.
1877
1878  glNormal3f( 0.0f, 1.0f, 0.0f);  glColor4f(0.5,0.5,0.5,.5);
1879
1880  glTexCoord2f(0.005f, 1.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.0f);
1881  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
1882  glTexCoord2f(1.995f, 0.005f); glVertex3f(cam->x+ 1.0f,  cam->y+1.0f,  cam->z +1.0f);
1883  glTexCoord2f(1.995f, 1.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z -1.0f);
1884
1885
1886  // Far face.  Green, 50% opaque, non-uniform texture cooridinates.
1887
1888  glNormal3f( 0.0f, 0.0f,-1.0f);  glColor4f(0.2,0.9,0.2,.5);
1889
1890  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z -1.3f);
1891  glTexCoord2f(2.995f, 2.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.3f);
1892  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x+ 1.0f,cam->y+  1.0f, cam->z -1.3f);
1893  glTexCoord2f(0.005f, 0.005f); glVertex3f( cam->x+1.0f,cam->y -1.0f, cam->z -1.3f);
1894
1895
1896  // Right face.  Blue; 25% opaque
1897
1898  glNormal3f( 1.0f, 0.0f, 0.0f);  glColor4f(0.2,0.2,0.9,.25);
1899
1900  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y -1.0f, cam->z -1.0f);
1901  glTexCoord2f(0.995f, 0.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z -1.0f);
1902  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z + 1.0f);
1903  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y-1.0f,  cam->z +1.0f);
1904
1905
1906  // Front face; offset.  Multi-colored, 50% opaque.
1907
1908  glNormal3f( 0.0f, 0.0f, 1.0f);
1909
1910  glColor4f( 0.9f, 0.2f, 0.2f, 0.5f);
1911  glTexCoord2f( 0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f,  cam->z +1.0f);
1912  glColor4f( 0.2f, 0.9f, 0.2f, 0.5f);
1913  glTexCoord2f( 0.995f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y-1.0f,  cam->z +1.0f);
1914  glColor4f( 0.2f, 0.2f, 0.9f, 0.5f);
1915  glTexCoord2f( 0.995f, 0.995f); glVertex3f( cam->x+1.0f,  cam->y+1.0f,  cam->z +1.0f);
1916  glColor4f( 0.1f, 0.1f, 0.1f, 0.5f);
1917  glTexCoord2f( 0.005f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
1918
1919
1920  // Left Face; offset.  Yellow, varying levels of opaque.
1921
1922  glNormal3f(-1.0f, 0.0f, 0.0f);
1923
1924  glColor4f(0.9,0.9,0.2,0.0);
1925  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z -1.0f);
1926  glColor4f(0.9,0.9,0.2,0.66);
1927  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x-1.0f,cam->y -1.0f,  cam->z +1.0f);
1928  glColor4f(0.9,0.9,0.2,1.0);
1929  glTexCoord2f(0.995f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
1930  glColor4f(0.9,0.9,0.2,0.33);
1931  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.0f);
1932
1933  glEnd();
1934}
1935
1936void BspManager::addFace(int f)
1937{
1938  face& curFace =  ((face *)(this->bspFile->faces))[f];
1939  if(this->bspFile->Materials[curFace.texture].alpha) this->trasparent.push_back(f);
1940  else this->opal.push_back(f);
1941}
Note: See TracBrowser for help on using the repository browser.