NLPACS::CGlobalRetriever Class Reference

#include <global_retriever.h>

Inheritance diagram for NLPACS::CGlobalRetriever:

NLPACS::UGlobalRetriever

Detailed Description

A class that allows to retrieve surface in a large amount of zones (referred as instances.)
Author:
Benjamin Legros

Nevrax France

Date:
2001

Definition at line 64 of file global_retriever.h.

Collisions part.

enum  TCollisionType { Circle, BBox }
void findCollisionChains (CCollisionSurfaceTemp &cst, const NLMISC::CAABBox &bboxMove, const NLMISC::CVector &origin) const
void testCollisionWithCollisionChains (CCollisionSurfaceTemp &cst, const CVector2f &startCol, const CVector2f &deltaCol, CSurfaceIdent startSurface, float radius, const CVector2f bbox[4], TCollisionType colType) const
CSurfaceIdent testMovementWithCollisionChains (CCollisionSurfaceTemp &cst, const CVector2f &startCol, const CVector2f &deltaCol, CSurfaceIdent startSurface, UGlobalPosition &restart) const
void testRotCollisionWithCollisionChains (CCollisionSurfaceTemp &cst, const CVector2f &startCol, CSurfaceIdent startSurface, const CVector2f bbox[4]) const
bool verticalChain (const CCollisionChain &colChain) const
 test if a collisionChain separate 2 walls.


Public Types

enum  { MissingLr = -2, Failed = -1, Success = 0 }
typedef std::vector< CLocalPathCGlobalPath

Public Member Functions

Position retrieving methods.
bool buildInstance (const std::string &id, const NLMISC::CVectorD &position, sint32 &instanceId)
NLMISC::CVectorD getDoubleGlobalPosition (const UGlobalPosition &global) const
 Converts a global position object into a 'human-readable' CVector (double instead.).

NLMISC::CVector getGlobalPosition (const UGlobalPosition &global) const
 Converts a global position object into a 'human-readable' CVector.

const std::string & getIdentifier (const UGlobalPosition &position) const
 Get the identifier of the global position.

sint32 getIdentifier (const std::string &id) const
 Return the retriever id from the string id.

sint32 getLocalRetrieverId (const UGlobalPosition &position) const
 Get the LocalRetrieverId of the global position.

bool insurePosition (UGlobalPosition &pos) const
 Insure position inside surface.

void removeInstance (sint32 instanceId)
UGlobalPosition retrievePosition (const NLMISC::CVectorD &estimated, uint h, sint &result) const
 Retrieves the position of an estimated point in the global retriever (double instead.).

UGlobalPosition retrievePosition (const NLMISC::CVectorD &estimated, double threshold, UGlobalPosition::TType retrieveSpec) const
 Retrieves the position of an estimated point in the global retriever (double instead.).

UGlobalPosition retrievePosition (const NLMISC::CVectorD &estimated, double threshold) const
 Retrieves the position of an estimated point in the global retriever (double instead.).

UGlobalPosition retrievePosition (const NLMISC::CVector &estimated, float threshold) const
 Retrieves the position of an estimated point in the global retriever.

UGlobalPosition retrievePosition (const NLMISC::CVectorD &estimated) const
 Retrieves the position of an estimated point in the global retriever (double instead.).

UGlobalPosition retrievePosition (const NLMISC::CVector &estimated) const
 Retrieves the position of an estimated point in the global retriever.

bool testPosition (UGlobalPosition &pos) const
bool testRaytrace (const NLMISC::CVectorD &v0, const NLMISC::CVectorD &v1)
 Make a raytrace test. For the time, always return false.

Initialisation
 CGlobalRetriever (const CRetrieverBank *bank=NULL)
void init ()
 Setup an empty global retriever.

void initQuadGrid ()
 Fill the quadgrid with the instances.

void initRetrieveTable ()
 Init the retrieve table.

virtual ~CGlobalRetriever ()
Mutators
void check () const
 Checks the retriever for errors.

float distanceToBorder (const UGlobalPosition &pos) const
 Checks the retriever for errors.

void getBorders (const NLMISC::CAABBox &sbox, std::vector< std::pair< NLMISC::CLine, uint8 > > &edges)
 Checks the retriever for errors.

void getBorders (const UGlobalPosition &pos, std::vector< std::pair< NLMISC::CLine, uint8 > > &edges)
 Checks the retriever for errors.

CRetrieverInstancegetInstanceFullAccess (uint id)
 Gets the instance by its id, with full read/write access.

void initAll (bool initInstances=true)
 Inits all the instances inside the global retriever.

void makeAllLinks ()
 Links all the instances inside the global retriever.

const CRetrieverInstancemakeInstance (uint32 retriever, uint8 orientation, const NLMISC::CVector &origin)
 Creates an instance of local retriever at the origine position with the given orientation.

void makeLinks (uint n)
 Links the instance referred by its id to its neighbors.

void resetAllLinks ()
 Resets all links within the global retriever.

void serial (NLMISC::IStream &f)
 Serialises the global retriever.

void setRetrieverBank (const CRetrieverBank *bank)
 Sets the retriever bank.

Collisions part.
UGlobalPosition doMove (const UGlobalPosition &start, const NLMISC::CVector &delta, float t, CCollisionSurfaceTemp &cst, bool rebuildChains=false) const
float getMeanHeight (const UGlobalPosition &pos) const
const CRetrievableSurfacegetSurfaceById (const CSurfaceIdent &surfId) const
const TCollisionSurfaceDescVectortestBBoxMove (const UGlobalPosition &start, const NLMISC::CVector &delta, const NLMISC::CVector &locI, const NLMISC::CVector &locJ, CCollisionSurfaceTemp &cst) const
const TCollisionSurfaceDescVectortestBBoxRot (const CGlobalPosition &start, const NLMISC::CVector &locI, const NLMISC::CVector &locJ, CCollisionSurfaceTemp &cst) const
const TCollisionSurfaceDescVectortestCylinderMove (const UGlobalPosition &start, const NLMISC::CVector &delta, float radius, CCollisionSurfaceTemp &cst) const
void updateHeight (UGlobalPosition &pos) const
 Upadates the height of the given global position.

Pathfinding part.
void findAStarPath (const UGlobalPosition &begin, const UGlobalPosition &end, std::vector< CRetrieverInstance::CAStarNodeAccess > &path, uint32 forbidFlags) const
void findPath (const UGlobalPosition &begin, const UGlobalPosition &end, CGlobalPath &path, uint32 forbidFlags=0) const
Selectors
const NLMISC::CAABBoxgetBBox () const
 Gets the BBox of the global retriever.

const CRetrieverInstancegetInstance (uint id) const
 Gets the retriever instance referred by its id.

const std::vector< CRetrieverInstance > & getInstances () const
 Gets the vector of retriever instances that compose the global retriever.

uint32 getMaterial (const UGlobalPosition &pos) const
 Get the material at this position.

const CLocalRetrievergetRetriever (uint32 id) const
 Get the local retriever.

const CRetrieverBankgetRetrieverBank () const
 Get the retriever bank associated to this global retriever.

bool isInterior (const UGlobalPosition &pos) const
 Test if the position is an interior.

bool isWaterPosition (const UGlobalPosition &pos, float &waterHeight) const
 Test if the position is in water.

bool selectInstances (const NLMISC::CAABBox &bbox, CCollisionSurfaceTemp &cst, UGlobalPosition::TType type=UGlobalPosition::Unspecified) const
Dynamic loading part.
void refreshLrAround (const NLMISC::CVector &position, float radius)
void refreshLrAroundNow (const NLMISC::CVector &position, float radius)

Static Public Member Functions

UGlobalRetrievercreateGlobalRetriever (const char *globalRetriever, const URetrieverBank *retrieverBank)
void deleteGlobalRetriever (UGlobalRetriever *retriever)

Protected Member Functions

CCollisionSurfaceTempgetInternalCST () const

Protected Attributes

NLMISC::CAABBox _BBox
 The axis aligned bounding box of the global retriever.

std::vector< sint32_ForbiddenInstances
 Forbidden instance for retrieve position.

CQuadGrid< uint32_InstanceGrid
 The grid of instances.

std::vector< CRetrieverInstance_Instances
 The instances of the global retriever.

std::list< CLrLoader_LrLoaderList
const CRetrieverBank_RetrieverBank
 The CRetrieverBank where the commmon retrievers are stored.


Private Types


Private Member Functions

Pathfinding part.
CRetrieverInstance::CAStarNodeInfogetNode (CRetrieverInstance::CAStarNodeAccess &access) const
 Gets the CAStarNodeInfo referred by its access.


Private Attributes

CCollisionSurfaceTemp _InternalCST
std::vector< uint8_RetrieveTable
 Used to retrieve the surface. Internal use only, to avoid large amount of new/delete.


Friends

class CLrLoader
class CRetrieverInstance


Member Typedef Documentation

typedef std::vector<CLocalPath> NLPACS::CGlobalRetriever::CGlobalPath
 

Definition at line 109 of file global_retriever.h.

Referenced by findPath().


Member Enumeration Documentation

anonymous enum
 

Enumeration values:
MissingLr 
Failed 
Success 

Definition at line 68 of file global_retriever.h.

00069         {
00070                 MissingLr = -2,
00071                 Failed = -1,
00072                 Success = 0
00073         };

enum NLPACS::CGlobalRetriever::TCollisionType [private]
 

Enumeration values:
Circle 
BBox 

Definition at line 494 of file global_retriever.h.

00494 { Circle, BBox };


Constructor & Destructor Documentation

NLPACS::CGlobalRetriever::CGlobalRetriever const CRetrieverBank bank = NULL  )  [inline]
 

Constructor. Creates a global retriever with given width, height and retriever bank.

Definition at line 178 of file global_retriever.h.

References _RetrieverBank.

00179                 : _RetrieverBank(bank)
00180         { }

virtual NLPACS::CGlobalRetriever::~CGlobalRetriever  )  [inline, virtual]
 

Constructor. Creates a global retriever with given width, height and retriever bank.

Definition at line 181 of file global_retriever.h.

00181 {}


Member Function Documentation

bool NLPACS::CGlobalRetriever::buildInstance const std::string &  id,
const NLMISC::CVectorD position,
sint32 instanceId
[virtual]
 

Builds a instance of retriever, and link it on the ground (or wherever)

Parameters:
id a valid retriever id to be instanciated
a valid position where the retriever should be instanciated
Returns:
false if failed

Implements NLPACS::UGlobalRetriever.

Definition at line 766 of file global_retriever.cpp.

References getIdentifier(), NLPACS::CRetrieverInstance::getInstanceId(), NLPACS::CRetrieverInstance::getRetrieverId(), makeInstance(), makeLinks(), and sint32.

00767 {
00768         NL_ALLOC_CONTEXT( Pacs )
00769 
00770         sint32  retrieverId = getIdentifier(id);
00771 
00772         instanceId = -1;
00773 
00774         // check retriever exists
00775         if (retrieverId < 0)
00776                 return false;
00777 
00778         const CRetrieverInstance        &instance = makeInstance(retrieverId, 0, CVector(position));
00779 
00780         // check make instance success
00781         if (&instance == NULL || instance.getInstanceId() == -1 || instance.getRetrieverId() != retrieverId)
00782                 return false;
00783 
00784         // links new instance to its neighbors
00785         makeLinks(instance.getInstanceId());
00786 
00787         instanceId = instance.getInstanceId();
00788 
00789         return true;
00790 }

void NLPACS::CGlobalRetriever::check  )  const
 

Checks the retriever for errors.

Definition at line 153 of file global_retriever.cpp.

References _RetrieverBank, NLPACS::CRetrieverInstance::CLink::BorderChainId, NLPACS::CRetrieverInstance::CLink::ChainId, NLPACS::CChain::getBorderChainIndex(), NLPACS::CRetrieverInstance::getBorderChainLink(), NLPACS::CRetrieverInstance::getBorderChainLinks(), NLPACS::CLocalRetriever::getBorderChains(), NLPACS::CLocalRetriever::getChain(), NLPACS::CLocalRetriever::getChains(), NLPACS::COrderedChain::getIndexInParent(), NLPACS::CRetrieverInstance::getInstanceId(), NLPACS::CChain::getLeft(), NLPACS::CLocalRetriever::getOrderedChain(), NLPACS::CLocalRetriever::getOrderedChains(), NLPACS::COrderedChain::getParentId(), getRetriever(), NLPACS::CRetrieverBank::getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CRetrieverBank::getRetrievers(), NLPACS::CChain::getRight(), NLPACS::CChain::getSubChain(), NLPACS::CChain::getSubChains(), NLPACS::CLocalRetriever::getSurfaces(), NLPACS::CRetrieverInstance::getType(), NLPACS::CRetrieverInstance::CLink::Instance, nlwarning, sint, NLPACS::CRetrieverInstance::CLink::SurfaceId, and uint.

00154 {
00155         uint    i, j, k;
00156 
00157         for (i=0; i<_Instances.size(); ++i)
00158         {
00159                 if (_Instances[i].getInstanceId() == -1)
00160                 {
00161                         nlwarning("Uninitialized instance %d", i);
00162                         continue;
00163                 }
00164 
00165                 if (_Instances[i].getInstanceId() != (sint)i)
00166                         nlwarning("InstanceId for instance %d is not correctly initialized", i);
00167 
00168                 if (_Instances[i].getRetrieverId() == -1)
00169                 {
00170                         nlwarning("No retriever at instance %d", i);
00171                         continue;
00172                 }
00173 
00174                 const CRetrieverInstance        &instance = _Instances[i];
00175 
00176                 if (instance.getRetrieverId()<0 || instance.getRetrieverId()>=(sint)_RetrieverBank->getRetrievers().size())
00177                 {
00178                         nlwarning("Instance %d has wrong retriever reference", i);
00179                         continue;
00180                 }
00181 
00182                 const CLocalRetriever           &retriever = _RetrieverBank->getRetriever(instance.getRetrieverId());
00183 
00184                 for (j=0; j<retriever.getChains().size(); ++j)
00185                 {
00186                         const CChain    &chain = retriever.getChain(j);
00187                         for (k=0; k<chain.getSubChains().size(); ++k)
00188                         {
00189                                 if (chain.getSubChain(k) >= retriever.getOrderedChains().size())
00190                                 {
00191                                         nlwarning("retriever %d, chain %d: subchain %d reference is not valid", instance.getRetrieverId(), j, k);
00192                                         continue;
00193                                 }
00194 
00195                                 if (retriever.getOrderedChain(chain.getSubChain(k)).getParentId() != j)
00196                                 {
00197                                         nlwarning("retriever %d, ochain %d: reference on parent is not valid", instance.getRetrieverId(), chain.getSubChain(k));
00198                                         continue;
00199                                 }
00200 
00201                                 if (retriever.getOrderedChain(chain.getSubChain(k)).getIndexInParent() != k)
00202                                 {
00203                                         nlwarning("retriever %d, ochain %d: index on parent is not valid", instance.getRetrieverId(), chain.getSubChain(k));
00204                                         continue;
00205                                 }
00206                         }
00207 
00208                         if (chain.getLeft()<0 || chain.getLeft()>=(sint)retriever.getSurfaces().size())
00209                         {
00210                                 nlwarning("retriever %d, chain %d: reference on left surface is not valid", instance.getRetrieverId(), j);
00211                         }
00212 
00213                         if (chain.getRight()>=(sint)retriever.getSurfaces().size() ||
00214                                 chain.getRight()<=CChain::getDummyBorderChainId() && !CChain::isBorderChainId(chain.getRight()))
00215                         {
00216                                 nlwarning("retriever %d, chain %d: reference on right surface is not valid", instance.getRetrieverId(), j);
00217                         }
00218 
00219                         if (CChain::isBorderChainId(chain.getRight()))
00220                         {
00221                                 sint    link = chain.getBorderChainIndex();
00222 
00223                                 if (link<0 || link>=(sint)instance.getBorderChainLinks().size())
00224                                 {
00225                                         nlwarning("retriever %d, instance %d, chain %d: reference on right link is not valid", instance.getRetrieverId(), instance.getInstanceId(), j);
00226                                 }
00227                                 else
00228                                 {
00229                                         CRetrieverInstance::CLink       lnk = instance.getBorderChainLink(link);
00230 
00231                                         if (lnk.Instance != 0xFFFF || lnk.SurfaceId != 0xFFFF ||
00232                                                 lnk.ChainId != 0xFFFF || lnk.BorderChainId != 0xFFFF)
00233                                         {
00234                                                 if (lnk.Instance >= _Instances.size() ||
00235                                                         _Instances[lnk.Instance].getRetrieverId()<0 ||
00236                                                         _Instances[lnk.Instance].getRetrieverId()>(sint)_RetrieverBank->getRetrievers().size() ||
00237                                                         lnk.SurfaceId >= getRetriever(_Instances[lnk.Instance].getRetrieverId()).getSurfaces().size() ||
00238                                                         ((lnk.ChainId >= getRetriever(_Instances[lnk.Instance].getRetrieverId()).getChains().size() ||
00239                                                         lnk.BorderChainId >= getRetriever(_Instances[lnk.Instance].getRetrieverId()).getBorderChains().size()) && instance.getType() != CLocalRetriever::Interior ))
00240                                                 {
00241                                                         nlwarning("retriever %d, instance %d, link %d: reference on instance may be not valid [Inst=%d, Surf=%d, Chain=%d, BorderChain=%d]", instance.getRetrieverId(), instance.getInstanceId(), link, lnk.Instance, lnk.SurfaceId, lnk.ChainId, lnk.BorderChainId);
00242                                                 }
00243                                         }
00244                                 }
00245                         }
00246                 }
00247         }
00248 }

NLPACS::UGlobalRetriever * NLPACS::UGlobalRetriever::createGlobalRetriever const char *  globalRetriever,
const URetrieverBank retrieverBank
[static, inherited]
 

Create a global retriever.

Parameters:
globalRetriver is the global retriver path file name. This method use the CPath to find the file.
retriverBank is the global retriver bank associated to the global retriever.
Returns:
the pointer on the global retriver or NULL if the file is not found.

Definition at line 2382 of file global_retriever.cpp.

References file, initAll(), and setRetrieverBank().

02383 {
02384         NL_ALLOC_CONTEXT( Pacs )
02385 
02386         // Cast
02387 //      nlassert (dynamic_cast<const NLPACS::CRetrieverBank*>(retrieverBank));
02388         const NLPACS::CRetrieverBank*   bank=static_cast<const NLPACS::CRetrieverBank*>(retrieverBank);
02389 
02390         CIFile  file;
02391         if (file.open(CPath::lookup(globalRetriever)))
02392         {
02393                 CGlobalRetriever        *retriever = new CGlobalRetriever();
02394 
02395                 // always set the retriever bank before serializing !!
02396                 retriever->setRetrieverBank(bank);
02397 
02398                 file.serial(*retriever);
02399                 retriever->initAll(false);      // don't init instances as we serialized them
02400 
02401                 return static_cast<UGlobalRetriever *>(retriever);
02402         }
02403         else
02404                 return NULL;
02405 }

void NLPACS::UGlobalRetriever::deleteGlobalRetriever UGlobalRetriever retriever  )  [static, inherited]
 

Delete a global retriever.

Definition at line 2409 of file global_retriever.cpp.

References nlassert, and r.

02410 {
02411         // Cast
02412         nlassert (dynamic_cast<NLPACS::CGlobalRetriever*>(retriever));
02413         NLPACS::CGlobalRetriever* r=static_cast<NLPACS::CGlobalRetriever*>(retriever);
02414 
02415         // Delete
02416         delete r;
02417 }

float NLPACS::CGlobalRetriever::distanceToBorder const UGlobalPosition pos  )  const [virtual]
 

Checks the retriever for errors.

Implements NLPACS::UGlobalRetriever.

Definition at line 252 of file global_retriever.cpp.

References NLPACS::CLocalRetriever::distanceToBorder(), getRetriever(), NLPACS::UGlobalPosition::InstanceId, NLPACS::UGlobalPosition::LocalPosition, and sint.

00253 {
00254         if (pos.InstanceId < 0 || pos.InstanceId > (sint)_Instances.size())
00255                 return 0.0f;
00256 
00257         return getRetriever(_Instances[pos.InstanceId].getRetrieverId()).distanceToBorder(pos.LocalPosition);
00258 }

NLPACS::UGlobalPosition NLPACS::CGlobalRetriever::doMove const UGlobalPosition start,
const NLMISC::CVector delta,
float  t,
CCollisionSurfaceTemp cst,
bool  rebuildChains = false
const
 

apply a movement of a point against surface world. This should be called after test???Move(). NB: It's up to you to give good t, relative to result of test???Move(). Else, undefined results... NB: if you don't give same start/delta as in preceding call to testMove(), and rebuildChains==false, start is returned (nlstop in debug).

Parameters:
start is the start position of the movement. (must be same as passed in test???Move()).
delta is the requested movement (must be same as passed in test???Move()).
t must be in [0,1]. t*delta is the actual requested movement.
cst is the CCollisionSurfaceTemp object used as temp computing (one per thread). (must be same as passed in test???Move()).
rebuildChains true if doMove() is not called just after the testMove(). Then CGlobalRetriever must recompute some part of the data needed to performing his task.
Returns:
new position of the entity.

Definition at line 2028 of file global_retriever.cpp.

References NLMISC::clamp(), NLPACS::CCollisionSurfaceTemp::CollisionDescs, NLPACS::ULocalPosition::Estimation, NLMISC::CAABBox::extend(), findCollisionChains(), getDoubleGlobalPosition(), getInstance(), NLPACS::CRetrieverInstance::getOrigin(), NLPACS::UGlobalPosition::InstanceId, NLPACS::UGlobalPosition::LocalPosition, nlassert, nlwarning, NLPACS::CCollisionSurfaceTemp::PrecDeltaPos, NLPACS::CCollisionSurfaceTemp::PrecStartPos, NLPACS::CCollisionSurfaceTemp::PrecStartSurface, NLPACS::CCollisionSurfaceTemp::PrecValid, res, NLPACS::CSurfaceIdent::RetrieverInstanceId, NLMISC::CAABBox::setCenter(), sint, NLPACS::SnapPrecision, NLPACS::ULocalPosition::Surface, NLPACS::CSurfaceIdent::SurfaceId, t, testMovementWithCollisionChains(), NLPACS::Vector2sAccuracy, x, NLMISC::CVector::x, y, NLMISC::CVector::y, and NLMISC::CVector::z.

Referenced by NLPACS::CPrimitiveWorldImage::doMove(), and NLPACS::CPrimitiveWorldImage::reaction().

02029 {
02030 //      H_AUTO(PACS_GR_doMove);
02031 
02032         CSurfaceIdent   startSurface(startPos.InstanceId, startPos.LocalPosition.Surface);
02033 
02034         // clamp factor.
02035         clamp(t, 0.0f, 1.0f);
02036 
02037         // 0. reset.
02038         //===========
02039         // reset CollisionDescs.
02040         cst.CollisionDescs.clear();
02041 
02042         // In a surface ?
02043         if (startPos.InstanceId==-1)
02044         {
02045                 // Warining: this primitive is not on a surface
02046                 //nlassertonce (0);
02047 
02048                 // Return startpos
02049                 return startPos;
02050         }
02051         
02052         if(!rebuildChains)
02053         {
02054                 // same move request than prec testMove() ??.
02055                 if( cst.PrecStartSurface != startSurface || 
02056                         cst.PrecStartPos!=startPos.LocalPosition.Estimation || 
02057                         cst.PrecDeltaPos!=delta ||
02058                         !cst.PrecValid)
02059                 {
02060                         // if not, just return start.
02061                         //nlstop;
02062                         nlwarning ("BEN: you must fix this, it s happen!!!");
02063                         return startPos;
02064                 }
02065                 // Since we are sure we have same movement than prec testMove(), no need to rebuild cst.CollisionChains.
02066         }
02067         else
02068         {
02069                 // we don't have same movement than prec testMove(), we must rebuild cst.CollisionChains.
02070                 // Prec settings no more valids.
02071                 cst.PrecValid= false;
02072         }
02073 
02074 
02075 
02076 
02077         // 1. Choose a local basis (same than in testMove()).
02078         //===========
02079         // Take the retrieverInstance of startPos as a local basis.
02080         CVector         origin;
02081         origin= getInstance(startPos.InstanceId).getOrigin();
02082 
02083 
02084         // 2. test collisions with CollisionChains.
02085         //===========
02086         CVector         start= startPos.LocalPosition.Estimation;
02087         // compute end with real delta position.
02088         CVector         end= start + delta*t;
02089 
02090         // If asked, we must rebuild array of collision chains.
02091         if(rebuildChains)
02092         {
02093 //              H_AUTO(PACS_GR_doMove_rebuildChains);
02094 
02095                 // compute bboxmove.
02096                 CAABBox         bboxMove;
02097                 // must add some extent, to be sure to include snapped CLocalRetriever vertex (2.0f/256 should be sufficient).
02098                 // Nb: this include the precision problem just below (move a little).
02099                 float   radius= 4.0f/Vector2sAccuracy;
02100                 bboxMove.setCenter(start-CVector(radius, radius, 0));
02101                 bboxMove.extend(start+CVector(radius, radius, 0));
02102                 bboxMove.extend(end-CVector(radius, radius, 0));
02103                 bboxMove.extend(end+CVector(radius, radius, 0));
02104 
02105                 // find possible collisions in bboxMove+origin. fill cst.CollisionChains.
02106                 findCollisionChains(cst, bboxMove, origin);
02107         }
02108 
02109 
02110         // look where we arrive.
02111         CSurfaceIdent   endSurface;
02112         CVector                 endRequest= end;
02113         const sint              maxPbPrec= 32;  // move away from 4 mm at max, in each 8 direction.
02114         sint                    pbPrecNum= 0;
02115 
02116         // must snap the end position.
02117         CRetrieverInstance::snapVector(endRequest);
02118         end= endRequest;
02119 
02120         // verify start is already snapped
02121         {
02122                 CVector         startTest= start;
02123                 CRetrieverInstance::snapVector(startTest);
02124                 nlassert( start == startTest );
02125         }
02126 
02127 
02128         // Normally, just one iteration is made in this loop (but if precision problem (stopOnEdge, startOnEdge....).
02129         while(true)
02130         {
02131                 // must snap the end position.
02132                 CRetrieverInstance::snapVector(end);
02133 
02134                 CVector2f       startCol(start.x, start.y);
02135                 CVector2f       endCol(end.x, end.y);
02136 
02137                 // If same 2D position, just return startPos (suppose no movement)
02138                 if(endCol==startCol)
02139                 {
02140                         UGlobalPosition         res;
02141                         res= startPos;
02142                         // keep good z movement.
02143                         res.LocalPosition.Estimation.z= end.z;
02144                         return res;
02145                 }
02146 
02147                 // search destination problem.
02148                 UGlobalPosition restart;
02149                 endSurface= testMovementWithCollisionChains(cst, startCol, endCol, startSurface, restart);
02150 
02151                 // if no precision problem, Ok, we have found our destination surface (or anormal collide against a wall).
02152                 if (endSurface.SurfaceId >= -1)
02153                 {
02154                         break;
02155                 }
02156                 // left an interior, retrieved position and ask to restart collision from retrieved position
02157                 else if (endSurface.SurfaceId == -3)
02158                 {
02159                         start = getDoubleGlobalPosition(restart) - origin;
02160                         startSurface.RetrieverInstanceId = restart.InstanceId;
02161                         startSurface.SurfaceId = restart.LocalPosition.Surface;
02162                         // should be snapped here
02163                         CVector         startTest= start;
02164                         CRetrieverInstance::snapVector(startTest);
02165                         nlassert( start == startTest );
02166                 }
02167                 /* else we are in deep chit, for one on those reason:
02168                         - traverse on point.
02169                         - stop on a edge (dist==0).
02170                         - start on a edge (dist==0).
02171                         - run // on a edge (NB: dist==0 too).
02172                 */
02173                 else if (endSurface.SurfaceId == -2)
02174                 {
02175                         // For simplicty, just try to move a little the end position
02176                         if(pbPrecNum<maxPbPrec)
02177                         {
02178                                 static struct   {sint x,y;}   dirs[8]= { {1,0}, {1,1}, {0,1}, {-1,1}, {-1,0}, {-1,-1}, {0,-1}, {1,-1}};
02179                                 sint    dir= pbPrecNum%8;
02180                                 sint    dist= pbPrecNum/8+1;
02181                                 CVector         dta;
02182 
02183                                 // compute small move.
02184                                 dta.x= dirs[dir].x * dist * 1.0f/SnapPrecision;
02185                                 dta.y= dirs[dir].y * dist * 1.0f/SnapPrecision;
02186                                 dta.z= 0;
02187 
02188                                 // add it to the original end pos requested.
02189                                 end= endRequest + dta;
02190 
02191                                 pbPrecNum++;
02192                         }
02193                         else
02194                         {
02195                                 // do not move at all.
02196                                 endSurface= CSurfaceIdent(-1,-1);
02197                                 break;
02198                         }
02199                 }
02200         }
02201 
02202         // 3. return result.
02203         //===========
02204         // Problem?? do not move.
02205         if(endSurface.SurfaceId==-1)
02206                 return startPos;
02207         else
02208         {
02209                 // else must return good GlobalPosition.
02210                 CGlobalPosition         res;
02211 
02212                 res.InstanceId= endSurface.RetrieverInstanceId;
02213                 res.LocalPosition.Surface= endSurface.SurfaceId;
02214 
02215                 // compute newPos, localy to the endSurface.
02216                 // get delta between startPos.instance and curInstance.
02217                 // NB: for float precision, it is important to compute deltaOrigin, and after compute newPos in local.
02218                 CVector         deltaOrigin;
02219                 deltaOrigin= origin - getInstance(res.InstanceId).getOrigin();
02220 
02221                 // Because Origin precision is 1 meter, and end precision is 1/1024 meter, we have no precision problem.
02222                 // this is true because we cannot move more than, say 4*160 meters in one doMove().
02223                 // So global position should not be bigger than 1024 * 1024/1024 meters.  => Hence 20 bits of precision is 
02224                 // required. We have 23 with floats.
02225                 res.LocalPosition.Estimation= end + deltaOrigin;
02226 
02227 
02228                 // result.
02229                 return res;
02230         }
02231 
02232 }

void NLPACS::CGlobalRetriever::findAStarPath const UGlobalPosition begin,
const UGlobalPosition end,
std::vector< CRetrieverInstance::CAStarNodeAccess > &  path,
uint32  forbidFlags
const
 

Finds an A* path from a given global position to another.

Todo:
secure search to avoid crashes...

Definition at line 855 of file global_retriever.cpp.

References NLPACS::CRetrieverInstance::_NodesInformation, _RetrieverBank, NLPACS::CRetrieverInstance::CAStarNodeInfo::Cost, NLPACS::CRetrieverInstance::CAStarNodeInfo::F, NLPACS::CRetrieverInstance::getBorderChainLink(), NLPACS::CLocalRetriever::getChain(), NLPACS::CRetrievableSurface::getChains(), NLPACS::CRetrievableSurface::getFlags(), getGlobalPosition(), NLPACS::CChain::getLeft(), getNode(), NLPACS::CRetrieverBank::getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CChain::getRight(), NLPACS::CLocalRetriever::getSurface(), NLPACS::CRetrieverInstance::CLink::Instance, NLPACS::UGlobalPosition::InstanceId, NLPACS::CRetrieverInstance::CAStarNodeAccess::InstanceId, NLPACS::UGlobalPosition::LocalPosition, nlassert, nlinfo, NLPACS::CRetrieverInstance::CAStarNodeAccess::NodeId, NLPACS::CRetrieverInstance::CAStarNodeInfo::Parent, NLPACS::CRetrieverInstance::CAStarNodeInfo::Position, sint, sint32, NLPACS::ULocalPosition::Surface, NLPACS::CRetrieverInstance::CLink::SurfaceId, ThisAStarTicks, NLMISC::TTicks, uint, uint16, and uint32.

Referenced by findPath().

00859 {
00860         TTicks  astarStart;
00861         ThisAStarTicks = 0;
00862         astarStart = CTime::getPerformanceTime();
00863 
00864         // open and close lists
00865         // TODO: Use a smart allocator to avoid huge alloc/free and memory fragmentation
00866         // open is a priority queue (implemented as a stl multimap)
00867         multimap<float, CRetrieverInstance::CAStarNodeAccess>   open;
00868         // close is a simple stl vector
00869         vector<CRetrieverInstance::CAStarNodeAccess>                    close;
00870 
00871         // inits start node and info
00872         CRetrieverInstance::CAStarNodeAccess                                    beginNode;
00873         beginNode.InstanceId = begin.InstanceId;
00874         beginNode.NodeId = (uint16)begin.LocalPosition.Surface;
00875         CRetrieverInstance::CAStarNodeInfo                                              &beginInfo = getNode(beginNode);
00876 
00877         // inits end node and info.
00878         CRetrieverInstance::CAStarNodeAccess                                    endNode;
00879         endNode.InstanceId = end.InstanceId;
00880         endNode.NodeId = (uint16)end.LocalPosition.Surface;
00881         CRetrieverInstance::CAStarNodeInfo                                              &endInfo = getNode(endNode);
00882 
00883         // set up first node...
00884         CRetrieverInstance::CAStarNodeAccess                                    node = beginNode;
00885         beginInfo.Parent.InstanceId = -1;
00886         beginInfo.Parent.NodeId = 0;
00887         beginInfo.Parent.ThroughChain = 0;
00888         beginInfo.Cost = 0;
00889         beginInfo.F = (endInfo.Position-beginInfo.Position).norm();
00890 
00891         // ... and inserts it in the open list.
00892         open.insert(make_pair(beginInfo.F, node));
00893 
00894         // TO DO: use a CVector2f instead
00895         CVector2f                                                                                               endPosition = CVector2f(getGlobalPosition(end));
00896 
00897         uint    i;
00898 
00899         path.clear();
00900 
00901         while (true)
00902         {
00903                 if (open.empty())
00904                 {
00905                         // couldn't find a path
00906                         return;
00907                 }
00908 
00909                 multimap<float, CRetrieverInstance::CAStarNodeAccess>::iterator it;
00910 
00911                 it = open.begin();
00912                 node = it->second;
00913                 open.erase(it);
00914 
00915                 if (node == endNode)
00916                 {
00917                         // found a path
00918                         CRetrieverInstance::CAStarNodeAccess                    pathNode = node;
00919                         uint                                                                                    numNodes = 0;
00920                         while (pathNode.InstanceId != -1)
00921                         {
00922                                 ++numNodes;
00923                                 CRetrieverInstance                                                      &instance = _Instances[pathNode.InstanceId];
00924                                 CRetrieverInstance::CAStarNodeInfo                      &pathInfo = instance._NodesInformation[pathNode.NodeId];
00925                                 pathNode = pathInfo.Parent;
00926                         }
00927 
00928                         path.resize(numNodes);
00929                         pathNode = node;
00930                         while (pathNode.InstanceId != -1)
00931                         {
00932                                 path[--numNodes] = pathNode;
00933                                 CRetrieverInstance                                                      &instance = _Instances[pathNode.InstanceId];
00934                                 CRetrieverInstance::CAStarNodeInfo                      &pathInfo = instance._NodesInformation[pathNode.NodeId];
00935                                 pathNode = pathInfo.Parent;
00936                         }
00937 
00938                         ThisAStarTicks += (CTime::getPerformanceTime()-astarStart);
00939 
00940                         nlinfo("found a path");
00941                         for (i=0; i<path.size(); ++i)
00942                         {
00943                                 CRetrieverInstance                                                      &instance = _Instances[path[i].InstanceId];
00944                                 const CLocalRetriever                                           &retriever = _RetrieverBank->getRetriever(instance.getRetrieverId());
00945                                 nlinfo("pathNode %d = (Inst=%d, Node=%d, Through=%d)", i, path[i].InstanceId, path[i].NodeId, path[i].ThroughChain);
00946                                 if (path[i].ThroughChain != 0xffff)
00947                                 {
00948                                         const CChain                                                            &chain = retriever.getChain(path[i].ThroughChain);
00949                                         nlinfo("   chain: left=%d right=%d", chain.getLeft(), chain.getRight());
00950                                         if (CChain::isBorderChainId(chain.getRight()))
00951                                         {
00952                                                 CRetrieverInstance::CLink       lnk = instance.getBorderChainLink(CChain::convertBorderChainId(chain.getRight()));
00953                                                 sint    instanceid = lnk.Instance;
00954                                                 sint    id = lnk.SurfaceId;
00955                                                 nlinfo("      right: instance=%d surf=%d", instanceid, id);
00956                                         }
00957                                 }
00958                         }
00959                         nlinfo("open.size()=%d", open.size());
00960                         nlinfo("close.size()=%d", close.size());
00961 
00962                         return;
00963                 }
00964 
00965                 // push successors of the current node
00966                 CRetrieverInstance                                                              &inst = _Instances[node.InstanceId];
00967                 const CLocalRetriever                                                   &retriever = _RetrieverBank->getRetriever(inst.getRetrieverId());
00968                 const CRetrievableSurface                                               &surf = retriever.getSurface(node.NodeId);
00969                 const vector<CRetrievableSurface::CSurfaceLink> &chains = surf.getChains();
00970 
00971                 CRetrieverInstance                                                              *nextInstance;
00972                 const CLocalRetriever                                                   *nextRetriever;
00973                 const CRetrievableSurface                                               *nextSurface;
00974 
00975                 nlinfo("examine node (instance=%d,surf=%d,cost=%g)", node.InstanceId, node.NodeId, inst._NodesInformation[node.NodeId].Cost);
00976 
00977                 for (i=0; i<chains.size(); ++i)
00978                 {
00979                         sint32  nextNodeId = chains[i].Surface;
00980                         CRetrieverInstance::CAStarNodeAccess            nextNode;
00981 
00982                         if (CChain::isBorderChainId(nextNodeId))
00983                         {
00984                                 // if the chain points to another retriever
00985 
00986                                 // first get the edge on the retriever
00987                                 CRetrieverInstance::CLink       lnk = inst.getBorderChainLink(CChain::convertBorderChainId(nextNodeId));
00988                                 nextNode.InstanceId = lnk.Instance;
00989 
00990                                 if (nextNode.InstanceId < 0)
00991                                         continue;
00992 
00993                                 nextInstance = &_Instances[nextNode.InstanceId];
00994                                 nextRetriever = &(_RetrieverBank->getRetriever(nextInstance->getRetrieverId()));
00995 
00996                                 sint    nodeId = lnk.SurfaceId;
00997                                 nlassert(nodeId >= 0);
00998                                 nextNode.NodeId = (uint16)nodeId;
00999                         }
01000                         else if (nextNodeId >= 0)
01001                         {
01002                                 // if the chain points to the same instance
01003                                 nextNode.InstanceId = node.InstanceId;
01004                                 nextNode.NodeId = (uint16) nextNodeId;
01005                                 nextInstance = &inst;
01006                                 nextRetriever = &retriever;
01007                         }
01008                         else
01009                         {
01010                                 // if the chain cannot be crossed
01011                                 continue;
01012                         }
01013 
01014                         nextSurface = &(nextRetriever->getSurface(nextNode.NodeId));
01015 
01016                         if (nextSurface->getFlags() & forbidFlags)
01017                                 continue;
01018 
01019                         // compute new node value (heuristic and cost)
01020 
01021                         CRetrieverInstance::CAStarNodeInfo      &nextInfo = nextInstance->_NodesInformation[nextNode.NodeId];
01022                         float   stepCost = (nextInfo.Position-inst._NodesInformation[node.NodeId].Position).norm();
01023                         float   nextCost = inst._NodesInformation[node.NodeId].Cost+stepCost;
01024                         float   nextHeuristic = (nextInfo.Position-endPosition).norm();
01025                         float   nextF = nextCost+nextHeuristic;
01026 
01027                         vector<CRetrieverInstance::CAStarNodeAccess>::iterator                  closeIt;
01028                         for (closeIt=close.begin(); closeIt!=close.end() && *closeIt!=nextNode; ++closeIt)
01029                                 ;
01030 
01031                         if (closeIt != close.end() && nextInfo.F < nextF)
01032                                 continue;
01033                         
01034                         multimap<float, CRetrieverInstance::CAStarNodeAccess>::iterator openIt;
01035                         for (openIt=open.begin(); openIt!=open.end() && openIt->second!=nextNode; ++openIt)
01036                                 ;
01037 
01038                         if (openIt != open.end() && nextInfo.F < nextF)
01039                                 continue;
01040 
01041                         if (openIt != open.end())
01042                                 open.erase(openIt);
01043 
01044                         if (closeIt != close.end())
01045                                 close.erase(closeIt);
01046 
01047                         nextInfo.Parent = node;
01048                         nextInfo.Parent.ThroughChain = (uint16)(chains[i].Chain);
01049                         nextInfo.Cost = nextCost;
01050                         nextInfo.F = nextF;
01051 
01052                         nlinfo("  adding node (instance=%d,surf=%d) f=%g, through=%d", nextNode.InstanceId, nextNode.NodeId, nextInfo.F, i);
01053 
01054                         open.insert(make_pair(nextInfo.F, nextNode));
01055                 }
01056                 close.push_back(node);
01057         }
01058 }

void NLPACS::CGlobalRetriever::findCollisionChains CCollisionSurfaceTemp cst,
const NLMISC::CAABBox bboxMove,
const NLMISC::CVector origin
const [private]
 

reset and fill cst.CollisionChains with possible collisions in bboxMove+origin. result: collisionChains, computed localy to origin.

Todo:
yoyo/ben: TODO_INTERIOR: activate this and modify code below

Definition at line 1177 of file global_retriever.cpp.

References _RetrieverBank, NLPACS::CCollisionChain::ChainId, NLPACS::CCollisionSurfaceTemp::CollisionChains, NLPACS::CCollisionSurfaceTemp::CollisionInstances, NLPACS::CCollisionChain::ExteriorEdge, NLPACS::CChain::getBorderChainIndex(), NLPACS::CRetrieverInstance::getBorderChainLink(), NLMISC::CAABBox::getCenter(), NLPACS::CLocalRetriever::getChain(), getInstance(), NLPACS::CRetrieverBank::getNamePrefix(), NLPACS::CRetrieverInstance::getOrigin(), getRetriever(), NLPACS::CRetrieverBank::getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CRetrieverInstance::getType(), NLPACS::CRetrieverInstance::CLink::Instance, NLPACS::CChain::isBorderChain(), NLPACS::CChain::isBorderChainId(), NLPACS::CLocalRetriever::isLoaded(), NLPACS::CCollisionChain::LeftSurface, nlassert, nlwarning, NLPACS::CCollisionSurfaceTemp::resetEdgeCollideNodes(), NLPACS::CSurfaceIdent::RetrieverInstanceId, NLPACS::CCollisionChain::RightSurface, selectInstances(), NLMISC::CAABBox::setCenter(), sint, sint16, sint32, NLPACS::CRetrieverInstance::CLink::SurfaceId, NLPACS::CSurfaceIdent::SurfaceId, NLPACS::CLocalRetriever::testCollision(), NLPACS::CRetrieverInstance::testExteriorCollision(), NLMISC::CVector::x, and NLMISC::CVector::y.

Referenced by doMove(), testBBoxMove(), testBBoxRot(), and testCylinderMove().

01178 {
01179 //      H_AUTO(PACS_GR_findCollisionChains);
01180 
01181         sint    i,j;
01182 
01183         // 0. reset.
01184         //===========
01185         // reset possible chains.
01186 //      H_BEFORE(PACS_GR_findCC_reset);
01187         cst.CollisionChains.clear();
01188         cst.resetEdgeCollideNodes();
01189 //      H_AFTER(PACS_GR_findCC_reset);
01190 
01191         // 1. Find Instances which may hit this movement.
01192         //===========
01193 //      H_BEFORE(PACS_GR_findCC_selectInstances);
01194         CAABBox         bboxMoveGlobal= bboxMove;
01195         bboxMoveGlobal.setCenter(bboxMoveGlobal.getCenter()+origin);
01196         selectInstances(bboxMoveGlobal, cst);
01197 //      H_AFTER(PACS_GR_findCC_selectInstances);
01198         // \todo yoyo: TODO_INTERIOR: add interiors meshes (static/dynamic houses etc...) to this list.
01199         // -> done automatically with the select
01200 
01201 
01202         // 2. Fill CollisionChains.
01203         //===========
01204         // For each possible surface mesh, test collision.
01205         for(i=0 ; i<(sint)cst.CollisionInstances.size(); i++)
01206         {
01207 //              H_BEFORE(PACS_GR_findCC_getAndComputeMove);
01208                 // get retrieverInstance.
01209                 sint32  curInstance= cst.CollisionInstances[i];
01210                 const CRetrieverInstance        &retrieverInstance= getInstance(curInstance);
01211 
01212                 // Retrieve the localRetriever of this instance.
01213                 sint32  localRetrieverId= retrieverInstance.getRetrieverId();
01214                 // If invalid one (hole), continue.
01215                 if(localRetrieverId<0)
01216                         continue;
01217                 const CLocalRetriever           &localRetriever= _RetrieverBank->getRetriever(localRetrieverId);
01218 
01219                 if (!localRetriever.isLoaded())
01220                 {
01221                         nlwarning("local retriever %d in %s not loaded, findCollisionChains in this retriever aborted", localRetrieverId, _RetrieverBank->getNamePrefix().c_str());
01222                         continue;
01223                 }
01224 
01225                 // get delta between startPos.instance and curInstance.
01226                 CVector         deltaOrigin;
01227                 deltaOrigin= origin - retrieverInstance.getOrigin();
01228 
01229                 // compute movement relative to this localRetriever.
01230                 CAABBox         bboxMoveLocal= bboxMove;
01231                 bboxMoveLocal.setCenter(bboxMoveLocal.getCenter()+deltaOrigin);
01232         
01233                 // add possible collision chains with movement.
01234                 //================
01235                 sint            firstCollisionChain= cst.CollisionChains.size();
01236                 CVector2f       transBase(-deltaOrigin.x, -deltaOrigin.y);
01237 //              H_AFTER(PACS_GR_findCC_getAndComputeMove);
01238 
01239 //              H_BEFORE(PACS_GR_findCC_testCollision);
01240                 // Go! fill collision chains that this movement intersect.
01241                 localRetriever.testCollision(cst, bboxMoveLocal, transBase);
01242                 // if an interior, also test for external collisions
01244                 if (retrieverInstance.getType() == CLocalRetriever::Interior)
01245                         retrieverInstance.testExteriorCollision(cst, bboxMoveLocal, transBase, localRetriever);
01246 
01247                 // how many collision chains added?  : nCollisionChain-firstCollisionChain.
01248                 sint            nCollisionChain= cst.CollisionChains.size();
01249 //              H_AFTER(PACS_GR_findCC_testCollision);
01250 
01251 
01252                 // For all collision chains added, fill good SurfaceIdent info.
01253                 //================
01254 //              H_BEFORE(PACS_GR_findCC_fillSurfIdent);
01255                 for(j=firstCollisionChain; j<nCollisionChain; j++)
01256                 {
01257                         CCollisionChain         &cc= cst.CollisionChains[j];
01258 
01259                         // info are already filled for exterior chains.
01260                         if (cc.ExteriorEdge)
01261                                 continue;
01262 
01263                         // LeftSurface retrieverInstance is always curInstance.
01264                         cc.LeftSurface.RetrieverInstanceId= curInstance;
01265 
01266                         // If RightSurface is not an "edgeId" ie a pointer on a neighbor surface on an other retrieverInstance.
01267                         const   CChain          &originalChain= localRetriever.getChain(cc.ChainId);
01268                         if( !originalChain.isBorderChainId(cc.RightSurface.SurfaceId) )
01269                         {
01270                                 cc.RightSurface.RetrieverInstanceId= curInstance;
01271                         }
01272                         else
01273                         {
01274                                 // we must find the surfaceIdent of the neighbor.
01275                                 // \todo yoyo: TODO_INTERIOR: this work only for zone. Must work too for houses.
01276 
01277                                 CRetrieverInstance::CLink       link;
01278                                 // get the link to the next surface from the instance
01279                                 link = retrieverInstance.getBorderChainLink(CChain::convertBorderChainId(cc.RightSurface.SurfaceId));
01280 
01281                                 // get the neighbor instanceId.
01282                                 sint    neighborInstanceId= (sint16)link.Instance;
01283                                 // store in the current collisionChain Right.
01284                                 cc.RightSurface.RetrieverInstanceId= neighborInstanceId;
01285 
01286                                 // If no instance near us, this is a WALL.
01287                                 if(neighborInstanceId<0)
01288                                 {
01289                                         // mark as a Wall.
01290                                         cc.RightSurface.SurfaceId= -1;
01291                                 }
01292                                 else
01293                                 {
01294                                         // Get the good neighbor surfaceId.
01295                                         cc.RightSurface.SurfaceId= (sint16)link.SurfaceId;
01296                                 }
01297                         }
01298 
01299                         nlassert(cc.LeftSurface.RetrieverInstanceId < (sint)_Instances.size());
01300                         nlassert(cc.RightSurface.RetrieverInstanceId < (sint)_Instances.size());
01301                 }
01302 //              H_AFTER(PACS_GR_findCC_fillSurfIdent);
01303 
01304 
01305                 // For all collision chains added, look if they are a copy of preceding collsion chain (same Left/Right). Then delete them.
01306                 //================
01307                 // \todo yoyo: TODO_OPTIMIZE: this is a N² complexity.
01308 //              H_BEFORE(PACS_GR_findCC_removeDouble);
01309                 for(j=firstCollisionChain; j<nCollisionChain; j++)
01310                 {
01311                         const CCollisionChain   &cj = cst.CollisionChains[j];
01312 
01313                         if (cj.ExteriorEdge && cj.LeftSurface.RetrieverInstanceId!=-1)
01314                                 continue;
01315 
01316                         // test for all collisionChain inserted before.
01317                         for(sint k=0; k<firstCollisionChain; k++)
01318                         {
01319                                 const CCollisionChain   &ck = cst.CollisionChains[k];
01320 
01321                                 if (cj.LeftSurface.RetrieverInstanceId != cj.RightSurface.RetrieverInstanceId &&
01322                                         cj.LeftSurface == ck.RightSurface && cj.RightSurface == ck.LeftSurface)
01323                                 {
01324                                         const CRetrieverInstance        &instj = getInstance(cj.LeftSurface.RetrieverInstanceId),
01325                                                                                                 &instk = getInstance(ck.LeftSurface.RetrieverInstanceId);
01326                                         const CLocalRetriever           &retrj = getRetriever(instj.getRetrieverId()),
01327                                                                                                 &retrk = getRetriever(instk.getRetrieverId());
01328 
01329                                         if (!retrj.isLoaded() || !retrk.isLoaded())
01330                                         {
01331                                                 nlwarning("using not loaded retriever %d or %d in bank '%s', aborted", instj.getRetrieverId(), instk.getRetrieverId(), _RetrieverBank->getNamePrefix().c_str());
01332                                                 continue;
01333                                         }
01334 
01335                                         nlassert(retrj.getChain(cj.ChainId).isBorderChain() && retrk.getChain(ck.ChainId).isBorderChain());
01336 
01337                                         if (instj.getBorderChainLink(retrj.getChain(cj.ChainId).getBorderChainIndex()).ChainId != ck.ChainId ||
01338                                                 instk.getBorderChainLink(retrk.getChain(ck.ChainId).getBorderChainIndex()).ChainId != cj.ChainId)
01339                                         {
01340                                                 continue;
01341                                         }
01342 
01343                                         // remove this jth entry.
01344                                         // by swapping with last entry. Only if not already last.
01345                                         if(j<nCollisionChain-1)
01346                                         {
01347                                                 swap(cst.CollisionChains[j], cst.CollisionChains[nCollisionChain-1]);
01348                                                 // NB: some holes remain in cst._EdgeCollideNodes, but do not matters since reseted at 
01349                                                 // each collision test.
01350                                         }
01351 
01352                                         // pop last entry.
01353                                         nCollisionChain--;
01354                                         cst.CollisionChains.resize(nCollisionChain);
01355 
01356                                         // next entry??
01357                                         j--;
01358                                         break;
01359                                 }
01360 /*
01361                                 // if same surface Ident Left/Right==Left/Right or swapped Left/Right==Right/Left
01362                                 if( cst.CollisionChains[j].sameSurfacesThan(cst.CollisionChains[k]) )
01363                                 {
01364                                         // remove this jth entry.
01365                                         // by swapping with last entry. Only if not already last.
01366                                         if(j<nCollisionChain-1)
01367                                         {
01368                                                 swap(cst.CollisionChains[j], cst.CollisionChains[nCollisionChain-1]);
01369                                                 // NB: some holes remain in cst._EdgeCollideNodes, but do not matters since reseted at 
01370                                                 // each collision test.
01371                                         }
01372 
01373                                         // pop last entry.
01374                                         nCollisionChain--;
01375                                         cst.CollisionChains.resize(nCollisionChain);
01376 
01377                                         // next entry??
01378                                         j--;
01379                                         break;
01380                                 }
01381 */
01382                         }
01383 
01384                 }
01385 //              H_AFTER(PACS_GR_findCC_removeDouble);
01386         }
01387 
01388 }

void NLPACS::CGlobalRetriever::findPath const UGlobalPosition begin,
const UGlobalPosition end,
CGlobalPath path,
uint32  forbidFlags = 0
const
 

Finds a path from a given global position to another

Todo:
include path width

Definition at line 1062 of file global_retriever.cpp.

References _InternalCST, _RetrieverBank, AStarTicks, CGlobalPath, ChainTicks, NLPACS::CGlobalRetriever::CLocalPath::End, NLPACS::ULocalPosition::Estimation, findAStarPath(), NLPACS::CLocalRetriever::findPath(), NLPACS::CLocalRetriever::getChain(), NLPACS::COrderedChain::getLength(), NLPACS::CChain::getLength(), NLPACS::CLocalRetriever::getOrderedChain(), NLPACS::CRetrieverBank::getRetriever(), NLPACS::CChain::getSubChain(), NLPACS::CChain::getSubChains(), NLPACS::COrderedChain::getVertices(), NLPACS::CGlobalRetriever::CLocalPath::InstanceId, NLPACS::UGlobalPosition::LocalPosition, NLPACS::CGlobalRetriever::CLocalPath::Path, PathTicks, NLPACS::CGlobalRetriever::CLocalPath::Start, NLPACS::ULocalPosition::Surface, SurfTicks, ThisAStarTicks, ThisChainTicks, ThisPathTicks, ThisSurfTicks, NLMISC::TTicks, uint, and uint32.

01066 {
01067 
01068         vector<CRetrieverInstance::CAStarNodeAccess>    astarPath;
01069         findAStarPath(begin, end, astarPath, forbidFlags);
01070 
01071         TTicks  surfStart;
01072         TTicks  chainStart;
01073 
01074         ThisChainTicks = 0;
01075         ThisSurfTicks = 0;
01076         ThisPathTicks = 0;
01077 
01078         path.clear();
01079         path.resize(astarPath.size());
01080 
01081         uint    i, j;
01082         for (i=0; i<astarPath.size(); ++i)
01083         {
01084                 chainStart = CTime::getPerformanceTime();
01085                 CLocalPath              &surf = path[i];
01086                 surf.InstanceId = astarPath[i].InstanceId;
01087                 const CLocalRetriever   &retriever = _RetrieverBank->getRetriever(_Instances[surf.InstanceId].getRetrieverId());
01088 
01089                 // computes start point
01090                 if (i == 0)
01091                 {
01092                         // if it is the first point, just copy the begin
01093                         surf.Start.ULocalPosition::operator= (begin.LocalPosition);
01094                 }
01095                 else
01096                 {
01097                         // else, take the previous value and convert it in the current instance axis
01098                         // TODO: avoid this if the instances are the same
01099                         CVector prev = _Instances[path[i-1].InstanceId].getGlobalPosition(path[i-1].End.Estimation);
01100                         CVector current = _Instances[surf.InstanceId].getLocalPosition(prev);
01101                         surf.Start.Surface = astarPath[i].NodeId;
01102                         surf.Start.Estimation = current;
01103                 }
01104 
01105                 // computes end point
01106                 if (i == astarPath.size()-1)
01107                 {
01108                         surf.End.ULocalPosition::operator= (end.LocalPosition);
01109                 }
01110                 else
01111                 {
01112                         // get to the middle of the chain
01113                         // first get the chain between the 2 surfaces
01114                         const CChain                    &chain = retriever.getChain(astarPath[i].ThroughChain);
01115                         float                                   cumulLength = 0.0f, midLength=chain.getLength()*0.5f;
01116                         for (j=0; j<chain.getSubChains().size() && cumulLength<=midLength; ++j)
01117                                 cumulLength += retriever.getOrderedChain(chain.getSubChain(j)).getLength();
01118                         --j;
01119                         const COrderedChain             &ochain = retriever.getOrderedChain(chain.getSubChain(j));
01120                         surf.End.Surface = astarPath[i].NodeId;
01121                         {
01122                                 if (ochain.getVertices().size() & 1)
01123                                 {
01124                                         surf.End.Estimation = ochain[ochain.getVertices().size()/2].unpack3f();
01125                                 }
01126                                 else
01127                                 {
01128                                         surf.End.Estimation = (ochain[ochain.getVertices().size()/2].unpack3f()+
01129                                                                                   ochain[ochain.getVertices().size()/2-1].unpack3f())*0.5f;
01130                                 }
01131                         }
01132                 }
01133                 ThisChainTicks += (CTime::getPerformanceTime()-chainStart);
01134 
01135                 surfStart = CTime::getPerformanceTime();
01136                 retriever.findPath(surf.Start, surf.End, surf.Path, _InternalCST);
01137                 ThisSurfTicks += (CTime::getPerformanceTime()-surfStart);
01138         }
01139 
01140         ThisPathTicks = ThisAStarTicks+ThisChainTicks+ThisSurfTicks;
01141         PathTicks += ThisPathTicks;
01142         SurfTicks += ThisSurfTicks;
01143         AStarTicks += ThisAStarTicks;
01144         ChainTicks += ThisChainTicks;
01145 }

const NLMISC::CAABBox& NLPACS::CGlobalRetriever::getBBox  )  const [inline, virtual]
 

Gets the BBox of the global retriever.

Implements NLPACS::UGlobalRetriever.

Definition at line 201 of file global_retriever.h.

Referenced by initQuadGrid().

00201 { return _BBox; }

void NLPACS::CGlobalRetriever::getBorders const NLMISC::CAABBox sbox,
std::vector< std::pair< NLMISC::CLine, uint8 > > &  edges
[virtual]
 

Checks the retriever for errors.

Implements NLPACS::UGlobalRetriever.

Definition at line 275 of file global_retriever.cpp.

References _InternalCST, NLPACS::CCollisionSurfaceTemp::CollisionInstances, NLPACS::CCollisionSurfaceTemp::EdgeChainEntries, NLPACS::CEdgeChainEntry::EdgeEnd, NLPACS::CEdgeChainEntry::EdgeStart, NLMISC::CAABBox::getCenter(), NLPACS::CLocalRetriever::getChain(), NLPACS::CLocalRetriever::getChainQuad(), NLPACS::CRetrievableSurface::getFlags(), NLPACS::CLocalRetriever::getFullOrderedChain(), NLPACS::CLocalRetriever::getFullOrderedChains(), NLMISC::CAABBox::getHalfSize(), NLPACS::CChain::getLeft(), NLPACS::CLocalRetriever::getOrderedChain(), NLPACS::CRetrieverInstance::getOrigin(), NLPACS::COrderedChain::getParentId(), getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CChain::getRight(), NLPACS::CLocalRetriever::getSurface(), NLPACS::CChain::isBorderChain(), NLPACS::CLocalRetriever::isLoaded(), NLPACS::CEdgeChainEntry::OChainId, NLPACS::CChainQuad::selectEdges(), selectInstances(), NLMISC::CAABBox::setCenter(), NLMISC::CAABBox::setHalfSize(), uint, uint8, and NLMISC::CVector::z.

00276 {
00277         edges.clear();
00278 
00279         selectInstances(sbox, _InternalCST);
00280 
00281         uint    inst;
00282         for (inst=0; inst<_InternalCST.CollisionInstances.size(); ++inst)
00283         {
00284                 CRetrieverInstance      &instance = _Instances[_InternalCST.CollisionInstances[inst]];
00285                 CLocalRetriever         &retriever = const_cast<CLocalRetriever &>(getRetriever(instance.getRetrieverId()));
00286                 if (!retriever.isLoaded())
00287                         continue;
00288 
00289                 CChainQuad                      &chainquad = retriever.getChainQuad();
00290 
00291                 CAABBox                         box;
00292                 CVector                         origin = instance.getOrigin();
00293                 box.setCenter(sbox.getCenter()-origin);
00294                 box.setHalfSize(sbox.getHalfSize());
00295                 chainquad.selectEdges(box, _InternalCST);
00296 
00297                 uint            ece;
00298 
00299                 CVector         dz(0.0f, 0.0f, 0.5f);
00300                 float           zp = (float)sbox.getCenter().z;
00301                 for (ece=0; ece<_InternalCST.EdgeChainEntries.size(); ++ece)
00302                 {
00303                         CEdgeChainEntry         &entry = _InternalCST.EdgeChainEntries[ece];
00304 
00305                         //
00306                         const CChain    &fchain = retriever.getChain(retriever.getOrderedChain(entry.OChainId).getParentId());
00307                         uint8                   chainType = (fchain.getRight() >= 0 ? 1 : (fchain.isBorderChain() ? 2 : 0));
00308 
00309                         //
00310                         if (chainType == 1)
00311                         {
00312                                 uint    left = fchain.getLeft();
00313                                 uint    right = fchain.getRight();
00314 
00315                                 const CRetrievableSurface       &lsurface = retriever.getSurface(left);
00316                                 const CRetrievableSurface       &rsurface = retriever.getSurface(right);
00317 
00318                                 bool    luw = (lsurface.getFlags() & (1 << CRetrievableSurface::IsUnderWaterBit)) != 0;
00319                                 bool    ruw = (rsurface.getFlags() & (1 << CRetrievableSurface::IsUnderWaterBit)) != 0;
00320 
00321                                 if (luw && !ruw || !luw && ruw)
00322                                         chainType = 3;
00323                         }
00324 
00325                         if (retriever.getFullOrderedChains().size() > 0)
00326                         {
00327                                 const COrderedChain3f   &ochain = retriever.getFullOrderedChain(entry.OChainId);
00328 
00329                                 uint    edge;
00330                                 for (edge=entry.EdgeStart; edge<entry.EdgeEnd; ++edge)
00331                                 {
00332                                         edges.push_back(make_pair(CLine(), chainType));
00333                                         edges.back().first.V0 = ochain[edge] + origin;
00334                                         edges.back().first.V1 = ochain[edge+1] + origin;
00335 /*
00336                                         edges.push_back(make_pair(CLine(), chainType));
00337                                         edges.back().first.V0 = ochain[edge] + origin;
00338                                         edges.back().first.V1 = ochain[edge] + origin +dz;
00339 
00340                                         edges.push_back(make_pair(CLine(), chainType));
00341                                         edges.back().first.V0 = ochain[edge+1] + origin;
00342                                         edges.back().first.V1 = ochain[edge+1] + origin +dz;
00343 */
00344                                 }
00345                         }
00346                         else
00347                         {
00348                                 const COrderedChain     &ochain = retriever.getOrderedChain(entry.OChainId);
00349 
00350                                 uint    edge;
00351                                 for (edge=entry.EdgeStart; edge<entry.EdgeEnd; ++edge)
00352                                 {
00353                                         edges.push_back(make_pair(CLine(), chainType));
00354                                         edges.back().first.V0 = ochain[edge].unpack3f() + origin;
00355                                         edges.back().first.V0.z = zp;
00356                                         edges.back().first.V1 = ochain[edge+1].unpack3f() + origin;
00357                                         edges.back().first.V1.z = zp;
00358                                 }
00359                         }
00360                 }
00361         }
00362 }

void NLPACS::CGlobalRetriever::getBorders const UGlobalPosition pos,
std::vector< std::pair< NLMISC::CLine, uint8 > > &  edges
[virtual]
 

Checks the retriever for errors.

Implements NLPACS::UGlobalRetriever.

Definition at line 260 of file global_retriever.cpp.

References getDoubleGlobalPosition(), NLPACS::UGlobalPosition::InstanceId, NLMISC::CAABBox::setCenter(), and NLMISC::CAABBox::setHalfSize().

00261 {
00262         edges.clear();
00263 
00264         if (pos.InstanceId < 0)
00265                 return;
00266 
00267         CVectorD                gpos = getDoubleGlobalPosition(pos);
00268         CAABBox                 sbox;
00269         sbox.setCenter(gpos);
00270         sbox.setHalfSize(CVector(50.0f, 50.0f, 100.0f));
00271 
00272         getBorders(sbox, edges);
00273 }

CVectorD NLPACS::CGlobalRetriever::getDoubleGlobalPosition const UGlobalPosition global  )  const [virtual]
 

Converts a global position object into a 'human-readable' CVector (double instead.).

Implements NLPACS::UGlobalRetriever.

Definition at line 840 of file global_retriever.cpp.

References NLPACS::ULocalPosition::Estimation, NLPACS::UGlobalPosition::InstanceId, and NLPACS::UGlobalPosition::LocalPosition.

Referenced by doMove(), getBorders(), NLPACS::CPrimitiveWorldImage::CPosition::setGlobalPos(), and NLPACS::CPrimitiveWorldImage::CPosition::setGlobalPosKeepZ().

00841 {
00842         if (global.InstanceId >= 0)
00843         {
00844                 return _Instances[global.InstanceId].getDoubleGlobalPosition(global.LocalPosition.Estimation);
00845         }
00846         else
00847         {
00848                 // it should be an error here
00849                 return CVectorD(global.LocalPosition.Estimation);
00850         }
00851 }

CVector NLPACS::CGlobalRetriever::getGlobalPosition const UGlobalPosition global  )  const [virtual]
 

Converts a global position object into a 'human-readable' CVector.

Implements NLPACS::UGlobalRetriever.

Definition at line 827 of file global_retriever.cpp.

References NLPACS::ULocalPosition::Estimation, NLPACS::UGlobalPosition::InstanceId, and NLPACS::UGlobalPosition::LocalPosition.

Referenced by findAStarPath().

00828 {
00829         if (global.InstanceId >= 0)
00830         {
00831                 return _Instances[global.InstanceId].getGlobalPosition(global.LocalPosition.Estimation);
00832         }
00833         else
00834         {
00835                 // it should be an error here
00836                 return global.LocalPosition.Estimation;
00837         }
00838 }

const string & NLPACS::CGlobalRetriever::getIdentifier const UGlobalPosition position  )  const [virtual]
 

Get the identifier of the global position.

Implements NLPACS::UGlobalRetriever.

Definition at line 746 of file global_retriever.cpp.

References NLPACS::CLocalRetriever::getIdentifier(), getRetriever(), and NLPACS::UGlobalPosition::InstanceId.

00747 {
00748         static const string             nullString = string("");
00749 
00750         if (position.InstanceId == -1)
00751                 return nullString;
00752 
00753         return getRetriever(_Instances[position.InstanceId].getRetrieverId()).getIdentifier();
00754 }

sint32 NLPACS::CGlobalRetriever::getIdentifier const std::string &  id  )  const [virtual]
 

Return the retriever id from the string id.

Implements NLPACS::UGlobalRetriever.

Definition at line 736 of file global_retriever.cpp.

References _RetrieverBank, NLPACS::CLocalRetriever::getIdentifier(), getRetriever(), NLPACS::CRetrieverBank::getRetrievers(), and sint32.

Referenced by buildInstance().

00737 {
00738         sint32  i;
00739         for (i=0; i<(sint32)(_RetrieverBank->getRetrievers().size()); ++i)
00740                 if (getRetriever(i).getIdentifier() == id)
00741                         return i;
00742 
00743         return -1;
00744 }

const CRetrieverInstance& NLPACS::CGlobalRetriever::getInstance uint  id  )  const [inline]
 

Gets the retriever instance referred by its id.

Definition at line 208 of file global_retriever.h.

References uint.

Referenced by NLPACS::CEdgeQuad::build(), doMove(), findCollisionChains(), getMeanHeight(), getSurfaceById(), testBBoxMove(), testBBoxRot(), testCollisionWithCollisionChains(), testCylinderMove(), and testMovementWithCollisionChains().

00208 { return _Instances[id]; }

CRetrieverInstance& NLPACS::CGlobalRetriever::getInstanceFullAccess uint  id  )  [inline]
 

Gets the instance by its id, with full read/write access.

Definition at line 363 of file global_retriever.h.

References uint.

00363 { return _Instances[id]; }

const std::vector<CRetrieverInstance>& NLPACS::CGlobalRetriever::getInstances  )  const [inline]
 

Gets the vector of retriever instances that compose the global retriever.

Definition at line 205 of file global_retriever.h.

00205 { return _Instances; }

CCollisionSurfaceTemp& NLPACS::CGlobalRetriever::getInternalCST  )  const [inline, protected]
 

Definition at line 523 of file global_retriever.h.

References _InternalCST.

Referenced by NLPACS::CRetrieverInstance::initEdgeQuad().

00523 { return _InternalCST; }

sint32 NLPACS::CGlobalRetriever::getLocalRetrieverId const UGlobalPosition position  )  const [virtual]
 

Get the LocalRetrieverId of the global position.

Implements NLPACS::UGlobalRetriever.

Definition at line 756 of file global_retriever.cpp.

References NLPACS::UGlobalPosition::InstanceId, and sint32.

00757 {
00758         if (position.InstanceId == -1)
00759                 return -1;
00760 
00761         return _Instances[position.InstanceId].getRetrieverId();
00762 }

uint32 NLPACS::CGlobalRetriever::getMaterial const UGlobalPosition pos  )  const [inline, virtual]
 

Get the material at this position.

Implements NLPACS::UGlobalRetriever.

Definition at line 224 of file global_retriever.h.

References NLPACS::CRetrievableSurface::getMaterial(), getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CLocalRetriever::getSurface(), NLPACS::CLocalRetriever::getSurfaces(), NLPACS::UGlobalPosition::InstanceId, NLPACS::CLocalRetriever::isLoaded(), NLPACS::UGlobalPosition::LocalPosition, sint, NLPACS::ULocalPosition::Surface, and uint32.

00225         {
00226                 if (pos.InstanceId < 0 || pos.InstanceId >= (sint)_Instances.size())
00227                         return 0xFFFFFFFF;
00228 
00229                 const CRetrieverInstance        &instance = _Instances[pos.InstanceId];
00230                 const CLocalRetriever           &retriever = getRetriever(instance.getRetrieverId());
00231 
00232                 if (!retriever.isLoaded() || pos.LocalPosition.Surface < 0 || pos.LocalPosition.Surface >= (sint)retriever.getSurfaces().size())
00233                         return 0xFFFFFFFF;
00234 
00235                 return retriever.getSurface(pos.LocalPosition.Surface).getMaterial();
00236         }

float NLPACS::CGlobalRetriever::getMeanHeight const UGlobalPosition pos  )  const [virtual]
 

return the mean height of the surface under pos..

Implements NLPACS::UGlobalRetriever.

Definition at line 2421 of file global_retriever.cpp.

References _RetrieverBank, NLPACS::ULocalPosition::Estimation, NLPACS::CLocalRetriever::getHeight(), getInstance(), NLPACS::CRetrieverBank::getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::UGlobalPosition::InstanceId, NLPACS::CLocalRetriever::isLoaded(), NLPACS::UGlobalPosition::LocalPosition, NLPACS::ULocalPosition::Surface, and NLMISC::CVector::z.

Referenced by NLPACS::CPrimitiveWorldImage::CPosition::setGlobalPos(), testCollisionWithCollisionChains(), testMovementWithCollisionChains(), and updateHeight().

02422 {
02423         // for wrong positions, leave it unchanged
02424         if ((pos.InstanceId==-1)||(pos.LocalPosition.Surface==-1))
02425                 return pos.LocalPosition.Estimation.z;
02426         
02427         // get instance/localretriever.
02428         const CRetrieverInstance        &instance = getInstance(pos.InstanceId);
02429         const CLocalRetriever           &retriever= _RetrieverBank->getRetriever(instance.getRetrieverId());
02430 
02431         if (!retriever.isLoaded())
02432                 return pos.LocalPosition.Estimation.z;
02433 
02434         // return height from local retriever
02435         return retriever.getHeight(pos.LocalPosition);
02436 }

CRetrieverInstance::CAStarNodeInfo& NLPACS::CGlobalRetriever::getNode CRetrieverInstance::CAStarNodeAccess access  )  const [inline, private]
 

Gets the CAStarNodeInfo referred by its access.

Definition at line 484 of file global_retriever.h.

References NLPACS::CRetrieverInstance::CAStarNodeAccess::InstanceId, and NLPACS::CRetrieverInstance::CAStarNodeAccess::NodeId.

Referenced by findAStarPath().

00485         {
00486                 return _Instances[access.InstanceId]._NodesInformation[access.NodeId];
00487         }

const CLocalRetriever& NLPACS::CGlobalRetriever::getRetriever uint32  id  )  const [inline]
 

Get the local retriever.

Definition at line 220 of file global_retriever.h.

References _RetrieverBank, NLPACS::CRetrieverBank::getRetriever(), and uint32.

Referenced by check(), distanceToBorder(), findCollisionChains(), getBorders(), getIdentifier(), getMaterial(), NLPACS::CRetrieverInstance::initEdgeQuad(), initRetrieveTable(), insurePosition(), isWaterPosition(), NLPACS::CRetrieverInstance::linkEdgeQuad(), makeInstance(), makeLinks(), and testPosition().

00220 { return _RetrieverBank->getRetriever(id); }

const CRetrieverBank* NLPACS::CGlobalRetriever::getRetrieverBank  )  const [inline]
 

Get the retriever bank associated to this global retriever.

Definition at line 217 of file global_retriever.h.

References _RetrieverBank.

00217 { return _RetrieverBank; }

const NLPACS::CRetrievableSurface * NLPACS::CGlobalRetriever::getSurfaceById const CSurfaceIdent surfId  )  const
 

retrieve a surface by its Id. NULL if not found or if -1.

Definition at line 1159 of file global_retriever.cpp.

References _RetrieverBank, getInstance(), NLPACS::CRetrieverBank::getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CLocalRetriever::getSurface(), NLPACS::CLocalRetriever::getSurfaces(), NLPACS::CLocalRetriever::isLoaded(), NLPACS::CSurfaceIdent::RetrieverInstanceId, sint, sint32, and NLPACS::CSurfaceIdent::SurfaceId.

Referenced by verticalChain().

01160 {
01161         if(surfId.RetrieverInstanceId>=0 && surfId.SurfaceId>=0)
01162         {
01163                 sint32  locRetId= this->getInstance(surfId.RetrieverInstanceId).getRetrieverId();
01164                 const CLocalRetriever           &retr = _RetrieverBank->getRetriever(locRetId);
01165                 if (!retr.isLoaded() || surfId.SurfaceId >= (sint)retr.getSurfaces().size())
01166                         return NULL;
01167                 const CRetrievableSurface       &surf= retr.getSurface(surfId.SurfaceId);
01168                 return &surf;
01169         }
01170         else
01171                 return NULL;
01172 }

void NLPACS::CGlobalRetriever::init  ) 
 

Setup an empty global retriever.

void NLPACS::CGlobalRetriever::initAll bool  initInstances = true  ) 
 

Inits all the instances inside the global retriever.

Definition at line 414 of file global_retriever.cpp.

References _RetrieverBank, NLPACS::CRetrieverBank::getRetriever(), initQuadGrid(), initRetrieveTable(), and uint.

Referenced by NLPACS::UGlobalRetriever::createGlobalRetriever(), and serial().

00415 {
00416         if (initInstances)
00417         {
00418                 uint    n;
00419                 for (n=0; n<_Instances.size(); ++n)
00420                         if (_Instances[n].getInstanceId() != -1 && _Instances[n].getRetrieverId() != -1)
00421                                 _Instances[n].init(_RetrieverBank->getRetriever(_Instances[n].getRetrieverId()));
00422         }
00423 
00424         initQuadGrid();
00425         initRetrieveTable();
00426 }

void NLPACS::CGlobalRetriever::initQuadGrid  ) 
 

Fill the quadgrid with the instances.

Definition at line 78 of file global_retriever.cpp.

References _InstanceGrid, NLPACS::CQuadGrid< uint32 >::clear(), NLPACS::CQuadGrid< uint32 >::create(), getBBox(), NLPACS::CQuadGrid< uint32 >::insert(), and uint.

Referenced by initAll().

00079 {
00080         _InstanceGrid.clear();
00081         _InstanceGrid.create(128, 160.0f);
00082 
00083         uint    i;
00084         for (i=0; i<_Instances.size(); ++i)
00085                 _InstanceGrid.insert(_Instances[i].getBBox().getMin(), _Instances[i].getBBox().getMax(), i);
00086 }

void NLPACS::CGlobalRetriever::initRetrieveTable  ) 
 

Init the retrieve table.

Definition at line 88 of file global_retriever.cpp.

References _RetrieveTable, getRetriever(), NLPACS::CLocalRetriever::getSurfaces(), size, and uint.

Referenced by initAll().

00089 {
00090         uint    i;
00091         uint    size = 0;
00092 
00093         for (i=0; i<_Instances.size(); ++i)
00094         {
00095                 if (_Instances[i].getInstanceId() != -1 && _Instances[i].getRetrieverId() != -1)
00096                 {
00097                         const CLocalRetriever   &retriever = getRetriever(_Instances[i].getRetrieverId());
00098                         size =  std::max((uint)retriever.getSurfaces().size(), size);
00099                 }
00100         }
00101 
00102         _RetrieveTable.resize(size);
00103         for (i=0; i<size; ++i)
00104                 _RetrieveTable[i] = 0;
00105 }

bool NLPACS::CGlobalRetriever::insurePosition UGlobalPosition pos  )  const [inline, virtual]
 

Insure position inside surface.

Implements NLPACS::UGlobalRetriever.

Definition at line 295 of file global_retriever.h.

References getRetriever(), NLPACS::UGlobalPosition::InstanceId, NLPACS::CLocalRetriever::insurePosition(), NLPACS::UGlobalPosition::LocalPosition, and sint.

00296         {
00297                 if (pos.InstanceId < 0 || pos.InstanceId >= (sint)_Instances.size())
00298                         return false;
00299 
00300                 const CLocalRetriever           &retriever = getRetriever(_Instances[pos.InstanceId].getRetrieverId());
00301                 return retriever.insurePosition(pos.LocalPosition);
00302         }

bool NLPACS::CGlobalRetriever::isInterior const UGlobalPosition pos  )  const [inline, virtual]
 

Test if the position is an interior.

Implements NLPACS::UGlobalRetriever.

Definition at line 239 of file global_retriever.h.

References NLPACS::UGlobalPosition::InstanceId, and sint.

00240         {
00241                 if (pos.InstanceId < 0 || pos.InstanceId >= (sint)_Instances.size())
00242                         return false;
00243 
00244                 return (_Instances[pos.InstanceId].getType() == CLocalRetriever::Interior);
00245         }

bool NLPACS::CGlobalRetriever::isWaterPosition const UGlobalPosition pos,
float &  waterHeight
const [inline, virtual]
 

Test if the position is in water.

Implements NLPACS::UGlobalRetriever.

Definition at line 248 of file global_retriever.h.

References NLPACS::CRetrievableSurface::getFlags(), getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CLocalRetriever::getSurface(), NLPACS::CRetrievableSurface::getWaterHeight(), NLPACS::UGlobalPosition::InstanceId, NLPACS::CLocalRetriever::isLoaded(), NLPACS::UGlobalPosition::LocalPosition, sint, and NLPACS::ULocalPosition::Surface.

00249         {
00250                 if (pos.InstanceId < 0 || pos.InstanceId >= (sint)_Instances.size())
00251                         return false;
00252 
00253                 const CRetrieverInstance        &instance = _Instances[pos.InstanceId];
00254                 const CLocalRetriever           &retriever = getRetriever(instance.getRetrieverId());
00255 
00256                 if (!retriever.isLoaded())
00257                         return false;
00258 
00259                 const CRetrievableSurface       &surface = retriever.getSurface(pos.LocalPosition.Surface);
00260 
00261                 waterHeight = surface.getWaterHeight();
00262 
00263                 return (surface.getFlags() & (1 << CRetrievableSurface::IsUnderWaterBit)) != 0;
00264         }

void NLPACS::CGlobalRetriever::makeAllLinks  ) 
 

Links all the instances inside the global retriever.

Definition at line 405 of file global_retriever.cpp.

References makeLinks(), resetAllLinks(), and uint.

00406 {
00407         resetAllLinks();
00408 
00409         uint    n;
00410         for (n=0; n<_Instances.size(); ++n)
00411                 makeLinks(n);
00412 }

const NLPACS::CRetrieverInstance & NLPACS::CGlobalRetriever::makeInstance uint32  retriever,
uint8  orientation,
const NLMISC::CVector origin
 

Creates an instance of local retriever at the origine position with the given orientation.

Definition at line 430 of file global_retriever.cpp.

References _InstanceGrid, _RetrieveTable, NLMISC::CAABBox::extend(), NLPACS::CRetrieverInstance::getBBox(), NLMISC::CAABBox::getHalfSize(), NLPACS::CRetrieverInstance::getInstanceId(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CLocalRetriever::getSurfaces(), NLPACS::CLocalRetriever::getType(), NLPACS::CRetrieverInstance::initEdgeQuad(), NLPACS::CQuadGrid< uint32 >::insert(), NLPACS::CRetrieverInstance::make(), uint, uint32, uint8, and NLMISC::CVector::z.

Referenced by buildInstance().

00431 {
00432         uint    id;
00433         for (id=0; id<_Instances.size() && _Instances[id].getInstanceId()!=-1; ++id)
00434                 ;
00435 
00436         if (id == _Instances.size())
00437                 _Instances.resize(id+1);
00438 
00439         CRetrieverInstance              &instance = _Instances[id];
00440         const CLocalRetriever   &retriever = getRetriever(retrieverId);
00441 
00442         if (_RetrieveTable.size() < retriever.getSurfaces().size())
00443                 _RetrieveTable.resize(retriever.getSurfaces().size(), 0);
00444 
00445         instance.make(id, retrieverId, retriever, orientation, origin);
00446 
00447         CVector hsize = instance.getBBox().getHalfSize();
00448         hsize.z = 0.0f;
00449         if (hsize != CVector::Null)
00450         {
00451                 if (_BBox.getHalfSize() == CVector::Null)
00452                 {
00453                         _BBox = instance.getBBox();
00454                 }
00455                 else
00456                 {
00457                         _BBox.extend(instance.getBBox().getMin());
00458                         _BBox.extend(instance.getBBox().getMax());
00459                 }
00460 
00461                 if (getRetriever(instance.getRetrieverId()).getType() == CLocalRetriever::Interior)
00462                         instance.initEdgeQuad(*this);
00463 
00464                 _InstanceGrid.insert(instance.getBBox().getMin(), instance.getBBox().getMax(), instance.getInstanceId());
00465         }
00466 
00467         return instance;
00468 }

void NLPACS::CGlobalRetriever::makeLinks uint  n  ) 
 

Links the instance referred by its id to its neighbors.

Definition at line 367 of file global_retriever.cpp.

References _InternalCST, _RetrieverBank, NLPACS::CCollisionSurfaceTemp::CollisionInstances, NLPACS::CRetrieverInstance::getBBox(), NLPACS::CRetrieverInstance::getInstanceId(), getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CRetrieverBank::getRetrievers(), NLPACS::CLocalRetriever::getType(), NLPACS::CRetrieverInstance::link(), NLPACS::CRetrieverInstance::linkEdgeQuad(), nlwarning, selectInstances(), and uint.

Referenced by buildInstance(), and makeAllLinks().

00368 {
00369         CRetrieverInstance      &instance = _Instances[n];
00370 
00371         selectInstances(instance.getBBox(), _InternalCST);
00372 
00373         uint    i;
00374         for (i=0; i<_InternalCST.CollisionInstances.size(); ++i)
00375         {
00376                 CRetrieverInstance      &neighbor = _Instances[_InternalCST.CollisionInstances[i]];
00377 
00378                 if (neighbor.getInstanceId() == instance.getInstanceId())
00379                         continue;
00380 
00381                 try
00382                 {
00383                         instance.link(neighbor, _RetrieverBank->getRetrievers());
00384                         neighbor.link(instance, _RetrieverBank->getRetrievers());
00385                 }
00386                 catch (Exception &e)
00387                 {
00388                         nlwarning("in NLPACS::CGlobalRetriever::makeLinks()");
00389                         nlwarning("caught an exception during linkage of %d and %d: %s", instance.getInstanceId(), neighbor.getInstanceId(), e.what());
00390                 }
00391         }
00392 
00393         if (getRetriever(instance.getRetrieverId()).getType() == CLocalRetriever::Interior)
00394                 instance.linkEdgeQuad(*this);
00395 }

void NLPACS::CGlobalRetriever::refreshLrAround const NLMISC::CVector position,
float  radius
[virtual]
 

Refresh loaded retrievers around a position (one retriever is loaded at a time)

Implements NLPACS::UGlobalRetriever.

Definition at line 2448 of file global_retriever.cpp.

References _InternalCST, _LrLoaderList, _RetrieverBank, NLPACS::CRetrieverBank::allLoaded(), NLPACS::CCollisionSurfaceTemp::CollisionInstances, NLPACS::CGlobalRetriever::CLrLoader::Finished, NLPACS::CRetrieverBank::getNamePrefix(), in, NLPACS::CGlobalRetriever::CLrLoader::LoadFile, NLPACS::CGlobalRetriever::CLrLoader::LrId, nlassert, nlinfo, NLPACS_HAUTO_REFRESH_LR_AROUND, selectInstances(), NLMISC::CAABBox::setCenter(), NLMISC::CAABBox::setHalfSize(), NLMISC::toString(), and uint.

02449 {
02450         NLPACS_HAUTO_REFRESH_LR_AROUND
02451 
02452         // check if retriever bank is all loaded, and if yes don't refresh it
02453         if (_RetrieverBank->allLoaded())
02454                 return;
02455 
02456         std::list<CLrLoader>::iterator ite = _LrLoaderList.begin();
02457         while (ite != _LrLoaderList.end())
02458         {
02459                 // Finished loaded a lr, stream it into rbank
02460                 if (ite->Finished && ite->Successful)
02461                 {
02462                         if (!ite->_Buffer.isReading())
02463                                 ite->_Buffer.invert();
02464                         
02465                         ite->_Buffer.resetBufPos();
02466                         
02467                         //              NLMEMORY::CheckHeap (true);
02468                         
02469                         const_cast<CRetrieverBank*>(_RetrieverBank)->loadRetriever(ite->LrId, ite->_Buffer);
02470                         
02471                         //              NLMEMORY::CheckHeap (true);
02472                         
02473                         ite->_Buffer.clear();
02474                         
02475                         //              NLMEMORY::CheckHeap (true);
02476                         
02477                         nlinfo("Lr '%s' loading task complete", ite->LoadFile.c_str());
02478 
02479                         // Remove this entry
02480                         _LrLoaderList.erase (ite);
02481 
02482                         break;
02483                 }
02484                 
02485                 // Next lr
02486                 ite++;
02487         }
02488 
02489         CAABBox box;
02490         box.setCenter(position);
02491         box.setHalfSize(CVector(radius, radius, 1000.0f));
02492 
02493         selectInstances(box, _InternalCST);
02494 
02495         set<uint>       newlr, in, out;
02496         map<uint, CVector>      lrPosition;
02497 
02498         uint    i;
02499         for (i=0; i<_InternalCST.CollisionInstances.size(); ++i)
02500         {
02501                 uint lrId = (uint)(_Instances[_InternalCST.CollisionInstances[i]].getRetrieverId());
02502                 newlr.insert(lrId);
02503                 lrPosition.insert (map<uint, CVector>::value_type(lrId, _Instances[_InternalCST.CollisionInstances[i]].getBBox().getCenter()));
02504         }
02505 
02506         const_cast<CRetrieverBank*>(_RetrieverBank)->diff(newlr, in, out);
02507 
02508         set<uint>::iterator     it;
02509 
02510         // unload all possible retrievers
02511         for (it=out.begin(); it!=out.end(); ++it)
02512         {
02513                 const_cast<CRetrieverBank*>(_RetrieverBank)->unloadRetriever(*it);
02514                 nlinfo("Freed Lr '%s'", (_RetrieverBank->getNamePrefix() + "_" + toString(*it) + ".lr").c_str());
02515         }
02516 
02517         // if load task idle and more lr to load, setup load task
02518         set<uint>::iterator iteIn = in.begin();
02519         while (iteIn != in.end())
02520         {
02521                 // Already exist ?
02522                 ite = _LrLoaderList.begin();
02523                 while (ite != _LrLoaderList.end())
02524                 {
02525                         if (ite->LrId == *iteIn)
02526                                 break;
02527 
02528                         ite++;
02529                 }
02530                 
02531                 // Not found ?
02532                 if (ite == _LrLoaderList.end())
02533                 {
02534                         // Get the position fot this LR
02535                         map<uint, CVector>::iterator iteLR = lrPosition.find(*iteIn);
02536                         nlassert (iteLR != lrPosition.end());
02537 
02538                         _LrLoaderList.push_back (CLrLoader (iteLR->second));
02539                         CLrLoader &loader = _LrLoaderList.back();
02540                         loader.Finished = false;
02541                         loader.LrId = *iteIn;
02542                         loader.LoadFile = _RetrieverBank->getNamePrefix() + "_" + toString(loader.LrId) + ".lr";
02543                         
02544                         CAsyncFileManager::getInstance().addLoadTask(&loader);
02545                         
02546                         nlinfo("Lr '%s' added to load", loader.LoadFile.c_str());
02547                 }
02548 
02549                 // Next lr to load
02550                 iteIn++;
02551         }
02552 }

void NLPACS::CGlobalRetriever::refreshLrAroundNow const NLMISC::CVector position,
float  radius
[virtual]
 

Refresh loaded retrievers around a position (all retrievers are updated at this time -- used at startup)

Implements NLPACS::UGlobalRetriever.

Definition at line 2554 of file global_retriever.cpp.

References _InternalCST, _LrLoaderList, _RetrieverBank, NLPACS::CRetrieverBank::allLoaded(), NLPACS::CCollisionSurfaceTemp::CollisionInstances, NLPACS::CRetrieverBank::getNamePrefix(), in, NLMISC::nlSleep(), nlwarning, selectInstances(), NLMISC::CAABBox::setCenter(), NLMISC::CAABBox::setHalfSize(), NLMISC::toString(), and uint.

02555 {
02556         // check if retriever bank is all loaded, and if yes don't refresh it
02557         if (_RetrieverBank->allLoaded())
02558                 return;
02559 
02560         while (_LrLoaderList.size ())
02561         {
02562                 std::list<CLrLoader>::iterator ite = _LrLoaderList.begin();
02563                 while (ite != _LrLoaderList.end())
02564                 {
02565                         // Finished loaded a lr, stream it into rbank
02566                         if (ite->Finished)
02567                         {
02568                                 if (!ite->_Buffer.isReading())
02569                                         ite->_Buffer.invert();
02570                                 
02571                                 const_cast<CRetrieverBank*>(_RetrieverBank)->loadRetriever(ite->LrId, ite->_Buffer);
02572                                 
02573                                 ite->_Buffer.clear();
02574                                 
02575                                 // Remove this from the list
02576                                 _LrLoaderList.erase(ite);
02577 
02578                                 break;
02579                         }
02580 
02581                         // 
02582                         ite++;
02583                 }
02584 
02585                 if (_LrLoaderList.size ())
02586                         nlSleep(0);
02587         }
02588 
02589         CAABBox box;
02590         box.setCenter(position);
02591         box.setHalfSize(CVector(radius, radius, 1000.0f));
02592 
02593         selectInstances(box, _InternalCST);
02594 
02595         set<uint>       newlr, in, out;
02596         uint    i;
02597         for (i=0; i<_InternalCST.CollisionInstances.size(); ++i)
02598                 newlr.insert((uint)(_Instances[_InternalCST.CollisionInstances[i]].getRetrieverId()));
02599 
02600         const_cast<CRetrieverBank*>(_RetrieverBank)->diff(newlr, in, out);
02601 
02602         set<uint>::iterator     it;
02603 
02604         // unload all possible retrievers
02605         for (it=out.begin(); it!=out.end(); ++it)
02606                 const_cast<CRetrieverBank*>(_RetrieverBank)->unloadRetriever(*it);
02607 
02608         // unload all possible retrievers
02609         for (it=in.begin(); it!=in.end(); ++it)
02610         {
02611                 string          fname = _RetrieverBank->getNamePrefix() + "_" + toString(*it) + ".lr";
02612                 CIFile          f;
02613                 if (!f.open(CPath::lookup(fname, false)))
02614                 {
02615                         nlwarning("Couldn't find file '%s' to load, retriever loading aborted", fname.c_str());
02616                         continue;
02617                 }
02618 
02619                 const_cast<CRetrieverBank*>(_RetrieverBank)->loadRetriever(*it, f);
02620         }
02621 }

void NLPACS::CGlobalRetriever::removeInstance sint32  instanceId  )  [virtual]
 

Removes an instance of retriever (perform all unlinks necessary)

Implements NLPACS::UGlobalRetriever.

Definition at line 794 of file global_retriever.cpp.

References nlwarning, sint32, and NLPACS::CRetrieverInstance::unlink().

00795 {
00796         if (instanceId < 0 || instanceId >= (sint32)_Instances.size() || _Instances[instanceId].getInstanceId() < 0)
00797         {
00798                 nlwarning("CGlobalRetriever::removeInstance(): Can't unlink instance %d, doesn't exist", instanceId);
00799                 return;
00800         }
00801 
00802         // get instance
00803         CRetrieverInstance      &instance = _Instances[instanceId];
00804 
00805         // unlink it from others
00806         instance.unlink(_Instances);
00807 
00808 
00809 }

void NLPACS::CGlobalRetriever::resetAllLinks  ) 
 

Resets all links within the global retriever.

Definition at line 397 of file global_retriever.cpp.

References uint.

Referenced by makeAllLinks().

00398 {
00399         uint    n;
00400         for (n=0; n<_Instances.size(); ++n)
00401                 _Instances[n].unlink(_Instances);
00402 }

NLPACS::UGlobalPosition NLPACS::CGlobalRetriever::retrievePosition const NLMISC::CVectorD estimated,
uint  h,
sint result
const
 

Retrieves the position of an estimated point in the global retriever (double instead.).

Definition at line 621 of file global_retriever.cpp.

References _ForbiddenInstances, _InternalCST, _RetrieverBank, NLPACS::CCollisionSurfaceTemp::CollisionInstances, NLPACS::ULocalPosition::Estimation, Failed, NLPACS::CRetrieverInstance::getLocalPosition(), NLPACS::CRetrieverBank::getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLMISC::CAABBox::include(), NLPACS::UGlobalPosition::InstanceId, NLPACS::CLocalRetriever::insurePosition(), NLPACS::CLocalRetriever::isLoaded(), NLPACS::UGlobalPosition::LocalPosition, MissingLr, nldebug, nlwarning, res, NLPACS::CRetrieverInstance::retrievePosition(), selectInstances(), NLMISC::CAABBox::setCenter(), NLMISC::CAABBox::setHalfSize(), sint, sint32, NLPACS::CRetrieverInstance::snap(), NLPACS::CCollisionSurfaceTemp::SortedSurfaces, Success, NLPACS::ULocalPosition::Surface, uint, uint32, NLMISC::CVector::x, NLMISC::CVectorD::x, NLMISC::CVector::y, NLMISC::CVectorD::y, and NLMISC::CVectorD::z.

00622 {
00623         // the retrieved position
00624         CGlobalPosition                         result = CGlobalPosition(-1, CLocalRetriever::CLocalPosition(-1, estimated));
00625 
00626         if (!_BBox.include(CVector((float)estimated.x, (float)estimated.y, (float)estimated.z)))
00627         {
00628                 _ForbiddenInstances.clear();
00629                 res = Failed;
00630                 return result;
00631         }
00632 
00633 
00634         // get the best matching instances
00635         CAABBox bbpos;
00636         bbpos.setCenter(estimated);
00637         bbpos.setHalfSize(CVector(0.5f, 0.5f, 0.5f));
00638         bool    canGet = selectInstances(bbpos, _InternalCST);
00639 
00640         if (!canGet)
00641         {
00642                 res = MissingLr;
00643                 return result;
00644         }
00645 
00646         uint    i;
00647 
00648         _InternalCST.SortedSurfaces.clear();
00649 
00650         // for each instance, try to retrieve the position
00651         for (i=0; i<_InternalCST.CollisionInstances.size(); ++i)
00652         {
00653                 uint32                                                  id = _InternalCST.CollisionInstances[i];
00654                 const CRetrieverInstance                &instance = _Instances[id];
00655                 const CLocalRetriever                   &retriever = _RetrieverBank->getRetriever(instance.getRetrieverId());
00656 
00657                 uint    j;
00658                 for (j=0; j<_ForbiddenInstances.size(); ++j)
00659                         if (_ForbiddenInstances[j] == (sint32)id)
00660                                 break;
00661 
00662                 if (j<_ForbiddenInstances.size() || !retriever.isLoaded())
00663                         continue;
00664 
00665                 instance.retrievePosition(estimated, retriever, _InternalCST, false);
00666         }
00667 
00668         _ForbiddenInstances.clear();
00669 
00670         if (!_InternalCST.SortedSurfaces.empty())
00671         {
00672                 // if there are some selected surfaces, sort them
00673                 std::sort(_InternalCST.SortedSurfaces.begin(), _InternalCST.SortedSurfaces.end(), CCollisionSurfaceTemp::CDistanceSurface());
00674 
00675                 if (h >= _InternalCST.SortedSurfaces.size())
00676                 {
00677                         // found less surfaces than expected, abort
00678                         res = Failed;
00679                         return result;
00680                 }
00681 
00682                 uint32                                                  id = _InternalCST.SortedSurfaces[h].Instance;
00683                 const CRetrieverInstance                &instance = _Instances[id];
00684                 const CLocalRetriever                   &retriever = _RetrieverBank->getRetriever(instance.getRetrieverId());
00685 
00686                 // get the UGlobalPosition of the estimation for this surface
00687                 result.InstanceId = id;
00688                 result.LocalPosition.Surface = _InternalCST.SortedSurfaces[h].Surface;
00689                 result.LocalPosition.Estimation = instance.getLocalPosition(estimated);
00690 
00691                 CRetrieverInstance::snapVector(result.LocalPosition.Estimation);
00692 
00693                 // if there are more than 1 one possible (and best matching) surface, insure the position within the surface (by moving the point)
00694 //              if (_InternalCST.SortedSurfaces.size() >= 2 && 
00695 //                      _InternalCST.SortedSurfaces[1].Distance-_InternalCST.SortedSurfaces[0].Distance < InsureSurfaceThreshold)
00696                 if (_InternalCST.SortedSurfaces[h].FoundCloseEdge)
00697                 {
00698                         bool    moved;
00699                         uint    numMove = 0;
00700                         do
00701                         {
00702                                 moved = retriever.insurePosition(result.LocalPosition);
00703                                 ++numMove;
00704                         }
00705                         while (moved && numMove < 100);
00706                         // the algo won't loop infinitely
00707 
00708                         if (numMove > 1)
00709                         {
00710                                 nldebug("PACS: insured position inside surface (%d,%d)-(%f,%f,%f), %d moves needed", result.InstanceId, result.LocalPosition.Surface, estimated.x, estimated.y, estimated.z, numMove-1);
00711                         }
00712 
00713                         if (moved)
00714                         {
00715                                 nlwarning ("PACS: couldn't insure position (%.f,%.f) within the surface (surf=%d,inst=%d) after 100 retries", result.LocalPosition.Estimation.x, result.LocalPosition.Estimation.y, result.LocalPosition.Surface, result.InstanceId);
00716                         }
00717                 }
00718 
00719                 // and after selecting the best surface (and some replacement) snap the point to the surface
00720                 instance.snap(result.LocalPosition, retriever);
00721         }
00722         else
00723         {
00724                 res = Failed;
00725 //              nlwarning("PACS: unable to retrieve correct position (%f,%f,%f)", estimated.x, estimated.y, estimated.z);
00726 //              nlSleep(1);
00727         }
00728 
00729         res = Success;
00730         return result;
00731 }

NLPACS::UGlobalPosition NLPACS::CGlobalRetriever::retrievePosition const NLMISC::CVectorD estimated,
double  threshold,
UGlobalPosition::TType  retrieveSpec
const
 

Retrieves the position of an estimated point in the global retriever (double instead.).

Reimplemented from NLPACS::UGlobalRetriever.

Definition at line 493 of file global_retriever.cpp.

References _ForbiddenInstances, _InternalCST, _RetrieverBank, NLPACS::CCollisionSurfaceTemp::CollisionInstances, NLPACS::CLocalRetriever::getIdentifier(), NLPACS::CRetrieverInstance::getLocalPosition(), NLPACS::CRetrieverBank::getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CLocalRetriever::getType(), NLPACS::CRetrieverInstance::getType(), NLMISC::CAABBox::include(), NLPACS::CLocalRetriever::insurePosition(), NLPACS::CLocalRetriever::isLoaded(), nldebug, nlinfo, NLPACS_HAUTO_RETRIEVE_POSITION, nlwarning, PacsRetrieveVerbose, NLPACS::CRetrieverInstance::retrievePosition(), selectInstances(), NLMISC::CAABBox::setCenter(), NLMISC::CAABBox::setHalfSize(), sint32, NLPACS::CRetrieverInstance::snap(), NLPACS::CCollisionSurfaceTemp::SortedSurfaces, uint, uint32, NLMISC::CVectorD::x, NLMISC::CVectorD::y, and NLMISC::CVectorD::z.

00494 {
00495         NLPACS_HAUTO_RETRIEVE_POSITION
00496 
00497         // the retrieved position
00498         CGlobalPosition                         result = CGlobalPosition(-1, CLocalRetriever::CLocalPosition(-1, estimated));
00499 
00500         if (!_BBox.include(CVector((float)estimated.x, (float)estimated.y, (float)estimated.z)))
00501         {
00502                 _ForbiddenInstances.clear();
00503                 return result;
00504         }
00505         
00506         
00507         // get the best matching instances
00508         CAABBox bbpos;
00509         bbpos.setCenter(estimated);
00510         bbpos.setHalfSize(CVector(0.5f, 0.5f, 0.5f));
00511         if (!selectInstances(bbpos, _InternalCST, retrieveSpec))
00512                 return result;
00513 
00514         uint    i;
00515 
00516         _InternalCST.SortedSurfaces.clear();
00517 
00518         // for each instance, try to retrieve the position
00519         for (i=0; i<_InternalCST.CollisionInstances.size(); ++i)
00520         {
00521                 uint32                                                  id = _InternalCST.CollisionInstances[i];
00522                 const CRetrieverInstance                &instance = _Instances[id];
00523                 const CLocalRetriever                   &retriever = _RetrieverBank->getRetriever(instance.getRetrieverId());
00524 
00525                 uint    j;
00526                 for (j=0; j<_ForbiddenInstances.size(); ++j)
00527                         if (_ForbiddenInstances[j] == (sint32)id)
00528                                 break;
00529 
00530                 if (j<_ForbiddenInstances.size() || !retriever.isLoaded())
00531                         continue;
00532 
00533                 instance.retrievePosition(estimated, retriever, _InternalCST);
00534         }
00535 
00536         _ForbiddenInstances.clear();
00537 
00538         if (!_InternalCST.SortedSurfaces.empty())
00539         {
00540                 // if there are some selected surfaces, sort them
00541                 std::sort(_InternalCST.SortedSurfaces.begin(), _InternalCST.SortedSurfaces.end(), CCollisionSurfaceTemp::CDistanceSurface());
00542 
00543                 uint    selInstance;
00544                 float   bestDist = 1.0e10f;
00545                 for (selInstance=0; selInstance<_InternalCST.SortedSurfaces.size(); ++selInstance)
00546                 {
00547                         uint32                                          id = _InternalCST.SortedSurfaces[selInstance].Instance;
00548                         const CRetrieverInstance        &instance = _Instances[id];
00549 
00550                         if (instance.getType() == CLocalRetriever::Interior && _InternalCST.SortedSurfaces[selInstance].Distance < bestDist+6.0f)
00551                                 break;
00552 
00553                         if (selInstance == 0)
00554                                 bestDist = _InternalCST.SortedSurfaces[0].Distance;
00555                 }
00556 
00557                 if (selInstance >= _InternalCST.SortedSurfaces.size())
00558                         selInstance = 0;
00559 
00560                 uint32                                                  id = _InternalCST.SortedSurfaces[selInstance].Instance;
00561                 const CRetrieverInstance                &instance = _Instances[id];
00562                 const CLocalRetriever                   &retriever = _RetrieverBank->getRetriever(instance.getRetrieverId());
00563 
00564                 // get the UGlobalPosition of the estimation for this surface
00565                 result.InstanceId = id;
00566                 result.LocalPosition.Surface = _InternalCST.SortedSurfaces[selInstance].Surface;
00567                 result.LocalPosition.Estimation = instance.getLocalPosition(estimated);
00568 
00569                 CRetrieverInstance::snapVector(result.LocalPosition.Estimation);
00570 
00571                 // if there are more than 1 one possible (and best matching) surface, insure the position within the surface (by moving the point)
00572 //              if (_InternalCST.SortedSurfaces.size() >= 2 && 
00573 //                      _InternalCST.SortedSurfaces[1].Distance-_InternalCST.SortedSurfaces[0].Distance < InsureSurfaceThreshold)
00574                 if (_InternalCST.SortedSurfaces[selInstance].FoundCloseEdge)
00575                 {
00576                         bool    moved;
00577                         uint    numMove = 0;
00578                         do
00579                         {
00580                                 moved = retriever.insurePosition(result.LocalPosition);
00581                                 ++numMove;
00582                         }
00583                         while (moved && numMove < 100);
00584                         // the algo won't loop infinitely
00585 
00586                         if (numMove > 1)
00587                         {
00588                                 nldebug("PACS: insured position inside surface (%d,%d)-(%f,%f,%f), %d moves needed", result.InstanceId, result.LocalPosition.Surface, estimated.x, estimated.y, estimated.z, numMove-1);
00589                         }
00590 
00591                         if (moved)
00592                         {
00593                                 nlwarning ("PACS: couldn't insure position (%.f,%.f) within the surface (surf=%d,inst=%d) after 100 retries", result.LocalPosition.Estimation.x, result.LocalPosition.Estimation.y, result.LocalPosition.Surface, result.InstanceId);
00594                         }
00595                 }
00596 
00597                 // and after selecting the best surface (and some replacement) snap the point to the surface
00598                 instance.snap(result.LocalPosition, retriever);
00599 
00600 
00601                 if (PacsRetrieveVerbose)
00602                         nlinfo("DebugBen: retrievePosition(%f,%f,%f) -> %d/%d/(%f,%f,%f) - %s/%s",
00603                                         estimated.x, estimated.y, estimated.z,
00604                                         result.InstanceId, result.LocalPosition.Surface, 
00605                                         result.LocalPosition.Estimation.x, result.LocalPosition.Estimation.y, result.LocalPosition.Estimation.z,
00606                                         retriever.getIdentifier().c_str(),
00607                                         retriever.getType() == CLocalRetriever::Interior ? "Interior" : "Landscape");
00608         }
00609         else
00610         {
00611 //              nlwarning("PACS: unable to retrieve correct position (%f,%f,%f)", estimated.x, estimated.y, estimated.z);
00612 //              nlSleep(1);
00613         }
00614 
00615         return result;
00616 }

NLPACS::UGlobalPosition NLPACS::CGlobalRetriever::retrievePosition const NLMISC::CVectorD estimated,
double  threshold
const [virtual]
 

Retrieves the position of an estimated point in the global retriever (double instead.).

Implements NLPACS::UGlobalRetriever.

Definition at line 477 of file global_retriever.cpp.

References retrievePosition().

00478 {
00479         return retrievePosition(estimated, threshold, UGlobalPosition::Unspecified);
00480 }

NLPACS::UGlobalPosition NLPACS::CGlobalRetriever::retrievePosition const NLMISC::CVector estimated,
float  threshold
const [virtual]
 

Retrieves the position of an estimated point in the global retriever.

Implements NLPACS::UGlobalRetriever.

Definition at line 472 of file global_retriever.cpp.

References retrievePosition().

00473 {
00474         return retrievePosition(CVectorD(estimated), (double)threshold, UGlobalPosition::Unspecified);
00475 }

NLPACS::UGlobalPosition NLPACS::CGlobalRetriever::retrievePosition const NLMISC::CVectorD estimated  )  const [virtual]
 

Retrieves the position of an estimated point in the global retriever (double instead.).

Implements NLPACS::UGlobalRetriever.

Definition at line 487 of file global_retriever.cpp.

References retrievePosition().

00488 {
00489         return retrievePosition(estimated, 1.0e10, UGlobalPosition::Unspecified);
00490 }

NLPACS::UGlobalPosition NLPACS::CGlobalRetriever::retrievePosition const NLMISC::CVector estimated  )  const [virtual]
 

Retrieves the position of an estimated point in the global retriever.

Implements NLPACS::UGlobalRetriever.

Definition at line 482 of file global_retriever.cpp.

Referenced by NLPACS::CEdgeQuad::build(), retrievePosition(), NLPACS::CPrimitiveWorldImage::setGlobalPosition(), testCollisionWithCollisionChains(), and testMovementWithCollisionChains().

00483 {
00484         return retrievePosition(estimated, 1.0e10f, UGlobalPosition::Unspecified);
00485 }

bool NLPACS::CGlobalRetriever::selectInstances const NLMISC::CAABBox bbox,
CCollisionSurfaceTemp cst,
UGlobalPosition::TType  type = UGlobalPosition::Unspecified
const
 

Select the instances that are in contact with the given bbox. The selected instances are stored in CCollisionSurfaceTemp.CollisionInstances

Definition at line 109 of file global_retriever.cpp.

References _InstanceGrid, _RetrieverBank, NLPACS::CQuadGrid< uint32 >::begin(), NLPACS::CCollisionSurfaceTemp::CollisionInstances, NLPACS::CQuadGrid< uint32 >::end(), NLMISC::CAABBox::getMax(), NLMISC::CAABBox::getMin(), NLPACS::CRetrieverBank::isLoaded(), NLPACS::CQuadGrid< uint32 >::select(), and type.

Referenced by findCollisionChains(), getBorders(), makeLinks(), refreshLrAround(), refreshLrAroundNow(), and retrievePosition().

00110 {
00111         _InstanceGrid.select(bbox.getMin(), bbox.getMax());
00112         cst.CollisionInstances.clear();
00113 
00114         bool    allLoaded = true;
00115 
00116         NLPACS::CQuadGrid<uint32>::CIterator    it;
00117         for (it=_InstanceGrid.begin(); it!=_InstanceGrid.end(); ++it)
00118         {
00119                 if (type == UGlobalPosition::Landscape && _Instances[*it].getType() == CLocalRetriever::Interior ||
00120                         type == UGlobalPosition::Interior && _Instances[*it].getType() == CLocalRetriever::Landscape)
00121                         continue;
00122 
00123                 if (_Instances[*it].getBBox().intersect(bbox))
00124                 {
00125                         if (!_RetrieverBank->isLoaded(_Instances[*it].getRetrieverId()))
00126                                 allLoaded = false;
00127                         cst.CollisionInstances.push_back(*it);
00128                 }
00129         }
00130 
00131         return allLoaded;
00132 }

void NLPACS::CGlobalRetriever::serial NLMISC::IStream f  ) 
 

Serialises the global retriever.

Definition at line 136 of file global_retriever.cpp.

References initAll(), NLMISC::IStream::isReading(), NLMISC::IStream::serial(), NLMISC::IStream::serialCont(), and NLMISC::IStream::serialVersion().

00137 {
00138         /*
00139         Version 0:
00140                 - base version.
00141         */
00142         (void)f.serialVersion(0);
00143 
00144         f.serialCont(_Instances);
00145         f.serial(_BBox);
00146 
00147         if (f.isReading())
00148                 initAll(false);
00149 }

void NLPACS::CGlobalRetriever::setRetrieverBank const CRetrieverBank bank  )  [inline]
 

Sets the retriever bank.

Definition at line 366 of file global_retriever.h.

References _RetrieverBank.

Referenced by NLPACS::UGlobalRetriever::createGlobalRetriever().

00366 { _RetrieverBank = bank; }

const NLPACS::TCollisionSurfaceDescVector * NLPACS::CGlobalRetriever::testBBoxMove const UGlobalPosition start,
const NLMISC::CVector delta,
const NLMISC::CVector locI,
const NLMISC::CVector locJ,
CCollisionSurfaceTemp cst
const
 

Test a movement of a bbox against surface world.

Parameters:
start is the start position of the movement.
delta is the requested movement.
locI is the oriented I vector of the BBox. I.norm()== Width/2.
locJ is the oriented J vector of the BBox. J.norm()== Height/2.
cst is the CCollisionSurfaceTemp object used as temp copmputing (one per thread).
Returns:
list of collision against surface, ordered by increasing time. this is a synonym for cst.CollisionDescs. NB: this array may be modified by CGlobalRetriever on any collision call.

Definition at line 1937 of file global_retriever.cpp.

References NLPACS::CCollisionSurfaceTemp::CollisionDescs, NLPACS::ULocalPosition::Estimation, NLMISC::CAABBox::extend(), findCollisionChains(), getInstance(), NLPACS::CRetrieverInstance::getOrigin(), NLPACS::UGlobalPosition::InstanceId, NLMISC::CVector::isNull(), NLPACS::UGlobalPosition::LocalPosition, NLPACS::CCollisionSurfaceTemp::PrecDeltaPos, NLPACS::CCollisionSurfaceTemp::PrecStartPos, NLPACS::CCollisionSurfaceTemp::PrecStartSurface, NLPACS::CCollisionSurfaceTemp::PrecValid, NLMISC::CAABBox::setCenter(), NLPACS::ULocalPosition::Surface, testCollisionWithCollisionChains(), x, NLMISC::CVector::x, y, and NLMISC::CVector::y.

Referenced by NLPACS::CPrimitiveWorldImage::evalCollision().

01939 {
01940 //      H_AUTO(PACS_GR_testBBoxMove);
01941 
01942         CSurfaceIdent   startSurface(startPos.InstanceId, startPos.LocalPosition.Surface);
01943 
01944         // 0. reset.
01945         //===========
01946         // reset result.
01947         cst.CollisionDescs.clear();
01948 
01949         // In a surface ?
01950         if (startPos.InstanceId==-1)
01951         {
01952                 // Warning this primitive is not on a surface
01953                 //nlassertonce (0);
01954 
01955                 // Return NULL when lost
01956                 return NULL;
01957         }
01958         
01959         // store this request in cst.
01960         cst.PrecStartSurface= startSurface;
01961         cst.PrecStartPos= startPos.LocalPosition.Estimation;
01962         cst.PrecDeltaPos= delta;
01963         cst.PrecValid= true;
01964 
01965         // 0.bis
01966         //===========
01967         // Abort if deltamove is 0,0,0.
01968         if (delta.isNull())
01969                 return &cst.CollisionDescs;
01970 
01971         // 1. Choose a local basis.
01972         //===========
01973         // Take the retrieverInstance of startPos as a local basis.
01974         CVector         origin;
01975         origin= getInstance(startPos.InstanceId).getOrigin();
01976 
01977 
01978         // 2. compute OBB.
01979         //===========
01980         CVector2f       obbStart[4];
01981         // compute start, relative to the retriever instance.
01982         CVector         start= startPos.LocalPosition.Estimation;
01983         CVector2f       obbCenter(start.x, start.y);
01984         CVector2f       locI2d(locI.x, locI.y);
01985         CVector2f       locJ2d(locJ.x, locJ.y);
01986 
01987         // build points in CCW.
01988         obbStart[0]= obbCenter - locI2d - locJ2d;
01989         obbStart[1]= obbCenter + locI2d - locJ2d;
01990         obbStart[2]= obbCenter + locI2d + locJ2d;
01991         obbStart[3]= obbCenter - locI2d + locJ2d;
01992 
01993         // 3. compute bboxmove.
01994         //===========
01995         CAABBox         bboxMove;
01996         // extend the bbox.
01997         bboxMove.setCenter(CVector(obbStart[0].x, obbStart[0].y, 0));
01998         bboxMove.extend(CVector(obbStart[1].x, obbStart[1].y, 0));
01999         bboxMove.extend(CVector(obbStart[2].x, obbStart[2].y, 0));
02000         bboxMove.extend(CVector(obbStart[3].x, obbStart[3].y, 0));
02001         bboxMove.extend(CVector(obbStart[0].x, obbStart[0].y, 0) + delta);
02002         bboxMove.extend(CVector(obbStart[1].x, obbStart[1].y, 0) + delta);
02003         bboxMove.extend(CVector(obbStart[2].x, obbStart[2].y, 0) + delta);
02004         bboxMove.extend(CVector(obbStart[3].x, obbStart[3].y, 0) + delta);
02005 
02006 
02007 
02008         // 4. find possible collisions in bboxMove+origin. fill cst.CollisionChains.
02009         //===========
02010         findCollisionChains(cst, bboxMove, origin);
02011 
02012 
02013 
02014         // 5. test collisions with CollisionChains.
02015         //===========
02016         CVector2f       startCol(start.x, start.y);
02017         CVector2f       deltaCol(delta.x, delta.y);
02018         testCollisionWithCollisionChains(cst, startCol, deltaCol, startSurface, 0, obbStart, CGlobalRetriever::BBox);
02019 
02020         // result.
02021         return &cst.CollisionDescs;
02022 }

const NLPACS::TCollisionSurfaceDescVector & NLPACS::CGlobalRetriever::testBBoxRot const CGlobalPosition start,
const NLMISC::CVector locI,
const NLMISC::CVector locJ,
CCollisionSurfaceTemp cst
const
 

Test a rotation of a BBox against the surfaces. NB: this function is not perfect because a ContactSurface may appears 2+ times in the returned array.

Parameters:
start is the center of the bbox.
locI is the new oriented I vector of the BBox. I.norm()== Width/2.
locJ is the new oriented J vector of the BBox. J.norm()== Height/2. NB : must have locI^locJ== aK (a>0)
cst is the CCollisionSurfaceTemp object used as temp copmputing (one per thread).
Returns:
list of collision against surface (ContactTime and ContactNormal has no means). this is a synonym for cst.CollisionDescs. NB: this array may be modified by CGlobalRetriever on any collision call.

Definition at line 2236 of file global_retriever.cpp.

References NLPACS::CCollisionSurfaceTemp::CollisionDescs, NLPACS::ULocalPosition::Estimation, NLMISC::CAABBox::extend(), findCollisionChains(), getInstance(), NLPACS::CRetrieverInstance::getOrigin(), NLPACS::UGlobalPosition::InstanceId, NLPACS::UGlobalPosition::LocalPosition, NLPACS::CCollisionSurfaceTemp::PrecValid, NLMISC::CAABBox::setCenter(), NLPACS::ULocalPosition::Surface, NLPACS::TCollisionSurfaceDescVector, testRotCollisionWithCollisionChains(), x, NLMISC::CVector::x, y, and NLMISC::CVector::y.

02238 {
02239 //      H_AUTO(PACS_GR_testBBoxRot);
02240 
02241         CSurfaceIdent   startSurface(startPos.InstanceId, startPos.LocalPosition.Surface);
02242 
02243         // 0. reset.
02244         //===========
02245         // reset result.
02246         cst.CollisionDescs.clear();
02247 
02248         // should not doMove() after a testBBoxRot.
02249         cst.PrecValid= false;
02250 
02251 
02252         // 1. Choose a local basis.
02253         //===========
02254         // Take the retrieverInstance of startPos as a local basis.
02255         CVector         origin;
02256         origin= getInstance(startPos.InstanceId).getOrigin();
02257 
02258 
02259         // 2. compute OBB.
02260         //===========
02261         CVector2f       obbStart[4];
02262         // compute start, relative to the retriever instance.
02263         CVector         start= startPos.LocalPosition.Estimation;
02264         CVector2f       obbCenter(start.x, start.y);
02265         CVector2f       locI2d(locI.x, locI.y);
02266         CVector2f       locJ2d(locJ.x, locJ.y);
02267 
02268         // build points in CCW.
02269         obbStart[0]= obbCenter - locI2d - locJ2d;
02270         obbStart[1]= obbCenter + locI2d - locJ2d;
02271         obbStart[2]= obbCenter + locI2d + locJ2d;
02272         obbStart[3]= obbCenter - locI2d + locJ2d;
02273 
02274         // 3. compute bboxmove.
02275         //===========
02276         CAABBox         bboxMove;
02277         // extend the bbox.
02278         bboxMove.setCenter(CVector(obbStart[0].x, obbStart[0].y, 0));
02279         bboxMove.extend(CVector(obbStart[1].x, obbStart[1].y, 0));
02280         bboxMove.extend(CVector(obbStart[2].x, obbStart[2].y, 0));
02281         bboxMove.extend(CVector(obbStart[3].x, obbStart[3].y, 0));
02282 
02283 
02284 
02285         // 4. find possible collisions in bboxMove+origin. fill cst.CollisionChains.
02286         //===========
02287         findCollisionChains(cst, bboxMove, origin);
02288 
02289 
02290 
02291         // 5. test Rotcollisions with CollisionChains.
02292         //===========
02293         CVector2f       startCol(start.x, start.y);
02294         testRotCollisionWithCollisionChains(cst, startCol, startSurface, obbStart);
02295 
02296 
02297         // result.
02298         return cst.CollisionDescs;
02299 }

void NLPACS::CGlobalRetriever::testCollisionWithCollisionChains CCollisionSurfaceTemp cst,
const CVector2f startCol,
const CVector2f deltaCol,
CSurfaceIdent  startSurface,
float  radius,
const CVector2f  bbox[4],
TCollisionType  colType
const [private]
 

reset and fill cst.CollisionDescs with effective collisions against current cst.CollisionChains. result: new collisionDescs in cst.

Definition at line 1392 of file global_retriever.cpp.

References _ForbiddenInstances, _RetrieverBank, NLPACS::CCollisionChain::ChainId, NLPACS::CCollisionSurfaceTemp::CollisionChains, NLPACS::CCollisionSurfaceTemp::CollisionDescs, NLPACS::CCollisionSurfaceDesc::ContactNormal, NLPACS::CCollisionSurfaceDesc::ContactSurface, NLPACS::CCollisionSurfaceDesc::ContactTime, NLPACS::ULocalPosition::Estimation, NLPACS::CCollisionChain::ExteriorEdge, NLPACS::CCollisionChain::FirstEdgeCollide, NLPACS::CCollisionSurfaceTemp::getEdgeCollideNode(), getInstance(), getMeanHeight(), NLPACS::CRetrieverInstance::getOrigin(), NLPACS::CCollisionChain::getOtherSurface(), NLPACS::CRetrieverBank::getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CLocalRetriever::getSurface(), NLPACS::CLocalRetriever::getSurfaces(), NLPACS::CCollisionChain::hasSurface(), NLPACS::UGlobalPosition::InstanceId, NLPACS::CRetrievableSurface::isCeiling(), NLPACS::CRetrievableSurface::isFloor(), NLPACS::CLocalRetriever::isLoaded(), NLPACS::CCollisionChain::LeftSurface, NLPACS::UGlobalPosition::LocalPosition, min, NLPACS::CEdgeCollideNode::Next, nlassert, retrievePosition(), NLPACS::CSurfaceIdent::RetrieverInstanceId, NLPACS::CCollisionChain::RightSurface, NLMISC::CVectorD::set(), sint, sint32, NLPACS::ULocalPosition::Surface, NLPACS::CSurfaceIdent::SurfaceId, t, NLPACS::CEdgeCollide::testBBoxMove(), NLPACS::CEdgeCollide::testCircleMove(), NLPACS::CCollisionChain::Tested, uint, NLMISC::CVector2f::x, NLMISC::CVector2f::y, and NLMISC::CVector::z.

Referenced by testBBoxMove(), and testCylinderMove().

01394 {
01395 //      H_AUTO(PACS_GR_testCollisionWithCollisionChains);
01396 
01397         // start currentSurface with surface start.
01398         CSurfaceIdent   currentSurface= startSurface;
01399         uint                    nextCollisionSurfaceTested=0;
01400         sint                    i;
01401 
01402         // reset result.
01403         cst.CollisionDescs.clear();
01404         // reset all collisionChain to not tested.
01405         for(i=0; i<(sint)cst.CollisionChains.size(); i++)
01406         {
01407                 CCollisionChain         &colChain= cst.CollisionChains[i];
01408                 colChain.Tested= false;
01409         }
01410 
01411         vector<pair<sint32, bool> >     checkedExtEdges;
01412 
01413 
01414         /*
01415                 To manage recovery, we must use such an algorithm, so we are sure to trace the way across all surfaces really 
01416                 collided, and discard any other (such as other floor or ceiling).
01417         */
01418         while(true)
01419         {
01420                 // run all collisionChain.
01421                 //========================
01422                 for(i=0; i<(sint)cst.CollisionChains.size(); i++)
01423                 {
01424                         CCollisionChain         &colChain= cst.CollisionChains[i];
01425 
01427                         nlassert(colChain.LeftSurface.RetrieverInstanceId < (sint)_Instances.size());
01428                         nlassert(colChain.RightSurface.RetrieverInstanceId < (sint)_Instances.size());
01429 
01430                         // test only currentSurface/X. And don't test chains already tested before.
01431                         if(colChain.hasSurface(currentSurface) && !colChain.Tested)
01432                         {
01433                                 // we are testing this chain.
01434                                 colChain.Tested= true;
01435 
01436                                 // avoid checking twice a door
01437                                 if (colChain.ExteriorEdge && colChain.LeftSurface.RetrieverInstanceId != -1)
01438                                 {
01439                                         bool    enterInterior = (currentSurface.RetrieverInstanceId == colChain.RightSurface.RetrieverInstanceId);
01440 
01441                                         uint    j;
01442                                         sint32  cmp = (colChain.LeftSurface.RetrieverInstanceId<<16) + colChain.ChainId;
01443                                         for (j=0; j<checkedExtEdges.size() && (checkedExtEdges[j].first != cmp); ++j)
01444                                                 ;
01445                                         // if already crossed this edge, abort
01446                                         // this a door that is crossing a surface frontier
01447                                         if (j < checkedExtEdges.size())
01448                                         {
01449                                                 if (checkedExtEdges[j].second != enterInterior)
01450                                                         continue;
01451                                         }
01452                                         else
01453                                                 checkedExtEdges.push_back(make_pair(cmp, enterInterior));
01454                                 }
01455 
01456                                 // test all edges of this chain, and get tmin
01457                                 //========================
01458 
01459                                 float           t=0.0, tMin=1;
01460                                 CVector2f       normal, normalMin;
01461                                 // run list of edge.
01462                                 sint32          curEdge= colChain.FirstEdgeCollide;
01463                                 while(curEdge!=(sint32)0xFFFFFFFF)
01464                                 {
01465                                         // get the edge.
01466                                         CEdgeCollideNode        &colEdge= cst.getEdgeCollideNode(curEdge);
01467 
01468                                         // test collision with this edge.
01469                                         if(colType==CGlobalRetriever::Circle)
01470                                                 t= colEdge.testCircleMove(startCol, deltaCol, radius, normal);
01471                                         else if(colType==CGlobalRetriever::BBox)
01472                                                 t= colEdge.testBBoxMove(startCol, deltaCol, bboxStart, normal);
01473 
01474                                         // earlier collision??
01475                                         if(t<tMin)
01476                                         {
01477                                                 tMin= t;
01478                                                 normalMin= normal;
01479                                         }
01480 
01481                                         // next edge.
01482                                         curEdge= colEdge.Next;
01483                                 }
01484 
01485 
01486                                 // If collision with this chain, must insert it in the array of collision.
01487                                 //========================
01488                                 if(tMin<1)
01489                                 {
01490                                         CSurfaceIdent   collidedSurface= colChain.getOtherSurface(currentSurface);
01491 
01492                                         // if flag as an interior/landscape interface and leave interior surf, retrieve correct surface
01493                                         if (colChain.ExteriorEdge && currentSurface == colChain.LeftSurface)
01494                                         {
01495                                                 CVector2f               p = startCol + deltaCol*tMin;
01496                                                 CVector                 ori = getInstance(startSurface.RetrieverInstanceId).getOrigin();
01497                                                 ori.z = 0.0f;
01498                                                 UGlobalPosition rp;
01499                                                 rp.InstanceId = currentSurface.RetrieverInstanceId;
01500                                                 rp.LocalPosition.Surface = currentSurface.SurfaceId;
01501                                                 rp.LocalPosition.Estimation = p;
01502                                                 rp.LocalPosition.Estimation.z = getMeanHeight(rp);
01503                                                 CVectorD                zp = CVectorD(p.x, p.y, rp.LocalPosition.Estimation.z) + CVectorD(ori);
01504                                                 _ForbiddenInstances.clear();
01505                                                 _ForbiddenInstances.push_back(currentSurface.RetrieverInstanceId);
01506                                                 UGlobalPosition gp = retrievePosition(zp);
01507 
01508                                                 collidedSurface.RetrieverInstanceId = gp.InstanceId;
01509                                                 collidedSurface.SurfaceId = gp.LocalPosition.Surface;
01510                                         }
01511 
01513                                         nlassert(collidedSurface.RetrieverInstanceId < (sint)_Instances.size());
01514 
01515                                         // insert or replace this collision in collisionDescs.
01516                                         // NB: yes this looks like a N algorithm (so N²). But not so many collisions may arise, so don't bother.
01517                                         sint    indexInsert= cst.CollisionDescs.size();
01518                                         sint    colFound= -1;
01519 
01520                                         // start to search with nextCollisionSurfaceTested, because can't insert before.
01521                                         for(sint j= nextCollisionSurfaceTested; j<(sint)cst.CollisionDescs.size(); j++)
01522                                         {
01523                                                 // we must keep time order.
01524                                                 if(tMin < cst.CollisionDescs[j].ContactTime)
01525                                                 {
01526                                                         indexInsert= min(j, indexInsert);
01527                                                 }
01528                                                 // Does the collision with this surface already exist??
01529                                                 if(cst.CollisionDescs[j].ContactSurface==collidedSurface)
01530                                                 {
01531                                                         colFound= j;
01532                                                         // if we have found our old collision, stop, there is no need to search more.
01533                                                         break;
01534                                                 }
01535                                         }
01536 
01537                                         // Insert only if the surface was not already collided, or that new collision arise before old.
01538                                         if(colFound==-1 || indexInsert<=colFound)
01539                                         {
01540                                                 CCollisionSurfaceDesc   newCol;
01541                                                 newCol.ContactSurface= collidedSurface;
01542                                                 newCol.ContactTime= tMin;
01543                                                 newCol.ContactNormal.set(normalMin.x, normalMin.y, 0);
01544 
01545                                                 // if, by chance, indexInsert==colFound, just replace old collision descriptor.
01546                                                 if(colFound==indexInsert)
01547                                                 {
01548                                                         cst.CollisionDescs[indexInsert]= newCol;
01549                                                 }
01550                                                 else
01551                                                 {
01552                                                         // if any, erase old collision against this surface. NB: here, colFound>indexInsert.
01553                                                         if(colFound!=-1)
01554                                                                 cst.CollisionDescs.erase(cst.CollisionDescs.begin() + colFound);
01555 
01556                                                         // must insert the collision.
01557                                                         cst.CollisionDescs.insert(cst.CollisionDescs.begin() + indexInsert, newCol);
01558                                                 }
01559                                         }
01560                                 }
01561                         }
01562                 }
01563 
01564                 // Find next surface to test.
01565                 //========================
01566                 // No more?? so this is the end.
01567                 if(nextCollisionSurfaceTested>=cst.CollisionDescs.size())
01568                         break;
01569                 // else next one.
01570                 else
01571                 {
01572                         // NB: with this algorithm, we are sure that no more collisions will arise before currentCollisionSurfaceTested.
01573                         // so just continue with following surface.
01574                         currentSurface= cst.CollisionDescs[nextCollisionSurfaceTested].ContactSurface;
01575 
01576                         // Do we touch a wall??
01577                         bool    isWall;
01578                         if(currentSurface.SurfaceId<0)
01579                                 isWall= true;
01580                         else
01581                         {
01582                                 // test if it is a walkable wall.
01583                                 sint32  locRetId= this->getInstance(currentSurface.RetrieverInstanceId).getRetrieverId();
01584 
01585                                 if (!_RetrieverBank->getRetriever(locRetId).isLoaded())
01586                                 {
01587                                         nextCollisionSurfaceTested++;
01588                                         continue;
01589                                 }
01590 
01591                                 const CLocalRetriever           &retr = _RetrieverBank->getRetriever(locRetId);
01592                                 if (currentSurface.SurfaceId < (sint)retr.getSurfaces().size())
01593                                 {
01594                                         const CRetrievableSurface       &surf= _RetrieverBank->getRetriever(locRetId).getSurface(currentSurface.SurfaceId);
01595                                         isWall= !(surf.isFloor() || surf.isCeiling());
01596                                 }
01597                                 else
01598                                 {
01599                                         isWall = true;
01600                                 }
01601                         }
01602 
01603                         // If we touch a wall, this is the end of search.
01604                         if(isWall)
01605                         {
01606                                 // There can be no more collision after this one.
01607                                 cst.CollisionDescs.resize(nextCollisionSurfaceTested+1);
01608                                 break;
01609                         }
01610                         else
01611                         {
01612                                 // Next time, we will test the following (NB: the array may grow during next pass, or reorder, 
01613                                 // but only after nextCollisionSurfaceTested).
01614                                 nextCollisionSurfaceTested++;
01615                         }
01616                 }
01617         }
01618 
01619 }

const NLPACS::TCollisionSurfaceDescVector * NLPACS::CGlobalRetriever::testCylinderMove const UGlobalPosition start,
const NLMISC::CVector delta,
float  radius,
CCollisionSurfaceTemp cst
const
 

Test a movement of a cylinder against surface world.

Parameters:
start is the start position of the movement.
delta is the requested movement.
radius is the radius of the vertical cylinder.
cst is the CCollisionSurfaceTemp object used as temp copmputing (one per thread).
Returns:
list of collision against surface, ordered by increasing time. this is a synonym for cst.CollisionDescs. NB: this array may be modified by CGlobalRetriever on any collision call.

Definition at line 1864 of file global_retriever.cpp.

References NLPACS::CCollisionSurfaceTemp::CollisionDescs, NLPACS::ULocalPosition::Estimation, NLMISC::CAABBox::extend(), findCollisionChains(), getInstance(), NLPACS::CRetrieverInstance::getOrigin(), NLPACS::UGlobalPosition::InstanceId, NLMISC::CVector::isNull(), NLPACS::UGlobalPosition::LocalPosition, NLPACS::CCollisionSurfaceTemp::PrecDeltaPos, NLPACS::CCollisionSurfaceTemp::PrecStartPos, NLPACS::CCollisionSurfaceTemp::PrecStartSurface, NLPACS::CCollisionSurfaceTemp::PrecValid, NLMISC::CAABBox::setCenter(), NLPACS::ULocalPosition::Surface, testCollisionWithCollisionChains(), NLMISC::CVector::x, and NLMISC::CVector::y.

Referenced by NLPACS::CEdgeQuad::build(), and NLPACS::CPrimitiveWorldImage::evalCollision().

01865 {
01866 //      H_AUTO(PACS_GR_testCylinderMove);
01867 
01868         CSurfaceIdent   startSurface(startPos.InstanceId, startPos.LocalPosition.Surface);
01869 
01870         // 0. reset.
01871         //===========
01872         // reset result.
01873         cst.CollisionDescs.clear();
01874 
01875         // In a surface ?
01876         if (startPos.InstanceId==-1)
01877         {
01878                 // Warning this primitive is not on a surface
01879                 //nlassertonce (0);
01880 
01881                 // Return NULL when lost
01882                 return NULL;
01883         }
01884         // store this request in cst.
01885         cst.PrecStartSurface= startSurface;
01886         cst.PrecStartPos= startPos.LocalPosition.Estimation;
01887         cst.PrecDeltaPos= delta;
01888         cst.PrecValid= true;
01889 
01890         // 0.bis
01891         //===========
01892         // Abort if deltamove is 0,0,0.
01893         if (delta.isNull())
01894                 return &cst.CollisionDescs;
01895 
01896         // 1. Choose a local basis.
01897         //===========
01898         // Take the retrieverInstance of startPos as a local basis.
01899         CVector         origin;
01900         origin= getInstance(startPos.InstanceId).getOrigin();
01901 
01902 
01903         // 2. compute bboxmove.
01904         //===========
01905         CAABBox         bboxMove;
01906         // bounds the movement in a bbox.
01907         // compute start and end, relative to the retriever instance.
01908         CVector         start= startPos.LocalPosition.Estimation;
01909         CVector         end= start+delta;
01910         // extend the bbox.
01911         bboxMove.setCenter(start-CVector(radius, radius, 0));
01912         bboxMove.extend(start+CVector(radius, radius, 0));
01913         bboxMove.extend(end-CVector(radius, radius, 0));
01914         bboxMove.extend(end+CVector(radius, radius, 0));
01915 
01916 
01917         // 3. find possible collisions in bboxMove+origin. fill cst.CollisionChains.
01918         //===========
01919         findCollisionChains(cst, bboxMove, origin);
01920 
01921 
01922 
01923         // 4. test collisions with CollisionChains.
01924         //===========
01925         CVector2f       startCol(start.x, start.y);
01926         CVector2f       deltaCol(delta.x, delta.y);
01927         CVector2f       obbDummy[4];    // dummy OBB (not obb here so don't bother)
01928         testCollisionWithCollisionChains(cst, startCol, deltaCol, startSurface, radius, obbDummy, CGlobalRetriever::Circle);
01929 
01930         // result.
01931         return &cst.CollisionDescs;
01932 }

NLPACS::CSurfaceIdent NLPACS::CGlobalRetriever::testMovementWithCollisionChains CCollisionSurfaceTemp cst,
const CVector2f startCol,
const CVector2f deltaCol,
CSurfaceIdent  startSurface,
UGlobalPosition restart
const [private]
 

reset and fill cst.MoveDescs with effective collisions of a point movement against current cst.CollisionChains. result: the surfaceIdent where we stop. -1 if we traverse a Wall, which should not happen because of collision test. NB: for precision pb, startCol and deltaCol should be snapped on a grid of 1/1024 meters, using snapVector(). NB: for precision pb (stop on edge etc....), return a "Precision problem ident", ie (-2,-2). NB: when leaving an interior, return a surface (-3, -3) and restart is set to the real restart position

Definition at line 1649 of file global_retriever.cpp.

References _ForbiddenInstances, _RetrieverBank, NLPACS::CMoveSurfaceDesc::ChainId, NLPACS::CCollisionChain::ChainId, NLPACS::CCollisionSurfaceTemp::CollisionChains, NLPACS::CMoveSurfaceDesc::ContactTime, NLPACS::CRational64::Denominator, NLPACS::ULocalPosition::Estimation, NLPACS::CMoveSurfaceDesc::ExteriorEdge, NLPACS::CCollisionChain::ExteriorEdge, NLPACS::CCollisionChain::FirstEdgeCollide, NLPACS::CCollisionSurfaceTemp::getEdgeCollideNode(), getInstance(), getMeanHeight(), NLPACS::CRetrieverInstance::getOrigin(), NLPACS::CMoveSurfaceDesc::getOtherSurface(), NLPACS::CRetrieverBank::getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLPACS::CLocalRetriever::getSurface(), NLPACS::CMoveSurfaceDesc::hasSurface(), NLPACS::UGlobalPosition::InstanceId, NLPACS::CRetrievableSurface::isCeiling(), NLPACS::CRetrievableSurface::isFloor(), NLPACS::CLocalRetriever::isLoaded(), NLPACS::CMoveSurfaceDesc::LeftSurface, NLPACS::CCollisionChain::LeftSurface, NLPACS::UGlobalPosition::LocalPosition, NLPACS::CCollisionSurfaceTemp::MoveDescs, NLPACS::CMoveSurfaceDesc::MovementSens, NLPACS::CEdgeCollideNode::Next, nlinfo, NLPACS::CEdgeCollide::Norm, NLPACS::CRational64::Numerator, retrievePosition(), NLPACS::CSurfaceIdent::RetrieverInstanceId, NLPACS::CMoveSurfaceDesc::RightSurface, NLPACS::CCollisionChain::RightSurface, sint, sint32, NLPACS::ULocalPosition::Surface, NLPACS::CSurfaceIdent::SurfaceId, t, NLPACS::CEdgeCollide::testPointMove(), uint, uint16, NLMISC::CVector2f::x, NLMISC::CVector2f::y, and NLMISC::CVector::z.

Referenced by doMove().

01651 {
01652 //      H_AUTO(PACS_GR_testMovementWithCollisionChains);
01653 
01654         // start currentSurface with surface start.
01655         CSurfaceIdent   currentSurface= startSurface;
01656         sint                    i;
01657 
01658         // reset result.
01659         cst.MoveDescs.clear();
01660 
01661 
01662         static vector<pair<sint32, bool> >      checkedExtEdges;
01663 
01664         /*
01665                 To manage recovery, we must use such an algorithm, so we are sure to trace the way across all surfaces really 
01666                 collided, and discard any other (such as other floor or ceiling).
01667 
01668                 This function is quite different from testCollisionWithCollisionChains() because she must detect all collisions
01669                 with all edges of any chains (and not the minimum collision with a chain).
01670                 This is done in 3 parts:
01671                         - detect collisions with all edges.
01672                         - sort.
01673                         - leave only real collisions.
01674         */
01675         // run all collisionChain.
01676         //========================
01677         for(i=0; i<(sint)cst.CollisionChains.size(); i++)
01678         {
01679                 CCollisionChain         &colChain= cst.CollisionChains[i];
01680 
01681                 if (colChain.ExteriorEdge)
01682                 {
01683                         sint32  cmp = (colChain.LeftSurface.RetrieverInstanceId<<16) + colChain.ChainId;
01684 
01685                         uint    j;
01686                         for (j=0; j<checkedExtEdges.size() && (checkedExtEdges[j].first != cmp); ++j)
01687                                 ;
01688                         // if already crossed this edge, abort
01689                         // this a door that is crossing a surface frontier
01690                         if (j < checkedExtEdges.size())
01691                                 continue;
01692                 }
01693 
01694                 // test all edges of this chain, and insert if necessary.
01695                 //========================
01696                 CRational64             t;
01697                 // run list of edge.
01698                 sint32          curEdge= colChain.FirstEdgeCollide;
01699                 while(curEdge!=(sint32)0xFFFFFFFF)
01700                 {
01701                         // get the edge.
01702                         CEdgeCollideNode        &colEdge= cst.getEdgeCollideNode(curEdge);
01703 
01704                         // test collision with this edge.
01705                         CEdgeCollide::TPointMoveProblem         pmpb;
01706                         t= colEdge.testPointMove(startCol, endCol, pmpb);
01707                         // manage multiple problems of precision.
01708                         if(t== -1)
01709                         {
01710                                 static const string     errs[CEdgeCollide::PointMoveProblemCount]= {
01711                                         "ParallelEdges", "StartOnEdge", "StopOnEdge", "TraverseEndPoint", "EdgeNull"};
01712                                 // return a "Precision Problem" ident. movement is invalid. 
01713                                 // BUT if startOnEdge, which should never arrive.
01714                                 if(pmpb==CEdgeCollide::StartOnEdge)
01715                                 {
01716                                         nlinfo("COL: Precision Problem: %s", errs[pmpb].c_str());
01717                                         checkedExtEdges.clear();
01718                                         return CSurfaceIdent(-1, -1);   // so in this case, block....
01719                                 }
01720                                 else if(pmpb==CEdgeCollide::EdgeNull)
01721                                 {
01722                                         /*
01723                                         // verify if it is an edge which separate 2 walls. in this case, ignore it. else, error.
01724                                         if(verticalChain(colChain))
01725                                         {
01726                                                 t=1;    // no collision with this edge.
01727                                         }
01728                                         else
01729                                         {
01730                                                 nlinfo("COL: Precision Problem: %s", errs[pmpb]);
01731                                                 nlstop;         // this should not append.
01732                                                 return CSurfaceIdent(-1, -1);
01733                                         }*/
01734                                         /* Actually, this is never a problem: we never get through this edge.
01735                                                 Instead, we'll get through the neighbors edge.
01736                                                 So just disable this edge.
01737                                         */
01738                                         t= 1;
01739                                 }
01740                                 else
01741                                         return  CSurfaceIdent(-2, -2);
01742                         }
01743 
01744                         // collision??
01745                         if(t<1)
01746                         {
01747                                 // insert in list.
01748                                 cst.MoveDescs.push_back(CMoveSurfaceDesc(t, colChain.LeftSurface, colChain.RightSurface));
01749                                 cst.MoveDescs.back().ExteriorEdge = colChain.ExteriorEdge;
01750                                 cst.MoveDescs.back().ChainId = (uint16)colChain.ChainId;
01751                                 cst.MoveDescs.back().MovementSens= colEdge.Norm*(endCol-startCol)>=0;
01752                         }
01753 
01754                         // next edge.
01755                         curEdge= colEdge.Next;
01756                 }
01757         }
01758 
01759 
01760         // sort.
01761         //================
01762         // sort the collisions in ascending time order.
01763         sort(cst.MoveDescs.begin(), cst.MoveDescs.end());
01764 
01765 
01766         // Traverse the array of collisions.
01767         //========================
01768         for(i=0;i<(sint)cst.MoveDescs.size();i++)
01769         {
01770                 CMoveSurfaceDesc        &msd = cst.MoveDescs[i];
01771 
01772                 // Do we collide with this chain??
01773                 if(msd.hasSurface(currentSurface))
01774                 {
01775                         // if flag as an interior/landscape interface and leave interior surf, retrieve correct surface
01776                         if (msd.ExteriorEdge && msd.LeftSurface.RetrieverInstanceId != -1)
01777                         {
01778                                 bool    enterInterior = (currentSurface.RetrieverInstanceId == msd.RightSurface.RetrieverInstanceId);
01779 
01780                                 // msd.MovementSens is true if we "geometrically" leave the interior.
01781                                 // If logic and geometric disagree, discard
01782                                 if(enterInterior == msd.MovementSens)
01783                                         continue;
01784 
01785                                 uint    j;
01786                                 sint32  cmp = (msd.LeftSurface.RetrieverInstanceId<<16) + msd.ChainId;
01787                                 for (j=0; j<checkedExtEdges.size() && (checkedExtEdges[j].first != cmp); ++j)
01788                                         ;
01789                                 // if already crossed this edge, abort
01790                                 // this a door that is crossing a surface frontier
01791                                 if (j < checkedExtEdges.size())
01792                                 {
01793                                         if (checkedExtEdges[j].second != enterInterior)
01794                                                 continue;
01795                                 }
01796                                 else
01797                                         checkedExtEdges.push_back(make_pair(cmp, enterInterior));
01798 
01799                                 // if leave interior, retrieve good position
01800                                 if (!enterInterior)
01801                                 {
01802                                         float                   ctime = (float)((double)(msd.ContactTime.Numerator)/(double)(msd.ContactTime.Denominator));
01803                                         CVector2f               p = startCol*(1.0f-ctime) + endCol*ctime;
01804                                         CVector                 ori = getInstance(startSurface.RetrieverInstanceId).getOrigin();
01805                                         ori.z = 0.0f;
01806                                         UGlobalPosition rp;
01807                                         rp.InstanceId = currentSurface.RetrieverInstanceId;
01808                                         rp.LocalPosition.Surface = currentSurface.SurfaceId;
01809                                         rp.LocalPosition.Estimation = p;
01810                                         rp.LocalPosition.Estimation.z = getMeanHeight(rp);
01811                                         CVectorD                zp = CVectorD(p.x, p.y, rp.LocalPosition.Estimation.z) + CVectorD(ori);
01812                                         //CVectorD              zp = CVectorD(p.x, p.y, getMeanHeight()) + CVectorD(ori);
01813                                         _ForbiddenInstances.clear();
01814                                         _ForbiddenInstances.push_back(currentSurface.RetrieverInstanceId);
01815 
01816                                         restart = retrievePosition(zp);
01817 
01818                                         return CSurfaceIdent(-3, -3);
01819                                 }
01820                                 else
01821                                 {
01822                                         currentSurface= msd.getOtherSurface(currentSurface);
01823                                 }
01824                         }
01825                         else
01826                         {
01827                                 currentSurface= msd.getOtherSurface(currentSurface);
01828                         }
01829 
01830                         // Do we touch a wall?? should not happens, but important for security.
01831                         bool    isWall;
01832                         if(currentSurface.SurfaceId<0)
01833                                 isWall= true;
01834                         else
01835                         {
01836                                 // test if it is a walkable wall.
01837                                 sint32  locRetId= this->getInstance(currentSurface.RetrieverInstanceId).getRetrieverId();
01838 
01839                                 if (!_RetrieverBank->getRetriever(locRetId).isLoaded())
01840                                         continue;
01841 
01842                                 const CRetrievableSurface       &surf= _RetrieverBank->getRetriever(locRetId).getSurface(currentSurface.SurfaceId);
01843                                 isWall= !(surf.isFloor() || surf.isCeiling());
01844                         }
01845 
01846                         // If we touch a wall, this is the end of search.
01847                         if(isWall)
01848                         {
01849                                 // return a Wall ident. movement is invalid.
01850                                 checkedExtEdges.clear();
01851                                 return  CSurfaceIdent(-1, -1);
01852                         }
01853                 }
01854         }
01855 
01856         checkedExtEdges.clear();
01857         return currentSurface;
01858 }

bool NLPACS::CGlobalRetriever::testPosition UGlobalPosition pos  )  const [inline, virtual]
 

Builds a instance of retriever, and link it on the ground (or wherever)

Parameters:
id a valid retriever id to be instanciated
a valid position where the retriever should be instanciated
Returns:
false if failed

Implements NLPACS::UGlobalRetriever.

Definition at line 305 of file global_retriever.h.

References _InternalCST, NLPACS::ULocalPosition::Estimation, NLPACS::CRetrieverInstance::getBBox(), NLPACS::CRetrieverInstance::getOrigin(), getRetriever(), NLPACS::CRetrieverInstance::getRetrieverId(), NLMISC::CAABBox::include(), NLPACS::UGlobalPosition::InstanceId, NLPACS::UGlobalPosition::LocalPosition, sint, and NLPACS::CLocalRetriever::testPosition().

00306         {
00307                 if (pos.InstanceId < 0 || pos.InstanceId >= (sint)_Instances.size())
00308                         return false;
00309 
00310                 const CRetrieverInstance        &instance = _Instances[pos.InstanceId];
00311 
00312                 if (!instance.getBBox().include(pos.LocalPosition.Estimation + instance.getOrigin()))
00313                         return false;
00314 
00315                 const CLocalRetriever           &retriever = getRetriever(instance.getRetrieverId());
00316                 return retriever.testPosition(pos.LocalPosition, _InternalCST);
00317         }

bool NLPACS::CGlobalRetriever::testRaytrace const NLMISC::CVectorD v0,
const NLMISC::CVectorD v1
[virtual]
 

Make a raytrace test. For the time, always return false.

Implements NLPACS::UGlobalRetriever.

Definition at line 2440 of file global_retriever.cpp.

02441 {
02442         // TODO: implement raytrace
02443         return false;
02444 }

void NLPACS::CGlobalRetriever::testRotCollisionWithCollisionChains CCollisionSurfaceTemp cst,
const CVector2f startCol,
CSurfaceIdent  startSurface,
const CVector2f  bbox[4]
const [private]
 

reset and fill cst.CollisionDescs with effective collisions against current cst.CollisionChains. result: new collisionDescs in cst.

Definition at line 2303 of file global_retriever.cpp.

References NLPACS::CCollisionSurfaceTemp::CollisionChains, NLPACS::CCollisionSurfaceTemp::CollisionDescs, NLPACS::CCollisionSurfaceDesc::ContactNormal, NLPACS::CCollisionSurfaceDesc::ContactSurface, NLPACS::CCollisionSurfaceDesc::ContactTime, NLPACS::CCollisionChain::FirstEdgeCollide, NLPACS::CCollisionSurfaceTemp::getEdgeCollideNode(), NLPACS::CCollisionChain::LeftSurface, NLPACS::CEdgeCollideNode::Next, NLPACS::CCollisionChain::RightSurface, NLPACS::CCollisionSurfaceTemp::RotDescs, sint, sint32, and NLPACS::CEdgeCollide::testBBoxCollide().

Referenced by testBBoxRot().

02304 {
02305 //      H_AUTO(PACS_GR_testRotCollisionWithCollisionChains);
02306 
02307         // start currentSurface with surface start.
02308         CSurfaceIdent   currentSurface= startSurface;
02309         sint                    i;
02310 
02311         // reset result.
02312         cst.RotDescs.clear();
02313         cst.CollisionDescs.clear();
02314 
02315 
02316         /*
02317                 Test collisions with all collision chains. Then, to manage recovery, test the graph of surfaces.
02318         */
02319         // run all collisionChain.
02320         //========================
02321         for(i=0; i<(sint)cst.CollisionChains.size(); i++)
02322         {
02323                 CCollisionChain         &colChain= cst.CollisionChains[i];
02324 
02325 
02326                 // test all edges of this chain, and insert if necessary.
02327                 //========================
02328                 // run list of edge.
02329                 sint32          curEdge= colChain.FirstEdgeCollide;
02330                 while(curEdge!=(sint32)0xFFFFFFFF)
02331                 {
02332                         // get the edge.
02333                         CEdgeCollideNode        &colEdge= cst.getEdgeCollideNode(curEdge);
02334 
02335                         // test collision with this edge.
02336                         if(colEdge.testBBoxCollide(bbox))
02337                         {
02338                                 // yes we have a 2D collision with this chain.
02339                                 cst.RotDescs.push_back(CRotSurfaceDesc(colChain.LeftSurface, colChain.RightSurface));
02340                                 break;
02341                         }
02342 
02343                         // next edge.
02344                         curEdge= colEdge.Next;
02345                 }
02346         }
02347 
02348 
02349         // Traverse the array of collisions.
02350         //========================
02351         sint    indexCD=0;
02352         while(true)
02353         {
02354                 // What surfaces collided do we reach from this currentSurface??
02355                 for(i=0;i<(sint)cst.RotDescs.size();i++)
02356                 {
02357                         // Do we collide with this chain?? chain not tested??
02358                         if(cst.RotDescs[i].hasSurface(currentSurface) && !cst.RotDescs[i].Tested)
02359                         {
02360                                 cst.RotDescs[i].Tested= true;
02361 
02362                                 // insert the collision with the other surface.
02363                                 CCollisionSurfaceDesc   col;
02364                                 col.ContactTime= 0;
02365                                 col.ContactNormal= CVector::Null;
02366                                 col.ContactSurface= cst.RotDescs[i].getOtherSurface(currentSurface);
02367                                 cst.CollisionDescs.push_back(col);
02368                         }
02369                 }
02370 
02371                 // get the next currentSurface from surface collided (traverse the graph of collisions).
02372                 if(indexCD<(sint)cst.CollisionDescs.size())
02373                         currentSurface= cst.CollisionDescs[indexCD++].ContactSurface;
02374                 else
02375                         break;
02376         }
02377 
02378 }

void NLPACS::CGlobalRetriever::updateHeight UGlobalPosition pos  )  const [inline]
 

Upadates the height of the given global position.

Definition at line 461 of file global_retriever.h.

References NLPACS::ULocalPosition::Estimation, getMeanHeight(), NLPACS::UGlobalPosition::LocalPosition, and NLMISC::CVector::z.

Referenced by NLPACS::CEdgeQuad::build().

00461 { pos.LocalPosition.Estimation.z = getMeanHeight(pos); }

bool NLPACS::CGlobalRetriever::verticalChain const CCollisionChain colChain  )  const [private]
 

test if a collisionChain separate 2 walls.

Definition at line 1623 of file global_retriever.cpp.

References getSurfaceById(), NLPACS::CRetrievableSurface::isCeiling(), NLPACS::CRetrievableSurface::isFloor(), NLPACS::CCollisionChain::LeftSurface, and NLPACS::CCollisionChain::RightSurface.

01624 {
01625         // retrieve surfaces.
01626         const CRetrievableSurface       *left= getSurfaceById(colChain.LeftSurface);
01627         const CRetrievableSurface       *right= getSurfaceById(colChain.RightSurface);
01628 
01629         // test if left surface is a wall.
01630         bool                                            leftWall;
01631         if(!left)
01632                 leftWall= true;
01633         else
01634                 leftWall= !(left->isFloor() || left->isCeiling());
01635 
01636         // test if right surface is a wall.
01637         bool                                            rightWall;
01638         if(!right)
01639                 rightWall= true;
01640         else
01641                 rightWall= !(right->isFloor() || right->isCeiling());
01642 
01643         // true if both are a wall.
01644         return leftWall && rightWall;
01645 }


Friends And Related Function Documentation

friend class CLrLoader [friend]
 

Definition at line 112 of file global_retriever.h.

friend class CRetrieverInstance [friend]
 

Definition at line 521 of file global_retriever.h.


Field Documentation

NLMISC::CAABBox NLPACS::CGlobalRetriever::_BBox [protected]
 

The axis aligned bounding box of the global retriever.

Definition at line 165 of file global_retriever.h.

std::vector<sint32> NLPACS::CGlobalRetriever::_ForbiddenInstances [mutable, protected]
 

Forbidden instance for retrieve position.

Definition at line 168 of file global_retriever.h.

Referenced by retrievePosition(), testCollisionWithCollisionChains(), and testMovementWithCollisionChains().

CQuadGrid<uint32> NLPACS::CGlobalRetriever::_InstanceGrid [mutable, protected]
 

The grid of instances.

Definition at line 162 of file global_retriever.h.

Referenced by initQuadGrid(), makeInstance(), and selectInstances().

std::vector<CRetrieverInstance> NLPACS::CGlobalRetriever::_Instances [mutable, protected]
 

The instances of the global retriever.

Definition at line 159 of file global_retriever.h.

CCollisionSurfaceTemp NLPACS::CGlobalRetriever::_InternalCST [mutable, private]
 

Definition at line 148 of file global_retriever.h.

Referenced by findPath(), getBorders(), getInternalCST(), makeLinks(), refreshLrAround(), refreshLrAroundNow(), retrievePosition(), and testPosition().

std::list<CLrLoader> NLPACS::CGlobalRetriever::_LrLoaderList [protected]
 

Definition at line 144 of file global_retriever.h.

Referenced by refreshLrAround(), and refreshLrAroundNow().

const CRetrieverBank* NLPACS::CGlobalRetriever::_RetrieverBank [protected]
 

The CRetrieverBank where the commmon retrievers are stored.

Definition at line 156 of file global_retriever.h.

Referenced by CGlobalRetriever(), check(), findAStarPath(), findCollisionChains(), findPath(), getIdentifier(), getMeanHeight(), getRetriever(), getRetrieverBank(), getSurfaceById(), initAll(), makeLinks(), refreshLrAround(), refreshLrAroundNow(), retrievePosition(), selectInstances(), setRetrieverBank(), testCollisionWithCollisionChains(), and testMovementWithCollisionChains().

std::vector<uint8> NLPACS::CGlobalRetriever::_RetrieveTable [mutable, private]
 

Used to retrieve the surface. Internal use only, to avoid large amount of new/delete.

Definition at line 151 of file global_retriever.h.

Referenced by initRetrieveTable(), and makeInstance().


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