Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/importer/bsp/bsp_manager.cc @ 10388

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

fixed a floating point problem

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