Blender V2.61 - r43446

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 OVERLAPPING_PAIR_CACHE_H
00017 #define 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 //OVERLAPPING_PAIR_CACHE_H
00468 
00469