Blender V2.61 - r43446
|
00001 /* 00002 Bullet Continuous Collision Detection and Physics Library 00003 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ 00004 00005 This software is provided 'as-is', without any express or implied warranty. 00006 In no event will the authors be held liable for any damages arising from the use of this software. 00007 Permission is granted to anyone to use this software for any purpose, 00008 including commercial applications, and to alter it and redistribute it freely, 00009 subject to the following restrictions: 00010 00011 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. 00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 00013 3. This notice may not be removed or altered from any source distribution. 00014 */ 00015 00016 #ifndef OVERLAPPING_PAIR_CACHE_H 00017 #define 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 //return true for deletion of the pair 00034 virtual bool processOverlap(btBroadphasePair& pair) = 0; 00035 00036 }; 00037 00038 struct btOverlapFilterCallback 00039 { 00040 virtual ~btOverlapFilterCallback() 00041 {} 00042 // return true when pairs need collision 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() {} // this is needed so we can get to the derived class destructor 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 // Add a pair and return the new pair. If the pair already exists, 00121 // no new pair is created and the old one is returned. 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 // btBroadphasePair* GetPairs() { return m_pairs; } 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 // Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm 00195 // This assumes proxyId1 and proxyId2 are 16-bit. 00196 SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2) 00197 { 00198 int key = (proxyId2 << 16) | proxyId1; 00199 key = ~key + (key << 15); 00200 key = key ^ (key >> 12); 00201 key = key + (key << 2); 00202 key = key ^ (key >> 4); 00203 key = key * 2057; 00204 key = key ^ (key >> 16); 00205 return key; 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 // Thomas Wang's hash 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 //avoid brute-force finding all the time 00285 btBroadphasePairArray m_overlappingPairArray; 00286 00287 //during the dispatch, check that user doesn't destroy/create proxy 00288 bool m_blockedForChanges; 00289 00291 bool m_hasDeferredRemoval; 00292 00293 //if set, use the callback instead of the built in filter in needBroadphaseCollision 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& /*pair*/,btDispatcher* /*dispatcher*/) 00407 { 00408 00409 } 00410 00411 virtual int getNumOverlappingPairs() const 00412 { 00413 return 0; 00414 } 00415 00416 virtual void cleanProxyFromPairs(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/) 00417 { 00418 00419 } 00420 00421 virtual void setOverlapFilterCallback(btOverlapFilterCallback* /*callback*/) 00422 { 00423 } 00424 00425 virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* /*dispatcher*/) 00426 { 00427 } 00428 00429 virtual btBroadphasePair* findPair(btBroadphaseProxy* /*proxy0*/, btBroadphaseProxy* /*proxy1*/) 00430 { 00431 return 0; 00432 } 00433 00434 virtual bool hasDeferredRemoval() 00435 { 00436 return true; 00437 } 00438 00439 virtual void setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */) 00440 { 00441 00442 } 00443 00444 virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/) 00445 { 00446 return 0; 00447 } 00448 00449 virtual void* removeOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/,btDispatcher* /*dispatcher*/) 00450 { 00451 return 0; 00452 } 00453 00454 virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/) 00455 { 00456 } 00457 00458 virtual void sortOverlappingPairs(btDispatcher* dispatcher) 00459 { 00460 (void) dispatcher; 00461 } 00462 00463 00464 }; 00465 00466 00467 #endif //OVERLAPPING_PAIR_CACHE_H 00468 00469