#include <global_retriever.h>
Inheritance diagram for NLPACS::CGlobalRetriever:
Nevrax France
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< CLocalPath > | CGlobalPath |
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. | |
CRetrieverInstance & | getInstanceFullAccess (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 CRetrieverInstance & | makeInstance (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 CRetrievableSurface * | getSurfaceById (const CSurfaceIdent &surfId) const |
const TCollisionSurfaceDescVector * | testBBoxMove (const UGlobalPosition &start, const NLMISC::CVector &delta, const NLMISC::CVector &locI, const NLMISC::CVector &locJ, CCollisionSurfaceTemp &cst) const |
const TCollisionSurfaceDescVector & | testBBoxRot (const CGlobalPosition &start, const NLMISC::CVector &locI, const NLMISC::CVector &locJ, CCollisionSurfaceTemp &cst) const |
const TCollisionSurfaceDescVector * | testCylinderMove (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::CAABBox & | getBBox () const |
Gets the BBox of the global retriever. | |
const CRetrieverInstance & | getInstance (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 CLocalRetriever & | getRetriever (uint32 id) const |
Get the local retriever. | |
const CRetrieverBank * | getRetrieverBank () 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 | |
UGlobalRetriever * | createGlobalRetriever (const char *globalRetriever, const URetrieverBank *retrieverBank) |
void | deleteGlobalRetriever (UGlobalRetriever *retriever) |
Protected Member Functions | |
CCollisionSurfaceTemp & | getInternalCST () 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::CAStarNodeInfo & | getNode (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 |
|
Definition at line 109 of file global_retriever.h. Referenced by findPath(). |
|
Definition at line 68 of file global_retriever.h.
|
|
Definition at line 494 of file global_retriever.h.
|
|
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 { } |
|
Constructor. Creates a global retriever with given width, height and retriever bank. Definition at line 181 of file global_retriever.h.
00181 {} |
|
Builds a instance of retriever, and link it on the ground (or wherever)
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 } |
|
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 } |
|
Create a global retriever.
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 } |
|
Delete a global retriever. Definition at line 2409 of file global_retriever.cpp.
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 } |
|
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 } |
|
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).
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 } |
|
Finds an A* path from a given global position to another.
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 } |
|
reset and fill cst.CollisionChains with possible collisions in bboxMove+origin. result: collisionChains, computed localy to origin.
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 } |
|
Finds a path from a given global position to another
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 } |
|
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; } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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]; } |
|
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]; } |
|
Gets the vector of retriever instances that compose the global retriever.
Definition at line 205 of file global_retriever.h.
00205 { return _Instances; } |
|
Definition at line 523 of file global_retriever.h. References _InternalCST. Referenced by NLPACS::CRetrieverInstance::initEdgeQuad().
00523 { return _InternalCST; } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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); } |
|
Get the retriever bank associated to this global retriever.
Definition at line 217 of file global_retriever.h. References _RetrieverBank.
00217 { return _RetrieverBank; } |
|
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 } |
|
Setup an empty global retriever.
|
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Sets the retriever bank.
Definition at line 366 of file global_retriever.h. References _RetrieverBank. Referenced by NLPACS::UGlobalRetriever::createGlobalRetriever().
00366 { _RetrieverBank = bank; } |
|
Test a movement of a bbox against surface world.
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 } |
|
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.
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 } |
|
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 } |
|
Test a movement of a cylinder against surface world.
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 } |
|
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 } |
|
Builds a instance of retriever, and link it on the ground (or wherever)
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 } |
|
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 } |
|
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 } |
|
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); } |
|
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 } |
|
Definition at line 112 of file global_retriever.h. |
|
Definition at line 521 of file global_retriever.h. |
|
The axis aligned bounding box of the global retriever.
Definition at line 165 of file global_retriever.h. |
|
Forbidden instance for retrieve position.
Definition at line 168 of file global_retriever.h. Referenced by retrievePosition(), testCollisionWithCollisionChains(), and testMovementWithCollisionChains(). |
|
The grid of instances.
Definition at line 162 of file global_retriever.h. Referenced by initQuadGrid(), makeInstance(), and selectInstances(). |
|
The instances of the global retriever.
Definition at line 159 of file global_retriever.h. |
|
Definition at line 148 of file global_retriever.h. Referenced by findPath(), getBorders(), getInternalCST(), makeLinks(), refreshLrAround(), refreshLrAroundNow(), retrievePosition(), and testPosition(). |
|
Definition at line 144 of file global_retriever.h. Referenced by refreshLrAround(), and refreshLrAroundNow(). |
|
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(). |
|
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(). |