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