Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 1, 2006, 4:42:01 PM (18 years ago)
Author:
bottac
Message:

Loadable from .oxw

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/bsp_model/src/lib/graphics/importer/bsp_manager.cc

    r8030 r8081  
    1111   ### File Specific:
    1212   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/
    1320*/
    1421
     
    3643#include "world_entity.h"
    3744
     45#include "util/loading/load_param.h"
     46#include "util/loading/factory.h"
     47
     48
     49//CREATE_FACTORY( BspManager, CL_BSP_MODEL);
     50
    3851BspManager::BspManager()
    3952{
    40   // open a BSP file
     53  /*// open a BSP file
    4154  this->bspFile = new BspFile();
     55  this->bspFile->scale = 0.4f;
    4256  this->bspFile->read(ResourceManager::getFullName("test.bsp").c_str());
    4357  this->bspFile->build_tree();
    4458  this->root  = this->bspFile->get_root();
    4559  this->alreadyVisible = new bool [this->bspFile->numFaces];
    46 
     60  */
    4761  CDEngine::getInstance()->setBSPModel(this);
    48 }
    49 
    50 void BspManager::draw()
    51 {
    52 
    53 
     62 
     63 
     64 
     65}
     66
     67
     68/*
     69BspManager::BspManager(const TiXmlElement* root)
     70{
     71
     72 
     73  if( root != NULL)
     74    this->loadParams(root);
     75 
     76  CDEngine::getInstance()->setBSPModel(this);
     77} */
     78
     79void BspManager::load(const char* fileName, float scale)
     80{
     81  //this->setClassID(CL_BSP_MODEL, "BspManager");
     82    // open a BSP file
     83  this->bspFile = new BspFile();
     84  this->bspFile->scale =  scale;
     85  this->bspFile->read(ResourceManager::getFullName(fileName).c_str());
     86  this->bspFile->build_tree();
     87  this->root  = this->bspFile->get_root();
     88  this->alreadyVisible = new bool [this->bspFile->numFaces];
     89
     90
     91}
     92/*
     93BspManager::BspManager(const char* fileName, float scale)
     94{
     95  // open a BSP file
     96  this->bspFile = new BspFile();
     97  this->bspFile->scale =  scale;
     98  this->bspFile->read(fileName);
     99  this->bspFile->build_tree();
     100  this->root  = this->bspFile->get_root();
     101  this->alreadyVisible = new bool [this->bspFile->numFaces];
     102
     103  CDEngine::getInstance()->setBSPModel(this);
     104}
     105*/
     106
     107const void BspManager::draw()
     108{
     109
     110  /*
    54111  this->drawDebugCube(&this->out);
    55112  this->out1 = this->out;
     
    67124  this->drawDebugCube(&this->out1);
    68125  this->drawDebugCube(&this->out2);
    69  
     126  */
    70127  // Draw Debug Terrain
    71128  /*
     
    192249        const float dMaxs = dir.x*(float)curLeaf.maxs[0] +dir.y*(float)curLeaf.maxs[1] +dir.z*(float)curLeaf.maxs[2] - dist;
    193250
    194         if(dMins < -100.0 && dMaxs < -  100.0) {
     251        if(dMins < -50.0 && dMaxs < -  50.0) {
    195252          continue;
    196253        }
     
    223280    this->trasparent.pop_back();
    224281  }
     282  //glEnable(GL_TEXTURE_2D);
    225283  glActiveTextureARB(GL_TEXTURE1_ARB);
    226284  glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap);
    227   glEnable(GL_TEXTURE_2D);
     285 
     286 
    228287
    229288}//draw
     
    479538      if (fraction > startFraction)
    480539        startFraction = fraction;
     540      // don't store plane
     541      // this->collPlane = &curPlane;
     542     
     543    } else {   // line is leaving the brush
     544      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
     545      if (fraction < endFraction)
     546        endFraction = fraction;
     547      // don't store plane
     548      //this->collPlane = & curPlane;
     549     
     550    }
     551
     552  }
     553  if (startsOut == false) {
     554    this->outputStartsOut = false;
     555    if (endsOut == false)
     556      this->outputAllSolid = true;
     557    return;
     558  }
     559
     560  if (startFraction < endFraction) {
     561    if (startFraction > -1.0f && startFraction < outputFraction) {
     562      if (startFraction < 0)
     563        startFraction = 0;
     564      this->outputFraction = startFraction;
     565    }
     566  }
     567
     568}
     569
     570void BspManager::checkBrushRayN(brush* curBrush)
     571{
     572  float EPSILON = 0.000001;
     573  float startDistance;
     574  float endDistance;
     575
     576  float startFraction = -1.0f;
     577  float endFraction = 1.0f;
     578  bool startsOut = false;
     579  bool endsOut = false;
     580
     581  Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
     582  Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
     583
     584  for (int i = 0; i < curBrush->n_brushsides; i++) {
     585    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
     586    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
     587
     588    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
     589    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
     590
     591    if (startDistance > 0)
     592      startsOut = true;
     593    if (endDistance > 0)
     594      endsOut = true;
     595
     596    // make sure the trace isn't completely on one side of the brush
     597    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
     598      return;
     599    }
     600    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
     601      continue;
     602    }
     603
     604    // MMM... BEEFY
     605    if (startDistance > endDistance) {   // line is entering into the brush
     606      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
     607      if (fraction > startFraction)
     608        startFraction = fraction;
    481609      // store plane
    482610      this->collPlane = &curPlane;
     
    508636
    509637}
     638
    510639
    511640void BspManager::checkCollisionRay(BspTreeNode* node, float startFraction, float endFraction, Vector* start, Vector* end)
     
    604733
    605734
     735
     736void BspManager::checkCollisionRayN(BspTreeNode* node, float startFraction, float endFraction, Vector* start, Vector* end)
     737{
     738
     739
     740  float EPSILON = 0.000001;
     741  float  endDistance = (end)->x * (node->plane.x) +(end)->y * (node->plane.y) +(end)->z * (node->plane.z)  - node->d;
     742  float  startDistance = (start)->x * (node->plane.x)+ (start)->y * (node->plane.y)+ (start)->z * (node->plane.z)- node->d;
     743
     744
     745  if(node->isLeaf) {
     746    leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
     747    for (int i = 0; i <  curLeaf.n_leafbrushes ; i++) {
     748      brush& curBrush = this->bspFile->brushes[((int*)(this->bspFile->leafBrushes))[curLeaf.leafbrush_first+i]];
     749      //object *brush = &BSP.brushes[BSP.leafBrushes[leaf->firstLeafBrush + i]];
     750      if (curBrush.n_brushsides > 0   &&
     751          ((((BspTexture*)(this->bspFile->textures))[curBrush.texture]).contents & 1))
     752        // CheckBrush( brush );
     753        this->checkBrushRayN(&curBrush);
     754      if(curBrush.n_brushsides <=0) this->outputAllSolid = true;
     755    }
     756    return;
     757  }
     758
     759
     760  if (startDistance >= 0 && endDistance >= 0)     // A
     761  {   // both points are in front of the plane
     762    // so check the front child
     763    this->checkCollisionRayN(node->left,0,0,start,end);
     764  } else if (startDistance < 0 && endDistance < 0)  // B
     765  {   // both points are behind the plane
     766    // so check the back child
     767    this->checkCollisionRayN(node->right,0,0,start,end);
     768  } else                                            // C
     769  {   // the line spans the splitting plane
     770    int side;
     771    float fraction1, fraction2, middleFraction;
     772    Vector middle;
     773
     774    // STEP 1: split the segment into two
     775    if (startDistance < endDistance) {
     776      side = 1; // back
     777      float inverseDistance = 1.0f / (startDistance - endDistance);
     778      fraction1 = (startDistance + EPSILON) * inverseDistance;
     779      fraction2 = (startDistance + EPSILON) * inverseDistance;
     780    } else if (endDistance < startDistance) {
     781      side = 0; // front(start)->x * (node->plane.x)+
     782      float inverseDistance = 1.0f / (startDistance - endDistance);
     783      fraction1 = (startDistance + EPSILON) * inverseDistance;
     784      fraction2 = (startDistance - EPSILON) * inverseDistance;
     785    } else {
     786      side = 0; // front
     787      fraction1 = 1.0f;
     788      fraction2 = 0.0f;
     789    }
     790
     791    // STEP 2: make sure the numbers are valid
     792    if (fraction1 < 0.0f) fraction1 = 0.0f;
     793    else if (fraction1 > 1.0f) fraction1 = 1.0f;
     794    if (fraction2 < 0.0f) fraction2 = 0.0f;
     795    else if (fraction2 > 1.0f) fraction2 = 1.0f;
     796
     797    // STEP 3: calculate the middle point for the first side
     798    middleFraction = startFraction +
     799        (endFraction - startFraction) * fraction1;
     800
     801    middle.x = start->x + fraction1 * (end->x - start->x);
     802    middle.y = start->y + fraction1 * (end->y - start->y);
     803    middle.z = start->z + fraction1 * (end->z - start->z);
     804
     805    // STEP 4: check the first side
     806    //CheckNode( node->children[side], startFraction, middleFraction, start, middle );
     807    if(side == 0) this->checkCollisionRayN(node->left,startFraction, middleFraction, start, &middle );
     808
     809    else this->checkCollisionRayN(node->right,startFraction, middleFraction,
     810                                 start, &middle );
     811
     812    // STEP 5: calculate the middle point for the second side
     813    middleFraction = startFraction +
     814        (endFraction - startFraction) * fraction2;
     815
     816    middle.x = start->x + fraction2 * (end->x - start->x);
     817    middle.y = start->y + fraction2 * (end->y - start->y);
     818    middle.z = start->z + fraction2 * (end->z - start->z);
     819
     820    // STEP 6: check the second side
     821    if(side == 1)this->checkCollisionRayN(node->left,middleFraction, endFraction, &middle, end);
     822
     823    else this->checkCollisionRayN(node->right,middleFraction, endFraction,&middle, end );
     824
     825
     826  }
     827
     828}
     829
    606830void BspManager::checkCollision(WorldEntity* worldEntity)
    607831{
    608  // return;
     832  return;
    609833 
    610834  Vector position = worldEntity->getAbsCoor();
     
    623847  Vector out = Vector(-1875.0,-1875.0,-1875.0);
    624848  if(!worldEntity->isA(CL_PLAYABLE)) {
     849   
     850   
     851   
     852 
    625853  }
    626854  else {
     
    634862    Vector out2;
    635863
    636     this->checkCollisionRay(this->root,0.0f,1.0f, &position1, &dest1 );
     864    this->checkCollisionRayN(this->root,0.0f,1.0f, &position1, &dest1 );
    637865    if(this->outputFraction == 1.0f)  out1 = dest;
    638866    else {
     
    644872    }
    645873
    646     this->checkCollisionRay(this->root,0.0f,1.0f, &position2, &dest2 );
     874    this->checkCollisionRayN(this->root,0.0f,1.0f, &position2, &dest2 );
    647875    if(this->outputFraction == 1.0f) out2= dest;
    648876    else
     
    655883    }
    656884   
    657     this->checkCollisionRay(this->root,0.0f,1.0f, &position, &dest );
     885    this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &dest );
    658886    if(this->outputFraction == 1.0f) out = dest;
    659887    else
     
    664892    out.z = position.z + (dest.z -position.z) * this->outputFraction;
    665893   
    666     Vector out3 = out + Vector(3*this->collPlane->x,3*this->collPlane->y,3*this->collPlane->z);
    667     this->out = out;
    668     this->out1 = out1;
    669     this->out2 = out2;
     894    //Vector out3 = out + Vector(3*this->collPlane->x,3*this->collPlane->y,3*this->collPlane->z);
     895    //this->out = out;
     896    //this->out1 = out1;
     897    //this->out2 = out2;
    670898    //this->drawDebugCube(&out1);
    671899    //this->drawDebugCube(&out2);
     
    675903    }
    676904   
    677    // if(collision) worldEntity->collidesWithGround(out,out1,out2);
     905    // Return the normal here: Normal's stored in this->collPlane;
     906    if(collision) worldEntity->collidesWithGround(out,out1,out2);
    678907 
    679908  }
Note: See TracChangeset for help on using the changeset viewer.