Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10660 was 10643, checked in by bknecht, 18 years ago

improvements by landauf on bsp, rotor and wireframe (does build, should work)

File size: 59.2 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
1698
1699/**
1700 * check wether a collision occured on the way from the last position to the current position
1701 */
1702bool BspManager::checkCollisionWay(WorldEntity* entity)
1703{
1704
1705
1706 
1707  plane*            testPlane          = NULL;  //!< the collision test plane
1708  Vector            to;
1709  Vector            collPos;                    //!< the collision position
1710
1711  bool              yCollisionUp       = false; //!< flag true if right collision
1712  bool              SolidFlag          = false; //!< flag set true if solid
1713
1714  Vector            from;                   //!< current position of the entity
1715  Vector            dirY;                       //!< direction x
1716
1717  from = entity->getLastAbsCoor();
1718  to    = entity->getAbsCoor();
1719  collPos = from;
1720  dirY =  Vector(0.0, 1.0, 0.0);
1721
1722
1723
1724
1725  /*   Y Ray up */
1726  // init some member variables before collision check
1727  this->inputStart = from;
1728  this->inputEnd   = to;
1729  this->checkCollisionRayN(this->root,0.0f,1.0f, &from, &to );
1730
1731  if( !this->outputStartsOut )
1732  {
1733    this->collPlane = new plane;
1734    this->collPlane->x = 0.0f;
1735    this->collPlane->y = 0.0f;
1736    this->collPlane->z = 0.0f;
1737    yCollisionUp = true;
1738  }
1739  else
1740  {
1741    if( this->outputFraction == 1.0f)
1742    {
1743      if( this->outputAllSolid )
1744      {
1745        this->collPlane = new plane;
1746        this->collPlane->x = 0.0f;
1747        this->collPlane->y = 0.0f;
1748        this->collPlane->z = 0.0f;
1749        yCollisionUp = true;
1750        SolidFlag = true;
1751      }
1752      else
1753      {
1754        yCollisionUp = false;
1755        collPos = to;
1756      }
1757    }
1758    else
1759    {
1760      yCollisionUp = true;
1761      collPos = from + (to - from) * this->outputFraction;
1762      this->out = collPos;        // why this????
1763    }
1764  }
1765  testPlane = this->collPlane;
1766
1767  // collision registration
1768  if( yCollisionUp)
1769  {
1770    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_WAY,
1771                              entity, this->parent,
1772                              Vector(testPlane->x, testPlane->y, testPlane->z),
1773                              collPos, SolidFlag);
1774  }
1775
1776 return yCollisionUp;
1777
1778}
1779
1780
1781
1782
1783void  BspManager::checkCollision(BspTreeNode* node, Vector* cam)
1784{
1785  Vector next = this->cam;
1786  next.x =   (State::getCameraTargetNode()->getLastAbsCoor()).x ;
1787  next.y =   (State::getCameraTargetNode()->getLastAbsCoor()).y ;
1788  next.z =   (State::getCameraTargetNode()->getLastAbsCoor()).z ;
1789
1790  float dist = 0;
1791  if(!(node->isLeaf)) {
1792    dist = (node->plane.x * this->cam.x + node->plane.y*this->cam.y + node->plane.z*this->cam.z) - node->d;
1793    if(dist > 4.0f) {
1794      checkCollision(node->left,cam);
1795      return;
1796    }
1797    if(dist < -4.0f) {
1798      checkCollision(node->right,cam);
1799      return;
1800    }
1801    if(dist<=4.0f && dist >= -4.0f) {
1802      checkCollision(node->left,cam);
1803      checkCollision(node->right,cam);
1804      return;
1805    }
1806    return;
1807  } else {
1808
1809    leaf& camLeaf =  ((leaf *)(this->bspFile->leaves))[(node->leafIndex ) ];
1810
1811    if (camLeaf.cluster < 0) {
1812      this->drawDebugCube(&this->cam);
1813      this->drawDebugCube(&next);
1814      // State::getPlayer()->getPlayable()->setRelCoor(-100,-100,-100);
1815      //State::getPlayer()->getPlayable()->collidesWith(NULL, State::getCameraTargetNode()->getLastAbsCoor());
1816    }
1817
1818
1819    /*
1820        for(int i = 0; i < camLeaf.n_leafbrushes && i < 10; i++ )
1821        {
1822                brush& curBrush = ((brush*)(this->bspFile->brushes))[(camLeaf.leafbrush_first +i)%this->bspFile->numLeafBrushes];
1823                if(curBrush.n_brushsides < 0) return;
1824                for(int j = 0; j < curBrush.n_brushsides; j++)
1825                {
1826                float dist = -0.1;
1827                brushside& curBrushSide = ((brushside*)(this->bspFile->brushSides))[(curBrush.brushside +j)%this->bspFile->numBrushSides];
1828                plane&      testPlane = ((plane*)(this->bspFile->planes))[curBrushSide.plane % this->bspFile->numPlanes];
1829                dist = testPlane.x * this->cam.x +  testPlane.y * this->cam.y  +  testPlane.z * this->cam.z   -testPlane.d ;
1830
1831                if(dist < -0.01f) dist = -1.0f *dist;
1832                if(dist < 1.0f){
1833                                this->drawDebugCube(&this->cam);
1834                                return;
1835                              }
1836                }
1837
1838        } */
1839
1840  }
1841  return;
1842}
1843
1844void BspManager::drawDebugCube(Vector* cam)
1845{
1846  glBegin(GL_QUADS);
1847
1848  // Bottom Face.  Red, 75% opaque, magnified texture
1849
1850  glNormal3f( 0.0f, -1.0f, 0.0f); // Needed for lighting
1851  glColor4f(0.9,0.2,0.2,.75); // Basic polygon color
1852
1853  glTexCoord2f(0.800f, 0.800f); glVertex3f(cam->x-1.0f, cam->y-1.0f,cam->z -1.0f);
1854  glTexCoord2f(0.200f, 0.800f); glVertex3f(cam->x+1.0f, cam->y-1.0f,cam->z -1.0f);
1855  glTexCoord2f(0.200f, 0.200f); glVertex3f(cam->x+ 1.0f,cam->y -1.0f,cam->z +  1.0f);
1856  glTexCoord2f(0.800f, 0.200f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z + 1.0f);
1857
1858
1859  // Top face; offset.  White, 50% opaque.
1860
1861  glNormal3f( 0.0f, 1.0f, 0.0f);  glColor4f(0.5,0.5,0.5,.5);
1862
1863  glTexCoord2f(0.005f, 1.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.0f);
1864  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
1865  glTexCoord2f(1.995f, 0.005f); glVertex3f(cam->x+ 1.0f,  cam->y+1.0f,  cam->z +1.0f);
1866  glTexCoord2f(1.995f, 1.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z -1.0f);
1867
1868
1869  // Far face.  Green, 50% opaque, non-uniform texture cooridinates.
1870
1871  glNormal3f( 0.0f, 0.0f,-1.0f);  glColor4f(0.2,0.9,0.2,.5);
1872
1873  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z -1.3f);
1874  glTexCoord2f(2.995f, 2.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.3f);
1875  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x+ 1.0f,cam->y+  1.0f, cam->z -1.3f);
1876  glTexCoord2f(0.005f, 0.005f); glVertex3f( cam->x+1.0f,cam->y -1.0f, cam->z -1.3f);
1877
1878
1879  // Right face.  Blue; 25% opaque
1880
1881  glNormal3f( 1.0f, 0.0f, 0.0f);  glColor4f(0.2,0.2,0.9,.25);
1882
1883  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y -1.0f, cam->z -1.0f);
1884  glTexCoord2f(0.995f, 0.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z -1.0f);
1885  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z + 1.0f);
1886  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y-1.0f,  cam->z +1.0f);
1887
1888
1889  // Front face; offset.  Multi-colored, 50% opaque.
1890
1891  glNormal3f( 0.0f, 0.0f, 1.0f);
1892
1893  glColor4f( 0.9f, 0.2f, 0.2f, 0.5f);
1894  glTexCoord2f( 0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f,  cam->z +1.0f);
1895  glColor4f( 0.2f, 0.9f, 0.2f, 0.5f);
1896  glTexCoord2f( 0.995f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y-1.0f,  cam->z +1.0f);
1897  glColor4f( 0.2f, 0.2f, 0.9f, 0.5f);
1898  glTexCoord2f( 0.995f, 0.995f); glVertex3f( cam->x+1.0f,  cam->y+1.0f,  cam->z +1.0f);
1899  glColor4f( 0.1f, 0.1f, 0.1f, 0.5f);
1900  glTexCoord2f( 0.005f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
1901
1902
1903  // Left Face; offset.  Yellow, varying levels of opaque.
1904
1905  glNormal3f(-1.0f, 0.0f, 0.0f);
1906
1907  glColor4f(0.9,0.9,0.2,0.0);
1908  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z -1.0f);
1909  glColor4f(0.9,0.9,0.2,0.66);
1910  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x-1.0f,cam->y -1.0f,  cam->z +1.0f);
1911  glColor4f(0.9,0.9,0.2,1.0);
1912  glTexCoord2f(0.995f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
1913  glColor4f(0.9,0.9,0.2,0.33);
1914  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.0f);
1915
1916  glEnd();
1917}
1918
1919void BspManager::addFace(int f)
1920{
1921  face& curFace =  ((face *)(this->bspFile->faces))[f];
1922  if(this->bspFile->Materials[curFace.texture].alpha) this->trasparent.push_back(f);
1923  else this->opal.push_back(f);
1924}
Note: See TracBrowser for help on using the repository browser.