Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/coll_rect.merge/src/lib/graphics/importer/bsp_manager.cc @ 10010

Last change on this file since 10010 was 10010, checked in by patrick, 17 years ago

merged the temp branch

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