Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/terrain/src/lib/graphics/importer/bsp_manager.cc @ 8593

Last change on this file since 8593 was 8186, checked in by bensch, 19 years ago

trunk: merged the branche bsp_model back here

File size: 34.2 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2006 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: bottac@ee.ethz.ch
13
14   Inspired by:
15   Rendering Q3 Maps by Morgan McGuire                  http://graphics.cs.brown.edu/games/quake/quake3.html
16   Unofficial Quake 3 Map Specs by Kekoa Proudfoot      http://graphics.stanford.edu/~kekoa/q3/
17
18   Collision detection adapted from:
19   Quake 3 Collision Detection by Nathan Ostgard        http://www.devmaster.net/articles/quake3collision/
20*/
21
22
23#include "vector.h"
24#include "bsp_file.h"
25#include "bsp_manager.h"
26#include "bsp_tree_leaf.h"
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"
33#include "world_entities/player.h"
34#include "world_entities/playable.h"
35#include "util/loading/resource_manager.h"
36// STL Containers
37#include <vector>
38#include <deque>
39#include "movie_player.h"
40
41#include "cd_engine.h"
42
43#include "world_entity.h"
44
45#include "util/loading/load_param.h"
46#include "util/loading/factory.h"
47
48
49//CREATE_FACTORY( BspManager, CL_BSP_MODEL);
50
51BspManager::BspManager()
52{
53  /*// open a BSP file
54  this->bspFile = new BspFile();
55  this->bspFile->scale = 0.4f;
56  this->bspFile->read(ResourceManager::getFullName("test.bsp").c_str());
57  this->bspFile->build_tree();
58  this->root  = this->bspFile->get_root();
59  this->alreadyVisible = new bool [this->bspFile->numFaces];
60  */
61  CDEngine::getInstance()->setBSPModel(this);
62}
63
64
65/*
66BspManager::BspManager(const TiXmlElement* root)
67{
68
69
70  if( root != NULL)
71    this->loadParams(root);
72
73  CDEngine::getInstance()->setBSPModel(this);
74} */
75
76void BspManager::load(const char* fileName, float scale)
77{
78  //this->setClassID(CL_BSP_MODEL, "BspManager");
79    // open a BSP file
80  this->bspFile = new BspFile();
81  this->bspFile->scale =  scale;
82  this->bspFile->read(ResourceManager::getFullName(fileName).c_str());
83  this->bspFile->build_tree();
84  this->root  = this->bspFile->get_root();
85  this->alreadyVisible = new bool [this->bspFile->numFaces];
86
87
88}
89/*
90BspManager::BspManager(const char* fileName, float scale)
91{
92  // open a BSP file
93  this->bspFile = new BspFile();
94  this->bspFile->scale =  scale;
95  this->bspFile->read(fileName);
96  this->bspFile->build_tree();
97  this->root  = this->bspFile->get_root();
98  this->alreadyVisible = new bool [this->bspFile->numFaces];
99
100  CDEngine::getInstance()->setBSPModel(this);
101}
102*/
103
104const void BspManager::draw()
105{
106
107  /*
108  this->drawDebugCube(&this->out);
109  this->out1 = this->out;
110  this->out2 = this->out;
111  if(this->collPlane != NULL)
112  {
113  this->out1.x += this->collPlane->x*5.0;
114  this->out1.y += this->collPlane->y*5.0;
115  this->out1.z += this->collPlane->z*5.0;
116
117  this->out2.x += this->collPlane->x*10.0;
118  this->out2.y += this->collPlane->y*10.0;
119  this->out2.z += this->collPlane->z*10.0;
120  }
121  this->drawDebugCube(&this->out1);
122  this->drawDebugCube(&this->out2);
123  */
124  // Draw Debug Terrain
125  /*
126  this->bspFile->Materials[0]->select();
127  for(int i = 0; i <  this->bspFile->numPatches ; i++)
128        {
129                this->bspFile->VertexArrayModels[i]->draw();
130
131        }
132  */
133
134
135
136  // erase alreadyVisible
137  for(int i = 0; i < this->bspFile->numFaces; i++) this->alreadyVisible[i] = false;
138  float tmp = 0;
139  //this->opal.clear();
140  //this->trasparent.clear();
141  // Find all visible faces...
142
143  this->cam = State::getCamera()->getAbsCoor() ;
144  //this->ship = State::getCameraTargetNode()->getAbsCoor();
145
146
147
148
149
150  // this->viewDir=    State::getCameraTarget()->getAbsCoor() -  State::getCamera()->getAbsCoor() ;
151  float d = (cam.x*viewDir.x + cam.y*viewDir.y + cam.z * viewDir.z);
152
153  BspTreeNode*  ActLeaf = this->getLeaf(this->bspFile->root, &ship);
154  int viscluster = -1;
155  viscluster =((leaf*)(this->bspFile->leaves))[ ActLeaf->leafIndex].cluster; // get the players cluster (viscluster)
156
157
158
159  this->cam = State::getCameraTargetNode()->getAbsCoor();
160  // this->checkCollision(this->root, &this->cam);   //!< Test Collision Detection
161  this->outputStartsOut = true;
162  this->outputAllSolid = false;
163  this->outputFraction = 1.0f;
164
165  this->checkCollisionRay(this->root,0.0f,1.0f, &(State::getCameraTargetNode()->getLastAbsCoor()), &this->cam);
166
167  //if(this->outputFraction != 1.0f || this->outputAllSolid ) this->drawDebugCube(&this->cam);
168
169  if ( viscluster < 0  || ((int *)(this->bspFile->header))[35] == 0 )  //!< if (sizeof(Visdata) == 0)
170  {
171
172
173
174    // Iterate through all Leafspublic final double readLEDouble()
175    for(int i = 0; i <  this->bspFile->numLeafs   ; i++ )
176    {
177      // cluster =  (this->bspFile->leaves)[i].cluster;
178      leaf& curLeaf = (this->bspFile->leaves)[i];
179      if(curLeaf.cluster<0) continue;
180
181
182      /** Do Frustum culling and draw 'em all **/
183      bool inFrustum = true;
184
185      Vector dir;
186      dir.x = State::getCameraNode()->getAbsDirX().x;
187      dir.y =  State::getCameraNode()->getAbsDirX().y;
188      dir.z =  State::getCameraNode()->getAbsDirX().z;
189      float dist =  dir.x*this->cam.x +dir.y*this->cam.y +dir.z*this->cam.z;
190      //if(dist < 0) dist = -dist;
191      const float dMins = dir.x*(float)curLeaf.mins[0] +dir.y*(float)curLeaf.mins[1] +dir.z*(float)curLeaf.mins[2] - dist ;
192      const float dMaxs = dir.x*(float)curLeaf.maxs[0] +dir.y*(float)curLeaf.maxs[1] +dir.z*(float)curLeaf.maxs[2] - dist ;
193
194      if(dMins < -150.0 && dMaxs < -150.0) {
195        continue;
196      }
197      if( (this->cam - Vector(curLeaf.mins[0],curLeaf.mins[1], curLeaf.mins[2])).len() > 3000  && (this->cam - Vector(curLeaf.maxs[0],curLeaf.maxs[1], curLeaf.maxs[2])).len() > 3000) {
198        continue;
199      }
200
201
202      // Iterate through all faces
203      for (int j = 0; j < curLeaf.n_leaffaces ; ++j) {
204        const int g = (j +  curLeaf.leafface);
205        const int f = ((int *)this->bspFile->leafFaces)[g];
206        if (f >=0 && !this->isAlreadyVisible(f)) {
207          this->alreadyVisible[f] = true;
208
209          addFace(f); // "visibleFaces.append(f)"
210        }
211      }
212
213
214
215
216    } //for
217  } else {
218
219
220    unsigned int v;
221    unsigned char  visSet;
222
223    // Iterate through all Leafs
224
225    for(int i = 0; i <  this->bspFile->numLeafs   ; ++i ) {
226      leaf& camLeaf =  (this->bspFile->leaves)[ActLeaf->leafIndex] ;
227      leaf& curLeaf =  (this->bspFile->leaves)[i] ;
228      int& cluster =  curLeaf.cluster;
229
230      if(cluster < 0) continue;
231      v = ((viscluster *  ( ((int *)this->bspFile->visData)[1]) ) + (cluster / 8));
232      visSet =((char*) (this->bspFile->visData))[v + 8];
233
234      // gets bit of visSet
235      if( ((visSet) & (1 << (cluster &  7))) != 0 ) {
236
237        // Frustum culling
238
239        Vector dir;
240        dir.x = State::getCameraNode()->getAbsDirX().x;
241        dir.y =  State::getCameraNode()->getAbsDirX().y;
242        dir.z =  State::getCameraNode()->getAbsDirX().z;
243        const float dist =  dir.x*this->cam.x +dir.y*this->cam.y +dir.z*this->cam.z;
244        //if(dist < 0) dist = -dist;
245        const float dMins = dir.x*(float)curLeaf.mins[0] +dir.y*(float)curLeaf.mins[1] +dir.z*(float)curLeaf.mins[2] - dist;
246        const float dMaxs = dir.x*(float)curLeaf.maxs[0] +dir.y*(float)curLeaf.maxs[1] +dir.z*(float)curLeaf.maxs[2] - dist;
247
248        if(dMins < -50.0 && dMaxs < -  50.0) {
249          continue;
250        }
251
252
253        // Iterate through all faces
254        for (int j = 0; j < curLeaf.n_leaffaces ; ++j) {
255          const int g = (j +  curLeaf.leafface);
256          const int f = ((int *)this->bspFile->leafFaces)[g];
257
258          if (!this->isAlreadyVisible(f) && f>=0) {
259            this->addFace(f);
260            this->alreadyVisible[f] = true;
261          }
262
263        }
264
265      }// if
266
267    }//for
268
269  }//else
270
271  while(!this->opal.empty()) {
272    this->draw_face(this->opal.front());
273    this->opal.pop_front();
274  }
275  while(!this->trasparent.empty()) {
276    this->draw_face(this->trasparent.back());
277    this->trasparent.pop_back();
278  }
279  //glEnable(GL_TEXTURE_2D);
280  glActiveTextureARB(GL_TEXTURE1_ARB);
281  glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap);
282
283
284
285}//draw
286
287
288
289void BspManager::draw_face(int curface)
290{
291  face& curFace =  (this->bspFile->faces)[curface];
292  const BspVertex* curVertex = (BspVertex *) this->bspFile->vertice;
293  int stride = sizeof(BspVertex);  // sizeof(Vertex)
294  int offset    = curFace.vertex;
295  if (curFace.effect != -1) return;
296  // PRINTF(0)("BSP Manager: ");
297  // PRINTF(0)("BSP Manager: type: %i  \n", curFace.texture);
298
299  //  if(  curFace.texture < 0 ) return;
300  if(curFace.type == 2) {
301    this->draw_patch( &curFace);
302    return;
303  }
304  if(curFace.type != 1) return;
305  if((char*)(this->bspFile->textures)[curFace.texture*72]== 0) return;
306
307  if(this->lastTex != curFace.texture) {
308    if(this->bspFile->Materials[curFace.texture].animated) {
309      glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_COLOR);
310      glEnable(GL_BLEND);
311      if(this->bspFile->Materials[curFace.texture].aviMat->getStatus() == 2) this->bspFile->Materials[curFace.texture].aviMat->start(0);
312      this->bspFile->Materials[curFace.texture].aviMat->tick(0.005);
313      int n =  this->bspFile->Materials[curFace.texture].aviMat->getTexture();
314      glActiveTextureARB(GL_TEXTURE0_ARB);
315      glBindTexture(GL_TEXTURE_2D, n );
316      glDisable(GL_BLEND);
317    } else {
318      this->bspFile->Materials[curFace.texture].mat->select();
319      this->lastTex = curFace.texture;
320    }
321  }
322
323  if(curFace.lm_index < 0) {
324    glActiveTextureARB(GL_TEXTURE1_ARB);
325    glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap );
326    glEnable(GL_TEXTURE_2D);
327  } else {
328    glActiveTextureARB(GL_TEXTURE1_ARB);
329    glBindTexture(GL_TEXTURE_2D, this->bspFile->glLightMapTextures[curFace.lm_index]);
330    glEnable(GL_TEXTURE_2D);
331  }
332
333  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
334
335  // glColor4f(3.0,3.0,3.0,1.0);
336  glEnableClientState(GL_VERTEX_ARRAY );
337  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
338  glEnableClientState(GL_NORMAL_ARRAY );
339  //  glEnableClientState(GL_COLOR_ARRAY);
340
341
342  glVertexPointer(3, GL_FLOAT, stride, &(curVertex[offset].position[0]));
343
344  glClientActiveTextureARB(GL_TEXTURE0_ARB);
345  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[0]));
346  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
347
348  glClientActiveTextureARB(GL_TEXTURE1_ARB);
349  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[1]));
350  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
351
352
353  glNormalPointer( GL_FLOAT, stride, &(curVertex[offset].normal[0]));
354  // glColorPointer(4, GL_BYTE, stride, &(curVertex[offset].color[0]));
355  glDrawElements(GL_TRIANGLES, curFace.n_meshverts,
356                 GL_UNSIGNED_INT, &(((meshvert *)this->bspFile->meshverts) [curFace.meshvert]));
357
358  glDisableClientState(GL_TEXTURE0_ARB);
359  glDisableClientState(GL_TEXTURE1_ARB);
360  glDisableClientState(GL_VERTEX_ARRAY );
361  glDisableClientState(GL_TEXTURE_COORD_ARRAY );
362  glDisableClientState(GL_NORMAL_ARRAY );
363  // glDisableClientState(GL_COLOR_ARRAY);
364
365}
366
367
368void BspManager::draw_debug_face(int curface)
369{
370  face& curFace =  (this->bspFile->faces)[curface];
371  const BspVertex* curVertex = (BspVertex *) this->bspFile->vertice;
372  int stride = 44;  // sizeof(Vertex)
373  int offset    = curFace.vertex;
374
375  // PRINTF(0)("BSP Manager: ");
376  // PRINTF(0)("BSP Manager: type: %i  \n", curFace.texture);
377
378  //  if(  curFace.texture < 0 ) return;
379  if(curFace.type == 2) {
380    this->draw_patch( &curFace);
381    return;
382  }
383  if(curFace.type == 3) return;
384  // if(this->bspFile->Materials[curFace.texture] != NULL)
385
386  this->bspFile->Materials[2].mat->select();
387  this->lastTex = 2;
388
389  glEnableClientState(GL_VERTEX_ARRAY );
390  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
391  glEnableClientState(GL_NORMAL_ARRAY );
392  //glEnableClientState(GL_COLOR_ARRAY);
393  // glEnableClientState(GL_VERTEX_ARRAY );
394  glClientActiveTextureARB(GL_TEXTURE0_ARB);
395  glVertexPointer(3, GL_FLOAT, stride, &(curVertex[offset].position[0]));
396  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
397  // glClientActiveTextureARB(GL_TEXTURE0_ARB);
398  glClientActiveTextureARB(GL_TEXTURE1_ARB);
399  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[0]));
400  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
401  // glClientActiveTextureARB(GL_TEXTURE1_ARB);
402  // glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[1]));
403  //glEnableClientState(GL_NORMAL_ARRAY );
404
405  glNormalPointer( GL_FLOAT, stride, &(curVertex[offset].normal[0]));
406  //  glColorPointer(4, GL_BYTE, stride, &(curVertex[offset].color[0]));
407  glDrawElements(GL_TRIANGLES, curFace.n_meshverts,
408                 GL_UNSIGNED_INT, &(((meshvert *)this->bspFile->meshverts) [curFace.meshvert]));
409
410}
411
412void BspManager::draw_patch(face* Face)
413{
414  if(this->lastTex != Face->texture) {
415    this->bspFile->Materials[Face->texture].mat->select();
416    this->lastTex = Face->texture;
417  }
418  if (Face->effect != -1) return;
419
420
421  if(Face->lm_index < 0) {
422    glActiveTextureARB(GL_TEXTURE1_ARB);
423    glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap);
424    glEnable(GL_TEXTURE_2D);
425  } else {
426    glActiveTextureARB(GL_TEXTURE1_ARB);
427    glBindTexture(GL_TEXTURE_2D, this->bspFile->glLightMapTextures[Face->lm_index]);
428    glEnable(GL_TEXTURE_2D);
429  }
430  //glColor4f(3.0,3.0,3.0,1.0);
431
432  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
433  glEnable( GL_AUTO_NORMAL);
434  glEnableClientState(GL_VERTEX_ARRAY );
435  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
436  for(int i = Face->n_meshverts -1; i >=0   ; i--) {
437    //glFrontFace(GL_CW);
438    //PRINTF(0)("BSP Manager: Face->size[0]: %i . \n", Face->size[0]);
439
440
441    //glEnableClientState(GL_NORMAL_ARRAY );
442
443    glVertexPointer(3, GL_FLOAT,44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).position[0]));
444
445
446    glClientActiveTextureARB(GL_TEXTURE0_ARB);
447    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
448    glTexCoordPointer(2, GL_FLOAT, 44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).texcoord[0][0]));
449
450
451
452    glClientActiveTextureARB(GL_TEXTURE1_ARB);
453    glTexCoordPointer(2, GL_FLOAT, 44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).texcoord[1][0]));
454    //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
455
456
457    //  glNormalPointer( GL_FLOAT, 44,&((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).normal[0]) );
458
459
460
461
462    for(int row=6; row>=0; --row) {
463      glDrawElements(GL_TRIANGLE_STRIP, 2*(8), GL_UNSIGNED_INT,
464                     & (     (((GLuint*)  (this->bspFile->patchIndexes))[7*8*2*(Face->meshvert+i)+ row*2*8]  ))  );
465    }
466
467    //glFrontFace(GL_CCW);
468  }
469  glDisableClientState(GL_TEXTURE0_ARB);
470  glDisableClientState(GL_TEXTURE1_ARB);
471  glDisable(GL_AUTO_NORMAL);
472  glDisableClientState(GL_VERTEX_ARRAY );
473  glDisableClientState(GL_TEXTURE_COORD_ARRAY );
474
475
476}
477
478bool BspManager::isAlreadyVisible(int Face)
479{
480  return this->alreadyVisible[Face];
481}
482
483
484BspTreeNode*  BspManager::getLeaf(BspTreeNode* node, Vector* cam)
485{
486  float dist = 0;
487  while(!(node->isLeaf)) {
488    dist = (node->plane.x * this->cam.x + node->plane.y*this->cam.y + node->plane.z*this->cam.z) - node->d;
489    if(dist >= 0.0f) {
490      node = node->left;
491    } else {
492      node = node->right;
493    }
494  }
495  return  node;
496}
497
498void BspManager::checkBrushRay(brush* curBrush)
499{
500  float EPSILON = 0.000001;
501  float startDistance;
502  float endDistance;
503
504  float startFraction = -1.0f;
505  float endFraction = 1.0f;
506  bool startsOut = false;
507  bool endsOut = false;
508
509  Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
510  Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
511
512  for (int i = 0; i < curBrush->n_brushsides; i++) {
513    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
514    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
515
516    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
517    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
518
519    if (startDistance > 0)
520      startsOut = true;
521    if (endDistance > 0)
522      endsOut = true;
523
524    // make sure the trace isn't completely on one side of the brush
525    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
526      return;
527    }
528    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
529      continue;
530    }
531
532    // MMM... BEEFY
533    if (startDistance > endDistance) {   // line is entering into the brush
534      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
535      if (fraction > startFraction)
536        startFraction = fraction;
537      // don't store plane
538      // this->collPlane = &curPlane;
539
540    } else {   // line is leaving the brush
541      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
542      if (fraction < endFraction)
543        endFraction = fraction;
544      // don't store plane
545      //this->collPlane = & curPlane;
546
547    }
548
549  }
550  if (startsOut == false) {
551    this->outputStartsOut = false;
552    if (endsOut == false)
553      this->outputAllSolid = true;
554    return;
555  }
556
557  if (startFraction < endFraction) {
558    if (startFraction > -1.0f && startFraction < outputFraction) {
559      if (startFraction < 0)
560        startFraction = 0;
561      this->outputFraction = startFraction;
562    }
563  }
564
565}
566
567void BspManager::checkBrushRayN(brush* curBrush)
568{
569  float EPSILON = 0.000001;
570  float startDistance;
571  float endDistance;
572
573  float startFraction = -1.0f;
574  float endFraction = 1.0f;
575  bool startsOut = false;
576  bool endsOut = false;
577
578  Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
579  Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
580
581  for (int i = 0; i < curBrush->n_brushsides; i++) {
582    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
583    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
584
585    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
586    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
587
588    if (startDistance > 0)
589      startsOut = true;
590    if (endDistance > 0)
591      endsOut = true;
592
593    // make sure the trace isn't completely on one side of the brush
594    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
595      return;
596    }
597    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
598      continue;
599    }
600
601    // MMM... BEEFY
602    if (startDistance > endDistance) {   // line is entering into the brush
603      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
604      if (fraction > startFraction)
605        startFraction = fraction;
606      // store plane
607      this->collPlane = &curPlane;
608
609    } else {   // line is leaving the brush
610      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
611      if (fraction < endFraction)
612        endFraction = fraction;
613      // store plane
614      this->collPlane = & curPlane;
615
616    }
617
618  }
619  if (startsOut == false) {
620    this->outputStartsOut = false;
621    if (endsOut == false)
622      this->outputAllSolid = true;
623    return;
624  }
625
626  if (startFraction < endFraction) {
627    if (startFraction > -1.0f && startFraction < outputFraction) {
628      if (startFraction < 0)
629        startFraction = 0;
630      this->outputFraction = startFraction;
631    }
632  }
633
634}
635
636
637void BspManager::checkCollisionRay(BspTreeNode* node, float startFraction, float endFraction, Vector* start, Vector* end)
638{
639
640
641  float EPSILON = 0.000001;
642  float  endDistance = (end)->x * (node->plane.x) +(end)->y * (node->plane.y) +(end)->z * (node->plane.z)  - node->d;
643  float  startDistance = (start)->x * (node->plane.x)+ (start)->y * (node->plane.y)+ (start)->z * (node->plane.z)- node->d;
644
645
646  if(node->isLeaf) {
647    leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
648    for (int i = 0; i <  curLeaf.n_leafbrushes ; i++) {
649      brush& curBrush = this->bspFile->brushes[((int*)(this->bspFile->leafBrushes))[curLeaf.leafbrush_first+i]];
650      //object *brush = &BSP.brushes[BSP.leafBrushes[leaf->firstLeafBrush + i]];
651      if (curBrush.n_brushsides > 0   &&
652          ((((BspTexture*)(this->bspFile->textures))[curBrush.texture]).contents & 1))
653        // CheckBrush( brush );
654        this->checkBrushRay(&curBrush);
655      if(curBrush.n_brushsides <=0) this->outputAllSolid = true;
656    }
657    return;
658  }
659
660
661  if (startDistance >= 0 && endDistance >= 0)     // A
662  {   // both points are in front of the plane
663    // so check the front child
664    this->checkCollisionRay(node->left,0,0,start,end);
665  } else if (startDistance < 0 && endDistance < 0)  // B
666  {   // both points are behind the plane
667    // so check the back child
668    this->checkCollisionRay(node->right,0,0,start,end);
669  } else                                            // C
670  {   // the line spans the splitting plane
671    int side;
672    float fraction1, fraction2, middleFraction;
673    Vector middle;
674
675    // STEP 1: split the segment into two
676    if (startDistance < endDistance) {
677      side = 1; // back
678      float inverseDistance = 1.0f / (startDistance - endDistance);
679      fraction1 = (startDistance + EPSILON) * inverseDistance;
680      fraction2 = (startDistance + EPSILON) * inverseDistance;
681    } else if (endDistance < startDistance) {
682      side = 0; // front(start)->x * (node->plane.x)+
683      float inverseDistance = 1.0f / (startDistance - endDistance);
684      fraction1 = (startDistance + EPSILON) * inverseDistance;
685      fraction2 = (startDistance - EPSILON) * inverseDistance;
686    } else {
687      side = 0; // front
688      fraction1 = 1.0f;
689      fraction2 = 0.0f;
690    }
691
692    // STEP 2: make sure the numbers are valid
693    if (fraction1 < 0.0f) fraction1 = 0.0f;
694    else if (fraction1 > 1.0f) fraction1 = 1.0f;
695    if (fraction2 < 0.0f) fraction2 = 0.0f;
696    else if (fraction2 > 1.0f) fraction2 = 1.0f;
697
698    // STEP 3: calculate the middle point for the first side
699    middleFraction = startFraction +
700                     (endFraction - startFraction) * fraction1;
701
702    middle.x = start->x + fraction1 * (end->x - start->x);
703    middle.y = start->y + fraction1 * (end->y - start->y);
704    middle.z = start->z + fraction1 * (end->z - start->z);
705
706    // STEP 4: check the first side
707    //CheckNode( node->children[side], startFraction, middleFraction, start, middle );
708    if(side == 0) this->checkCollisionRay(node->left,startFraction, middleFraction, start, &middle );
709
710    else this->checkCollisionRay(node->right,startFraction, middleFraction,
711                                   start, &middle );
712
713    // STEP 5: calculate the middle point for the second side
714    middleFraction = startFraction +
715                     (endFraction - startFraction) * fraction2;
716
717    middle.x = start->x + fraction2 * (end->x - start->x);
718    middle.y = start->y + fraction2 * (end->y - start->y);
719    middle.z = start->z + fraction2 * (end->z - start->z);
720
721    // STEP 6: check the second side
722    if(side == 1)this->checkCollisionRay(node->left,middleFraction, endFraction, &middle, end);
723
724    else this->checkCollisionRay(node->right,middleFraction, endFraction,&middle, end );
725
726
727  }
728
729}
730
731
732
733void BspManager::checkCollisionRayN(BspTreeNode* node, float startFraction, float endFraction, Vector* start, Vector* end)
734{
735
736
737  float EPSILON = 0.000001;
738  float  endDistance = (end)->x * (node->plane.x) +(end)->y * (node->plane.y) +(end)->z * (node->plane.z)  - node->d;
739  float  startDistance = (start)->x * (node->plane.x)+ (start)->y * (node->plane.y)+ (start)->z * (node->plane.z)- node->d;
740
741
742  if(node->isLeaf) {
743    leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
744    for (int i = 0; i <  curLeaf.n_leafbrushes ; i++) {
745      brush& curBrush = this->bspFile->brushes[((int*)(this->bspFile->leafBrushes))[curLeaf.leafbrush_first+i]];
746      //object *brush = &BSP.brushes[BSP.leafBrushes[leaf->firstLeafBrush + i]];
747      if (curBrush.n_brushsides > 0   &&
748          ((((BspTexture*)(this->bspFile->textures))[curBrush.texture]).contents & 1))
749        // CheckBrush( brush );
750        this->checkBrushRayN(&curBrush);
751      if(curBrush.n_brushsides <=0) this->outputAllSolid = true;
752    }
753    return;
754  }
755
756
757  if (startDistance >= 0 && endDistance >= 0)     // A
758  {   // both points are in front of the plane
759    // so check the front child
760    this->checkCollisionRayN(node->left,0,0,start,end);
761  } else if (startDistance < 0 && endDistance < 0)  // B
762  {   // both points are behind the plane
763    // so check the back child
764    this->checkCollisionRayN(node->right,0,0,start,end);
765  } else                                            // C
766  {   // the line spans the splitting plane
767    int side;
768    float fraction1, fraction2, middleFraction;
769    Vector middle;
770
771    // STEP 1: split the segment into two
772    if (startDistance < endDistance) {
773      side = 1; // back
774      float inverseDistance = 1.0f / (startDistance - endDistance);
775      fraction1 = (startDistance + EPSILON) * inverseDistance;
776      fraction2 = (startDistance + EPSILON) * inverseDistance;
777    } else if (endDistance < startDistance) {
778      side = 0; // front(start)->x * (node->plane.x)+
779      float inverseDistance = 1.0f / (startDistance - endDistance);
780      fraction1 = (startDistance + EPSILON) * inverseDistance;
781      fraction2 = (startDistance - EPSILON) * inverseDistance;
782    } else {
783      side = 0; // front
784      fraction1 = 1.0f;
785      fraction2 = 0.0f;
786    }
787
788    // STEP 2: make sure the numbers are valid
789    if (fraction1 < 0.0f) fraction1 = 0.0f;
790    else if (fraction1 > 1.0f) fraction1 = 1.0f;
791    if (fraction2 < 0.0f) fraction2 = 0.0f;
792    else if (fraction2 > 1.0f) fraction2 = 1.0f;
793
794    // STEP 3: calculate the middle point for the first side
795    middleFraction = startFraction +
796        (endFraction - startFraction) * fraction1;
797
798    middle.x = start->x + fraction1 * (end->x - start->x);
799    middle.y = start->y + fraction1 * (end->y - start->y);
800    middle.z = start->z + fraction1 * (end->z - start->z);
801
802    // STEP 4: check the first side
803    //CheckNode( node->children[side], startFraction, middleFraction, start, middle );
804    if(side == 0) this->checkCollisionRayN(node->left,startFraction, middleFraction, start, &middle );
805
806    else this->checkCollisionRayN(node->right,startFraction, middleFraction,
807                                 start, &middle );
808
809    // STEP 5: calculate the middle point for the second side
810    middleFraction = startFraction +
811        (endFraction - startFraction) * fraction2;
812
813    middle.x = start->x + fraction2 * (end->x - start->x);
814    middle.y = start->y + fraction2 * (end->y - start->y);
815    middle.z = start->z + fraction2 * (end->z - start->z);
816
817    // STEP 6: check the second side
818    if(side == 1)this->checkCollisionRayN(node->left,middleFraction, endFraction, &middle, end);
819
820    else this->checkCollisionRayN(node->right,middleFraction, endFraction,&middle, end );
821
822
823  }
824
825}
826
827void BspManager::checkCollision(WorldEntity* worldEntity)
828{
829  return;
830
831  Vector position = worldEntity->getAbsCoor();
832
833
834  Vector forwardDir = worldEntity->getAbsDirX();
835  forwardDir.x =2.0*forwardDir.x;
836  forwardDir.y =2.0*forwardDir.y;
837  forwardDir.z =2.0*forwardDir.z;
838
839  Vector upDir = worldEntity->getAbsDirY();
840  Vector dest = position;
841  dest.+= forwardDir.x;
842  dest.+= forwardDir.y;
843  dest.+= forwardDir.z;
844  Vector out = Vector(-1875.0,-1875.0,-1875.0);
845  if(!worldEntity->isA(CL_PLAYABLE)) {
846
847
848
849
850  }
851  else {
852    bool collision = false;
853    Vector position1 = position + Vector(0.0,0.1,0.0);
854    Vector position2 = position + Vector(0.0,0.2,0.0);
855    Vector dest1 = position1 + forwardDir;
856    Vector dest2 = position2 + forwardDir;
857    dest = position - upDir;
858    Vector out1;
859    Vector out2;
860
861    this->checkCollisionRayN(this->root,0.0f,1.0f, &position1, &dest1 );
862    if(this->outputFraction == 1.0f)  out1 = dest;
863    else {
864      collision = true;
865      out1.x = position1.x + (dest1.x -position1.x) * this->outputFraction;
866      out1.y = position1.y + (dest1.y -position1.y) * this->outputFraction;
867      out1.z = position1.z + (dest1.z - position1.z) * this->outputFraction;
868
869    }
870
871    this->checkCollisionRayN(this->root,0.0f,1.0f, &position2, &dest2 );
872    if(this->outputFraction == 1.0f) out2= dest;
873    else
874    {
875      collision = true;
876    out2.x = position2.x + (dest2.x -position2.x) * this->outputFraction;
877    out2.y = position2.y + (dest2.y -position2.y) * this->outputFraction;
878    out2.z = position2.z + (dest2.z - position2.z) * this->outputFraction;
879
880    }
881
882    this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &dest );
883    if(this->outputFraction == 1.0f) out = dest;
884    else
885    {
886    collision = true;
887    out.x = position.x + (dest.x -position.x) * this->outputFraction;
888    out.y = position.y + (dest.y -position.y) * this->outputFraction;
889    out.z = position.z + (dest.z -position.z) * this->outputFraction;
890
891    //Vector out3 = out + Vector(3*this->collPlane->x,3*this->collPlane->y,3*this->collPlane->z);
892    //this->out = out;
893    //this->out1 = out1;
894    //this->out2 = out2;
895    //this->drawDebugCube(&out1);
896    //this->drawDebugCube(&out2);
897
898    //this->drawDebugCube(&out3);
899
900    }
901
902    // Return the normal here: Normal's stored in this->collPlane;
903//    if(collision) worldEntity->collidesWithGround(out,out1,out2);
904
905  }
906
907}
908
909void  BspManager::checkCollision(BspTreeNode* node, Vector* cam)
910{
911  Vector next = this->cam;
912  next.x =   (State::getCameraTargetNode()->getLastAbsCoor()).x ;
913  next.y =   (State::getCameraTargetNode()->getLastAbsCoor()).y ;
914  next.z =   (State::getCameraTargetNode()->getLastAbsCoor()).z ;
915
916  float dist = 0;
917  if(!(node->isLeaf)) {
918    dist = (node->plane.x * this->cam.x + node->plane.y*this->cam.y + node->plane.z*this->cam.z) - node->d;
919    if(dist > 4.0f) {
920      checkCollision(node->left,cam);
921      return;
922    }
923    if(dist < -4.0f) {
924      checkCollision(node->right,cam);
925      return;
926    }
927    if(dist<=4.0f && dist >= -4.0f) {
928      checkCollision(node->left,cam);
929      checkCollision(node->right,cam);
930      return;
931    }
932    return;
933  } else {
934
935    leaf& camLeaf =  ((leaf *)(this->bspFile->leaves))[(node->leafIndex ) ];
936
937    if (camLeaf.cluster < 0) {
938      this->drawDebugCube(&this->cam);
939      this->drawDebugCube(&next);
940      State::getPlayer()->getPlayable()->setRelCoor(-100,-100,-100);
941      State::getPlayer()->getPlayable()->collidesWith(NULL, State::getCameraTargetNode()->getLastAbsCoor());
942    }
943
944
945    /*
946        for(int i = 0; i < camLeaf.n_leafbrushes && i < 10; i++ )
947        {
948                brush& curBrush = ((brush*)(this->bspFile->brushes))[(camLeaf.leafbrush_first +i)%this->bspFile->numLeafBrushes];
949                if(curBrush.n_brushsides < 0) return;
950                for(int j = 0; j < curBrush.n_brushsides; j++)
951                {
952                float dist = -0.1;
953                brushside& curBrushSide = ((brushside*)(this->bspFile->brushSides))[(curBrush.brushside +j)%this->bspFile->numBrushSides];
954                plane&      testPlane = ((plane*)(this->bspFile->planes))[curBrushSide.plane % this->bspFile->numPlanes];
955                dist = testPlane.x * this->cam.x +  testPlane.y * this->cam.y  +  testPlane.z * this->cam.z   -testPlane.d ;
956
957                if(dist < -0.01f) dist = -1.0f *dist;
958                if(dist < 1.0f){
959                                this->drawDebugCube(&this->cam);
960                                return;
961                              }
962                }
963
964        } */
965
966  }
967  return;
968}
969
970void BspManager::drawDebugCube(Vector* cam)
971{
972  glBegin(GL_QUADS);
973
974  // Bottom Face.  Red, 75% opaque, magnified texture
975
976  glNormal3f( 0.0f, -1.0f, 0.0f); // Needed for lighting
977  glColor4f(0.9,0.2,0.2,.75); // Basic polygon color
978
979  glTexCoord2f(0.800f, 0.800f); glVertex3f(cam->x-1.0f, cam->y-1.0f,cam->z -1.0f);
980  glTexCoord2f(0.200f, 0.800f); glVertex3f(cam->x+1.0f, cam->y-1.0f,cam->z -1.0f);
981  glTexCoord2f(0.200f, 0.200f); glVertex3f(cam->x+ 1.0f,cam->y -1.0f,cam->z +  1.0f);
982  glTexCoord2f(0.800f, 0.200f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z + 1.0f);
983
984
985  // Top face; offset.  White, 50% opaque.
986
987  glNormal3f( 0.0f, 1.0f, 0.0f);  glColor4f(0.5,0.5,0.5,.5);
988
989  glTexCoord2f(0.005f, 1.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.0f);
990  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
991  glTexCoord2f(1.995f, 0.005f); glVertex3f(cam->x+ 1.0f,  cam->y+1.0f,  cam->z +1.0f);
992  glTexCoord2f(1.995f, 1.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z -1.0f);
993
994
995  // Far face.  Green, 50% opaque, non-uniform texture cooridinates.
996
997  glNormal3f( 0.0f, 0.0f,-1.0f);  glColor4f(0.2,0.9,0.2,.5);
998
999  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z -1.3f);
1000  glTexCoord2f(2.995f, 2.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.3f);
1001  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x+ 1.0f,cam->y+  1.0f, cam->z -1.3f);
1002  glTexCoord2f(0.005f, 0.005f); glVertex3f( cam->x+1.0f,cam->y -1.0f, cam->z -1.3f);
1003
1004
1005  // Right face.  Blue; 25% opaque
1006
1007  glNormal3f( 1.0f, 0.0f, 0.0f);  glColor4f(0.2,0.2,0.9,.25);
1008
1009  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y -1.0f, cam->z -1.0f);
1010  glTexCoord2f(0.995f, 0.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z -1.0f);
1011  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z + 1.0f);
1012  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y-1.0f,  cam->z +1.0f);
1013
1014
1015  // Front face; offset.  Multi-colored, 50% opaque.
1016
1017  glNormal3f( 0.0f, 0.0f, 1.0f);
1018
1019  glColor4f( 0.9f, 0.2f, 0.2f, 0.5f);
1020  glTexCoord2f( 0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f,  cam->z +1.0f);
1021  glColor4f( 0.2f, 0.9f, 0.2f, 0.5f);
1022  glTexCoord2f( 0.995f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y-1.0f,  cam->z +1.0f);
1023  glColor4f( 0.2f, 0.2f, 0.9f, 0.5f);
1024  glTexCoord2f( 0.995f, 0.995f); glVertex3f( cam->x+1.0f,  cam->y+1.0f,  cam->z +1.0f);
1025  glColor4f( 0.1f, 0.1f, 0.1f, 0.5f);
1026  glTexCoord2f( 0.005f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
1027
1028
1029  // Left Face; offset.  Yellow, varying levels of opaque.
1030
1031  glNormal3f(-1.0f, 0.0f, 0.0f);
1032
1033  glColor4f(0.9,0.9,0.2,0.0);
1034  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z -1.0f);
1035  glColor4f(0.9,0.9,0.2,0.66);
1036  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x-1.0f,cam->y -1.0f,  cam->z +1.0f);
1037  glColor4f(0.9,0.9,0.2,1.0);
1038  glTexCoord2f(0.995f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
1039  glColor4f(0.9,0.9,0.2,0.33);
1040  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.0f);
1041
1042  glEnd();
1043}
1044
1045void BspManager::addFace(int f)
1046{
1047  face& curFace =  ((face *)(this->bspFile->faces))[f];
1048  if(this->bspFile->Materials[curFace.texture].alpha) this->trasparent.push_back(f);
1049  else this->opal.push_back(f);
1050}
Note: See TracBrowser for help on using the repository browser.