Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 9235 was 9235, checked in by bensch, 18 years ago

merged the presentation back

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