2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
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:
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.
16 #include "btSimpleBroadphase.h"
17 #include "BulletCollision/BroadphaseCollision/btDispatcher.h"
18 #include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
20 #include "LinearMath/btVector3.h"
21 #include "LinearMath/btTransform.h"
22 #include "LinearMath/btMatrix3x3.h"
23 #include "LinearMath/btAabbUtil2.h"
27 void btSimpleBroadphase::validate()
29 for (int i = 0; i < m_numHandles; i++)
31 for (int j = i + 1; j < m_numHandles; j++)
33 btAssert(&m_pHandles[i] != &m_pHandles[j]);
38 btSimpleBroadphase::btSimpleBroadphase(int maxProxies, btOverlappingPairCache* overlappingPairCache)
39 : m_pairCache(overlappingPairCache),
40 m_ownsPairCache(false),
43 if (!overlappingPairCache)
45 void* mem = btAlignedAlloc(sizeof(btHashedOverlappingPairCache), 16);
46 m_pairCache = new (mem) btHashedOverlappingPairCache();
47 m_ownsPairCache = true;
50 // allocate handles buffer and put all handles on free list
51 m_pHandlesRawPtr = btAlignedAlloc(sizeof(btSimpleBroadphaseProxy) * maxProxies, 16);
52 m_pHandles = new (m_pHandlesRawPtr) btSimpleBroadphaseProxy[maxProxies];
53 m_maxHandles = maxProxies;
55 m_firstFreeHandle = 0;
56 m_LastHandleIndex = -1;
59 for (int i = m_firstFreeHandle; i < maxProxies; i++)
61 m_pHandles[i].SetNextFree(i + 1);
62 m_pHandles[i].m_uniqueId = i + 2; //any UID will do, we just avoid too trivial values (0,1) for debugging purposes
64 m_pHandles[maxProxies - 1].SetNextFree(0);
68 btSimpleBroadphase::~btSimpleBroadphase()
70 btAlignedFree(m_pHandlesRawPtr);
74 m_pairCache->~btOverlappingPairCache();
75 btAlignedFree(m_pairCache);
79 btBroadphaseProxy* btSimpleBroadphase::createProxy(const btVector3& aabbMin, const btVector3& aabbMax, int shapeType, void* userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher* /*dispatcher*/)
81 if (m_numHandles >= m_maxHandles)
84 return 0; //should never happen, but don't let the game crash ;-)
86 btAssert(aabbMin[0] <= aabbMax[0] && aabbMin[1] <= aabbMax[1] && aabbMin[2] <= aabbMax[2]);
88 int newHandleIndex = allocHandle();
89 btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex]) btSimpleBroadphaseProxy(aabbMin, aabbMax, shapeType, userPtr, collisionFilterGroup, collisionFilterMask);
94 class RemovingOverlapCallback : public btOverlapCallback
97 virtual bool processOverlap(btBroadphasePair& pair)
105 class RemovePairContainingProxy
107 btBroadphaseProxy* m_targetProxy;
110 virtual ~RemovePairContainingProxy()
115 virtual bool processOverlap(btBroadphasePair& pair)
117 btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy0);
118 btSimpleBroadphaseProxy* proxy1 = static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy1);
120 return ((m_targetProxy == proxy0 || m_targetProxy == proxy1));
124 void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg, btDispatcher* dispatcher)
126 m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg, dispatcher);
128 btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg);
134 void btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const
136 const btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
137 aabbMin = sbp->m_aabbMin;
138 aabbMax = sbp->m_aabbMax;
141 void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* /*dispatcher*/)
143 btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
144 sbp->m_aabbMin = aabbMin;
145 sbp->m_aabbMax = aabbMax;
148 void btSimpleBroadphase::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin, const btVector3& aabbMax)
150 for (int i = 0; i <= m_LastHandleIndex; i++)
152 btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
153 if (!proxy->m_clientObject)
157 rayCallback.process(proxy);
161 void btSimpleBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
163 for (int i = 0; i <= m_LastHandleIndex; i++)
165 btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
166 if (!proxy->m_clientObject)
170 if (TestAabbAgainstAabb2(aabbMin, aabbMax, proxy->m_aabbMin, proxy->m_aabbMax))
172 callback.process(proxy);
177 bool btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0, btSimpleBroadphaseProxy* proxy1)
179 return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] &&
180 proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] &&
181 proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2];
184 //then remove non-overlapping ones
185 class CheckOverlapCallback : public btOverlapCallback
188 virtual bool processOverlap(btBroadphasePair& pair)
190 return (!btSimpleBroadphase::aabbOverlap(static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy0), static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy1)));
194 void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
196 //first check for new overlapping pairs
198 if (m_numHandles >= 0)
200 int new_largest_index = -1;
201 for (i = 0; i <= m_LastHandleIndex; i++)
203 btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i];
204 if (!proxy0->m_clientObject)
208 new_largest_index = i;
209 for (j = i + 1; j <= m_LastHandleIndex; j++)
211 btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j];
212 btAssert(proxy0 != proxy1);
213 if (!proxy1->m_clientObject)
218 btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
219 btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
221 if (aabbOverlap(p0, p1))
223 if (!m_pairCache->findPair(proxy0, proxy1))
225 m_pairCache->addOverlappingPair(proxy0, proxy1);
230 if (!m_pairCache->hasDeferredRemoval())
232 if (m_pairCache->findPair(proxy0, proxy1))
234 m_pairCache->removeOverlappingPair(proxy0, proxy1, dispatcher);
241 m_LastHandleIndex = new_largest_index;
243 if (m_ownsPairCache && m_pairCache->hasDeferredRemoval())
245 btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray();
247 //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
248 overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
250 overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
253 btBroadphasePair previousPair;
254 previousPair.m_pProxy0 = 0;
255 previousPair.m_pProxy1 = 0;
256 previousPair.m_algorithm = 0;
258 for (i = 0; i < overlappingPairArray.size(); i++)
260 btBroadphasePair& pair = overlappingPairArray[i];
262 bool isDuplicate = (pair == previousPair);
266 bool needsRemoval = false;
270 bool hasOverlap = testAabbOverlap(pair.m_pProxy0, pair.m_pProxy1);
274 needsRemoval = false; //callback->processOverlap(pair);
285 //should have no algorithm
286 btAssert(!pair.m_algorithm);
291 m_pairCache->cleanOverlappingPair(pair, dispatcher);
293 // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
294 // m_overlappingPairArray.pop_back();
301 ///if you don't like to skip the invalid pairs in the array, execute following code:
302 #define CLEAN_INVALID_PAIRS 1
303 #ifdef CLEAN_INVALID_PAIRS
305 //perform a sort, to sort 'invalid' pairs to the end
306 overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
308 overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
310 #endif //CLEAN_INVALID_PAIRS
315 bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
317 btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
318 btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
319 return aabbOverlap(p0, p1);
322 void btSimpleBroadphase::resetPool(btDispatcher* dispatcher)