Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/bsp_model/src/lib/graphics/importer/bsp_manager.cc @ 8203

Last change on this file since 8203 was 8203, checked in by patrick, 18 years ago

bsp: some mods

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