Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/ODE/src/lib/graphics/importer/bsp/bsp_manager.cc @ 10355

Last change on this file since 10355 was 10355, checked in by bottac, 17 years ago

Here comes the updated version.

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