00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef BT_OVERLAPPING_PAIR_CACHE_H
00017 #define BT_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
00034 virtual bool processOverlap(btBroadphasePair& pair) = 0;
00035
00036 };
00037
00038 struct btOverlapFilterCallback
00039 {
00040 virtual ~btOverlapFilterCallback()
00041 {}
00042
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() {}
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
00121
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
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
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
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
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
00285 btBroadphasePairArray m_overlappingPairArray;
00286
00287
00288 bool m_blockedForChanges;
00289
00291 bool m_hasDeferredRemoval;
00292
00293
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& ,btDispatcher* )
00407 {
00408
00409 }
00410
00411 virtual int getNumOverlappingPairs() const
00412 {
00413 return 0;
00414 }
00415
00416 virtual void cleanProxyFromPairs(btBroadphaseProxy* ,btDispatcher* )
00417 {
00418
00419 }
00420
00421 virtual void setOverlapFilterCallback(btOverlapFilterCallback* )
00422 {
00423 }
00424
00425 virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* )
00426 {
00427 }
00428
00429 virtual btBroadphasePair* findPair(btBroadphaseProxy* , btBroadphaseProxy* )
00430 {
00431 return 0;
00432 }
00433
00434 virtual bool hasDeferredRemoval()
00435 {
00436 return true;
00437 }
00438
00439 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* )
00440 {
00441
00442 }
00443
00444 virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* ,btBroadphaseProxy* )
00445 {
00446 return 0;
00447 }
00448
00449 virtual void* removeOverlappingPair(btBroadphaseProxy* ,btBroadphaseProxy* ,btDispatcher* )
00450 {
00451 return 0;
00452 }
00453
00454 virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* ,btDispatcher* )
00455 {
00456 }
00457
00458 virtual void sortOverlappingPairs(btDispatcher* dispatcher)
00459 {
00460 (void) dispatcher;
00461 }
00462
00463
00464 };
00465
00466
00467 #endif //BT_OVERLAPPING_PAIR_CACHE_H
00468
00469