Bullet Collision Detection & Physics Library: btSimpleBroadphase.cpp Source File

Bullet Collision Detection & Physics Library

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

btSimpleBroadphase.cpp
Go to the documentation of this file.
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 "LinearMath/btAabbUtil2.h"
24
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;
60 m_LastHandleIndex = -1;
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 }
94 btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
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
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
150 void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/)
151 {
152 btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
153 sbp->m_aabbMin = aabbMin;
154 sbp->m_aabbMax = aabbMax;
155 }
156
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 }
169
170
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 }
186
187
188
189
190
191
192
193 bool btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1)
194 {
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];
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 {
219 int new_largest_index = -1;
220 for (i=0; i <= m_LastHandleIndex; i++)
221 {
222 btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i];
223 if(!proxy0->m_clientObject)
224 {
225 continue;
226 }
227 new_largest_index = i;
228 for (j=i+1; j <= m_LastHandleIndex; j++)
229 {
230 btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j];
231 btAssert(proxy0 != proxy1);
232 if(!proxy1->m_clientObject)
233 {
234 continue;
235 }
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
259 m_LastHandleIndex = new_largest_index;
260
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
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
346 void btSimpleBroadphase::resetPool(btDispatcher* dispatcher)
347 {
348 //not yet
349 }
btSimpleBroadphase::m_pHandles
btSimpleBroadphaseProxy * m_pHandles
Definition: btSimpleBroadphase.h:58
btSimpleBroadphase::allocHandle
int allocHandle()
Definition: btSimpleBroadphase.h:63
RemovingOverlapCallback
Definition: btSimpleBroadphase.cpp:102
RemovePairContainingProxy
Definition: btSimpleBroadphase.cpp:113
btSimpleBroadphase::m_maxHandles
int m_maxHandles
Definition: btSimpleBroadphase.h:55
btOverlapCallback
Definition: btOverlappingPairCache.h:29
CheckOverlapCallback::processOverlap
virtual bool processOverlap(btBroadphasePair &pair)
Definition: btSimpleBroadphase.cpp:207
btOverlappingPairCache::cleanOverlappingPair
virtual void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)=0
btSimpleBroadphase::m_invalidPair
int m_invalidPair
Definition: btSimpleBroadphase.h:95
btSimpleBroadphase::freeHandle
void freeHandle(btSimpleBroadphaseProxy *proxy)
Definition: btSimpleBroadphase.h:76
btAlignedObjectArray< btBroadphasePair >
btVector3.h
btOverlappingPairCache::hasDeferredRemoval
virtual bool hasDeferredRemoval()=0
btSimpleBroadphase::m_firstFreeHandle
int m_firstFreeHandle
Definition: btSimpleBroadphase.h:61
btBroadphaseProxy::m_aabbMax
btVector3 m_aabbMax
Definition: btBroadphaseProxy.h:110
btSimpleBroadphase::m_ownsPairCache
bool m_ownsPairCache
Definition: btSimpleBroadphase.h:93
btSimpleBroadphase::getSimpleProxyFromProxy
btSimpleBroadphaseProxy * getSimpleProxyFromProxy(btBroadphaseProxy *proxy)
Definition: btSimpleBroadphase.h:99
btAssert
#define btAssert(x)
Definition: btScalar.h:113
btSimpleBroadphase::aabbOverlap
static bool aabbOverlap(btSimpleBroadphaseProxy *proxy0, btSimpleBroadphaseProxy *proxy1)
Definition: btSimpleBroadphase.cpp:193
btTransform.h
btSimpleBroadphase::m_LastHandleIndex
int m_LastHandleIndex
Definition: btSimpleBroadphase.h:56
btMatrix3x3.h
btSimpleBroadphase::destroyProxy
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
Definition: btSimpleBroadphase.cpp:131
TestAabbAgainstAabb2
bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, const btVector3 &aabbMin2, const btVector3 &aabbMax2)
conservative test for overlap between two aabbs
Definition: btAabbUtil2.h:48
btSimpleBroadphaseProxy::SetNextFree
void SetNextFree(int next)
Definition: btSimpleBroadphase.h:39
RemovePairContainingProxy::m_targetProxy
btBroadphaseProxy * m_targetProxy
Definition: btSimpleBroadphase.cpp:116
RemovingOverlapCallback::processOverlap
virtual bool processOverlap(btBroadphasePair &pair)
Definition: btSimpleBroadphase.cpp:105
btSimpleBroadphase::resetPool
virtual void resetPool(btDispatcher *dispatcher)
reset broadphase internal structures, to ensure determinism/reproducability
Definition: btSimpleBroadphase.cpp:346
btOverlappingPairCache
The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
Definition: btOverlappingPairCache.h:60
gOverlappingPairs
int gOverlappingPairs
btSapBroadphaseArray m_sapBroadphases;
Definition: btOverlappingPairCache.cpp:26
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:149
btSimpleBroadphase::m_pairCache
btOverlappingPairCache * m_pairCache
Definition: btSimpleBroadphase.h:92
btSimpleBroadphase.h
btAabbUtil2.h
btOverlappingPairCache::getOverlappingPairArray
virtual btBroadphasePairArray & getOverlappingPairArray()=0
btOverlappingPairCache::findPair
virtual btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
btSimpleBroadphase::createProxy
virtual btBroadphaseProxy * createProxy(const btVector3 &aabbMin, const btVector3 &aabbMax, int shapeType, void *userPtr, short int collisionFilterGroup, short int collisionFilterMask, btDispatcher *dispatcher, void *multiSapProxy)
Definition: btSimpleBroadphase.cpp:87
btSimpleBroadphase::rayTest
virtual void rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, btBroadphaseRayCallback &rayCallback, const btVector3 &aabbMin=btVector3(0, 0, 0), const btVector3 &aabbMax=btVector3(0, 0, 0))
Definition: btSimpleBroadphase.cpp:157
btSimpleBroadphaseProxy
Definition: btSimpleBroadphase.h:23
RemovePairContainingProxy::processOverlap
virtual bool processOverlap(btBroadphasePair &pair)
Definition: btSimpleBroadphase.cpp:122
btBroadphaseRayCallback
Definition: btBroadphaseInterface.h:36
btAlignedFree
#define btAlignedFree(ptr)
Definition: btAlignedAllocator.h:42
btBroadphaseProxy::m_clientObject
void * m_clientObject
Definition: btBroadphaseProxy.h:103
btOverlappingPairCallback::removeOverlappingPairsContainingProxy
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy *proxy0, btDispatcher *dispatcher)=0
btSimpleBroadphase::~btSimpleBroadphase
virtual ~btSimpleBroadphase()
Definition: btSimpleBroadphase.cpp:75
btSimpleBroadphase::getAabb
virtual void getAabb(btBroadphaseProxy *proxy, btVector3 &aabbMin, btVector3 &aabbMax) const
Definition: btSimpleBroadphase.cpp:143
btOverlappingPairCache::~btOverlappingPairCache
virtual ~btOverlappingPairCache()
Definition: btOverlappingPairCache.h:63
btBroadphaseProxy
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
Definition: btBroadphaseProxy.h:85
btBroadphasePair::m_pProxy1
btBroadphaseProxy * m_pProxy1
Definition: btBroadphaseProxy.h:227
btBroadphasePair::m_algorithm
btCollisionAlgorithm * m_algorithm
Definition: btBroadphaseProxy.h:229
btVector3
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
btBroadphaseAabbCallback::process
virtual bool process(const btBroadphaseProxy *proxy)=0
btBroadphasePair::m_pProxy0
btBroadphaseProxy * m_pProxy0
Definition: btBroadphaseProxy.h:226
btSimpleBroadphase::testAabbOverlap
bool testAabbOverlap(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
Definition: btSimpleBroadphase.cpp:339
btBroadphaseProxy::m_aabbMin
btVector3 m_aabbMin
Definition: btBroadphaseProxy.h:109
btOverlappingPairCallback::addOverlappingPair
virtual btBroadphasePair * addOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
CheckOverlapCallback
Definition: btSimpleBroadphase.cpp:204
btSimpleBroadphase::aabbTest
virtual void aabbTest(const btVector3 &aabbMin, const btVector3 &aabbMax, btBroadphaseAabbCallback &callback)
Definition: btSimpleBroadphase.cpp:171
btSimpleBroadphase::calculateOverlappingPairs
virtual void calculateOverlappingPairs(btDispatcher *dispatcher)
calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during th...
Definition: btSimpleBroadphase.cpp:213
btAlignedObjectArray::resize
void resize(int newsize, const T &fillData=T())
Definition: btAlignedObjectArray.h:212
btSimpleBroadphase::m_pHandlesRawPtr
void * m_pHandlesRawPtr
Definition: btSimpleBroadphase.h:60
btBroadphasePairSortPredicate
Definition: btBroadphaseProxy.h:245
btBroadphaseProxy::m_uniqueId
int m_uniqueId
Definition: btBroadphaseProxy.h:107
btSimpleBroadphase::btSimpleBroadphase
btSimpleBroadphase(int maxProxies=16384, btOverlappingPairCache *overlappingPairCache=0)
Definition: btSimpleBroadphase.cpp:41
btSimpleBroadphase::validate
void validate()
Definition: btSimpleBroadphase.cpp:29
btSimpleBroadphase::setAabb
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)
Definition: btSimpleBroadphase.cpp:150
btAlignedAlloc
#define btAlignedAlloc(size, alignment)
Definition: btAlignedAllocator.h:41
RemovePairContainingProxy::~RemovePairContainingProxy
virtual ~RemovePairContainingProxy()
Definition: btSimpleBroadphase.cpp:118
btBroadphaseAabbCallback
Definition: btBroadphaseInterface.h:29
btSimpleBroadphase::m_numHandles
int m_numHandles
Definition: btSimpleBroadphase.h:54
btDispatcher
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:69
btDispatcher.h
btHashedOverlappingPairCache
Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman...
Definition: btOverlappingPairCache.h:93
btAlignedObjectArray::quickSort
void quickSort(const L &CompareFunc)
Definition: btAlignedObjectArray.h:357
btOverlappingPairCallback::removeOverlappingPair
virtual void * removeOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, btDispatcher *dispatcher)=0
btCollisionAlgorithm.h
btBroadphasePair
The btBroadphasePair class contains a pair of aabb-overlapping objects.
Definition: btBroadphaseProxy.h:186