2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
16 #ifndef BT_OVERLAPPING_PAIR_CACHE_H
17 #define BT_OVERLAPPING_PAIR_CACHE_H
20 #include "btBroadphaseInterface.h"
21 #include "btBroadphaseProxy.h"
22 #include "btOverlappingPairCallback.h"
24 #include "LinearMath/btAlignedObjectArray.h"
27 typedef btAlignedObjectArray<btBroadphasePair> btBroadphasePairArray;
29 struct btOverlapCallback
31 virtual ~btOverlapCallback()
33 //return true for deletion of the pair
34 virtual bool processOverlap(btBroadphasePair& pair) = 0;
38 struct btOverlapFilterCallback
40 virtual ~btOverlapFilterCallback()
42 // return true when pairs need collision
43 virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0;
52 extern int gRemovePairs;
53 extern int gAddedPairs;
54 extern int gFindPairs;
56 const int BT_NULL_PAIR=0xffffffff;
58 ///The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
59 ///The btHashedOverlappingPairCache and btSortedOverlappingPairCache classes are two implementations.
60 class btOverlappingPairCache : public btOverlappingPairCallback
63 virtual ~btOverlappingPairCache() {} // this is needed so we can get to the derived class destructor
65 virtual btBroadphasePair* getOverlappingPairArrayPtr() = 0;
67 virtual const btBroadphasePair* getOverlappingPairArrayPtr() const = 0;
69 virtual btBroadphasePairArray& getOverlappingPairArray() = 0;
71 virtual void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) = 0;
73 virtual int getNumOverlappingPairs() const = 0;
75 virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) = 0;
77 virtual void setOverlapFilterCallback(btOverlapFilterCallback* callback) = 0;
79 virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher) = 0;
81 virtual btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) = 0;
83 virtual bool hasDeferredRemoval() = 0;
85 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0;
87 virtual void sortOverlappingPairs(btDispatcher* dispatcher) = 0;
92 /// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com
93 class btHashedOverlappingPairCache : public btOverlappingPairCache
95 btBroadphasePairArray m_overlappingPairArray;
96 btOverlapFilterCallback* m_overlapFilterCallback;
97 bool m_blockedForChanges;
101 btHashedOverlappingPairCache();
102 virtual ~btHashedOverlappingPairCache();
105 void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
107 virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
109 SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
111 if (m_overlapFilterCallback)
112 return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
114 bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
115 collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
120 // Add a pair and return the new pair. If the pair already exists,
121 // no new pair is created and the old one is returned.
122 virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
126 if (!needsBroadphaseCollision(proxy0,proxy1))
129 return internalAddPair(proxy0,proxy1);
134 void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
137 virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
139 virtual btBroadphasePair* getOverlappingPairArrayPtr()
141 return &m_overlappingPairArray[0];
144 const btBroadphasePair* getOverlappingPairArrayPtr() const
146 return &m_overlappingPairArray[0];
149 btBroadphasePairArray& getOverlappingPairArray()
151 return m_overlappingPairArray;
154 const btBroadphasePairArray& getOverlappingPairArray() const
156 return m_overlappingPairArray;
159 void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
163 btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1);
165 int GetCount() const { return m_overlappingPairArray.size(); }
166 // btBroadphasePair* GetPairs() { return m_pairs; }
168 btOverlapFilterCallback* getOverlapFilterCallback()
170 return m_overlapFilterCallback;
173 void setOverlapFilterCallback(btOverlapFilterCallback* callback)
175 m_overlapFilterCallback = callback;
178 int getNumOverlappingPairs() const
180 return m_overlappingPairArray.size();
184 btBroadphasePair* internalAddPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
188 SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2)
190 return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2;
194 // Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm
195 // This assumes proxyId1 and proxyId2 are 16-bit.
196 SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2)
198 int key = (proxyId2 << 16) | proxyId1;
199 key = ~key + (key << 15);
200 key = key ^ (key >> 12);
201 key = key + (key << 2);
202 key = key ^ (key >> 4);
204 key = key ^ (key >> 16);
211 SIMD_FORCE_INLINE unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2)
213 int key = static_cast<int>(((unsigned int)proxyId1) | (((unsigned int)proxyId2) <<16));
214 // Thomas Wang's hash
222 return static_cast<unsigned int>(key);
229 SIMD_FORCE_INLINE btBroadphasePair* internalFindPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, int hash)
231 int proxyId1 = proxy0->getUid();
232 int proxyId2 = proxy1->getUid();
233 #if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat.
234 if (proxyId1 > proxyId2)
235 btSwap(proxyId1, proxyId2);
238 int index = m_hashTable[hash];
240 while( index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false)
242 index = m_next[index];
245 if ( index == BT_NULL_PAIR )
250 btAssert(index < m_overlappingPairArray.size());
252 return &m_overlappingPairArray[index];
255 virtual bool hasDeferredRemoval()
260 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
262 m_ghostPairCallback = ghostPairCallback;
265 virtual void sortOverlappingPairs(btDispatcher* dispatcher);
270 btAlignedObjectArray<int> m_hashTable;
271 btAlignedObjectArray<int> m_next;
272 btOverlappingPairCallback* m_ghostPairCallback;
279 ///btSortedOverlappingPairCache maintains the objects with overlapping AABB
280 ///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
281 class btSortedOverlappingPairCache : public btOverlappingPairCache
284 //avoid brute-force finding all the time
285 btBroadphasePairArray m_overlappingPairArray;
287 //during the dispatch, check that user doesn't destroy/create proxy
288 bool m_blockedForChanges;
290 ///by default, do the removal during the pair traversal
291 bool m_hasDeferredRemoval;
293 //if set, use the callback instead of the built in filter in needBroadphaseCollision
294 btOverlapFilterCallback* m_overlapFilterCallback;
296 btOverlappingPairCallback* m_ghostPairCallback;
300 btSortedOverlappingPairCache();
301 virtual ~btSortedOverlappingPairCache();
303 virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
305 void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
307 void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
309 btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
311 btBroadphasePair* findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
314 void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
316 void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
319 inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
321 if (m_overlapFilterCallback)
322 return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
324 bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
325 collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
330 btBroadphasePairArray& getOverlappingPairArray()
332 return m_overlappingPairArray;
335 const btBroadphasePairArray& getOverlappingPairArray() const
337 return m_overlappingPairArray;
343 btBroadphasePair* getOverlappingPairArrayPtr()
345 return &m_overlappingPairArray[0];
348 const btBroadphasePair* getOverlappingPairArrayPtr() const
350 return &m_overlappingPairArray[0];
353 int getNumOverlappingPairs() const
355 return m_overlappingPairArray.size();
358 btOverlapFilterCallback* getOverlapFilterCallback()
360 return m_overlapFilterCallback;
363 void setOverlapFilterCallback(btOverlapFilterCallback* callback)
365 m_overlapFilterCallback = callback;
368 virtual bool hasDeferredRemoval()
370 return m_hasDeferredRemoval;
373 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
375 m_ghostPairCallback = ghostPairCallback;
378 virtual void sortOverlappingPairs(btDispatcher* dispatcher);
385 ///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing.
386 class btNullPairCache : public btOverlappingPairCache
389 btBroadphasePairArray m_overlappingPairArray;
393 virtual btBroadphasePair* getOverlappingPairArrayPtr()
395 return &m_overlappingPairArray[0];
397 const btBroadphasePair* getOverlappingPairArrayPtr() const
399 return &m_overlappingPairArray[0];
401 btBroadphasePairArray& getOverlappingPairArray()
403 return m_overlappingPairArray;
406 virtual void cleanOverlappingPair(btBroadphasePair& /*pair*/,btDispatcher* /*dispatcher*/)
411 virtual int getNumOverlappingPairs() const
416 virtual void cleanProxyFromPairs(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/)
421 virtual void setOverlapFilterCallback(btOverlapFilterCallback* /*callback*/)
425 virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* /*dispatcher*/)
429 virtual btBroadphasePair* findPair(btBroadphaseProxy* /*proxy0*/, btBroadphaseProxy* /*proxy1*/)
434 virtual bool hasDeferredRemoval()
439 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */)
444 virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/)
449 virtual void* removeOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/,btDispatcher* /*dispatcher*/)
454 virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/)
458 virtual void sortOverlappingPairs(btDispatcher* dispatcher)
467 #endif //BT_OVERLAPPING_PAIR_CACHE_H