#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(). |
1.3.6