Bullet Collision Detection & Physics Library
btOverlappingPairCache.h
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#ifndef BT_OVERLAPPING_PAIR_CACHE_H
17#define BT_OVERLAPPING_PAIR_CACHE_H
18
20#include "btBroadphaseProxy.h"
22
24class btDispatcher;
25
27
29{
31 {
32 }
33 //return true for deletion of the pair
34 virtual bool processOverlap(btBroadphasePair& pair) = 0;
35};
36
38{
40 {
41 }
42 // return true when pairs need collision
43 virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const = 0;
44};
45
46const int BT_NULL_PAIR = 0xffffffff;
47
51{
52public:
53 virtual ~btOverlappingPairCache() {} // this is needed so we can get to the derived class destructor
54
56
57 virtual const btBroadphasePair* getOverlappingPairArrayPtr() const = 0;
58
60
61 virtual void cleanOverlappingPair(btBroadphasePair& pair, btDispatcher* dispatcher) = 0;
62
63 virtual int getNumOverlappingPairs() const = 0;
64 virtual bool needsBroadphaseCollision(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1) const = 0;
66 virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy, btDispatcher* dispatcher) = 0;
67
69
71
72 virtual void processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher, const struct btDispatcherInfo& /*dispatchInfo*/)
73 {
74 processAllOverlappingPairs(callback, dispatcher);
75 }
77
78 virtual bool hasDeferredRemoval() = 0;
79
80 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback) = 0;
81
82 virtual void sortOverlappingPairs(btDispatcher* dispatcher) = 0;
83};
84
86
89{
92
93protected:
97
98public:
100
103
104 void removeOverlappingPairsContainingProxy(btBroadphaseProxy * proxy, btDispatcher * dispatcher);
105
106 virtual void* removeOverlappingPair(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1, btDispatcher * dispatcher);
107
109 {
110 if (m_overlapFilterCallback)
111 return m_overlapFilterCallback->needBroadphaseCollision(proxy0, proxy1);
112
113 bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
114 collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
115
116 return collides;
117 }
118
119 // Add a pair and return the new pair. If the pair already exists,
120 // no new pair is created and the old one is returned.
122 {
123 if (!needsBroadphaseCollision(proxy0, proxy1))
124 return 0;
125
126 return internalAddPair(proxy0, proxy1);
127 }
128
129 void cleanProxyFromPairs(btBroadphaseProxy * proxy, btDispatcher * dispatcher);
130
131 virtual void processAllOverlappingPairs(btOverlapCallback*, btDispatcher * dispatcher);
132
133 virtual void processAllOverlappingPairs(btOverlapCallback * callback, btDispatcher * dispatcher, const struct btDispatcherInfo& dispatchInfo);
134
136 {
137 return &m_overlappingPairArray[0];
138 }
139
141 {
142 return &m_overlappingPairArray[0];
143 }
144
146 {
147 return m_overlappingPairArray;
148 }
149
151 {
152 return m_overlappingPairArray;
153 }
154
155 void cleanOverlappingPair(btBroadphasePair & pair, btDispatcher * dispatcher);
156
157 btBroadphasePair* findPair(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1);
158
159 int GetCount() const { return m_overlappingPairArray.size(); }
160 // btBroadphasePair* GetPairs() { return m_pairs; }
161
163 {
164 return m_overlapFilterCallback;
165 }
166
168 {
169 m_overlapFilterCallback = callback;
170 }
171
173 {
174 return m_overlappingPairArray.size();
175 }
176
177private:
178 btBroadphasePair* internalAddPair(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1);
179
180 void growTables();
181
182 SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2)
183 {
184 return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2;
185 }
186
187 /*
188 // Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm
189 // This assumes proxyId1 and proxyId2 are 16-bit.
190 SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2)
191 {
192 int key = (proxyId2 << 16) | proxyId1;
193 key = ~key + (key << 15);
194 key = key ^ (key >> 12);
195 key = key + (key << 2);
196 key = key ^ (key >> 4);
197 key = key * 2057;
198 key = key ^ (key >> 16);
199 return key;
200 }
201 */
202
203 SIMD_FORCE_INLINE unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2)
204 {
205 unsigned int key = proxyId1 | (proxyId2 << 16);
206 // Thomas Wang's hash
207
208 key += ~(key << 15);
209 key ^= (key >> 10);
210 key += (key << 3);
211 key ^= (key >> 6);
212 key += ~(key << 11);
213 key ^= (key >> 16);
214 return key;
215 }
216
218 {
219 int proxyId1 = proxy0->getUid();
220 int proxyId2 = proxy1->getUid();
221#if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat.
222 if (proxyId1 > proxyId2)
223 btSwap(proxyId1, proxyId2);
224#endif
225
226 int index = m_hashTable[hash];
227
228 while (index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false)
229 {
230 index = m_next[index];
231 }
232
233 if (index == BT_NULL_PAIR)
234 {
235 return NULL;
236 }
237
238 btAssert(index < m_overlappingPairArray.size());
239
240 return &m_overlappingPairArray[index];
241 }
242
243 virtual bool hasDeferredRemoval()
244 {
245 return false;
246 }
247
249 {
250 m_ghostPairCallback = ghostPairCallback;
251 }
252
253 virtual void sortOverlappingPairs(btDispatcher * dispatcher);
254};
255
259{
260protected:
261 //avoid brute-force finding all the time
263
264 //during the dispatch, check that user doesn't destroy/create proxy
266
269
270 //if set, use the callback instead of the built in filter in needBroadphaseCollision
272
274
275public:
278
280
281 void* removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, btDispatcher* dispatcher);
282
283 void cleanOverlappingPair(btBroadphasePair& pair, btDispatcher* dispatcher);
284
286
288
289 void cleanProxyFromPairs(btBroadphaseProxy* proxy, btDispatcher* dispatcher);
290
292
294 {
296 return m_overlapFilterCallback->needBroadphaseCollision(proxy0, proxy1);
297
298 bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
299 collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
300
301 return collides;
302 }
303
305 {
307 }
308
310 {
312 }
313
315 {
316 return &m_overlappingPairArray[0];
317 }
318
320 {
321 return &m_overlappingPairArray[0];
322 }
323
325 {
327 }
328
330 {
332 }
333
335 {
336 m_overlapFilterCallback = callback;
337 }
338
339 virtual bool hasDeferredRemoval()
340 {
342 }
343
345 {
346 m_ghostPairCallback = ghostPairCallback;
347 }
348
349 virtual void sortOverlappingPairs(btDispatcher* dispatcher);
350};
351
354{
356
357public:
359 {
360 return &m_overlappingPairArray[0];
361 }
363 {
364 return &m_overlappingPairArray[0];
365 }
367 {
369 }
370
371 virtual void cleanOverlappingPair(btBroadphasePair& /*pair*/, btDispatcher* /*dispatcher*/)
372 {
373 }
374
375 virtual int getNumOverlappingPairs() const
376 {
377 return 0;
378 }
379
380 virtual void cleanProxyFromPairs(btBroadphaseProxy* /*proxy*/, btDispatcher* /*dispatcher*/)
381 {
382 }
383
385 {
386 return true;
387 }
389 {
390 return 0;
391 }
393 {
394 }
395
397 {
398 }
399
401 {
402 return 0;
403 }
404
405 virtual bool hasDeferredRemoval()
406 {
407 return true;
408 }
409
410 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */)
411 {
412 }
413
415 {
416 return 0;
417 }
418
419 virtual void* removeOverlappingPair(btBroadphaseProxy* /*proxy0*/, btBroadphaseProxy* /*proxy1*/, btDispatcher* /*dispatcher*/)
420 {
421 return 0;
422 }
423
425 {
426 }
427
428 virtual void sortOverlappingPairs(btDispatcher* dispatcher)
429 {
430 (void)dispatcher;
431 }
432};
433
434#endif //BT_OVERLAPPING_PAIR_CACHE_H
btAlignedObjectArray< btBroadphasePair > btBroadphasePairArray
const int BT_NULL_PAIR
#define ATTRIBUTE_ALIGNED16(a)
Definition: btScalar.h:99
#define SIMD_FORCE_INLINE
Definition: btScalar.h:98
void btSwap(T &a, T &b)
Definition: btScalar.h:643
#define btAssert(x)
Definition: btScalar.h:153
int size() const
return the number of elements in the array
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:77
Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman,...
const btBroadphasePair * getOverlappingPairArrayPtr() const
btAlignedObjectArray< int > m_next
btBroadphasePairArray m_overlappingPairArray
btOverlapFilterCallback * m_overlapFilterCallback
btBroadphasePair * internalFindPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, int hash)
virtual btBroadphasePair * addOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
const btBroadphasePairArray & getOverlappingPairArray() const
virtual btBroadphasePair * getOverlappingPairArrayPtr()
bool equalsPair(const btBroadphasePair &pair, int proxyId1, int proxyId2)
void setOverlapFilterCallback(btOverlapFilterCallback *callback)
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *ghostPairCallback)
unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2)
btAlignedObjectArray< int > m_hashTable
btOverlapFilterCallback * getOverlapFilterCallback()
btOverlappingPairCallback * m_ghostPairCallback
btBroadphasePairArray & getOverlappingPairArray()
bool needsBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing.
btOverlapFilterCallback * getOverlapFilterCallback()
virtual void sortOverlappingPairs(btDispatcher *dispatcher)
virtual void cleanOverlappingPair(btBroadphasePair &, btDispatcher *)
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *)
btBroadphasePairArray m_overlappingPairArray
bool needsBroadphaseCollision(btBroadphaseProxy *, btBroadphaseProxy *) const
virtual void setOverlapFilterCallback(btOverlapFilterCallback *)
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *)
virtual btBroadphasePair * findPair(btBroadphaseProxy *, btBroadphaseProxy *)
virtual int getNumOverlappingPairs() const
virtual void * removeOverlappingPair(btBroadphaseProxy *, btBroadphaseProxy *, btDispatcher *)
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy *, btDispatcher *)
virtual bool hasDeferredRemoval()
btBroadphasePairArray & getOverlappingPairArray()
virtual btBroadphasePair * getOverlappingPairArrayPtr()
virtual void cleanProxyFromPairs(btBroadphaseProxy *, btDispatcher *)
virtual btBroadphasePair * addOverlappingPair(btBroadphaseProxy *, btBroadphaseProxy *)
const btBroadphasePair * getOverlappingPairArrayPtr() const
The btOverlappingPairCache provides an interface for overlapping pair management (add,...
virtual btBroadphasePairArray & getOverlappingPairArray()=0
virtual int getNumOverlappingPairs() const =0
virtual void cleanProxyFromPairs(btBroadphaseProxy *proxy, btDispatcher *dispatcher)=0
virtual void setOverlapFilterCallback(btOverlapFilterCallback *callback)=0
virtual btBroadphasePair * getOverlappingPairArrayPtr()=0
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *dispatcher)=0
virtual btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
virtual void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)=0
virtual void sortOverlappingPairs(btDispatcher *dispatcher)=0
virtual bool needsBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const =0
virtual const btBroadphasePair * getOverlappingPairArrayPtr() const =0
virtual btOverlapFilterCallback * getOverlapFilterCallback()=0
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *ghostPairCallback)=0
virtual bool hasDeferredRemoval()=0
virtual void processAllOverlappingPairs(btOverlapCallback *callback, btDispatcher *dispatcher, const struct btDispatcherInfo &)
The btOverlappingPairCallback class is an additional optional broadphase user callback for adding/rem...
btSortedOverlappingPairCache maintains the objects with overlapping AABB Typically managed by the Bro...
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *dispatcher)
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *ghostPairCallback)
btOverlapFilterCallback * getOverlapFilterCallback()
btBroadphasePair * addOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
btBroadphasePair * getOverlappingPairArrayPtr()
btOverlapFilterCallback * m_overlapFilterCallback
btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
this findPair becomes really slow.
bool needsBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
void removeOverlappingPairsContainingProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
btOverlappingPairCallback * m_ghostPairCallback
const btBroadphasePair * getOverlappingPairArrayPtr() const
btBroadphasePairArray & getOverlappingPairArray()
void setOverlapFilterCallback(btOverlapFilterCallback *callback)
void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)
void * removeOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, btDispatcher *dispatcher)
bool m_hasDeferredRemoval
by default, do the removal during the pair traversal
btBroadphasePairArray m_overlappingPairArray
void cleanProxyFromPairs(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
virtual void sortOverlappingPairs(btDispatcher *dispatcher)
const btBroadphasePairArray & getOverlappingPairArray() const
The btBroadphasePair class contains a pair of aabb-overlapping objects.
btBroadphaseProxy * m_pProxy1
btBroadphaseProxy * m_pProxy0
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
virtual bool processOverlap(btBroadphasePair &pair)=0
virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const =0