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 
20 #include "btBroadphaseInterface.h"
21 #include "btBroadphaseProxy.h"
23 
26 
28 
30 {
32  {}
33  //return true for deletion of the pair
34  virtual bool processOverlap(btBroadphasePair& pair) = 0;
35 
36 };
37 
39 {
41  {}
42  // return true when pairs need collision
43  virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0;
44 };
45 
46 
47 
48 
49 
50 
51 
52 extern int gRemovePairs;
53 extern int gAddedPairs;
54 extern int gFindPairs;
55 
56 const int BT_NULL_PAIR=0xffffffff;
57 
61 {
62 public:
63  virtual ~btOverlappingPairCache() {} // this is needed so we can get to the derived class destructor
64 
66 
67  virtual const btBroadphasePair* getOverlappingPairArrayPtr() const = 0;
68 
70 
71  virtual void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) = 0;
72 
73  virtual int getNumOverlappingPairs() const = 0;
74 
75  virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) = 0;
76 
77  virtual void setOverlapFilterCallback(btOverlapFilterCallback* callback) = 0;
78 
79  virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher) = 0;
80 
81  virtual btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) = 0;
82 
83  virtual bool hasDeferredRemoval() = 0;
84 
85  virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0;
86 
87  virtual void sortOverlappingPairs(btDispatcher* dispatcher) = 0;
88 
89 
90 };
91 
94 {
98 
99 protected:
100 
104 
105 
106 public:
109 
110 
112 
113  virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
114 
116  {
118  return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
119 
120  bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
121  collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
122 
123  return collides;
124  }
125 
126  // Add a pair and return the new pair. If the pair already exists,
127  // no new pair is created and the old one is returned.
129  {
130  gAddedPairs++;
131 
132  if (!needsBroadphaseCollision(proxy0,proxy1))
133  return 0;
134 
135  return internalAddPair(proxy0,proxy1);
136  }
137 
138 
139 
140  void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
141 
142 
143  virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
144 
146  {
147  return &m_overlappingPairArray[0];
148  }
149 
151  {
152  return &m_overlappingPairArray[0];
153  }
154 
156  {
157  return m_overlappingPairArray;
158  }
159 
161  {
162  return m_overlappingPairArray;
163  }
164 
165  void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
166 
167 
168 
170 
171  int GetCount() const { return m_overlappingPairArray.size(); }
172 // btBroadphasePair* GetPairs() { return m_pairs; }
173 
175  {
177  }
178 
180  {
181  m_overlapFilterCallback = callback;
182  }
183 
185  {
186  return m_overlappingPairArray.size();
187  }
188 private:
189 
191 
192  void growTables();
193 
194  SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2)
195  {
196  return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2;
197  }
198 
199  /*
200  // Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm
201  // This assumes proxyId1 and proxyId2 are 16-bit.
202  SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2)
203  {
204  int key = (proxyId2 << 16) | proxyId1;
205  key = ~key + (key << 15);
206  key = key ^ (key >> 12);
207  key = key + (key << 2);
208  key = key ^ (key >> 4);
209  key = key * 2057;
210  key = key ^ (key >> 16);
211  return key;
212  }
213  */
214 
215 
216 
217  SIMD_FORCE_INLINE unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2)
218  {
219  int key = static_cast<int>(((unsigned int)proxyId1) | (((unsigned int)proxyId2) <<16));
220  // Thomas Wang's hash
221 
222  key += ~(key << 15);
223  key ^= (key >> 10);
224  key += (key << 3);
225  key ^= (key >> 6);
226  key += ~(key << 11);
227  key ^= (key >> 16);
228  return static_cast<unsigned int>(key);
229  }
230 
231 
232 
233 
234 
236  {
237  int proxyId1 = proxy0->getUid();
238  int proxyId2 = proxy1->getUid();
239  #if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat.
240  if (proxyId1 > proxyId2)
241  btSwap(proxyId1, proxyId2);
242  #endif
243 
244  int index = m_hashTable[hash];
245 
246  while( index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false)
247  {
248  index = m_next[index];
249  }
250 
251  if ( index == BT_NULL_PAIR )
252  {
253  return NULL;
254  }
255 
257 
258  return &m_overlappingPairArray[index];
259  }
260 
261  virtual bool hasDeferredRemoval()
262  {
263  return false;
264  }
265 
267  {
268  m_ghostPairCallback = ghostPairCallback;
269  }
270 
271  virtual void sortOverlappingPairs(btDispatcher* dispatcher);
272 
273 
274 
275 };
276 
277 
278 
279 
283 {
284  protected:
285  //avoid brute-force finding all the time
287 
288  //during the dispatch, check that user doesn't destroy/create proxy
290 
293 
294  //if set, use the callback instead of the built in filter in needBroadphaseCollision
296 
298 
299  public:
300 
303 
304  virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
305 
306  void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
307 
308  void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
309 
311 
313 
314 
315  void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
316 
318 
319 
321  {
323  return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
324 
325  bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
326  collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
327 
328  return collides;
329  }
330 
332  {
333  return m_overlappingPairArray;
334  }
335 
337  {
338  return m_overlappingPairArray;
339  }
340 
341 
342 
343 
345  {
346  return &m_overlappingPairArray[0];
347  }
348 
350  {
351  return &m_overlappingPairArray[0];
352  }
353 
355  {
356  return m_overlappingPairArray.size();
357  }
358 
360  {
362  }
363 
365  {
366  m_overlapFilterCallback = callback;
367  }
368 
369  virtual bool hasDeferredRemoval()
370  {
371  return m_hasDeferredRemoval;
372  }
373 
375  {
376  m_ghostPairCallback = ghostPairCallback;
377  }
378 
379  virtual void sortOverlappingPairs(btDispatcher* dispatcher);
380 
381 
382 };
383 
384 
385 
388 {
389 
391 
392 public:
393 
395  {
396  return &m_overlappingPairArray[0];
397  }
399  {
400  return &m_overlappingPairArray[0];
401  }
403  {
404  return m_overlappingPairArray;
405  }
406 
407  virtual void cleanOverlappingPair(btBroadphasePair& /*pair*/,btDispatcher* /*dispatcher*/)
408  {
409 
410  }
411 
412  virtual int getNumOverlappingPairs() const
413  {
414  return 0;
415  }
416 
417  virtual void cleanProxyFromPairs(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/)
418  {
419 
420  }
421 
423  {
424  }
425 
427  {
428  }
429 
431  {
432  return 0;
433  }
434 
435  virtual bool hasDeferredRemoval()
436  {
437  return true;
438  }
439 
440  virtual void setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */)
441  {
442 
443  }
444 
446  {
447  return 0;
448  }
449 
450  virtual void* removeOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/,btDispatcher* /*dispatcher*/)
451  {
452  return 0;
453  }
454 
455  virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/)
456  {
457  }
458 
459  virtual void sortOverlappingPairs(btDispatcher* dispatcher)
460  {
461  (void) dispatcher;
462  }
463 
464 
465 };
466 
467 
468 #endif //BT_OVERLAPPING_PAIR_CACHE_H
469 
470 
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *dispatcher)
const btBroadphasePair * getOverlappingPairArrayPtr() const
virtual void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)=0
btOverlapFilterCallback * getOverlapFilterCallback()
bool needsBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
btOverlapFilterCallback * m_overlapFilterCallback
const int BT_NULL_PAIR
virtual bool hasDeferredRemoval()=0
btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing...
short int m_collisionFilterGroup
btBroadphasePair * internalFindPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, int hash)
virtual void sortOverlappingPairs(btDispatcher *dispatcher)=0
btAlignedObjectArray< int > m_hashTable
#define btAssert(x)
Definition: btScalar.h:101
virtual bool hasDeferredRemoval()
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *ghostPairCallback)=0
btBroadphasePairArray & getOverlappingPairArray()
btOverlappingPairCallback * m_ghostPairCallback
virtual void setOverlapFilterCallback(btOverlapFilterCallback *callback)=0
#define SIMD_FORCE_INLINE
Definition: btScalar.h:58
btBroadphasePairArray m_overlappingPairArray
bool equalsPair(const btBroadphasePair &pair, int proxyId1, int proxyId2)
bool needsBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
btOverlappingPairCallback * m_ghostPairCallback
btOverlapFilterCallback * m_overlapFilterCallback
void cleanProxyFromPairs(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
virtual void cleanProxyFromPairs(btBroadphaseProxy *, btDispatcher *)
const btBroadphasePair * getOverlappingPairArrayPtr() const
virtual btBroadphasePair * getOverlappingPairArrayPtr()
void setOverlapFilterCallback(btOverlapFilterCallback *callback)
virtual btBroadphasePair * getOverlappingPairArrayPtr()
const btBroadphasePairArray & getOverlappingPairArray() const
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *)
The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
virtual void sortOverlappingPairs(btDispatcher *dispatcher)
unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2)
virtual int getNumOverlappingPairs() const
int size() const
return the number of elements in the array
btBroadphasePairArray & getOverlappingPairArray()
btBroadphasePair * internalAddPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
virtual btBroadphasePairArray & getOverlappingPairArray()=0
void btSwap(T &a, T &b)
Definition: btScalar.h:535
virtual btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
btOverlapFilterCallback * getOverlapFilterCallback()
void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)
virtual void cleanProxyFromPairs(btBroadphaseProxy *proxy, btDispatcher *dispatcher)=0
btBroadphasePair * addOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy *, btDispatcher *)
int gFindPairs
int gAddedPairs
btSortedOverlappingPairCache maintains the objects with overlapping AABB Typically managed by the Bro...
void setOverlapFilterCallback(btOverlapFilterCallback *callback)
virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const =0
virtual bool processOverlap(btBroadphasePair &pair)=0
void * removeOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, btDispatcher *dispatcher)
btAlignedObjectArray< int > m_next
virtual int getNumOverlappingPairs() const =0
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
btBroadphaseProxy * m_pProxy1
virtual void * removeOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, btDispatcher *dispatcher)
btBroadphasePairArray m_overlappingPairArray
btBroadphaseProxy * m_pProxy0
virtual void sortOverlappingPairs(btDispatcher *dispatcher)
virtual void cleanOverlappingPair(btBroadphasePair &, btDispatcher *)
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *ghostPairCallback)
btAlignedObjectArray< btBroadphasePair > btBroadphasePairArray
const btBroadphasePairArray & getOverlappingPairArray() const
void removeOverlappingPairsContainingProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *)
virtual void setOverlapFilterCallback(btOverlapFilterCallback *)
virtual void setInternalGhostPairCallback(btOverlappingPairCallback *ghostPairCallback)
btBroadphasePairArray m_overlappingPairArray
bool m_hasDeferredRemoval
by default, do the removal during the pair traversal
short int m_collisionFilterMask
const btBroadphasePair * getOverlappingPairArrayPtr() const
virtual void sortOverlappingPairs(btDispatcher *dispatcher)
virtual btBroadphasePair * addOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *dispatcher)
void cleanProxyFromPairs(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
virtual btBroadphasePair * findPair(btBroadphaseProxy *, btBroadphaseProxy *)
btBroadphasePairArray & getOverlappingPairArray()
virtual btBroadphasePair * getOverlappingPairArrayPtr()=0
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:69
virtual void processAllOverlappingPairs(btOverlapCallback *, btDispatcher *dispatcher)=0
btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
this findPair becomes really slow.
void removeOverlappingPairsContainingProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)
Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman...
virtual void * removeOverlappingPair(btBroadphaseProxy *, btBroadphaseProxy *, btDispatcher *)
The btOverlappingPairCallback class is an additional optional broadphase user callback for adding/rem...
int gRemovePairs
virtual btBroadphasePair * addOverlappingPair(btBroadphaseProxy *, btBroadphaseProxy *)
The btBroadphasePair class contains a pair of aabb-overlapping objects.
btBroadphasePair * getOverlappingPairArrayPtr()