| [1963] | 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 | #include "btSimpleBroadphase.h" | 
|---|
 | 17 | #include "BulletCollision/BroadphaseCollision/btDispatcher.h" | 
|---|
 | 18 | #include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" | 
|---|
 | 19 |  | 
|---|
 | 20 | #include "LinearMath/btVector3.h" | 
|---|
 | 21 | #include "LinearMath/btTransform.h" | 
|---|
 | 22 | #include "LinearMath/btMatrix3x3.h" | 
|---|
| [8351] | 23 | #include "LinearMath/btAabbUtil2.h" | 
|---|
 | 24 |  | 
|---|
| [1963] | 25 | #include <new> | 
|---|
 | 26 |  | 
|---|
 | 27 | extern int gOverlappingPairs; | 
|---|
 | 28 |  | 
|---|
 | 29 | void    btSimpleBroadphase::validate() | 
|---|
 | 30 | { | 
|---|
 | 31 |         for (int i=0;i<m_numHandles;i++) | 
|---|
 | 32 |         { | 
|---|
 | 33 |                 for (int j=i+1;j<m_numHandles;j++) | 
|---|
 | 34 |                 { | 
|---|
 | 35 |                         btAssert(&m_pHandles[i] != &m_pHandles[j]); | 
|---|
 | 36 |                 } | 
|---|
 | 37 |         } | 
|---|
 | 38 |          | 
|---|
 | 39 | } | 
|---|
 | 40 |  | 
|---|
 | 41 | btSimpleBroadphase::btSimpleBroadphase(int maxProxies, btOverlappingPairCache* overlappingPairCache) | 
|---|
 | 42 |         :m_pairCache(overlappingPairCache), | 
|---|
 | 43 |         m_ownsPairCache(false), | 
|---|
 | 44 |         m_invalidPair(0) | 
|---|
 | 45 | { | 
|---|
 | 46 |  | 
|---|
 | 47 |         if (!overlappingPairCache) | 
|---|
 | 48 |         { | 
|---|
 | 49 |                 void* mem = btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16); | 
|---|
 | 50 |                 m_pairCache = new (mem)btHashedOverlappingPairCache(); | 
|---|
 | 51 |                 m_ownsPairCache = true; | 
|---|
 | 52 |         } | 
|---|
 | 53 |  | 
|---|
 | 54 |         // allocate handles buffer and put all handles on free list | 
|---|
 | 55 |         m_pHandlesRawPtr = btAlignedAlloc(sizeof(btSimpleBroadphaseProxy)*maxProxies,16); | 
|---|
 | 56 |         m_pHandles = new(m_pHandlesRawPtr) btSimpleBroadphaseProxy[maxProxies]; | 
|---|
 | 57 |         m_maxHandles = maxProxies; | 
|---|
 | 58 |         m_numHandles = 0; | 
|---|
 | 59 |         m_firstFreeHandle = 0; | 
|---|
| [2430] | 60 |         m_LastHandleIndex = -1; | 
|---|
| [1963] | 61 |          | 
|---|
 | 62 |  | 
|---|
 | 63 |         { | 
|---|
 | 64 |                 for (int i = m_firstFreeHandle; i < maxProxies; i++) | 
|---|
 | 65 |                 { | 
|---|
 | 66 |                         m_pHandles[i].SetNextFree(i + 1); | 
|---|
 | 67 |                         m_pHandles[i].m_uniqueId = i+2;//any UID will do, we just avoid too trivial values (0,1) for debugging purposes | 
|---|
 | 68 |                 } | 
|---|
 | 69 |                 m_pHandles[maxProxies - 1].SetNextFree(0); | 
|---|
 | 70 |          | 
|---|
 | 71 |         } | 
|---|
 | 72 |  | 
|---|
 | 73 | } | 
|---|
 | 74 |  | 
|---|
 | 75 | btSimpleBroadphase::~btSimpleBroadphase() | 
|---|
 | 76 | { | 
|---|
 | 77 |         btAlignedFree(m_pHandlesRawPtr); | 
|---|
 | 78 |  | 
|---|
 | 79 |         if (m_ownsPairCache) | 
|---|
 | 80 |         { | 
|---|
 | 81 |                 m_pairCache->~btOverlappingPairCache(); | 
|---|
 | 82 |                 btAlignedFree(m_pairCache); | 
|---|
 | 83 |         } | 
|---|
 | 84 | } | 
|---|
 | 85 |  | 
|---|
 | 86 |  | 
|---|
 | 87 | btBroadphaseProxy*      btSimpleBroadphase::createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* /*dispatcher*/,void* multiSapProxy) | 
|---|
 | 88 | { | 
|---|
 | 89 |         if (m_numHandles >= m_maxHandles) | 
|---|
 | 90 |         { | 
|---|
 | 91 |                 btAssert(0); | 
|---|
 | 92 |                 return 0; //should never happen, but don't let the game crash ;-) | 
|---|
 | 93 |         } | 
|---|
| [2430] | 94 |         btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]); | 
|---|
| [1963] | 95 |  | 
|---|
 | 96 |         int newHandleIndex = allocHandle(); | 
|---|
 | 97 |         btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy); | 
|---|
 | 98 |  | 
|---|
 | 99 |         return proxy; | 
|---|
 | 100 | } | 
|---|
 | 101 |  | 
|---|
 | 102 | class   RemovingOverlapCallback : public btOverlapCallback | 
|---|
 | 103 | { | 
|---|
 | 104 | protected: | 
|---|
 | 105 |         virtual bool    processOverlap(btBroadphasePair& pair) | 
|---|
 | 106 |         { | 
|---|
 | 107 |                 (void)pair; | 
|---|
 | 108 |                 btAssert(0); | 
|---|
 | 109 |                 return false; | 
|---|
 | 110 |         } | 
|---|
 | 111 | }; | 
|---|
 | 112 |  | 
|---|
 | 113 | class RemovePairContainingProxy | 
|---|
 | 114 | { | 
|---|
 | 115 |  | 
|---|
 | 116 |         btBroadphaseProxy*      m_targetProxy; | 
|---|
 | 117 |         public: | 
|---|
 | 118 |         virtual ~RemovePairContainingProxy() | 
|---|
 | 119 |         { | 
|---|
 | 120 |         } | 
|---|
 | 121 | protected: | 
|---|
 | 122 |         virtual bool processOverlap(btBroadphasePair& pair) | 
|---|
 | 123 |         { | 
|---|
 | 124 |                 btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy0); | 
|---|
 | 125 |                 btSimpleBroadphaseProxy* proxy1 = static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy1); | 
|---|
 | 126 |  | 
|---|
 | 127 |                 return ((m_targetProxy == proxy0 || m_targetProxy == proxy1)); | 
|---|
 | 128 |         }; | 
|---|
 | 129 | }; | 
|---|
 | 130 |  | 
|---|
 | 131 | void    btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher* dispatcher) | 
|---|
 | 132 | { | 
|---|
 | 133 |                  | 
|---|
 | 134 |                 btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg); | 
|---|
 | 135 |                 freeHandle(proxy0); | 
|---|
 | 136 |  | 
|---|
 | 137 |                 m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg,dispatcher); | 
|---|
 | 138 |  | 
|---|
 | 139 |                 //validate(); | 
|---|
 | 140 |                  | 
|---|
 | 141 | } | 
|---|
 | 142 |  | 
|---|
| [2430] | 143 | void    btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const | 
|---|
 | 144 | { | 
|---|
 | 145 |         const btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy); | 
|---|
 | 146 |         aabbMin = sbp->m_aabbMin; | 
|---|
 | 147 |         aabbMax = sbp->m_aabbMax; | 
|---|
 | 148 | } | 
|---|
 | 149 |  | 
|---|
| [1963] | 150 | void    btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/) | 
|---|
 | 151 | { | 
|---|
 | 152 |         btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy); | 
|---|
| [2430] | 153 |         sbp->m_aabbMin = aabbMin; | 
|---|
 | 154 |         sbp->m_aabbMax = aabbMax; | 
|---|
| [1963] | 155 | } | 
|---|
 | 156 |  | 
|---|
| [2430] | 157 | void    btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax) | 
|---|
 | 158 | { | 
|---|
 | 159 |         for (int i=0; i <= m_LastHandleIndex; i++) | 
|---|
 | 160 |         { | 
|---|
 | 161 |                 btSimpleBroadphaseProxy* proxy = &m_pHandles[i]; | 
|---|
 | 162 |                 if(!proxy->m_clientObject) | 
|---|
 | 163 |                 { | 
|---|
 | 164 |                         continue; | 
|---|
 | 165 |                 } | 
|---|
 | 166 |                 rayCallback.process(proxy); | 
|---|
 | 167 |         } | 
|---|
 | 168 | } | 
|---|
| [1963] | 169 |  | 
|---|
 | 170 |  | 
|---|
| [8351] | 171 | void    btSimpleBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) | 
|---|
 | 172 | { | 
|---|
 | 173 |         for (int i=0; i <= m_LastHandleIndex; i++) | 
|---|
 | 174 |         { | 
|---|
 | 175 |                 btSimpleBroadphaseProxy* proxy = &m_pHandles[i]; | 
|---|
 | 176 |                 if(!proxy->m_clientObject) | 
|---|
 | 177 |                 { | 
|---|
 | 178 |                         continue; | 
|---|
 | 179 |                 } | 
|---|
 | 180 |                 if (TestAabbAgainstAabb2(aabbMin,aabbMax,proxy->m_aabbMin,proxy->m_aabbMax)) | 
|---|
 | 181 |                 { | 
|---|
 | 182 |                         callback.process(proxy); | 
|---|
 | 183 |                 } | 
|---|
 | 184 |         } | 
|---|
 | 185 | } | 
|---|
| [1963] | 186 |  | 
|---|
| [8351] | 187 |  | 
|---|
 | 188 |  | 
|---|
| [1963] | 189 |          | 
|---|
 | 190 |  | 
|---|
 | 191 |  | 
|---|
 | 192 |  | 
|---|
 | 193 | bool    btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1) | 
|---|
 | 194 | { | 
|---|
| [2430] | 195 |         return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] &&  | 
|---|
 | 196 |                    proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] && | 
|---|
 | 197 |                    proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2]; | 
|---|
| [1963] | 198 |  | 
|---|
 | 199 | } | 
|---|
 | 200 |  | 
|---|
 | 201 |  | 
|---|
 | 202 |  | 
|---|
 | 203 | //then remove non-overlapping ones | 
|---|
 | 204 | class CheckOverlapCallback : public btOverlapCallback | 
|---|
 | 205 | { | 
|---|
 | 206 | public: | 
|---|
 | 207 |         virtual bool processOverlap(btBroadphasePair& pair) | 
|---|
 | 208 |         { | 
|---|
 | 209 |                 return (!btSimpleBroadphase::aabbOverlap(static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy0),static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy1))); | 
|---|
 | 210 |         } | 
|---|
 | 211 | }; | 
|---|
 | 212 |  | 
|---|
 | 213 | void    btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) | 
|---|
 | 214 | { | 
|---|
 | 215 |         //first check for new overlapping pairs | 
|---|
 | 216 |         int i,j; | 
|---|
 | 217 |         if (m_numHandles >= 0) | 
|---|
 | 218 |         { | 
|---|
| [2430] | 219 |                 int new_largest_index = -1; | 
|---|
 | 220 |                 for (i=0; i <= m_LastHandleIndex; i++) | 
|---|
| [1963] | 221 |                 { | 
|---|
 | 222 |                         btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i]; | 
|---|
| [2430] | 223 |                         if(!proxy0->m_clientObject) | 
|---|
| [1963] | 224 |                         { | 
|---|
| [2430] | 225 |                                 continue; | 
|---|
 | 226 |                         } | 
|---|
 | 227 |                         new_largest_index = i; | 
|---|
 | 228 |                         for (j=i+1; j <= m_LastHandleIndex; j++) | 
|---|
 | 229 |                         { | 
|---|
| [1963] | 230 |                                 btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j]; | 
|---|
 | 231 |                                 btAssert(proxy0 != proxy1); | 
|---|
| [2430] | 232 |                                 if(!proxy1->m_clientObject) | 
|---|
 | 233 |                                 { | 
|---|
 | 234 |                                         continue; | 
|---|
 | 235 |                                 } | 
|---|
| [1963] | 236 |  | 
|---|
 | 237 |                                 btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0); | 
|---|
 | 238 |                                 btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1); | 
|---|
 | 239 |  | 
|---|
 | 240 |                                 if (aabbOverlap(p0,p1)) | 
|---|
 | 241 |                                 { | 
|---|
 | 242 |                                         if ( !m_pairCache->findPair(proxy0,proxy1)) | 
|---|
 | 243 |                                         { | 
|---|
 | 244 |                                                 m_pairCache->addOverlappingPair(proxy0,proxy1); | 
|---|
 | 245 |                                         } | 
|---|
 | 246 |                                 } else | 
|---|
 | 247 |                                 { | 
|---|
 | 248 |                                         if (!m_pairCache->hasDeferredRemoval()) | 
|---|
 | 249 |                                         { | 
|---|
 | 250 |                                                 if ( m_pairCache->findPair(proxy0,proxy1)) | 
|---|
 | 251 |                                                 { | 
|---|
 | 252 |                                                         m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher); | 
|---|
 | 253 |                                                 } | 
|---|
 | 254 |                                         } | 
|---|
 | 255 |                                 } | 
|---|
 | 256 |                         } | 
|---|
 | 257 |                 } | 
|---|
 | 258 |  | 
|---|
| [2430] | 259 |                 m_LastHandleIndex = new_largest_index; | 
|---|
 | 260 |  | 
|---|
| [1963] | 261 |                 if (m_ownsPairCache && m_pairCache->hasDeferredRemoval()) | 
|---|
 | 262 |                 { | 
|---|
 | 263 |  | 
|---|
 | 264 |                         btBroadphasePairArray&  overlappingPairArray = m_pairCache->getOverlappingPairArray(); | 
|---|
 | 265 |  | 
|---|
 | 266 |                         //perform a sort, to find duplicates and to sort 'invalid' pairs to the end | 
|---|
 | 267 |                         overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); | 
|---|
 | 268 |  | 
|---|
 | 269 |                         overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); | 
|---|
 | 270 |                         m_invalidPair = 0; | 
|---|
 | 271 |  | 
|---|
 | 272 |  | 
|---|
 | 273 |                         btBroadphasePair previousPair; | 
|---|
 | 274 |                         previousPair.m_pProxy0 = 0; | 
|---|
 | 275 |                         previousPair.m_pProxy1 = 0; | 
|---|
 | 276 |                         previousPair.m_algorithm = 0; | 
|---|
 | 277 |  | 
|---|
 | 278 |  | 
|---|
 | 279 |                         for (i=0;i<overlappingPairArray.size();i++) | 
|---|
 | 280 |                         { | 
|---|
 | 281 |  | 
|---|
 | 282 |                                 btBroadphasePair& pair = overlappingPairArray[i]; | 
|---|
 | 283 |  | 
|---|
 | 284 |                                 bool isDuplicate = (pair == previousPair); | 
|---|
 | 285 |  | 
|---|
 | 286 |                                 previousPair = pair; | 
|---|
 | 287 |  | 
|---|
 | 288 |                                 bool needsRemoval = false; | 
|---|
 | 289 |  | 
|---|
 | 290 |                                 if (!isDuplicate) | 
|---|
 | 291 |                                 { | 
|---|
 | 292 |                                         bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1); | 
|---|
 | 293 |  | 
|---|
 | 294 |                                         if (hasOverlap) | 
|---|
 | 295 |                                         { | 
|---|
 | 296 |                                                 needsRemoval = false;//callback->processOverlap(pair); | 
|---|
 | 297 |                                         } else | 
|---|
 | 298 |                                         { | 
|---|
 | 299 |                                                 needsRemoval = true; | 
|---|
 | 300 |                                         } | 
|---|
 | 301 |                                 } else | 
|---|
 | 302 |                                 { | 
|---|
 | 303 |                                         //remove duplicate | 
|---|
 | 304 |                                         needsRemoval = true; | 
|---|
 | 305 |                                         //should have no algorithm | 
|---|
 | 306 |                                         btAssert(!pair.m_algorithm); | 
|---|
 | 307 |                                 } | 
|---|
 | 308 |  | 
|---|
 | 309 |                                 if (needsRemoval) | 
|---|
 | 310 |                                 { | 
|---|
 | 311 |                                         m_pairCache->cleanOverlappingPair(pair,dispatcher); | 
|---|
 | 312 |  | 
|---|
 | 313 |                                         //              m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); | 
|---|
 | 314 |                                         //              m_overlappingPairArray.pop_back(); | 
|---|
 | 315 |                                         pair.m_pProxy0 = 0; | 
|---|
 | 316 |                                         pair.m_pProxy1 = 0; | 
|---|
 | 317 |                                         m_invalidPair++; | 
|---|
 | 318 |                                         gOverlappingPairs--; | 
|---|
 | 319 |                                 }  | 
|---|
 | 320 |  | 
|---|
 | 321 |                         } | 
|---|
 | 322 |  | 
|---|
 | 323 |                         ///if you don't like to skip the invalid pairs in the array, execute following code: | 
|---|
 | 324 | #define CLEAN_INVALID_PAIRS 1 | 
|---|
 | 325 | #ifdef CLEAN_INVALID_PAIRS | 
|---|
 | 326 |  | 
|---|
 | 327 |                         //perform a sort, to sort 'invalid' pairs to the end | 
|---|
 | 328 |                         overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); | 
|---|
 | 329 |  | 
|---|
 | 330 |                         overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); | 
|---|
 | 331 |                         m_invalidPair = 0; | 
|---|
 | 332 | #endif//CLEAN_INVALID_PAIRS | 
|---|
 | 333 |  | 
|---|
 | 334 |                 } | 
|---|
 | 335 |         } | 
|---|
 | 336 | } | 
|---|
 | 337 |  | 
|---|
 | 338 |  | 
|---|
 | 339 | bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) | 
|---|
 | 340 | { | 
|---|
 | 341 |         btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0); | 
|---|
 | 342 |         btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1); | 
|---|
 | 343 |         return aabbOverlap(p0,p1); | 
|---|
 | 344 | } | 
|---|
 | 345 |  | 
|---|
| [2882] | 346 | void    btSimpleBroadphase::resetPool(btDispatcher* dispatcher) | 
|---|
 | 347 | { | 
|---|
 | 348 |         //not yet | 
|---|
 | 349 | } | 
|---|