Bullet Collision Detection & Physics Library
btOverlappingPairCache.h
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4 
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:
10 
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.
14 */
15 
16 #ifndef BT_OVERLAPPING_PAIR_CACHE_H
17 #define BT_OVERLAPPING_PAIR_CACHE_H
18 
19 #include "btBroadphaseInterface.h"
20 #include "btBroadphaseProxy.h"
22 
24 class 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 
46 const int BT_NULL_PAIR = 0xffffffff;
47 
51 {
52 public:
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 
93 protected:
97 
98 public:
100 
102  virtual ~btHashedOverlappingPairCache();
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 
177 private:
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 
248  virtual void setInternalGhostPairCallback(btOverlappingPairCallback * ghostPairCallback)
249  {
250  m_ghostPairCallback = ghostPairCallback;
251  }
252 
253  virtual void sortOverlappingPairs(btDispatcher * dispatcher);
254 };
255 
259 {
260 protected:
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 
275 public:
278 
279  virtual void processAllOverlappingPairs(btOverlapCallback*, btDispatcher* dispatcher);
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  {
306  return m_overlappingPairArray;
307  }
308 
310  {
311  return m_overlappingPairArray;
312  }
313 
315  {
316  return &m_overlappingPairArray[0];
317  }
318 
320  {
321  return &m_overlappingPairArray[0];
322  }
323 
325  {
326  return m_overlappingPairArray.size();
327  }
328 
330  {
332  }
333 
335  {
336  m_overlapFilterCallback = callback;
337  }
338 
339  virtual bool hasDeferredRemoval()
340  {
341  return m_hasDeferredRemoval;
342  }
343 
345  {
346  m_ghostPairCallback = ghostPairCallback;
347  }
348 
349  virtual void sortOverlappingPairs(btDispatcher* dispatcher);
350 };
351 
354 {
356 
357 public:
359  {
360  return &m_overlappingPairArray[0];
361  }
363  {
364  return &m_overlappingPairArray[0];
365  }
367  {
368  return m_overlappingPairArray;
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 
424  virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/, btDispatcher* /*dispatcher*/)
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,...
btAlignedObjectArray< int > m_next
btBroadphasePairArray m_overlappingPairArray
btOverlapFilterCallback * getOverlapFilterCallback()
const btBroadphasePair * getOverlappingPairArrayPtr() const
btOverlapFilterCallback * m_overlapFilterCallback
bool equalsPair(const btBroadphasePair &pair, int proxyId1, int proxyId2)
virtual btBroadphasePair * addOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
void setOverlapFilterCallback(btOverlapFilterCallback *callback)
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *ghostPairCallback)
virtual btBroadphasePair * getOverlappingPairArrayPtr()
btBroadphasePairArray & getOverlappingPairArray()
unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2)
const btBroadphasePairArray & getOverlappingPairArray() const
btAlignedObjectArray< int > m_hashTable
btOverlappingPairCallback * m_ghostPairCallback
btBroadphasePair * internalFindPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, int hash)
bool needsBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing.
virtual void sortOverlappingPairs(btDispatcher *dispatcher)
virtual btBroadphasePair * findPair(btBroadphaseProxy *, btBroadphaseProxy *)
virtual void cleanOverlappingPair(btBroadphasePair &, btDispatcher *)
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *)
const btBroadphasePair * getOverlappingPairArrayPtr() const
virtual void * removeOverlappingPair(btBroadphaseProxy *, btBroadphaseProxy *, btDispatcher *)
btBroadphasePairArray m_overlappingPairArray
virtual btBroadphasePair * getOverlappingPairArrayPtr()
bool needsBroadphaseCollision(btBroadphaseProxy *, btBroadphaseProxy *) const
virtual void setOverlapFilterCallback(btOverlapFilterCallback *)
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *)
virtual btBroadphasePair * addOverlappingPair(btBroadphaseProxy *, btBroadphaseProxy *)
virtual int getNumOverlappingPairs() const
btOverlapFilterCallback * getOverlapFilterCallback()
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy *, btDispatcher *)
virtual bool hasDeferredRemoval()
btBroadphasePairArray & getOverlappingPairArray()
virtual void cleanProxyFromPairs(btBroadphaseProxy *, btDispatcher *)
The btOverlappingPairCache provides an interface for overlapping pair management (add,...
virtual int getNumOverlappingPairs() const =0
virtual void cleanProxyFromPairs(btBroadphaseProxy *proxy, btDispatcher *dispatcher)=0
virtual void setOverlapFilterCallback(btOverlapFilterCallback *callback)=0
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *dispatcher)=0
virtual btOverlapFilterCallback * getOverlapFilterCallback()=0
virtual btBroadphasePair * getOverlappingPairArrayPtr()=0
virtual const btBroadphasePair * getOverlappingPairArrayPtr() const =0
virtual void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)=0
virtual btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
virtual void sortOverlappingPairs(btDispatcher *dispatcher)=0
virtual bool needsBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const =0
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *ghostPairCallback)=0
virtual bool hasDeferredRemoval()=0
virtual void processAllOverlappingPairs(btOverlapCallback *callback, btDispatcher *dispatcher, const struct btDispatcherInfo &)
virtual btBroadphasePairArray & getOverlappingPairArray()=0
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)
btBroadphasePair * getOverlappingPairArrayPtr()
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *ghostPairCallback)
btBroadphasePair * addOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
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
void setOverlapFilterCallback(btOverlapFilterCallback *callback)
void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)
const btBroadphasePair * getOverlappingPairArrayPtr() const
void * removeOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, btDispatcher *dispatcher)
bool m_hasDeferredRemoval
by default, do the removal during the pair traversal
btOverlapFilterCallback * getOverlapFilterCallback()
btBroadphasePairArray m_overlappingPairArray
void cleanProxyFromPairs(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
virtual void sortOverlappingPairs(btDispatcher *dispatcher)
btBroadphasePairArray & getOverlappingPairArray()
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