Bullet Collision Detection & Physics Library
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"
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 
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);
49  m_ownsPairCache = true;
50  }
51 
52  // allocate handles buffer and put all handles on free list
55  m_maxHandles = maxProxies;
56  m_numHandles = 0;
58  m_LastHandleIndex = -1;
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 
74 {
76 
77  if (m_ownsPairCache)
78  {
81  }
82 }
83 
84 
85 btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr , int collisionFilterGroup, int collisionFilterMask, btDispatcher* /*dispatcher*/)
86 {
88  {
89  btAssert(0);
90  return 0; //should never happen, but don't let the game crash ;-)
91  }
92  btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
93 
94  int newHandleIndex = allocHandle();
95  btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask);
96 
97  return proxy;
98 }
99 
101 {
102 protected:
103  virtual bool processOverlap(btBroadphasePair& pair)
104  {
105  (void)pair;
106  btAssert(0);
107  return false;
108  }
109 };
110 
112 {
113 
115  public:
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 
130 {
131 
132  btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg);
133  freeHandle(proxy0);
134 
136 
137  //validate();
138 
139 }
140 
141 void btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
142 {
144  aabbMin = sbp->m_aabbMin;
145  aabbMax = sbp->m_aabbMax;
146 }
147 
148 void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/)
149 {
151  sbp->m_aabbMin = aabbMin;
152  sbp->m_aabbMax = aabbMax;
153 }
154 
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 }
167 
168 
169 void btSimpleBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
170 {
171  for (int i=0; i <= m_LastHandleIndex; i++)
172  {
173  btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
174  if(!proxy->m_clientObject)
175  {
176  continue;
177  }
178  if (TestAabbAgainstAabb2(aabbMin,aabbMax,proxy->m_aabbMin,proxy->m_aabbMax))
179  {
180  callback.process(proxy);
181  }
182  }
183 }
184 
185 
186 
187 
188 
189 
190 
192 {
193  return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] &&
194  proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] &&
195  proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2];
196 
197 }
198 
199 
200 
201 //then remove non-overlapping ones
203 {
204 public:
205  virtual bool processOverlap(btBroadphasePair& pair)
206  {
207  return (!btSimpleBroadphase::aabbOverlap(static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy0),static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy1)));
208  }
209 };
210 
212 {
213  //first check for new overlapping pairs
214  int i,j;
215  if (m_numHandles >= 0)
216  {
217  int new_largest_index = -1;
218  for (i=0; i <= m_LastHandleIndex; i++)
219  {
220  btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i];
221  if(!proxy0->m_clientObject)
222  {
223  continue;
224  }
225  new_largest_index = i;
226  for (j=i+1; j <= m_LastHandleIndex; j++)
227  {
228  btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j];
229  btAssert(proxy0 != proxy1);
230  if(!proxy1->m_clientObject)
231  {
232  continue;
233  }
234 
237 
238  if (aabbOverlap(p0,p1))
239  {
240  if ( !m_pairCache->findPair(proxy0,proxy1))
241  {
242  m_pairCache->addOverlappingPair(proxy0,proxy1);
243  }
244  } else
245  {
247  {
248  if ( m_pairCache->findPair(proxy0,proxy1))
249  {
250  m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher);
251  }
252  }
253  }
254  }
255  }
256 
257  m_LastHandleIndex = new_largest_index;
258 
260  {
261 
262  btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray();
263 
264  //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
265  overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
266 
267  overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
268  m_invalidPair = 0;
269 
270 
271  btBroadphasePair previousPair;
272  previousPair.m_pProxy0 = 0;
273  previousPair.m_pProxy1 = 0;
274  previousPair.m_algorithm = 0;
275 
276 
277  for (i=0;i<overlappingPairArray.size();i++)
278  {
279 
280  btBroadphasePair& pair = overlappingPairArray[i];
281 
282  bool isDuplicate = (pair == previousPair);
283 
284  previousPair = pair;
285 
286  bool needsRemoval = false;
287 
288  if (!isDuplicate)
289  {
290  bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
291 
292  if (hasOverlap)
293  {
294  needsRemoval = false;//callback->processOverlap(pair);
295  } else
296  {
297  needsRemoval = true;
298  }
299  } else
300  {
301  //remove duplicate
302  needsRemoval = true;
303  //should have no algorithm
304  btAssert(!pair.m_algorithm);
305  }
306 
307  if (needsRemoval)
308  {
309  m_pairCache->cleanOverlappingPair(pair,dispatcher);
310 
311  // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
312  // m_overlappingPairArray.pop_back();
313  pair.m_pProxy0 = 0;
314  pair.m_pProxy1 = 0;
315  m_invalidPair++;
316  }
317 
318  }
319 
321 #define CLEAN_INVALID_PAIRS 1
322 #ifdef CLEAN_INVALID_PAIRS
323 
324  //perform a sort, to sort 'invalid' pairs to the end
325  overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
326 
327  overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
328  m_invalidPair = 0;
329 #endif//CLEAN_INVALID_PAIRS
330 
331  }
332  }
333 }
334 
335 
337 {
340  return aabbOverlap(p0,p1);
341 }
342 
344 {
345  //not yet
346 }
btSimpleBroadphaseProxy * m_pHandles
virtual bool processOverlap(btBroadphasePair &pair)
virtual void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)=0
void freeHandle(btSimpleBroadphaseProxy *proxy)
virtual bool hasDeferredRemoval()=0
btSimpleBroadphaseProxy * getSimpleProxyFromProxy(btBroadphaseProxy *proxy)
#define btAssert(x)
Definition: btScalar.h:131
static bool aabbOverlap(btSimpleBroadphaseProxy *proxy0, btSimpleBroadphaseProxy *proxy1)
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
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
btBroadphaseProxy * m_targetProxy
virtual bool processOverlap(btBroadphasePair &pair)
virtual void resetPool(btDispatcher *dispatcher)
reset broadphase internal structures, to ensure determinism/reproducability
The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
int size() const
return the number of elements in the array
btOverlappingPairCache * m_pairCache
virtual btBroadphasePairArray & getOverlappingPairArray()=0
virtual btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
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))
virtual bool processOverlap(btBroadphasePair &pair)
#define btAlignedFree(ptr)
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy *proxy0, btDispatcher *dispatcher)=0
virtual void getAabb(btBroadphaseProxy *proxy, btVector3 &aabbMin, btVector3 &aabbMax) const
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
btBroadphaseProxy * m_pProxy1
btCollisionAlgorithm * m_algorithm
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
virtual bool process(const btBroadphaseProxy *proxy)=0
btBroadphaseProxy * m_pProxy0
bool testAabbOverlap(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
virtual btBroadphasePair * addOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
virtual void aabbTest(const btVector3 &aabbMin, const btVector3 &aabbMax, btBroadphaseAabbCallback &callback)
virtual void calculateOverlappingPairs(btDispatcher *dispatcher)
calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during th...
void resize(int newsize, const T &fillData=T())
btSimpleBroadphase(int maxProxies=16384, btOverlappingPairCache *overlappingPairCache=0)
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)
#define btAlignedAlloc(size, alignment)
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:77
Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman...
virtual btBroadphaseProxy * createProxy(const btVector3 &aabbMin, const btVector3 &aabbMax, int shapeType, void *userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher *dispatcher)
void quickSort(const L &CompareFunc)
virtual void * removeOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, btDispatcher *dispatcher)=0
The btBroadphasePair class contains a pair of aabb-overlapping objects.