Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file was 10698, checked in by snellen, 17 years ago

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

File size: 59.7 KB
RevLine 
[7353]1/*
2   orxonox - the future of 3D-vertical-scrollers
[9003]3
[7353]4   Copyright (C) 2006 orx
[9003]5
[7353]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.
[9003]10
[7353]11   ### File Specific:
12   main-programmer: bottac@ee.ethz.ch
[9003]13
[8081]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/
[9003]17
[8081]18   Collision detection adapted from:
19   Quake 3 Collision Detection by Nathan Ostgard        http://www.devmaster.net/articles/quake3collision/
[7353]20*/
21
22
[10519]23#include "limits.h"
[7353]24#include "vector.h"
25#include "bsp_file.h"
26#include "bsp_manager.h"
[7385]27#include "bsp_tree_leaf.h"
[7353]28#include "p_node.h"
29#include "state.h"
30#include "debug.h"
31#include "material.h"
[10618]32#include "tools/camera.h"
[7353]33#include "vertex_array_model.h"
[7579]34#include "world_entities/player.h"
35#include "world_entities/playable.h"
[9869]36
[7385]37// STL Containers
38#include <vector>
39#include <deque>
[7801]40#include "movie_player.h"
[7353]41
[7833]42#include "world_entity.h"
[7353]43
[9869]44#include "util/loading/resource_manager.h"
[8081]45#include "util/loading/load_param.h"
46#include "util/loading/factory.h"
47
[8796]48#include "aabb.h"
[10013]49#include "cr_engine.h"
50#include "collision_tube.h"
[8081]51
[8490]52
[8081]53//CREATE_FACTORY( BspManager, CL_BSP_MODEL);
54
[8490]55BspManager::BspManager(WorldEntity* parent)
[7353]56{
[8724]57
[9235]58  this->lastTex = -1;
[8490]59  this->parent = parent;
[8081]60  /*// open a BSP file
[7395]61  this->bspFile = new BspFile();
[8081]62  this->bspFile->scale = 0.4f;
[7596]63  this->bspFile->read(ResourceManager::getFullName("test.bsp").c_str());
[7395]64  this->bspFile->build_tree();
65  this->root  = this->bspFile->get_root();
66  this->alreadyVisible = new bool [this->bspFile->numFaces];
[8081]67  */
[8490]68
[8081]69}
[7833]70
[8081]71
72/*
73BspManager::BspManager(const TiXmlElement* root)
74{
[9003]75
76
[8081]77  if( root != NULL)
78    this->loadParams(root);
[9003]79
[7833]80  CDEngine::getInstance()->setBSPModel(this);
[8081]81} */
82
[9003]83BspManager::~BspManager()
[8081]84{
[9003]85  if(this->bspFile)
86    delete this->bspFile;
87}
88
89int BspManager::load(const char* fileName, float scale)
90{
[8490]91  // open a BSP file
[9003]92
93
[8081]94  this->bspFile = new BspFile();
95  this->bspFile->scale =  scale;
[9869]96  if(this->bspFile->read(Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName).c_str()) == -1)
[9003]97    return -1;
98
[8081]99  this->bspFile->build_tree();
100  this->root  = this->bspFile->get_root();
101  this->alreadyVisible = new bool [this->bspFile->numFaces];
102
[8490]103  this->outputFraction = 1.0f;
[9003]104
105  return 0;
[7353]106}
[9235]107
108
[8081]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];
[9003]119
[8081]120  CDEngine::getInstance()->setBSPModel(this);
121}
122*/
123
[8490]124const void BspManager::tick(float time)
125{
126
[8796]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 );
[8490]134
135
136  }
137
138}
[8081]139const void BspManager::draw()
[7353]140{
141
[8081]142  /*
[8030]143  this->drawDebugCube(&this->out);
144  this->out1 = this->out;
145  this->out2 = this->out;
[8490]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;
[8087]150
[8490]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;
[8030]154  }
155  this->drawDebugCube(&this->out1);
156  this->drawDebugCube(&this->out2);
[8490]157
[8087]158  */
[8490]159
160
[7395]161  // Draw Debug Terrain
162  /*
[8087]163  this->bspFile->Materials[0]->select();
[7395]164  for(int i = 0; i <  this->bspFile->numPatches ; i++)
[8087]165        {
166                this->bspFile->VertexArrayModels[i]->draw();
167
168        }
[7395]169  */
[7353]170
171
[10076]172  this->lastTex = -1;
[7395]173  // erase alreadyVisible
174  for(int i = 0; i < this->bspFile->numFaces; i++) this->alreadyVisible[i] = false;
[10698]175//   float tmp = 0;
[7579]176  //this->opal.clear();
177  //this->trasparent.clear();
[7353]178  // Find all visible faces...
179
[7395]180  this->cam = State::getCamera()->getAbsCoor() ;
[7579]181  //this->ship = State::getCameraTargetNode()->getAbsCoor();
[7353]182
183
184
185
[7833]186
[8490]187  this->viewDir=    State::getCamera()->getAbsDirX();
[10698]188//   float d = (cam.x*viewDir.x + cam.y*viewDir.y + cam.z * viewDir.z);
[7353]189
[7395]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)
[7353]193
194
195
[8490]196
[8796]197  // this->checkCollision(this->root, &this->cam);   //!< Test Collision Detection
[8490]198
199
[7563]200  this->outputStartsOut = true;
201  this->outputAllSolid = false;
202  this->outputFraction = 1.0f;
[7833]203
[7801]204  if ( viscluster < 0  || ((int *)(this->bspFile->header))[35] == 0 )  //!< if (sizeof(Visdata) == 0)
[7395]205  {
[7833]206
207
208
[8490]209    // Iterate through all Leafs
[7395]210    for(int i = 0; i <  this->bspFile->numLeafs   ; i++ )
[7353]211    {
[7395]212      // cluster =  (this->bspFile->leaves)[i].cluster;
213      leaf& curLeaf = (this->bspFile->leaves)[i];
[7563]214      if(curLeaf.cluster<0) continue;
[7833]215
[7563]216      /** Do Frustum culling and draw 'em all **/
[7801]217
[8490]218      Vector dir = State::getCameraNode()->getAbsDirX();
219
[7563]220      float dist =  dir.x*this->cam.x +dir.y*this->cam.y +dir.z*this->cam.z;
221      //if(dist < 0) dist = -dist;
[7801]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 ;
[7833]224
[8490]225      if(dMins < -300.0 && dMaxs < -300.0) {
[8030]226        continue;
[7563]227      }
[8490]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) {
[8030]229        continue;
[7801]230      }
[7833]231
232
[7395]233      // Iterate through all faces
234      for (int j = 0; j < curLeaf.n_leaffaces ; ++j) {
[7596]235        const int g = (j +  curLeaf.leafface);
236        const int f = ((int *)this->bspFile->leafFaces)[g];
[7395]237        if (f >=0 && !this->isAlreadyVisible(f)) {
238          this->alreadyVisible[f] = true;
239          addFace(f); // "visibleFaces.append(f)"
240        }
241      }
[7353]242
243
244
245
[7395]246    } //for
[7833]247  } else {
[7579]248
[7833]249
[7395]250    unsigned int v;
251    unsigned char  visSet;
[7353]252
[7395]253    // Iterate through all Leafs
[7385]254
[7395]255    for(int i = 0; i <  this->bspFile->numLeafs   ; ++i ) {
[10698]256//       leaf& camLeaf =  (this->bspFile->leaves)[ActLeaf->leafIndex] ;
[7395]257      leaf& curLeaf =  (this->bspFile->leaves)[i] ;
[7579]258      int& cluster =  curLeaf.cluster;
[7563]259
260      if(cluster < 0) continue;
[7395]261      v = ((viscluster *  ( ((int *)this->bspFile->visData)[1]) ) + (cluster / 8));
[7579]262      visSet =((char*) (this->bspFile->visData))[v + 8];
[7563]263
[7833]264      // gets bit of visSet
[7579]265      if( ((visSet) & (1 << (cluster &  7))) != 0 ) {
[7833]266
[7592]267        // Frustum culling
[7833]268
[7592]269        Vector dir;
[7833]270        dir.x = State::getCameraNode()->getAbsDirX().x;
271        dir.y =  State::getCameraNode()->getAbsDirX().y;
272        dir.z =  State::getCameraNode()->getAbsDirX().z;
[7592]273        const float dist =  dir.x*this->cam.x +dir.y*this->cam.y +dir.z*this->cam.z;
[7833]274        //if(dist < 0) dist = -dist;
[7592]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;
[7833]277
[9235]278        if(dMins < -70.0 && dMaxs < -70.0) {
[7833]279          continue;
[7592]280        }
[7833]281
282
[7395]283        // Iterate through all faces
[7563]284        for (int j = 0; j < curLeaf.n_leaffaces ; ++j) {
[7579]285          const int g = (j +  curLeaf.leafface);
286          const int f = ((int *)this->bspFile->leafFaces)[g];
[7395]287
288          if (!this->isAlreadyVisible(f) && f>=0) {
289            this->addFace(f);
290            this->alreadyVisible[f] = true;
291          }
292
293        }
294
[7563]295      }// if
[7395]296
297    }//for
298
299  }//else
300
[10314]301
302  // now sort the transparent faces in the right order
[10519]303  if (this->sortTransparency == 1) {
304      int size = this->trasparent.size();
305     
306      // bubble sort
307      bool hasSwapped = true;
308      Vector v1, v2;
[10314]309
[10519]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]];
[10314]316
[10519]317          // get center of face 1
318          const BspVertex* curVertex = (BspVertex *) this->bspFile->vertice;
[10314]319
[10519]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          }
[10314]342
[10519]343          // relativly to observer
344          v1 = this->cam - v1;
[10314]345
[10519]346          // save in array
347          distToPlayer[i] = v1.len();
348      }
[10314]349
[10519]350      while( hasSwapped)
351      {
352        hasSwapped = false;
[10337]353
[10519]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]];
[10337]360
[10519]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]);
[10314]381
[10519]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          }
[10337]402
[10519]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        }
[10314]429      }
[10519]430      //printf("hasSwapped == false\n");
[10314]431  }
432
433
434  // draw all solid faces
[7395]435  while(!this->opal.empty()) {
[10314]436    this->draw_face(this->opal.back()); // front()
437    this->opal.pop_back();              // pop_back()
[7395]438  }
[10314]439
440  // draw all transparent faces
[7395]441  while(!this->trasparent.empty()) {
442    this->draw_face(this->trasparent.back());
443    this->trasparent.pop_back();
444  }
[8081]445  //glEnable(GL_TEXTURE_2D);
[7801]446  glActiveTextureARB(GL_TEXTURE1_ARB);
447  glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap);
[7395]448
[8087]449
450
[7353]451}//draw
452
453
[7563]454
[7353]455void BspManager::draw_face(int curface)
456{
[7395]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;
[7801]461  if (curFace.effect != -1) return;
[7353]462  // PRINTF(0)("BSP Manager: ");
463  // PRINTF(0)("BSP Manager: type: %i  \n", curFace.texture);
[7395]464
465  //  if(  curFace.texture < 0 ) return;
466  if(curFace.type == 2) {
467    this->draw_patch( &curFace);
468    return;
469  }
[8796]470  // if(curFace.type != 1) return;
[7801]471  if((char*)(this->bspFile->textures)[curFace.texture*72]== 0) return;
[7563]472
[7544]473  if(this->lastTex != curFace.texture) {
[7833]474    if(this->bspFile->Materials[curFace.texture].animated) {
[8796]475      // glBlendFunc(GL_ZERO,GL_ONE);
[8490]476
477
478
[7801]479      if(this->bspFile->Materials[curFace.texture].aviMat->getStatus() == 2) this->bspFile->Materials[curFace.texture].aviMat->start(0);
[8490]480      //this->bspFile->Materials[curFace.texture].aviMat->tick(0.005);
[7801]481      int n =  this->bspFile->Materials[curFace.texture].aviMat->getTexture();
482      glActiveTextureARB(GL_TEXTURE0_ARB);
483      glBindTexture(GL_TEXTURE_2D, n );
[8490]484      this->lastTex = curFace.texture;
485
[7833]486    } else {
487      this->bspFile->Materials[curFace.texture].mat->select();
488      this->lastTex = curFace.texture;
[7801]489    }
[7544]490  }
[7563]491
492  if(curFace.lm_index < 0) {
[8490]493    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
[7465]494    glActiveTextureARB(GL_TEXTURE1_ARB);
[7563]495    glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap );
496    glEnable(GL_TEXTURE_2D);
497  } else {
[8796]498    // glEnable(GL_BLEND);
[8490]499    //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
500    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
[7563]501    glActiveTextureARB(GL_TEXTURE1_ARB);
[7465]502    glBindTexture(GL_TEXTURE_2D, this->bspFile->glLightMapTextures[curFace.lm_index]);
503    glEnable(GL_TEXTURE_2D);
[8796]504    //  glDisable(GL_BLEND);
[7563]505  }
[10643]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  }
[7563]513
[7801]514  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
[7833]515
[7544]516  glEnableClientState(GL_VERTEX_ARRAY );
517  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
[7353]518  glEnableClientState(GL_NORMAL_ARRAY );
[7395]519  //  glEnableClientState(GL_COLOR_ARRAY);
520
[7563]521
[7353]522  glVertexPointer(3, GL_FLOAT, stride, &(curVertex[offset].position[0]));
[7563]523
[7465]524  glClientActiveTextureARB(GL_TEXTURE0_ARB);
[7353]525  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[0]));
[7801]526  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
[7563]527
[7465]528  glClientActiveTextureARB(GL_TEXTURE1_ARB);
529  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[1]));
[7544]530  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
[7353]531
[7563]532
[7353]533  glNormalPointer( GL_FLOAT, stride, &(curVertex[offset].normal[0]));
[7395]534  // glColorPointer(4, GL_BYTE, stride, &(curVertex[offset].color[0]));
[7353]535  glDrawElements(GL_TRIANGLES, curFace.n_meshverts,
[7395]536                 GL_UNSIGNED_INT, &(((meshvert *)this->bspFile->meshverts) [curFace.meshvert]));
[7353]537
[7465]538  glDisableClientState(GL_TEXTURE0_ARB);
539  glDisableClientState(GL_TEXTURE1_ARB);
[7353]540  glDisableClientState(GL_VERTEX_ARRAY );
[7801]541  glDisableClientState(GL_TEXTURE_COORD_ARRAY );
[7353]542  glDisableClientState(GL_NORMAL_ARRAY );
[7395]543  // glDisableClientState(GL_COLOR_ARRAY);
[10643]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  }
[7353]550}
551
552
553void BspManager::draw_debug_face(int curface)
554{
[7395]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
[7353]560  // PRINTF(0)("BSP Manager: ");
561  // PRINTF(0)("BSP Manager: type: %i  \n", curFace.texture);
562
[7395]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)
[7353]570
[7395]571  this->bspFile->Materials[2].mat->select();
572  this->lastTex = 2;
573
[7353]574  glEnableClientState(GL_VERTEX_ARRAY );
575  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
576  glEnableClientState(GL_NORMAL_ARRAY );
[7395]577  //glEnableClientState(GL_COLOR_ARRAY);
[7353]578  // glEnableClientState(GL_VERTEX_ARRAY );
[7465]579  glClientActiveTextureARB(GL_TEXTURE0_ARB);
[7353]580  glVertexPointer(3, GL_FLOAT, stride, &(curVertex[offset].position[0]));
[7465]581  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
[7395]582  // glClientActiveTextureARB(GL_TEXTURE0_ARB);
[7465]583  glClientActiveTextureARB(GL_TEXTURE1_ARB);
[7353]584  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[0]));
[7465]585  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
[7395]586  // glClientActiveTextureARB(GL_TEXTURE1_ARB);
587  // glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[1]));
588  //glEnableClientState(GL_NORMAL_ARRAY );
[7353]589
590  glNormalPointer( GL_FLOAT, stride, &(curVertex[offset].normal[0]));
[7395]591  //  glColorPointer(4, GL_BYTE, stride, &(curVertex[offset].color[0]));
[7353]592  glDrawElements(GL_TRIANGLES, curFace.n_meshverts,
[7395]593                 GL_UNSIGNED_INT, &(((meshvert *)this->bspFile->meshverts) [curFace.meshvert]));
594
[7353]595}
596
597void BspManager::draw_patch(face* Face)
598{
[7544]599  if(this->lastTex != Face->texture) {
[7510]600    this->bspFile->Materials[Face->texture].mat->select();
[7544]601    this->lastTex = Face->texture;
602  }
[7801]603  if (Face->effect != -1) return;
[7563]604
605  if(Face->lm_index < 0) {
[7465]606    glActiveTextureARB(GL_TEXTURE1_ARB);
[7511]607    glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap);
[7465]608    glEnable(GL_TEXTURE_2D);
[7563]609  } else {
[7465]610    glActiveTextureARB(GL_TEXTURE1_ARB);
611    glBindTexture(GL_TEXTURE_2D, this->bspFile->glLightMapTextures[Face->lm_index]);
612    glEnable(GL_TEXTURE_2D);
[7563]613  }
[10643]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  }
[7563]621
[10643]622
[7801]623  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
624  glEnable( GL_AUTO_NORMAL);
[7465]625  glEnableClientState(GL_VERTEX_ARRAY );
626  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
[7801]627  for(int i = Face->n_meshverts -1; i >=0   ; i--) {
[7833]628    //glFrontFace(GL_CW);
[7395]629    //PRINTF(0)("BSP Manager: Face->size[0]: %i . \n", Face->size[0]);
[7563]630
631
[7801]632    //glEnableClientState(GL_NORMAL_ARRAY );
[7353]633
[7395]634    glVertexPointer(3, GL_FLOAT,44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).position[0]));
[7563]635
636
[7465]637    glClientActiveTextureARB(GL_TEXTURE0_ARB);
[7801]638    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
[7395]639    glTexCoordPointer(2, GL_FLOAT, 44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).texcoord[0][0]));
[7465]640
[7563]641
[7833]642
[7465]643    glClientActiveTextureARB(GL_TEXTURE1_ARB);
644    glTexCoordPointer(2, GL_FLOAT, 44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).texcoord[1][0]));
[7544]645    //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
[7465]646
[7563]647
[7833]648    //  glNormalPointer( GL_FLOAT, 44,&((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).normal[0]) );
[7353]649
650
651
[7563]652
[7801]653    for(int row=6; row>=0; --row) {
[7395]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    }
[7563]657
[7801]658    //glFrontFace(GL_CCW);
[7395]659  }
[7465]660  glDisableClientState(GL_TEXTURE0_ARB);
661  glDisableClientState(GL_TEXTURE1_ARB);
[7801]662  glDisable(GL_AUTO_NORMAL);
[7465]663  glDisableClientState(GL_VERTEX_ARRAY );
664  glDisableClientState(GL_TEXTURE_COORD_ARRAY );
[10643]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  }
[7353]671}
672
673bool BspManager::isAlreadyVisible(int Face)
674{
[7395]675  return this->alreadyVisible[Face];
[7353]676}
677
678
679BspTreeNode*  BspManager::getLeaf(BspTreeNode* node, Vector* cam)
680{
[7395]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;
[7353]691}
692
[7563]693void BspManager::checkBrushRay(brush* curBrush)
694{
695  float EPSILON = 0.000001;
696  float startDistance;
697  float endDistance;
[7833]698
[7563]699  float startFraction = -1.0f;
700  float endFraction = 1.0f;
701  bool startsOut = false;
702  bool endsOut = false;
[7833]703
[7563]704  Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
705  Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
706
[7833]707  for (int i = 0; i < curBrush->n_brushsides; i++) {
[7563]708    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
709    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
710
[7833]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;
[7563]713
714    if (startDistance > 0)
715      startsOut = true;
716    if (endDistance > 0)
717      endsOut = true;
718
[7833]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
[7563]721      return;
722    }
[7833]723    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
[7563]724      continue;
725    }
726
[7833]727    // MMM... BEEFY
728    if (startDistance > endDistance) {   // line is entering into the brush
[7563]729      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
730      if (fraction > startFraction)
731        startFraction = fraction;
[8081]732      // don't store plane
733      // this->collPlane = &curPlane;
[8087]734
[8081]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;
[8087]741
[8081]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;
[8087]756      this->outputFraction = startFraction;
[8081]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;
[8490]770  bool  startsOut = false;
771  bool  endsOut = false;
[8081]772
[8796]773  // Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
774  // Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
[8081]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;
[8030]801      // store plane
802      this->collPlane = &curPlane;
[8087]803
[7833]804    } else {   // line is leaving the brush
[7563]805      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
806      if (fraction < endFraction)
807        endFraction = fraction;
[8030]808      // store plane
809      this->collPlane = & curPlane;
[8087]810
[7563]811    }
[7833]812
[7563]813  }
[7833]814  if (startsOut == false) {
815    this->outputStartsOut = false;
816    if (endsOut == false)
817      this->outputAllSolid = true;
818    return;
819  }
[7563]820
[7833]821  if (startFraction < endFraction) {
822    if (startFraction > -1.0f && startFraction < outputFraction) {
[7563]823      if (startFraction < 0)
824        startFraction = 0;
[8087]825      this->outputFraction = startFraction;
[7563]826    }
827  }
[7833]828
[7563]829}
830
[8490]831void BspManager::checkBrushRayN(brush* curBrush, Vector& inputStart, Vector& inputEnd)
832{
833  float EPSILON = 0.000001;
834  float startDistance;
835  float endDistance;
[8081]836
[8490]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
[7563]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   &&
[7833]916          ((((BspTexture*)(this->bspFile->textures))[curBrush.texture]).contents & 1))
917        // CheckBrush( brush );
918        this->checkBrushRay(&curBrush);
[7563]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) {
[7833]946      side = 0; // front(start)->x * (node->plane.x)+
[7563]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}
[7833]994
995
[8081]996
997void BspManager::checkCollisionRayN(BspTreeNode* node, float startFraction, float endFraction, Vector* start, Vector* end)
998{
999
1000
1001  float EPSILON = 0.000001;
1002
[8490]1003  float endDistance = end->dot(node->plane) - node->d;
1004  float startDistance = start->dot(node->plane) - node->d;
[10618]1005 
[8490]1006  if( node->isLeaf) {
[8081]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;
[8796]1016    }
1017
[8081]1018    return;
1019  }
1020
[10618]1021  //TODO valgrind complains about uninitialised value here
[8081]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
[8490]1060    middleFraction = startFraction + (endFraction - startFraction) * fraction1;
1061    middle = (*start) + ((*end) - (*start)) * fraction1;
[8081]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,
[8490]1069                                    start, &middle );
[8081]1070
1071    // STEP 5: calculate the middle point for the second side
[8490]1072    middleFraction = startFraction + (endFraction - startFraction) * fraction2;
1073    middle = (*start) + ((*end) - (*start)) * fraction2;
[8081]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}
[8724]1084
1085float BspManager::checkPatchAltitude(BspTreeNode* node)
1086{
1087  leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
[8894]1088  for(int i = 0; i < curLeaf.n_leaffaces ; i++) {}
[8724]1089  return 10.0f;
1090}
1091
[8490]1092void BspManager::checkCollisionBox(void)
[8894]1093{}
[8081]1094
[8894]1095
[8490]1096void BspManager::TraceBox( Vector& inputStart, Vector& inputEnd,
[8796]1097                           Vector& inputMins, Vector& inputMaxs )
[8490]1098{
1099  if (inputMins.x == 0 && inputMins.y == 0 && inputMins.z == 0 &&
[8796]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
[8490]1103    //traceType = TT_BOX;
1104    this->traceMins = inputMins;
1105    this->traceMaxs = inputMaxs;
1106    this->traceExtents.x = -traceMins.x > traceMaxs.x ?
[8796]1107                           -traceMins.x : traceMaxs.x;
[8490]1108    this->traceExtents.y = -traceMins.y > traceMaxs.y ?
[8796]1109                           -traceMins.y : traceMaxs.y;
[8490]1110    this->traceExtents.z = -traceMins.z > traceMaxs.z ?
[8796]1111                           -traceMins.z : traceMaxs.z;
1112    //!> FIXME Trace( inputStart, inputEnd );
[8490]1113  }
1114}
1115
[7833]1116void BspManager::checkCollision(WorldEntity* worldEntity)
1117{
[8724]1118
[8796]1119  // Init  Collision Detection
[8490]1120  this->outputStartsOut = true;
1121  this->outputAllSolid = false;
1122  this->outputFraction = 1.0f;
[7833]1123
[9110]1124  this->checkCollisionX(worldEntity);
1125  this->checkCollisionZ(worldEntity);
1126
[10618]1127  if(!(this->checkCollisionY(worldEntity)))
1128  this->checkCollisionWay(worldEntity);
[9110]1129
[10618]1130
[9110]1131#if 0
[8796]1132  // Retrieve Bounding box
1133  AABB* box = worldEntity->getModelAABB();
[7833]1134
[8724]1135
[8894]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();
[8087]1139
[8894]1140  bool SolidFlag = false;
[8490]1141  bool collision = false;
[8796]1142  Vector position1 = position;
[8724]1143  Vector position2 = position + Vector(0.0,1.0,0.0);
[9061]1144  Vector position3 = position;
1145  Vector position4 = position + Vector(0.0,1.0,0.0);
[8894]1146  Vector dest = worldEntity->getAbsCoor() - upDir*40.0f; //
[8724]1147  Vector dest1 = position + forwardDir*4.0f;
[9003]1148  Vector dest2 = position2 + forwardDir*4.0;
[9061]1149  Vector dest3 = position + forwardDir*4.0f;
1150  Vector dest4 = position2 + forwardDir*4.0;
[8490]1151  dest = position - Vector(0.0, 40.0,0.0);
[8894]1152  Vector out = dest;
[8490]1153  Vector out1;
1154  Vector out2;
[7833]1155
1156
[9110]1157  plane* testPlane;
[8894]1158
[9110]1159  bool xCollision = false;
1160  bool zCollision = false;
1161
1162
[8490]1163  float height = 40;
[8894]1164
1165
1166  if( box != NULL) {
[9061]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;
[8894]1169
[9061]1170    Vector dirX =  worldEntity->getAbsDirX(); dirX.y = 0.0f; dirX.normalize();
[8894]1171
[9061]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);
[9110]1175
[9061]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);
[8894]1180  } else {
1181    // Init positions and destinations to anything useful!
1182
[8796]1183  }
[8724]1184
[8894]1185
1186
[9110]1187  // 1st Ray: Y RAY
[8490]1188  this->inputStart =  position;
1189  this->inputEnd =   dest;
1190  this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &dest );
1191
[8724]1192
[8796]1193  //
1194  if(!this->outputStartsOut ) {
[8724]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;
[8796]1200  } else {
[8724]1201
[8796]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;
[8894]1209        SolidFlag = true;
1210      } else
[8796]1211        collision = false;
[8894]1212
1213
1214      out = dest;
1215
[8796]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;
[8724]1221
[8796]1222      Vector out3 = out + Vector(height*this->collPlane->x,height*this->collPlane->y,height*this->collPlane->z);
1223      this->out = out;
[7833]1224    }
[8490]1225  }
[9110]1226    testPlane = this->collPlane;
[8490]1227
[8087]1228
[9061]1229  bool xCollisionNeg = false;
1230  bool zCollisionNeg = false;
[8894]1231
[9003]1232
[9110]1233
1234    // 2nd Collision Detection X-RAY
[8894]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
[9003]1242    if(this->outputFraction < 1.0f) {
[8894]1243      out.x = dest1.x + (dest1.x -position1.x) * this->outputFraction;
[9003]1244      dest1 = position1 + (dest1 -position1) * this->outputFraction;
[8894]1245      xCollision = true;
1246      testPlane = this->collPlane;
1247    }
[9003]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;
[8894]1255      SolidFlag = true;
[9003]1256      xCollision = true;
[8894]1257    }
1258    //out.z = this->outputFraction;
1259
1260
[9003]1261
[9110]1262      // 3rd Collision Detection Z-RAY
[8894]1263      this->outputStartsOut = true;
1264      this->outputAllSolid = false;
1265      this->outputFraction = 1.0f;
1266      this->inputStart =  position2;
1267      this->inputEnd =   dest2;
[9003]1268
[8894]1269      this->checkCollisionRayN(this->root,0.0f,1.0f, &position2, &dest2 );
1270      //out.x = this->outputFraction;
1271
[9003]1272      if(this->outputFraction < 1.0f ) {
[8894]1273        out.z = out.z = dest2.z + (dest2.z -position2.z) * this->outputFraction;
[9003]1274        dest2 = position2 + (dest2 -position2) * this->outputFraction;
[8894]1275        zCollision = true;
1276        testPlane = this->collPlane;
1277
1278      }
[9003]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;
[8894]1288      }
[9003]1289
[8796]1290
[8490]1291  // Return the normal here: Normal's stored in this->collPlane;
[8894]1292  if( collision) {
[9110]1293    worldEntity->registerCollision(COLLISION_TYPE_AXIS_Y , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z), out, SolidFlag);
[9003]1294}
1295  if(xCollision) {
1296    worldEntity->registerCollision(COLLISION_TYPE_AXIS_X , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z),dest1 , SolidFlag);
1297  }
[9110]1298
[9003]1299  if(zCollision) {
1300    worldEntity->registerCollision(COLLISION_TYPE_AXIS_Z , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z), dest2 , SolidFlag);
1301  }
[9110]1302#endif
[7833]1303
[9110]1304}
[8894]1305
1306
[9110]1307
1308/**
1309 * check the collision in the x direction (forward, backward)
1310 */
[10618]1311bool BspManager::checkCollisionX(WorldEntity* entity)
[9110]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  {
[10013]1376    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X ,
1377                              entity, this->parent,
[9110]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  {
[10013]1415    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_X_NEG,
1416                              entity, this->parent,
[9110]1417                              Vector(testPlane->x, testPlane->y, testPlane->z),
1418                              collPos,
1419                              SolidFlag);
1420  }
[10618]1421
1422 return (xCollisionBackward || xCollisionForward);
[7833]1423}
1424
[8490]1425
[9110]1426/**
1427 * check the collision in the z direction (up, down)
1428 */
[10618]1429bool BspManager::checkCollisionY(WorldEntity* entity)
[9110]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  {
[10013]1513    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y,
1514                              entity, this->parent,
[9110]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  {
[9235]1538    if( this->outputFraction == 1.0f) // No collision Detected
[9110]1539    {
[9869]1540      if( this->outputAllSolid )
[9110]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      }
[9235]1549      else      // No collision happened
[9110]1550      {
1551        yCollisionDown = false;
1552        collPos = down;
1553      }
1554    }
[9235]1555    else           // A collision has happended
[9110]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  {
[10013]1566    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Y_NEG ,
1567                              entity, this->parent,
[9110]1568                              Vector(testPlane->x, testPlane->y, testPlane->z),
1569                              collPos, SolidFlag);
1570  }
[10618]1571
1572 return (yCollisionUp || yCollisionDown);
[9110]1573}
1574
1575
1576
1577
1578/**
1579 * check the collision in the z direction (left, right)
1580 */
[10618]1581bool BspManager::checkCollisionZ(WorldEntity* entity)
[9110]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) {
[10013]1647    CoRe::CollisionTube::getInstance()->registerCollisionEvent( CoRe::CREngine::CR_COLLISION_TYPE_AXIS_Z ,
1648                              entity, this->parent,
[9110]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) {
[10013]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);
[9110]1690  }
1691
[10618]1692 return (zCollisionLeft || zCollisionRight);
1693
[9110]1694}
1695
1696
1697
[10698]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;
[9110]1707
[10698]1708  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &StartPoint, &(End) );
1709
1710  return (this->outputFraction * length);
1711
1712}
1713
1714
1715
[10618]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
[7353]1800void  BspManager::checkCollision(BspTreeNode* node, Vector* cam)
1801{
[7563]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
[7395]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 {
[7353]1825
[7395]1826    leaf& camLeaf =  ((leaf *)(this->bspFile->leaves))[(node->leafIndex ) ];
[7353]1827
[7579]1828    if (camLeaf.cluster < 0) {
[7833]1829      this->drawDebugCube(&this->cam);
1830      this->drawDebugCube(&next);
[8796]1831      // State::getPlayer()->getPlayable()->setRelCoor(-100,-100,-100);
[8490]1832      //State::getPlayer()->getPlayable()->collidesWith(NULL, State::getCameraTargetNode()->getLastAbsCoor());
[7833]1833    }
[7395]1834
1835
1836    /*
[8087]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 ;
[7395]1847
[8087]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
[7395]1857  }
1858  return;
[7353]1859}
1860
1861void BspManager::drawDebugCube(Vector* cam)
1862{
[7395]1863  glBegin(GL_QUADS);
[7353]1864
[7395]1865  // Bottom Face.  Red, 75% opaque, magnified texture
[7353]1866
[7395]1867  glNormal3f( 0.0f, -1.0f, 0.0f); // Needed for lighting
1868  glColor4f(0.9,0.2,0.2,.75); // Basic polygon color
[7353]1869
[7395]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);
[7353]1874
1875
[7395]1876  // Top face; offset.  White, 50% opaque.
[7353]1877
[7395]1878  glNormal3f( 0.0f, 1.0f, 0.0f);  glColor4f(0.5,0.5,0.5,.5);
[7353]1879
[7395]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);
[7353]1884
1885
[7395]1886  // Far face.  Green, 50% opaque, non-uniform texture cooridinates.
[7353]1887
[7395]1888  glNormal3f( 0.0f, 0.0f,-1.0f);  glColor4f(0.2,0.9,0.2,.5);
[7353]1889
[7395]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);
[7353]1894
1895
[7395]1896  // Right face.  Blue; 25% opaque
[7353]1897
[7395]1898  glNormal3f( 1.0f, 0.0f, 0.0f);  glColor4f(0.2,0.2,0.9,.25);
[7353]1899
[7465]1900  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y -1.0f, cam->z -1.0f);
[7395]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);
[7353]1904
1905
[7395]1906  // Front face; offset.  Multi-colored, 50% opaque.
[7353]1907
[7395]1908  glNormal3f( 0.0f, 0.0f, 1.0f);
[7353]1909
[7395]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();
[7385]1934}
[7353]1935
[7385]1936void BspManager::addFace(int f)
1937{
[7395]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.