btOverlappingPairCache.h
Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #ifndef BT_OVERLAPPING_PAIR_CACHE_H
00017 #define BT_OVERLAPPING_PAIR_CACHE_H
00018 
00019 
00020 #include "btBroadphaseInterface.h"
00021 #include "btBroadphaseProxy.h"
00022 #include "btOverlappingPairCallback.h"
00023 
00024 #include "LinearMath/btAlignedObjectArray.h"
00025 class btDispatcher;
00026 
00027 typedef btAlignedObjectArray<btBroadphasePair>  btBroadphasePairArray;
00028 
00029 struct  btOverlapCallback
00030 {
00031         virtual ~btOverlapCallback()
00032         {}
00033         //return true for deletion of the pair
00034         virtual bool    processOverlap(btBroadphasePair& pair) = 0;
00035 
00036 };
00037 
00038 struct btOverlapFilterCallback
00039 {
00040         virtual ~btOverlapFilterCallback()
00041         {}
00042         // return true when pairs need collision
00043         virtual bool    needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0;
00044 };
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 extern int gRemovePairs;
00053 extern int gAddedPairs;
00054 extern int gFindPairs;
00055 
00056 const int BT_NULL_PAIR=0xffffffff;
00057 
00060 class btOverlappingPairCache : public btOverlappingPairCallback
00061 {
00062 public:
00063         virtual ~btOverlappingPairCache() {} // this is needed so we can get to the derived class destructor
00064 
00065         virtual btBroadphasePair*       getOverlappingPairArrayPtr() = 0;
00066         
00067         virtual const btBroadphasePair* getOverlappingPairArrayPtr() const = 0;
00068 
00069         virtual btBroadphasePairArray&  getOverlappingPairArray() = 0;
00070 
00071         virtual void    cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) = 0;
00072 
00073         virtual int getNumOverlappingPairs() const = 0;
00074 
00075         virtual void    cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) = 0;
00076 
00077         virtual void setOverlapFilterCallback(btOverlapFilterCallback* callback) = 0;
00078 
00079         virtual void    processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher) = 0;
00080 
00081         virtual btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) = 0;
00082 
00083         virtual bool    hasDeferredRemoval() = 0;
00084 
00085         virtual void    setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0;
00086 
00087         virtual void    sortOverlappingPairs(btDispatcher* dispatcher) = 0;
00088 
00089 
00090 };
00091 
00093 class btHashedOverlappingPairCache : public btOverlappingPairCache
00094 {
00095         btBroadphasePairArray   m_overlappingPairArray;
00096         btOverlapFilterCallback* m_overlapFilterCallback;
00097         bool            m_blockedForChanges;
00098 
00099 
00100 public:
00101         btHashedOverlappingPairCache();
00102         virtual ~btHashedOverlappingPairCache();
00103 
00104         
00105         void    removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
00106 
00107         virtual void*   removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
00108         
00109         SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
00110         {
00111                 if (m_overlapFilterCallback)
00112                         return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
00113 
00114                 bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
00115                 collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
00116                 
00117                 return collides;
00118         }
00119 
00120         // Add a pair and return the new pair. If the pair already exists,
00121         // no new pair is created and the old one is returned.
00122         virtual btBroadphasePair*       addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
00123         {
00124                 gAddedPairs++;
00125 
00126                 if (!needsBroadphaseCollision(proxy0,proxy1))
00127                         return 0;
00128 
00129                 return internalAddPair(proxy0,proxy1);
00130         }
00131 
00132         
00133 
00134         void    cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
00135 
00136         
00137         virtual void    processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
00138 
00139         virtual btBroadphasePair*       getOverlappingPairArrayPtr()
00140         {
00141                 return &m_overlappingPairArray[0];
00142         }
00143 
00144         const btBroadphasePair* getOverlappingPairArrayPtr() const
00145         {
00146                 return &m_overlappingPairArray[0];
00147         }
00148 
00149         btBroadphasePairArray&  getOverlappingPairArray()
00150         {
00151                 return m_overlappingPairArray;
00152         }
00153 
00154         const btBroadphasePairArray&    getOverlappingPairArray() const
00155         {
00156                 return m_overlappingPairArray;
00157         }
00158 
00159         void    cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
00160 
00161 
00162 
00163         btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1);
00164 
00165         int GetCount() const { return m_overlappingPairArray.size(); }
00166 //      btBroadphasePair* GetPairs() { return m_pairs; }
00167 
00168         btOverlapFilterCallback* getOverlapFilterCallback()
00169         {
00170                 return m_overlapFilterCallback;
00171         }
00172 
00173         void setOverlapFilterCallback(btOverlapFilterCallback* callback)
00174         {
00175                 m_overlapFilterCallback = callback;
00176         }
00177 
00178         int     getNumOverlappingPairs() const
00179         {
00180                 return m_overlappingPairArray.size();
00181         }
00182 private:
00183         
00184         btBroadphasePair*       internalAddPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
00185 
00186         void    growTables();
00187 
00188         SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2)
00189         {       
00190                 return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2;
00191         }
00192 
00193         /*
00194         // Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm
00195         // This assumes proxyId1 and proxyId2 are 16-bit.
00196         SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2)
00197         {
00198                 int key = (proxyId2 << 16) | proxyId1;
00199                 key = ~key + (key << 15);
00200                 key = key ^ (key >> 12);
00201                 key = key + (key << 2);
00202                 key = key ^ (key >> 4);
00203                 key = key * 2057;
00204                 key = key ^ (key >> 16);
00205                 return key;
00206         }
00207         */
00208 
00209 
00210         
00211         SIMD_FORCE_INLINE       unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2)
00212         {
00213                 int key = static_cast<int>(((unsigned int)proxyId1) | (((unsigned int)proxyId2) <<16));
00214                 // Thomas Wang's hash
00215 
00216                 key += ~(key << 15);
00217                 key ^=  (key >> 10);
00218                 key +=  (key << 3);
00219                 key ^=  (key >> 6);
00220                 key += ~(key << 11);
00221                 key ^=  (key >> 16);
00222                 return static_cast<unsigned int>(key);
00223         }
00224         
00225 
00226 
00227 
00228 
00229         SIMD_FORCE_INLINE btBroadphasePair* internalFindPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, int hash)
00230         {
00231                 int proxyId1 = proxy0->getUid();
00232                 int proxyId2 = proxy1->getUid();
00233                 #if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat.
00234                 if (proxyId1 > proxyId2) 
00235                         btSwap(proxyId1, proxyId2);
00236                 #endif
00237 
00238                 int index = m_hashTable[hash];
00239                 
00240                 while( index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false)
00241                 {
00242                         index = m_next[index];
00243                 }
00244 
00245                 if ( index == BT_NULL_PAIR )
00246                 {
00247                         return NULL;
00248                 }
00249 
00250                 btAssert(index < m_overlappingPairArray.size());
00251 
00252                 return &m_overlappingPairArray[index];
00253         }
00254 
00255         virtual bool    hasDeferredRemoval()
00256         {
00257                 return false;
00258         }
00259 
00260         virtual void    setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
00261         {
00262                 m_ghostPairCallback = ghostPairCallback;
00263         }
00264 
00265         virtual void    sortOverlappingPairs(btDispatcher* dispatcher);
00266         
00267 
00268 protected:
00269         
00270         btAlignedObjectArray<int>       m_hashTable;
00271         btAlignedObjectArray<int>       m_next;
00272         btOverlappingPairCallback*      m_ghostPairCallback;
00273         
00274 };
00275 
00276 
00277 
00278 
00281 class   btSortedOverlappingPairCache : public btOverlappingPairCache
00282 {
00283         protected:
00284                 //avoid brute-force finding all the time
00285                 btBroadphasePairArray   m_overlappingPairArray;
00286 
00287                 //during the dispatch, check that user doesn't destroy/create proxy
00288                 bool            m_blockedForChanges;
00289 
00291                 bool            m_hasDeferredRemoval;
00292                 
00293                 //if set, use the callback instead of the built in filter in needBroadphaseCollision
00294                 btOverlapFilterCallback* m_overlapFilterCallback;
00295 
00296                 btOverlappingPairCallback*      m_ghostPairCallback;
00297 
00298         public:
00299                         
00300                 btSortedOverlappingPairCache(); 
00301                 virtual ~btSortedOverlappingPairCache();
00302 
00303                 virtual void    processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
00304 
00305                 void*   removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
00306 
00307                 void    cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
00308                 
00309                 btBroadphasePair*       addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
00310 
00311                 btBroadphasePair*       findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
00312                         
00313                 
00314                 void    cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
00315 
00316                 void    removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
00317 
00318 
00319                 inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
00320                 {
00321                         if (m_overlapFilterCallback)
00322                                 return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
00323 
00324                         bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
00325                         collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
00326                         
00327                         return collides;
00328                 }
00329                 
00330                 btBroadphasePairArray&  getOverlappingPairArray()
00331                 {
00332                         return m_overlappingPairArray;
00333                 }
00334 
00335                 const btBroadphasePairArray&    getOverlappingPairArray() const
00336                 {
00337                         return m_overlappingPairArray;
00338                 }
00339 
00340                 
00341 
00342 
00343                 btBroadphasePair*       getOverlappingPairArrayPtr()
00344                 {
00345                         return &m_overlappingPairArray[0];
00346                 }
00347 
00348                 const btBroadphasePair* getOverlappingPairArrayPtr() const
00349                 {
00350                         return &m_overlappingPairArray[0];
00351                 }
00352 
00353                 int     getNumOverlappingPairs() const
00354                 {
00355                         return m_overlappingPairArray.size();
00356                 }
00357                 
00358                 btOverlapFilterCallback* getOverlapFilterCallback()
00359                 {
00360                         return m_overlapFilterCallback;
00361                 }
00362 
00363                 void setOverlapFilterCallback(btOverlapFilterCallback* callback)
00364                 {
00365                         m_overlapFilterCallback = callback;
00366                 }
00367 
00368                 virtual bool    hasDeferredRemoval()
00369                 {
00370                         return m_hasDeferredRemoval;
00371                 }
00372 
00373                 virtual void    setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
00374                 {
00375                         m_ghostPairCallback = ghostPairCallback;
00376                 }
00377 
00378                 virtual void    sortOverlappingPairs(btDispatcher* dispatcher);
00379                 
00380 
00381 };
00382 
00383 
00384 
00386 class btNullPairCache : public btOverlappingPairCache
00387 {
00388 
00389         btBroadphasePairArray   m_overlappingPairArray;
00390 
00391 public:
00392 
00393         virtual btBroadphasePair*       getOverlappingPairArrayPtr()
00394         {
00395                 return &m_overlappingPairArray[0];
00396         }
00397         const btBroadphasePair* getOverlappingPairArrayPtr() const
00398         {
00399                 return &m_overlappingPairArray[0];
00400         }
00401         btBroadphasePairArray&  getOverlappingPairArray()
00402         {
00403                 return m_overlappingPairArray;
00404         }
00405         
00406         virtual void    cleanOverlappingPair(btBroadphasePair& /*pair*/,btDispatcher* /*dispatcher*/)
00407         {
00408 
00409         }
00410 
00411         virtual int getNumOverlappingPairs() const
00412         {
00413                 return 0;
00414         }
00415 
00416         virtual void    cleanProxyFromPairs(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/)
00417         {
00418 
00419         }
00420 
00421         virtual void setOverlapFilterCallback(btOverlapFilterCallback* /*callback*/)
00422         {
00423         }
00424 
00425         virtual void    processAllOverlappingPairs(btOverlapCallback*,btDispatcher* /*dispatcher*/)
00426         {
00427         }
00428 
00429         virtual btBroadphasePair* findPair(btBroadphaseProxy* /*proxy0*/, btBroadphaseProxy* /*proxy1*/)
00430         {
00431                 return 0;
00432         }
00433 
00434         virtual bool    hasDeferredRemoval()
00435         {
00436                 return true;
00437         }
00438 
00439         virtual void    setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */)
00440         {
00441 
00442         }
00443 
00444         virtual btBroadphasePair*       addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/)
00445         {
00446                 return 0;
00447         }
00448 
00449         virtual void*   removeOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/,btDispatcher* /*dispatcher*/)
00450         {
00451                 return 0;
00452         }
00453 
00454         virtual void    removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/)
00455         {
00456         }
00457         
00458         virtual void    sortOverlappingPairs(btDispatcher* dispatcher)
00459         {
00460         (void) dispatcher;
00461         }
00462 
00463 
00464 };
00465 
00466 
00467 #endif //BT_OVERLAPPING_PAIR_CACHE_H
00468 
00469 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


bullet
Author(s): Erwin Coumans, ROS package maintained by Tully Foote
autogenerated on Wed Oct 31 2012 07:54:31