Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/graphics/importer/bsp_manager.cc @ 9847

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

orxonox/new_class_id: Taken out the old ResourceManager.
On the way, i had to desintegrate the old MD3-model loading process (via ResourceManager) MD3 is untouched, but also not loaded anymore neither from ResourceMangers nor from the WorldEntity

@patrick: MD3-ModelLoading class must be implemented… this should be quite easy, with the way MD3 is, and the new Resource-paradigm
cheers

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