NL3D::CVisualCollisionEntity Class Reference

#include <visual_collision_entity.h>


Detailed Description

An entity created by CVisualCollisionManager.
Author:
Lionel Berenguier

Nevrax France

Date:
2001

Definition at line 50 of file visual_collision_entity.h.

Landscape part.

void doComputeLandscape (const CVector &pos)
 compute tiles infos around the position.

CTrianglePatchgetPatchTriangleUnderUs (const CVector &pos, CVector &res)
void snapToLandscapeCurrentTesselation (CVector &pos, const CTrianglePatch &tri)
 snap to current rendered tesselation.

void testComputeLandscape (const CVector &pos)
 test if the new position is outside the preceding setuped bbox, and then compute tiles infos around the position.

bool triangleIntersect (CTriangle &tri, const CVector &pos0, const CVector &pos1, CVector &hit)
 Fast "2D" test of a triangle against ray P0 P1.

CAABBox _CurrentBBoxValidity
 The current BBox where we don't need to recompute the patchQuadBlocks if the entity is in.

CLandscapeCollisionGrid _LandscapeQuadGrid
 A quadgrid of chainlist of tileId (CVisualTileDescNode), which are around the entity.

CVector _LastGPTPosInput
 compute tiles infos around the position.

CVector _LastGPTPosOutput
 compute tiles infos around the position.

CTrianglePatch _LastGPTTrianglePatch
 compute tiles infos around the position.

bool _LastGPTValid
 Cache for getPatchTriangleUnderUs().

std::vector< CPatchQuadBlock * > _PatchQuadBlocks
void computeUvForPos (const CTrianglePatch &tri, const CVector &pos, CUV &uv)
 given a CTrianglePatch, compute Patch uv according to position.

bool triangleIntersect2DCeil (CTriangle &tri, const CVector &pos0)
 compute tiles infos around the position.

bool triangleIntersect2DGround (CTriangle &tri, const CVector &pos0)
 Fast "2D" test of a triangle against ray P0 P1.

const uint32 _StartPatchQuadBlockSize = 64
 Default capacity of _PatchQuadBlocks.

std::vector< CPatchBlockIdent_TmpBlockIds
 This is the temp array of BlockIds filled by landscape search.

std::vector< CPatchQuadBlock * > _TmpPatchQuadBlocks
 This is the temp array of PatchBlocks ptr.


Public Member Functions

 CVisualCollisionEntity (CVisualCollisionManager *owner)
 Constructor.

bool getCeilMode () const
bool getGroundMode () const
bool getSnapToRenderedTesselation () const
bool getSurfaceInfo (const CVector &pos, CSurfaceInfo &info)
void setCeilMode (bool ceilMode)
void setGroundMode (bool groundMode)
void setSnapToRenderedTesselation (bool snapMode)
bool snapToGround (CVector &pos, CVector &normal)
bool snapToGround (CVector &pos)
 ~CVisualCollisionEntity ()
Debug display
void displayDebugGrid (IDriver &drv) const
 Draw lines for the landscape quadgrid collision faces under us.

Static Lighting
bool getStaticLightSetup (const CVector &pos, std::vector< CPointLightInfluence > &pointLightList, uint8 &sunContribution, NLMISC::CRGBA &localAmbient)

Static Public Attributes

Parameters.
const float BBoxRadius = 10
 This is the radius of the bbox around the entity where we have correct collisions: 10m.

const float BBoxRadiusZ = 20

Private Attributes

bool _CeilMode
bool _GroundMode
CVisualCollisionManager_Owner
bool _SnapToRenderedTesselation


Constructor & Destructor Documentation

NL3D::CVisualCollisionEntity::CVisualCollisionEntity CVisualCollisionManager owner  ) 
 

Constructor.

Definition at line 56 of file visual_collision_entity.cpp.

References _CeilMode, _CurrentBBoxValidity, _GroundMode, _LastGPTValid, _PatchQuadBlocks, _SnapToRenderedTesselation, _StartPatchQuadBlockSize, and NLMISC::CAABBox::setHalfSize().

00056                                                                              : _LandscapeQuadGrid(owner)
00057 {
00058         _Owner= owner;
00059         _PatchQuadBlocks.reserve(_StartPatchQuadBlockSize);
00060 
00061         _CurrentBBoxValidity.setHalfSize(CVector::Null);
00062 
00063         _GroundMode= true;
00064         _CeilMode= false;
00065         _SnapToRenderedTesselation= true;
00066 
00067         _LastGPTValid= false;
00068 }

NL3D::CVisualCollisionEntity::~CVisualCollisionEntity  ) 
 

Definition at line 72 of file visual_collision_entity.cpp.

References _LandscapeQuadGrid, _PatchQuadBlocks, NL3D::CLandscapeCollisionGrid::clear(), NL3D::CVisualCollisionManager::deletePatchQuadBlock(), and sint.

00073 {
00074         // delete the _PatchQuadBlocks.
00075         for(sint i=0; i<(sint)_PatchQuadBlocks.size(); i++)
00076         {
00077                 _Owner->deletePatchQuadBlock(_PatchQuadBlocks[i]);
00078         }
00079         _PatchQuadBlocks.clear();
00080 
00081         // delete the quadgrid.
00082         _LandscapeQuadGrid.clear();
00083 }


Member Function Documentation

void NL3D::CVisualCollisionEntity::computeUvForPos const CTrianglePatch tri,
const CVector pos,
CUV uv
[static, private]
 

given a CTrianglePatch, compute Patch uv according to position.

Definition at line 247 of file visual_collision_entity.cpp.

References NLMISC::CTriangle::computeGradient(), NLMISC::CUV::U, NLMISC::CTriangleUV::Uv0, NLMISC::CTriangleUV::Uv1, NLMISC::CTriangleUV::Uv2, NLMISC::CUV::V, and NLMISC::CTriangle::V0.

Referenced by getStaticLightSetup(), getSurfaceInfo(), and snapToLandscapeCurrentTesselation().

00248 {
00249         // compute UV gradients.
00250         CVector         Gu;
00251         CVector         Gv;
00252         tri.computeGradient(tri.Uv0.U, tri.Uv1.U, tri.Uv2.U, Gu);
00253         tri.computeGradient(tri.Uv0.V, tri.Uv1.V, tri.Uv2.V, Gv);
00254         // interpolate
00255         uv.U= tri.Uv0.U + Gu*(pos-tri.V0);
00256         uv.V= tri.Uv0.V + Gv*(pos-tri.V0);
00257 }

void NL3D::CVisualCollisionEntity::displayDebugGrid IDriver drv  )  const
 

Draw lines for the landscape quadgrid collision faces under us.

Definition at line 612 of file visual_collision_entity.cpp.

References _PatchQuadBlocks, NL3D::CMaterial::initUnlit(), NL_PATCH_BLOCK_MAX_VERTEX, NL3D::CPatchQuadBlock::PatchBlockId, s, NL3D::CPatchBlockIdent::S0, NL3D::CPatchBlockIdent::S1, t, NL3D::CPatchBlockIdent::T0, NL3D::CPatchBlockIdent::T1, uint, and NL3D::CPatchQuadBlock::Vertices.

Referenced by NL3D::CVisualCollisionEntityUser::displayDebugGrid().

00613 {
00614         // static to not reallocate each frame
00615         static  CMaterial       mat;
00616         static  bool            inited= false;
00617         if(!inited)
00618         {
00619                 inited= true;
00620                 mat.initUnlit();
00621         }
00622         static  vector<CLine>   lineList;
00623         lineList.clear();
00624 
00625         // Build lines for all patch quad blocks.
00626         for(uint i=0;i<_PatchQuadBlocks.size();i++)
00627         {
00628                 CPatchQuadBlock         &pqb= *_PatchQuadBlocks[i];
00629                 // Parse all quads of this patch block.
00630                 CPatchBlockIdent        &pbid= pqb.PatchBlockId;
00631                 for(uint t= pbid.T0; t<pbid.T1; t++)
00632                 {
00633                         for(uint s= pbid.S0; s<pbid.S1; s++)
00634                         {
00635                                 // compute quad coordinate in pqb.
00636                                 uint    sd0= (s-pbid.S0);
00637                                 uint    td0= (t-pbid.T0);
00638                                 uint    sd1= sd0+1;
00639                                 uint    td1= td0+1;
00640                                 // get 4 vertex coord of quad
00641                                 const CVector   &p0= pqb.Vertices[sd0 + td0*NL_PATCH_BLOCK_MAX_VERTEX];
00642                                 const CVector   &p1= pqb.Vertices[sd0 + td1*NL_PATCH_BLOCK_MAX_VERTEX];
00643                                 const CVector   &p2= pqb.Vertices[sd1 + td1*NL_PATCH_BLOCK_MAX_VERTEX];
00644                                 const CVector   &p3= pqb.Vertices[sd1 + td0*NL_PATCH_BLOCK_MAX_VERTEX];
00645 
00646                                 // build the 5 lines
00647                                 lineList.push_back(CLine(p0, p1));
00648                                 lineList.push_back(CLine(p1, p2));
00649                                 lineList.push_back(CLine(p2, p3));
00650                                 lineList.push_back(CLine(p3, p0));
00651                                 lineList.push_back(CLine(p0, p2));
00652                         }
00653                 }
00654         }
00655 
00656         // Display the lines.
00657         CDRU::drawLinesUnlit(lineList, mat, drv);
00658 }

void NL3D::CVisualCollisionEntity::doComputeLandscape const CVector pos  )  [private]
 

compute tiles infos around the position.

Definition at line 414 of file visual_collision_entity.cpp.

References _CurrentBBoxValidity, NL3D::CVisualCollisionManager::_Landscape, _LandscapeQuadGrid, _PatchQuadBlocks, _TmpBlockIds, _TmpPatchQuadBlocks, BBoxRadius, BBoxRadiusZ, NL3D::CLandscapeCollisionGrid::build(), NL3D::CVisualCollisionManager::deletePatchQuadBlock(), NL3D::CVisualCollisionManager::newPatchQuadBlock(), NLMISC::CAABBox::setCenter(), NLMISC::CAABBox::setHalfSize(), sint, uint, NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z.

Referenced by testComputeLandscape().

00415 {
00416         sint    i;
00417 
00418         // setup new bbox.
00419         //==================
00420         // compute the bbox which must includes the patchQuadBlocks
00421         CAABBox         bboxToIncludePatchs;
00422         bboxToIncludePatchs.setCenter(pos);
00423         bboxToIncludePatchs.setHalfSize(CVector(BBoxRadius, BBoxRadius, BBoxRadiusZ));
00424         // setup the _CurrentBBoxValidity with same values, but BBoxRadiusZ/2
00425         _CurrentBBoxValidity.setCenter(pos);
00426         _CurrentBBoxValidity.setHalfSize(CVector(BBoxRadius, BBoxRadius, BBoxRadiusZ/2));
00427 
00428 
00429         // Search landscape blocks which are in the bbox.
00430         //==================
00431         _Owner->_Landscape->buildPatchBlocksInBBox(bboxToIncludePatchs, _TmpBlockIds);
00432 
00433 
00434 
00435         // Recompute PatchQuadBlockcs.
00436         //==================
00437         // This parts try to keeps old patch blocks so they are not recomputed if they already here.
00438 
00439         // sort PatchBlockIdent.
00440         sort(_TmpBlockIds.begin(), _TmpBlockIds.end());
00441 
00442         // Copy old array of ptr (ptr copy only).
00443         _TmpPatchQuadBlocks= _PatchQuadBlocks;
00444 
00445         // allocate dest array.
00446         _PatchQuadBlocks.resize(_TmpBlockIds.size());
00447 
00448         // Traverse all current patchBlocks, deleting old ones no longer needed, and creating new ones.
00449         // this algorithm suppose both array are sorted.
00450         uint    iOld=0;
00451         // parse until dest is filled.
00452         for(i=0; i<(sint)_PatchQuadBlocks.size();)
00453         {
00454                 // get requested new BlockIdent.
00455                 CPatchBlockIdent        newBi= _TmpBlockIds[i];
00456 
00457                 // get requested old BlockIdent in the array.
00458                 bool                            oldEnd= false;
00459                 CPatchBlockIdent        oldBi;
00460                 if(iOld==_TmpPatchQuadBlocks.size())
00461                         oldEnd= true;
00462                 else
00463                         oldBi= _TmpPatchQuadBlocks[iOld]->PatchBlockId;
00464 
00465                 // if no more old blocks, or if new Block is < than current, we must create a new block, and insert it.
00466                 if(oldEnd || newBi < oldBi)
00467                 {
00468                         // allocate the patch block.
00469                         _PatchQuadBlocks[i]= _Owner->newPatchQuadBlock();
00470                         // fill the patch block.
00471                         _PatchQuadBlocks[i]->PatchBlockId= _TmpBlockIds[i];
00472                         _Owner->_Landscape->fillPatchQuadBlock(*_PatchQuadBlocks[i]);
00473 
00474                         // next new patch block.
00475                         i++;
00476                 }
00477                 // else if current new Block is same than old block, just copy ptr.
00478                 else if(newBi==oldBi)
00479                 {
00480                         // just copy ptr with the old one.
00481                         _PatchQuadBlocks[i]= _TmpPatchQuadBlocks[iOld];
00482 
00483                         // next new and old patch block.
00484                         i++;
00485                         iOld++;
00486                 }
00487                 // else, this old block is no longer used, delete it.
00488                 else
00489                 {
00490                         _Owner->deletePatchQuadBlock(_TmpPatchQuadBlocks[iOld]);
00491                         // next old patch block.
00492                         iOld++;
00493                 }
00494         }
00495         // Here, must delete old blocks not yet processed.
00496         for(;iOld<_TmpPatchQuadBlocks.size(); iOld++)
00497         {
00498                 _Owner->deletePatchQuadBlock(_TmpPatchQuadBlocks[iOld]);
00499         }
00500         _TmpPatchQuadBlocks.clear();
00501 
00502 
00503         // Compute the quadGrid.
00504         //==================
00505 
00506         // Compute a delta so elt position for CLandscapeCollisionGrid are positive, and so fastFloor() used will work.
00507         CVector         delta;
00508         // center the position on 0.
00509         // floor may be important for precision when the delta is applied.
00510         delta.x= (float)floor(-pos.x);
00511         delta.y= (float)floor(-pos.y);
00512         delta.z= 0;
00513         // We must always have positive values for patchBlocks vertices.
00514         float   val= (float)ceil(BBoxRadius + 256);
00515         // NB: 256 is a security. Because of size of patchs, a value of 32 at max should be sufficient (64 for bigger patch (gfx))
00516         // we are large because doesn't matter, the CLandscapeCollisionGrid tiles.
00517         delta.x+= val;
00518         delta.y+= val;
00519 
00520         // rebuild the quadGrid.
00521         _LandscapeQuadGrid.build(_PatchQuadBlocks, delta);
00522 
00523 }

bool NL3D::CVisualCollisionEntity::getCeilMode  )  const [inline]
 

Definition at line 90 of file visual_collision_entity.h.

References _CeilMode.

Referenced by NL3D::CVisualCollisionEntityUser::getCeilMode().

00090 {return _CeilMode;}

bool NL3D::CVisualCollisionEntity::getGroundMode  )  const [inline]
 

Definition at line 89 of file visual_collision_entity.h.

References _GroundMode.

Referenced by NL3D::CVisualCollisionEntityUser::getGroundMode().

00089 {return _GroundMode;}

CTrianglePatch * NL3D::CVisualCollisionEntity::getPatchTriangleUnderUs const CVector pos,
CVector res
[private]
 

return the best trianglePatch under what we are. NULL if not found. Ptr is valid until next call to getPatchTriangleUnderUs() Actually return NULL or

Definition at line 96 of file visual_collision_entity.cpp.

References NL3D::CVisualCollisionManager::_Landscape, _LandscapeQuadGrid, _LastGPTPosInput, _LastGPTPosOutput, _LastGPTTrianglePatch, _LastGPTValid, _PatchQuadBlocks, NL3D::CPatchQuadBlock::buildTileTriangles(), NL3D::CVisualTileDescNode::Next, nlassert, NL3D::CVisualTileDescNode::PatchQuadBlocId, NL3D::CVisualTileDescNode::QuadId, res, NL3D::CLandscapeCollisionGrid::select(), sint, NLMISC::sqr(), testComputeLandscape(), triangleIntersect(), and uint8.

Referenced by getStaticLightSetup(), getSurfaceInfo(), and snapToGround().

00097 {
00098         // verify if landscape (refptr) is here.
00099         if(_Owner->_Landscape==NULL)
00100         {
00101                 _LastGPTValid= false;
00102                 return NULL;
00103         }
00104 
00105 
00106         // Test GPT cache.
00107         //==================
00108         // If last call was valid, and if same pos (input or output), return cached information
00109         if(_LastGPTValid && (pos==_LastGPTPosInput || pos==_LastGPTPosOutput) )
00110         {
00111                 // copy from cache.
00112                 res= _LastGPTPosOutput;
00113                 /* don't modify _LastGPTPosInput cache, for best cache behavior in all cases.
00114                         1/ this is not necessary (here, if pos!=_LastGPTPosInput, THEN pos==_LastGPTPosOutput, no other possibilities)
00115                         2/ it causes problems when getPatchTriangleUnderUs() is called randomly with the unsnapped or snapped position:
00116                                 1st Time: zin:9.0  =>  zout:9.5 cache fail (ok, 1st time...)
00117                                 2nd Time: zin:9.0  =>  zout:9.5 cache OK (_LastGPTPosInput.z==zin)
00118                                 3rd Time: zin:9.5  =>  zout:9.5 cache OK (_LastGPTPosOutput.z==zin)
00119                                 4th Time: zin:9.0  =>  zout:9.5 cache FAILS (_LastGPTPosInput.z= 9.5 => !=zin)
00120                 */
00121                 // and return ptr on cache.
00122                 return &_LastGPTTrianglePatch;
00123         }
00124 
00125 
00126         // update the cache of tile info near this position.
00127         // =================
00128         testComputeLandscape(pos);
00129 
00130 
00131         // find possible faces under the entity.
00132         // =================
00133         CVisualTileDescNode             *ptr= _LandscapeQuadGrid.select(pos); 
00134 
00135 
00136         // find the better face under the entity.
00137         // =================
00138         float   sqrBestDist= sqr(1000.f);
00139         CVector hit;
00140         // build the vertical ray.
00141         CVector         segP0= pos - CVector(0,0,100);
00142         CVector         segP1= pos + CVector(0,0,100);
00143 
00144 
00145         // triangles builded from this list.
00146         static  vector<CTrianglePatch>          testTriangles;
00147         // NB: not so many reallocation here, because static.
00148         testTriangles.clear();
00149         sint    bestTriangle= 0;
00150 
00151 
00152         // For all the faces in this quadgrid node.
00153         while(ptr)
00154         {
00155                 // what is the quad block of this tile Id.
00156                 sint                            qbId= ptr->PatchQuadBlocId;
00157                 nlassert(qbId>=0 && qbId<(sint)_PatchQuadBlocks.size());
00158                 CPatchQuadBlock         &qb= *_PatchQuadBlocks[qbId];
00159 
00160                 // Build the 2 triangles of this tile Id.
00161                 sint    idStart= testTriangles.size();
00162                 testTriangles.resize(idStart+2);
00163                 qb.buildTileTriangles((uint8)ptr->QuadId, &testTriangles[idStart]);
00164 
00165                 // Test the 2 triangles.
00166                 for(sint i=0; i<2; i++)
00167                 {
00168                         CTrianglePatch  &tri= testTriangles[idStart+i];
00169                         // test if the ray intersect.
00170                         // NB: triangleIntersect() is faster than CTriangle::intersect().
00171                         if(triangleIntersect(tri, segP0, segP1, hit))
00172                         {
00173                                 // find the nearest triangle.
00174                                 float sqrdist= (hit-pos).sqrnorm();
00175                                 if(sqrdist<sqrBestDist)
00176                                 {
00177                                         bestTriangle= idStart+i;
00178                                         res= hit;
00179                                         sqrBestDist= sqrdist;
00180                                 }
00181                         }
00182                 }
00183 
00184 
00185                 // Next in the list.
00186                 ptr= ptr->Next;
00187         }
00188 
00189 
00190         // found ??
00191         if(sqrBestDist<sqr(1000))
00192         {
00193                 // copy into cache
00194                 _LastGPTValid= true;
00195                 _LastGPTTrianglePatch= testTriangles[bestTriangle];
00196                 _LastGPTPosInput= pos;
00197                 _LastGPTPosOutput= res;
00198                 // and return ptr on cache.
00199                 return &_LastGPTTrianglePatch;
00200         }
00201         else
00202         {
00203                 _LastGPTValid= false;
00204                 return NULL;
00205         }
00206 
00207 }

bool NL3D::CVisualCollisionEntity::getSnapToRenderedTesselation  )  const [inline]
 

Definition at line 98 of file visual_collision_entity.h.

References _SnapToRenderedTesselation.

Referenced by NL3D::CVisualCollisionEntityUser::getSnapToRenderedTesselation().

bool NL3D::CVisualCollisionEntity::getStaticLightSetup const CVector pos,
std::vector< CPointLightInfluence > &  pointLightList,
uint8 sunContribution,
NLMISC::CRGBA localAmbient
 

Get the static Light Setup, using landscape under us. append lights to pointLightList. NB: if find no landscape faces, don't modify pointLightList, set sunContribution=255, and return false Else, use CPatch::TileLightInfluences to get lights, and use CPatch::Lumels to get sunContribution. NB: because CPatch::Lumels encode the gouraud shading on the surface, returning lumelValue will darken the object too much. To avoid this, the sunContribution is raised to a power (0..1). See CVisualCollisionManager::setSunContributionPower(). Default is 0.5

Definition at line 527 of file visual_collision_entity.cpp.

References NL3D::CVisualCollisionManager::_Landscape, NL3D::CVisualCollisionManager::_SunContributionLUT, computeUvForPos(), getPatchTriangleUnderUs(), NL3D::CTrianglePatch::PatchId, res, NLMISC::CRGBA::set(), and uint8.

Referenced by NL3D::CInstanceLighter::computeSunContribution(), and NL3D::CVisualCollisionEntityUser::getStaticLightSetup().

00529 {
00530         // Get Patch Triangle Under Us
00531         CVector         res;
00532         CTrianglePatch  *tri= getPatchTriangleUnderUs(pos, res);
00533 
00534         // For now, no localAmbient support on landscape.
00535         localAmbient.set(0,0,0,0);
00536 
00537         // result. NB: if not found, dot not modify.
00538         if( tri )
00539         {
00540                 // compute UV for position.
00541                 CUV             uv;
00542                 computeUvForPos(*tri, pos, uv);
00543 
00544                 // get the sunContribution
00545                 sunContribution= _Owner->_Landscape->getLumel(tri->PatchId, uv);
00546                 // see getStaticLightSetup.
00547                 sunContribution= _Owner->_SunContributionLUT[sunContribution];
00548                 
00549                 // append any lights of interest.
00550                 _Owner->_Landscape->appendTileLightInfluences(tri->PatchId, uv, pointLightList);
00551 
00552                 return true;
00553         }
00554         else
00555         {
00556                 // Suppose full Sun Contribution, and don't add any pointLight
00557                 sunContribution= 255;
00558 
00559                 return false;
00560         }
00561 }

bool NL3D::CVisualCollisionEntity::getSurfaceInfo const CVector pos,
CSurfaceInfo info
 

Get surface informations. pos is checked with polygons that are at least (cache dependent) at +- 10m in altitude.

Parameters:
info will be filled with surface informations if the method returns true.
Returns:
true if the surface has been found and informations has been filled.

Definition at line 565 of file visual_collision_entity.cpp.

References NL3D::CVisualCollisionManager::_Landscape, computeUvForPos(), getPatchTriangleUnderUs(), NL3D::CTileBank::getTileSet(), NL3D::CTileBank::getTileXRef(), H_AUTO, NL_TILE_ELM_LAYER_EMPTY, NL3D::CTrianglePatch::PatchId, res, NL3D::CTileSet::SurfaceData, NL3D::CTileElement::Tile, type, uint16, and NL3D::CSurfaceInfo::UserSurfaceData.

Referenced by NL3D::CVisualCollisionEntityUser::getSurfaceInfo().

00566 {
00567         H_AUTO( NL3D_CVisualCollisionEntity_getSurfaceInfo )
00568         // Get Patch Triangle Under Us
00569         CVector         res;
00570         CTrianglePatch  *tri= getPatchTriangleUnderUs(pos, res);
00571 
00572         // result. NB: if not found, dot not modify.
00573         if( tri )
00574         {
00575                 // compute UV for position.
00576                 CUV             uv;
00577                 computeUvForPos(*tri, pos, uv);
00578 
00579                 // get the tileelement
00580                 CTileElement *tileElm = _Owner->_Landscape->getTileElement(tri->PatchId, uv);
00581                 if (tileElm)
00582                 {
00583                         // Valid tile ?
00584                         uint16 tileId = tileElm->Tile[0];
00585                         if (tileId != NL_TILE_ELM_LAYER_EMPTY)
00586                         {
00587                                 // The tilebank
00588                                 CTileBank &tileBank = _Owner->_Landscape->TileBank;
00589 
00590                                 // Get xref info for this tile
00591                                 int tileSet;
00592                                 int number;
00593                                 CTileBank::TTileType type;
00594                                 tileBank.getTileXRef ((int)tileId, tileSet, number, type);
00595 
00596                                 // Get the tileset from layer 0
00597                                 const CTileSet* tileSetPtr = tileBank.getTileSet (tileSet);
00598 
00599                                 // Fill the surface
00600                                 surfaceInfo.UserSurfaceData = tileSetPtr->SurfaceData;
00601 
00602                                 // Ok
00603                                 return true;
00604                         }
00605                 }
00606         }
00607         return false;
00608 }

void NL3D::CVisualCollisionEntity::setCeilMode bool  ceilMode  )  [inline]
 

If ceilMode is true, the entity is snapped on faces with normal.z < 0. Default is false. NB: if both groundMode and ceilMode are false, snapToGround is a no-op.

Definition at line 86 of file visual_collision_entity.h.

References _CeilMode.

Referenced by NL3D::CVisualCollisionEntityUser::setCeilMode().

00086 {_CeilMode= ceilMode;}

void NL3D::CVisualCollisionEntity::setGroundMode bool  groundMode  )  [inline]
 

If groundMode is true, the entity is snapped on faces with normal.z > 0. Default is true. NB: if both groundMode and ceilMode are false, snapToGround is a no-op.

Definition at line 80 of file visual_collision_entity.h.

References _GroundMode.

Referenced by NL3D::CVisualCollisionEntityUser::setGroundMode().

00080 {_GroundMode= groundMode;}

void NL3D::CVisualCollisionEntity::setSnapToRenderedTesselation bool  snapMode  )  [inline]
 

By default, the visual collision entity is snapped on rendered/geomorphed tesselation (true). Use this method to change this behavior. if false, the entity is snapped to the tile level tesselation according to noise etc...

Definition at line 97 of file visual_collision_entity.h.

References _SnapToRenderedTesselation.

Referenced by NL3D::CVisualCollisionEntityUser::setSnapToRenderedTesselation().

00097 {_SnapToRenderedTesselation= snapMode;}

bool NL3D::CVisualCollisionEntity::snapToGround CVector pos,
CVector normal
 

Snap the entity onto the ground. pos.z is modified so that it lies on the ground, according to rendered landscapes and meshes. pos is checked with polygons that are at least (cache dependent) at +- 10m in altitude.

Parameters:
normal the ret normal of where it is snapped. NB: if return false, not modified.
Returns:
true if pos.z has been modified (sometimes it may not find a solution).

Definition at line 211 of file visual_collision_entity.cpp.

References _SnapToRenderedTesselation, getPatchTriangleUnderUs(), NLMISC::CVector::normalize(), res, snapToLandscapeCurrentTesselation(), NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, and NLMISC::CTriangle::V2.

00212 {
00213         // Get Patch Triangle Under Us
00214         CVector         res;
00215         CTrianglePatch  *tri= getPatchTriangleUnderUs(pos, res);
00216 
00217         // result. NB: if not found, dot not modify.
00218         if( tri )
00219         {
00220                 if(_SnapToRenderedTesselation)
00221                 {
00222                         // snap the position to the nearest tesselation.
00223                         pos= res;
00224 
00225                         // snap the position to the current rendered tesselation.
00226                         snapToLandscapeCurrentTesselation(pos, *tri);
00227                 }
00228                 else
00229                 {
00230                         // just snap to the accurate tile tesselation.
00231                         pos= res;
00232                 }
00233 
00234 
00235                 // compute the normal.
00236                 normal= (tri->V1-tri->V0)^(tri->V2-tri->V0);
00237                 normal.normalize();
00238 
00239                 return true;
00240         }
00241         else
00242                 return false;
00243 }

bool NL3D::CVisualCollisionEntity::snapToGround CVector pos  ) 
 

Snap the entity onto the ground. pos.z is modified so that it lies on the ground, according to rendered landscapes and meshes. see setSnapToRenderedTesselation() option. pos is checked with polygons that are at least (cache dependent) at +- 10m in altitude.

Returns:
true if pos.z has been modified (sometimes it may not find a solution).

Definition at line 87 of file visual_collision_entity.cpp.

Referenced by NL3D::CVisualCollisionEntityUser::snapToGround().

00088 {
00089         CVector         normal;
00090         // Not optimized, but doesn't matter (one cross product is negligible).
00091         return snapToGround(pos, normal);
00092 }

void NL3D::CVisualCollisionEntity::snapToLandscapeCurrentTesselation CVector pos,
const CTrianglePatch tri
[private]
 

snap to current rendered tesselation.

Definition at line 261 of file visual_collision_entity.cpp.

References NL3D::CVisualCollisionManager::_Landscape, computeUvForPos(), NL3D::CTrianglePatch::PatchId, and NLMISC::CVector::z.

Referenced by snapToGround().

00262 {
00263         // compute UV for position.
00264         CUV             uv;
00265         computeUvForPos(tri, pos, uv);
00266 
00267         // Ask pos to landscape.
00268         CVector         posLand;
00269         posLand= _Owner->_Landscape->getTesselatedPos(tri.PatchId, uv);
00270 
00271         // just keep Z.
00272         pos.z= posLand.z;
00273 }

void NL3D::CVisualCollisionEntity::testComputeLandscape const CVector pos  )  [private]
 

test if the new position is outside the preceding setuped bbox, and then compute tiles infos around the position.

Definition at line 403 of file visual_collision_entity.cpp.

References _CurrentBBoxValidity, doComputeLandscape(), NLMISC::CAABBox::getHalfSize(), and NLMISC::CAABBox::include().

Referenced by getPatchTriangleUnderUs().

00404 {
00405         // if new position is out of the bbox surounding the entity.
00406         if(_CurrentBBoxValidity.getHalfSize()==CVector::Null || !_CurrentBBoxValidity.include(pos))
00407         {
00408                 // must recompute the data around the entity.
00409                 doComputeLandscape(pos);
00410         }
00411 }

bool NL3D::CVisualCollisionEntity::triangleIntersect CTriangle tri,
const CVector pos0,
const CVector pos1,
CVector hit
[private]
 

Fast "2D" test of a triangle against ray P0 P1.

Definition at line 366 of file visual_collision_entity.cpp.

References _CeilMode, _GroundMode, NLMISC::CPlane::intersect(), NLMISC::CPlane::make(), triangleIntersect2DCeil(), triangleIntersect2DGround(), NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, NLMISC::CTriangle::V2, NLMISC::CVector::x, NLMISC::CVector::y, and NLMISC::CVector::z.

Referenced by getPatchTriangleUnderUs().

00367 {
00368         CVector         &p0= tri.V0;
00369         CVector         &p1= tri.V1;
00370         CVector         &p2= tri.V2;
00371 
00372         bool    ok= false;
00373         if( _GroundMode && triangleIntersect2DGround(tri, pos0) )
00374                 ok= true;
00375         if(!ok && _CeilMode && triangleIntersect2DCeil(tri, pos0) )
00376                 ok= true;
00377         if(!ok)
00378                 return false;
00379 
00380 
00381         // Compute the possible height.
00382         CVector         tmp;
00383         // build the plane
00384         CPlane plane;
00385         plane.make (p0, p1, p2);
00386         // intersect the vertical line with the plane.
00387         tmp= plane.intersect(pos0, pos1);
00388 
00389         float           h= tmp.z;
00390         // Test if it would fit in the wanted field.
00391         if(h>pos1.z)    return false;
00392         if(h<pos0.z)    return false;
00393 
00394         // OK!!
00395         // For cache completness, ensure that X and Y don't move, take same XY than pos0
00396         hit.x= pos0.x;
00397         hit.y= pos0.y;
00398         hit.z= h;
00399         return true;
00400 }

bool NL3D::CVisualCollisionEntity::triangleIntersect2DCeil CTriangle tri,
const CVector pos0
[static, private]
 

compute tiles infos around the position.

Definition at line 336 of file visual_collision_entity.cpp.

References NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, NLMISC::CTriangle::V2, NLMISC::CVector::x, and NLMISC::CVector::y.

Referenced by triangleIntersect().

00337 {
00338         CVector         &p0= tri.V0;
00339         CVector         &p1= tri.V1;
00340         CVector         &p2= tri.V2;
00341 
00342         // Test if the face enclose the pos in X/Y plane.
00343         // NB: compute and using a BBox to do a rapid test is not a very good idea, since it will 
00344         // add an overhead which is NOT negligeable compared to the following test.
00345         float           a,b,c;          // 2D cartesian coefficients of line in plane X/Y.
00346         // Line p0-p1.
00347         a= -(p1.y-p0.y);
00348         b= (p1.x-p0.x);
00349         c= -(p0.x*a + p0.y*b);
00350         if( (a*pos0.x + b*pos0.y + c) > 0)      return false;
00351         // Line p1-p2.
00352         a= -(p2.y-p1.y);
00353         b= (p2.x-p1.x);
00354         c= -(p1.x*a + p1.y*b);
00355         if( (a*pos0.x + b*pos0.y + c) > 0)      return false;
00356         // Line p2-p0.
00357         a= -(p0.y-p2.y);
00358         b= (p0.x-p2.x);
00359         c= -(p2.x*a + p2.y*b);
00360         if( (a*pos0.x + b*pos0.y + c) > 0)      return false;
00361 
00362         return true;
00363 }

bool NL3D::CVisualCollisionEntity::triangleIntersect2DGround CTriangle tri,
const CVector pos0
[static, private]
 

Fast "2D" test of a triangle against ray P0 P1.

Definition at line 299 of file visual_collision_entity.cpp.

References NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, NLMISC::CTriangle::V2, NLMISC::CVector::x, and NLMISC::CVector::y.

Referenced by triangleIntersect().

00300 {
00301         CVector         &p0= tri.V0;
00302         CVector         &p1= tri.V1;
00303         CVector         &p2= tri.V2;
00304 
00305         // TestYoyo. Test for precision problems.
00306         /*if( testLine(p1, p0, pos0) && testLine(p2, p1, pos0) && testLine(p0, p2, pos0) )
00307         {
00308                 nlinfo("Found Tri For Pos: %.07f, %.07f\n   P0: %.07f, %.07f\n   P1: %.07f, %.07f\n   P2: %.07f, %.07f",
00309                         pos0.x, pos0.y, p0.x, p0.y, p1.x, p1.y, p2.x, p2.y);
00310         }*/
00311 
00312         // Test if the face enclose the pos in X/Y plane.
00313         // NB: compute and using a BBox to do a rapid test is not a very good idea, since it will 
00314         // add an overhead which is NOT negligeable compared to the following test.
00315         float           a,b,c;          // 2D cartesian coefficients of line in plane X/Y.
00316         // Line p0-p1.
00317         a= -(p1.y-p0.y);
00318         b= (p1.x-p0.x);
00319         c= -(p0.x*a + p0.y*b);
00320         if( (a*pos0.x + b*pos0.y + c) < 0)      return false;
00321         // Line p1-p2.
00322         a= -(p2.y-p1.y);
00323         b= (p2.x-p1.x);
00324         c= -(p1.x*a + p1.y*b);
00325         if( (a*pos0.x + b*pos0.y + c) < 0)      return false;
00326         // Line p2-p0.
00327         a= -(p0.y-p2.y);
00328         b= (p0.x-p2.x);
00329         c= -(p2.x*a + p2.y*b);
00330         if( (a*pos0.x + b*pos0.y + c) < 0)      return false;
00331 
00332         return true;
00333 }


Field Documentation

bool NL3D::CVisualCollisionEntity::_CeilMode [private]
 

Definition at line 149 of file visual_collision_entity.h.

Referenced by CVisualCollisionEntity(), getCeilMode(), setCeilMode(), and triangleIntersect().

CAABBox NL3D::CVisualCollisionEntity::_CurrentBBoxValidity [private]
 

The current BBox where we don't need to recompute the patchQuadBlocks if the entity is in.

Definition at line 171 of file visual_collision_entity.h.

Referenced by CVisualCollisionEntity(), doComputeLandscape(), and testComputeLandscape().

bool NL3D::CVisualCollisionEntity::_GroundMode [private]
 

Definition at line 150 of file visual_collision_entity.h.

Referenced by CVisualCollisionEntity(), getGroundMode(), setGroundMode(), and triangleIntersect().

CLandscapeCollisionGrid NL3D::CVisualCollisionEntity::_LandscapeQuadGrid [private]
 

A quadgrid of chainlist of tileId (CVisualTileDescNode), which are around the entity.

Definition at line 169 of file visual_collision_entity.h.

Referenced by doComputeLandscape(), getPatchTriangleUnderUs(), and ~CVisualCollisionEntity().

CVector NL3D::CVisualCollisionEntity::_LastGPTPosInput [private]
 

compute tiles infos around the position.

Definition at line 174 of file visual_collision_entity.h.

Referenced by getPatchTriangleUnderUs().

CVector NL3D::CVisualCollisionEntity::_LastGPTPosOutput [private]
 

compute tiles infos around the position.

Definition at line 175 of file visual_collision_entity.h.

Referenced by getPatchTriangleUnderUs().

CTrianglePatch NL3D::CVisualCollisionEntity::_LastGPTTrianglePatch [private]
 

compute tiles infos around the position.

Definition at line 176 of file visual_collision_entity.h.

Referenced by getPatchTriangleUnderUs().

bool NL3D::CVisualCollisionEntity::_LastGPTValid [private]
 

Cache for getPatchTriangleUnderUs().

Definition at line 173 of file visual_collision_entity.h.

Referenced by CVisualCollisionEntity(), and getPatchTriangleUnderUs().

CVisualCollisionManager* NL3D::CVisualCollisionEntity::_Owner [private]
 

Definition at line 147 of file visual_collision_entity.h.

std::vector<CPatchQuadBlock*> NL3D::CVisualCollisionEntity::_PatchQuadBlocks [private]
 

Array of quadBlock which are around the entity. NB: plain vector, because not so big (ptrs). NB: reserve to a big size (64), so reallocation rarely occurs. NB: this array is sorted in ascending order (comparison of CPatchBlockIdent).

Definition at line 167 of file visual_collision_entity.h.

Referenced by CVisualCollisionEntity(), displayDebugGrid(), doComputeLandscape(), getPatchTriangleUnderUs(), and ~CVisualCollisionEntity().

bool NL3D::CVisualCollisionEntity::_SnapToRenderedTesselation [private]
 

Definition at line 151 of file visual_collision_entity.h.

Referenced by CVisualCollisionEntity(), getSnapToRenderedTesselation(), setSnapToRenderedTesselation(), and snapToGround().

const uint32 NL3D::CVisualCollisionEntity::_StartPatchQuadBlockSize = 64 [static, private]
 

Default capacity of _PatchQuadBlocks.

Definition at line 50 of file visual_collision_entity.cpp.

Referenced by CVisualCollisionEntity().

vector< CPatchBlockIdent > NL3D::CVisualCollisionEntity::_TmpBlockIds [static, private]
 

This is the temp array of BlockIds filled by landscape search.

Definition at line 51 of file visual_collision_entity.cpp.

Referenced by doComputeLandscape().

vector< CPatchQuadBlock * > NL3D::CVisualCollisionEntity::_TmpPatchQuadBlocks [static, private]
 

This is the temp array of PatchBlocks ptr.

Definition at line 52 of file visual_collision_entity.cpp.

Referenced by doComputeLandscape().

const float NL3D::CVisualCollisionEntity::BBoxRadius = 10 [static]
 

This is the radius of the bbox around the entity where we have correct collisions: 10m.

Definition at line 48 of file visual_collision_entity.cpp.

Referenced by doComputeLandscape().

const float NL3D::CVisualCollisionEntity::BBoxRadiusZ = 20 [static]
 

Same as BBoxRadius, but for z value. This later should be greater because of NLPACS surface quadtree imprecision. 20m NB: Because of caching, if the pos.z passed to snapToGround() is outside of the currentBBox with BBoxRadiuZ/2 (=> 10m), then the bbox is recomputed. Hence, this actually means that a pos is checked with patchs that are at least at +- 10m in altitude.

Definition at line 49 of file visual_collision_entity.cpp.

Referenced by doComputeLandscape().


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 08:26:34 2004 for NeL by doxygen 1.3.6