Bullet Collision Detection & Physics Library
btAxisSweep3.h
Go to the documentation of this file.
1 //Bullet Continuous Collision Detection and Physics Library
2 //Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
3 
4 //
5 // btAxisSweep3.h
6 //
7 // Copyright (c) 2006 Simon Hobbs
8 //
9 // This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
10 //
11 // Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
12 //
13 // 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.
14 //
15 // 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
16 //
17 // 3. This notice may not be removed or altered from any source distribution.
18 
19 #ifndef BT_AXIS_SWEEP_3_H
20 #define BT_AXIS_SWEEP_3_H
21 
22 #include "LinearMath/btVector3.h"
23 #include "btOverlappingPairCache.h"
24 #include "btBroadphaseInterface.h"
25 #include "btBroadphaseProxy.h"
27 #include "btDbvtBroadphase.h"
28 
29 //#define DEBUG_BROADPHASE 1
30 #define USE_OVERLAP_TEST_ON_REMOVES 1
31 
35 template <typename BP_FP_INT_TYPE>
37 {
38 protected:
39 
40  BP_FP_INT_TYPE m_bpHandleMask;
41  BP_FP_INT_TYPE m_handleSentinel;
42 
43 public:
44 
46 
47  class Edge
48  {
49  public:
50  BP_FP_INT_TYPE m_pos; // low bit is min/max
51  BP_FP_INT_TYPE m_handle;
52 
53  BP_FP_INT_TYPE IsMax() const {return static_cast<BP_FP_INT_TYPE>(m_pos & 1);}
54  };
55 
56 public:
57  class Handle : public btBroadphaseProxy
58  {
59  public:
61 
62  // indexes into the edge arrays
63  BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12
64 // BP_FP_INT_TYPE m_uniqueId;
65  btBroadphaseProxy* m_dbvtProxy;//for faster raycast
66  //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
67 
68  SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;}
69  SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];}
70  }; // 24 bytes + 24 for Edge structures = 44 bytes total per entry
71 
72 
73 protected:
74  btVector3 m_worldAabbMin; // overall system bounds
75  btVector3 m_worldAabbMax; // overall system bounds
76 
77  btVector3 m_quantize; // scaling factor for quantization
78 
79  BP_FP_INT_TYPE m_numHandles; // number of active handles
80  BP_FP_INT_TYPE m_maxHandles; // max number of handles
81  Handle* m_pHandles; // handles pool
82 
83  BP_FP_INT_TYPE m_firstFreeHandle; // free handles list
84 
85  Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries)
86  void* m_pEdgesRawPtr[3];
87 
89 
92 
94 
96 
101 
102 
103  // allocation/deallocation
104  BP_FP_INT_TYPE allocHandle();
105  void freeHandle(BP_FP_INT_TYPE handle);
106 
107 
108  bool testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1);
109 
110 #ifdef DEBUG_BROADPHASE
111  void debugPrintAxis(int axis,bool checkCardinality=true);
112 #endif //DEBUG_BROADPHASE
113 
114  //Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
115  //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
116 
117 
118 
119  void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
120  void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
121  void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
122  void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
123 
124 public:
125 
126  btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0,bool disableRaycastAccelerator = false);
127 
128  virtual ~btAxisSweep3Internal();
129 
130  BP_FP_INT_TYPE getNumHandles() const
131  {
132  return m_numHandles;
133  }
134 
135  virtual void calculateOverlappingPairs(btDispatcher* dispatcher);
136 
137  BP_FP_INT_TYPE addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
138  void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher);
139  void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
140  SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
141 
142  virtual void resetPool(btDispatcher* dispatcher);
143 
145 
146  //Broadphase Interface
147  virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
148  virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
149  virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
150  virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
151 
152  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));
153  virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
154 
155 
156  void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const;
158  void unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
159 
161 
163  {
164  return m_pairCache;
165  }
167  {
168  return m_pairCache;
169  }
170 
172  {
173  m_userPairCallback = pairCallback;
174  }
176  {
177  return m_userPairCallback;
178  }
179 
182  virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
183  {
184  aabbMin = m_worldAabbMin;
185  aabbMax = m_worldAabbMax;
186  }
187 
188  virtual void printStats()
189  {
190 /* printf("btAxisSweep3.h\n");
191  printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles);
192  printf("aabbMin=%f,%f,%f,aabbMax=%f,%f,%f\n",m_worldAabbMin.getX(),m_worldAabbMin.getY(),m_worldAabbMin.getZ(),
193  m_worldAabbMax.getX(),m_worldAabbMax.getY(),m_worldAabbMax.getZ());
194  */
195 
196  }
197 
198 };
199 
201 
202 
203 
204 
205 #ifdef DEBUG_BROADPHASE
206 #include <stdio.h>
207 
208 template <typename BP_FP_INT_TYPE>
209 void btAxisSweep3<BP_FP_INT_TYPE>::debugPrintAxis(int axis, bool checkCardinality)
210 {
211  int numEdges = m_pHandles[0].m_maxEdges[axis];
212  printf("SAP Axis %d, numEdges=%d\n",axis,numEdges);
213 
214  int i;
215  for (i=0;i<numEdges+1;i++)
216  {
217  Edge* pEdge = m_pEdges[axis] + i;
218  Handle* pHandlePrev = getHandle(pEdge->m_handle);
219  int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis];
220  char beginOrEnd;
221  beginOrEnd=pEdge->IsMax()?'E':'B';
222  printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex);
223  }
224 
225  if (checkCardinality)
226  btAssert(numEdges == m_numHandles*2+1);
227 }
228 #endif //DEBUG_BROADPHASE
229 
230 template <typename BP_FP_INT_TYPE>
231 btBroadphaseProxy* btAxisSweep3Internal<BP_FP_INT_TYPE>::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
232 {
233  (void)shapeType;
234  BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,multiSapProxy);
235 
236  Handle* handle = getHandle(handleId);
237 
238  if (m_raycastAccelerator)
239  {
240  btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,0);
241  handle->m_dbvtProxy = rayProxy;
242  }
243  return handle;
244 }
245 
246 
247 
248 template <typename BP_FP_INT_TYPE>
250 {
251  Handle* handle = static_cast<Handle*>(proxy);
252  if (m_raycastAccelerator)
253  m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy,dispatcher);
254  removeHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), dispatcher);
255 }
256 
257 template <typename BP_FP_INT_TYPE>
259 {
260  Handle* handle = static_cast<Handle*>(proxy);
261  handle->m_aabbMin = aabbMin;
262  handle->m_aabbMax = aabbMax;
263  updateHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), aabbMin, aabbMax,dispatcher);
264  if (m_raycastAccelerator)
265  m_raycastAccelerator->setAabb(handle->m_dbvtProxy,aabbMin,aabbMax,dispatcher);
266 
267 }
268 
269 template <typename BP_FP_INT_TYPE>
270 void btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax)
271 {
272  if (m_raycastAccelerator)
273  {
274  m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback,aabbMin,aabbMax);
275  } else
276  {
277  //choose axis?
278  BP_FP_INT_TYPE axis = 0;
279  //for each proxy
280  for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++)
281  {
282  if (m_pEdges[axis][i].IsMax())
283  {
284  rayCallback.process(getHandle(m_pEdges[axis][i].m_handle));
285  }
286  }
287  }
288 }
289 
290 template <typename BP_FP_INT_TYPE>
292 {
293  if (m_raycastAccelerator)
294  {
295  m_raycastAccelerator->aabbTest(aabbMin,aabbMax,callback);
296  } else
297  {
298  //choose axis?
299  BP_FP_INT_TYPE axis = 0;
300  //for each proxy
301  for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++)
302  {
303  if (m_pEdges[axis][i].IsMax())
304  {
305  Handle* handle = getHandle(m_pEdges[axis][i].m_handle);
306  if (TestAabbAgainstAabb2(aabbMin,aabbMax,handle->m_aabbMin,handle->m_aabbMax))
307  {
308  callback.process(handle);
309  }
310  }
311  }
312  }
313 }
314 
315 
316 
317 template <typename BP_FP_INT_TYPE>
319 {
320  Handle* pHandle = static_cast<Handle*>(proxy);
321  aabbMin = pHandle->m_aabbMin;
322  aabbMax = pHandle->m_aabbMax;
323 }
324 
325 
326 template <typename BP_FP_INT_TYPE>
328 {
329  Handle* pHandle = static_cast<Handle*>(proxy);
330 
331  unsigned short vecInMin[3];
332  unsigned short vecInMax[3];
333 
334  vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos ;
335  vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos +1 ;
336  vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos ;
337  vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos +1 ;
338  vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos ;
339  vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos +1 ;
340 
341  aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()),(btScalar)(vecInMin[1]) / (m_quantize.getY()),(btScalar)(vecInMin[2]) / (m_quantize.getZ()));
342  aabbMin += m_worldAabbMin;
343 
344  aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()),(btScalar)(vecInMax[1]) / (m_quantize.getY()),(btScalar)(vecInMax[2]) / (m_quantize.getZ()));
345  aabbMax += m_worldAabbMin;
346 }
347 
348 
349 
350 
351 template <typename BP_FP_INT_TYPE>
352 btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
353 :m_bpHandleMask(handleMask),
354 m_handleSentinel(handleSentinel),
355 m_pairCache(pairCache),
356 m_userPairCallback(0),
357 m_ownsPairCache(false),
358 m_invalidPair(0),
359 m_raycastAccelerator(0)
360 {
361  BP_FP_INT_TYPE maxHandles = static_cast<BP_FP_INT_TYPE>(userMaxHandles+1);//need to add one sentinel handle
362 
363  if (!m_pairCache)
364  {
365  void* ptr = btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16);
367  m_ownsPairCache = true;
368  }
369 
370  if (!disableRaycastAccelerator)
371  {
374  m_raycastAccelerator->m_deferedcollide = true;//don't add/remove pairs
375  }
376 
377  //btAssert(bounds.HasVolume());
378 
379  // init bounds
380  m_worldAabbMin = worldAabbMin;
381  m_worldAabbMax = worldAabbMax;
382 
384 
385  BP_FP_INT_TYPE maxInt = m_handleSentinel;
386 
387  m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize;
388 
389  // allocate handles buffer, using btAlignedAlloc, and put all handles on free list
390  m_pHandles = new Handle[maxHandles];
391 
392  m_maxHandles = maxHandles;
393  m_numHandles = 0;
394 
395  // handle 0 is reserved as the null index, and is also used as the sentinel
396  m_firstFreeHandle = 1;
397  {
398  for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++)
399  m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
400  m_pHandles[maxHandles - 1].SetNextFree(0);
401  }
402 
403  {
404  // allocate edge buffers
405  for (int i = 0; i < 3; i++)
406  {
407  m_pEdgesRawPtr[i] = btAlignedAlloc(sizeof(Edge)*maxHandles*2,16);
408  m_pEdges[i] = new(m_pEdgesRawPtr[i]) Edge[maxHandles * 2];
409  }
410  }
411  //removed overlap management
412 
413  // make boundary sentinels
414 
415  m_pHandles[0].m_clientObject = 0;
416 
417  for (int axis = 0; axis < 3; axis++)
418  {
419  m_pHandles[0].m_minEdges[axis] = 0;
420  m_pHandles[0].m_maxEdges[axis] = 1;
421 
422  m_pEdges[axis][0].m_pos = 0;
423  m_pEdges[axis][0].m_handle = 0;
424  m_pEdges[axis][1].m_pos = m_handleSentinel;
425  m_pEdges[axis][1].m_handle = 0;
426 #ifdef DEBUG_BROADPHASE
427  debugPrintAxis(axis);
428 #endif //DEBUG_BROADPHASE
429 
430  }
431 
432 }
433 
434 template <typename BP_FP_INT_TYPE>
436 {
437  if (m_raycastAccelerator)
438  {
439  m_nullPairCache->~btOverlappingPairCache();
440  btAlignedFree(m_nullPairCache);
441  m_raycastAccelerator->~btDbvtBroadphase();
442  btAlignedFree (m_raycastAccelerator);
443  }
444 
445  for (int i = 2; i >= 0; i--)
446  {
447  btAlignedFree(m_pEdgesRawPtr[i]);
448  }
449  delete [] m_pHandles;
450 
451  if (m_ownsPairCache)
452  {
453  m_pairCache->~btOverlappingPairCache();
454  btAlignedFree(m_pairCache);
455  }
456 }
457 
458 template <typename BP_FP_INT_TYPE>
459 void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const
460 {
461 #ifdef OLD_CLAMPING_METHOD
462  btVector3 clampedPoint(point);
465  clampedPoint.setMax(m_worldAabbMin);
466  clampedPoint.setMin(m_worldAabbMax);
467  btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
468  out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & m_bpHandleMask) | isMax);
469  out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & m_bpHandleMask) | isMax);
470  out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax);
471 #else
472  btVector3 v = (point - m_worldAabbMin) * m_quantize;
473  out[0]=(v[0]<=0)?(BP_FP_INT_TYPE)isMax:(v[0]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[0]&m_bpHandleMask)|isMax);
474  out[1]=(v[1]<=0)?(BP_FP_INT_TYPE)isMax:(v[1]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[1]&m_bpHandleMask)|isMax);
475  out[2]=(v[2]<=0)?(BP_FP_INT_TYPE)isMax:(v[2]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[2]&m_bpHandleMask)|isMax);
476 #endif //OLD_CLAMPING_METHOD
477 }
478 
479 
480 template <typename BP_FP_INT_TYPE>
482 {
483  btAssert(m_firstFreeHandle);
484 
485  BP_FP_INT_TYPE handle = m_firstFreeHandle;
486  m_firstFreeHandle = getHandle(handle)->GetNextFree();
487  m_numHandles++;
488 
489  return handle;
490 }
491 
492 template <typename BP_FP_INT_TYPE>
494 {
495  btAssert(handle > 0 && handle < m_maxHandles);
496 
497  getHandle(handle)->SetNextFree(m_firstFreeHandle);
498  m_firstFreeHandle = handle;
499 
500  m_numHandles--;
501 }
502 
503 
504 template <typename BP_FP_INT_TYPE>
505 BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
506 {
507  // quantize the bounds
508  BP_FP_INT_TYPE min[3], max[3];
509  quantize(min, aabbMin, 0);
510  quantize(max, aabbMax, 1);
511 
512  // allocate a handle
513  BP_FP_INT_TYPE handle = allocHandle();
514 
515 
516  Handle* pHandle = getHandle(handle);
517 
518  pHandle->m_uniqueId = static_cast<int>(handle);
519  //pHandle->m_pOverlaps = 0;
520  pHandle->m_clientObject = pOwner;
521  pHandle->m_collisionFilterGroup = collisionFilterGroup;
522  pHandle->m_collisionFilterMask = collisionFilterMask;
523  pHandle->m_multiSapParentProxy = multiSapProxy;
524 
525  // compute current limit of edge arrays
526  BP_FP_INT_TYPE limit = static_cast<BP_FP_INT_TYPE>(m_numHandles * 2);
527 
528 
529  // insert new edges just inside the max boundary edge
530  for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++)
531  {
532 
533  m_pHandles[0].m_maxEdges[axis] += 2;
534 
535  m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1];
536 
537  m_pEdges[axis][limit - 1].m_pos = min[axis];
538  m_pEdges[axis][limit - 1].m_handle = handle;
539 
540  m_pEdges[axis][limit].m_pos = max[axis];
541  m_pEdges[axis][limit].m_handle = handle;
542 
543  pHandle->m_minEdges[axis] = static_cast<BP_FP_INT_TYPE>(limit - 1);
544  pHandle->m_maxEdges[axis] = limit;
545  }
546 
547  // now sort the new edges to their correct position
548  sortMinDown(0, pHandle->m_minEdges[0], dispatcher,false);
549  sortMaxDown(0, pHandle->m_maxEdges[0], dispatcher,false);
550  sortMinDown(1, pHandle->m_minEdges[1], dispatcher,false);
551  sortMaxDown(1, pHandle->m_maxEdges[1], dispatcher,false);
552  sortMinDown(2, pHandle->m_minEdges[2], dispatcher,true);
553  sortMaxDown(2, pHandle->m_maxEdges[2], dispatcher,true);
554 
555 
556  return handle;
557 }
558 
559 
560 template <typename BP_FP_INT_TYPE>
562 {
563 
564  Handle* pHandle = getHandle(handle);
565 
566  //explicitly remove the pairs containing the proxy
567  //we could do it also in the sortMinUp (passing true)
569  if (!m_pairCache->hasDeferredRemoval())
570  {
571  m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher);
572  }
573 
574  // compute current limit of edge arrays
575  int limit = static_cast<int>(m_numHandles * 2);
576 
577  int axis;
578 
579  for (axis = 0;axis<3;axis++)
580  {
581  m_pHandles[0].m_maxEdges[axis] -= 2;
582  }
583 
584  // remove the edges by sorting them up to the end of the list
585  for ( axis = 0; axis < 3; axis++)
586  {
587  Edge* pEdges = m_pEdges[axis];
588  BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis];
589  pEdges[max].m_pos = m_handleSentinel;
590 
591  sortMaxUp(axis,max,dispatcher,false);
592 
593 
594  BP_FP_INT_TYPE i = pHandle->m_minEdges[axis];
595  pEdges[i].m_pos = m_handleSentinel;
596 
597 
598  sortMinUp(axis,i,dispatcher,false);
599 
600  pEdges[limit-1].m_handle = 0;
601  pEdges[limit-1].m_pos = m_handleSentinel;
602 
603 #ifdef DEBUG_BROADPHASE
604  debugPrintAxis(axis,false);
605 #endif //DEBUG_BROADPHASE
606 
607 
608  }
609 
610 
611  // free the handle
612  freeHandle(handle);
613 
614 
615 }
616 
617 template <typename BP_FP_INT_TYPE>
619 {
620  if (m_numHandles == 0)
621  {
622  m_firstFreeHandle = 1;
623  {
624  for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < m_maxHandles; i++)
625  m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
626  m_pHandles[m_maxHandles - 1].SetNextFree(0);
627  }
628  }
629 }
630 
631 
632 extern int gOverlappingPairs;
633 //#include <stdio.h>
634 
635 template <typename BP_FP_INT_TYPE>
637 {
638 
639  if (m_pairCache->hasDeferredRemoval())
640  {
641 
642  btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray();
643 
644  //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
645  overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
646 
647  overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
648  m_invalidPair = 0;
649 
650 
651  int i;
652 
653  btBroadphasePair previousPair;
654  previousPair.m_pProxy0 = 0;
655  previousPair.m_pProxy1 = 0;
656  previousPair.m_algorithm = 0;
657 
658 
659  for (i=0;i<overlappingPairArray.size();i++)
660  {
661 
662  btBroadphasePair& pair = overlappingPairArray[i];
663 
664  bool isDuplicate = (pair == previousPair);
665 
666  previousPair = pair;
667 
668  bool needsRemoval = false;
669 
670  if (!isDuplicate)
671  {
673  bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
674 
675  if (hasOverlap)
676  {
677  needsRemoval = false;//callback->processOverlap(pair);
678  } else
679  {
680  needsRemoval = true;
681  }
682  } else
683  {
684  //remove duplicate
685  needsRemoval = true;
686  //should have no algorithm
687  btAssert(!pair.m_algorithm);
688  }
689 
690  if (needsRemoval)
691  {
692  m_pairCache->cleanOverlappingPair(pair,dispatcher);
693 
694  // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
695  // m_overlappingPairArray.pop_back();
696  pair.m_pProxy0 = 0;
697  pair.m_pProxy1 = 0;
698  m_invalidPair++;
699  gOverlappingPairs--;
700  }
701 
702  }
703 
705  #define CLEAN_INVALID_PAIRS 1
706  #ifdef CLEAN_INVALID_PAIRS
707 
708  //perform a sort, to sort 'invalid' pairs to the end
709  overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
710 
711  overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
712  m_invalidPair = 0;
713  #endif//CLEAN_INVALID_PAIRS
714 
715  //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
716  }
717 
718 }
719 
720 
721 template <typename BP_FP_INT_TYPE>
723 {
724  const Handle* pHandleA = static_cast<Handle*>(proxy0);
725  const Handle* pHandleB = static_cast<Handle*>(proxy1);
726 
727  //optimization 1: check the array index (memory address), instead of the m_pos
728 
729  for (int axis = 0; axis < 3; axis++)
730  {
731  if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] ||
732  pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis])
733  {
734  return false;
735  }
736  }
737  return true;
738 }
739 
740 template <typename BP_FP_INT_TYPE>
741 bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1)
742 {
743  //optimization 1: check the array index (memory address), instead of the m_pos
744 
745  if (pHandleA->m_maxEdges[axis0] < pHandleB->m_minEdges[axis0] ||
746  pHandleB->m_maxEdges[axis0] < pHandleA->m_minEdges[axis0] ||
747  pHandleA->m_maxEdges[axis1] < pHandleB->m_minEdges[axis1] ||
748  pHandleB->m_maxEdges[axis1] < pHandleA->m_minEdges[axis1])
749  {
750  return false;
751  }
752  return true;
753 }
754 
755 template <typename BP_FP_INT_TYPE>
756 void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher)
757 {
758 // btAssert(bounds.IsFinite());
759  //btAssert(bounds.HasVolume());
760 
761  Handle* pHandle = getHandle(handle);
762 
763  // quantize the new bounds
764  BP_FP_INT_TYPE min[3], max[3];
765  quantize(min, aabbMin, 0);
766  quantize(max, aabbMax, 1);
767 
768  // update changed edges
769  for (int axis = 0; axis < 3; axis++)
770  {
771  BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis];
772  BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis];
773 
774  int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos;
775  int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos;
776 
777  m_pEdges[axis][emin].m_pos = min[axis];
778  m_pEdges[axis][emax].m_pos = max[axis];
779 
780  // expand (only adds overlaps)
781  if (dmin < 0)
782  sortMinDown(axis, emin,dispatcher,true);
783 
784  if (dmax > 0)
785  sortMaxUp(axis, emax,dispatcher,true);
786 
787  // shrink (only removes overlaps)
788  if (dmin > 0)
789  sortMinUp(axis, emin,dispatcher,true);
790 
791  if (dmax < 0)
792  sortMaxDown(axis, emax,dispatcher,true);
793 
794 #ifdef DEBUG_BROADPHASE
795  debugPrintAxis(axis);
796 #endif //DEBUG_BROADPHASE
797  }
798 
799 
800 }
801 
802 
803 
804 
805 // sorting a min edge downwards can only ever *add* overlaps
806 template <typename BP_FP_INT_TYPE>
807 void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps)
808 {
809 
810  Edge* pEdge = m_pEdges[axis] + edge;
811  Edge* pPrev = pEdge - 1;
812  Handle* pHandleEdge = getHandle(pEdge->m_handle);
813 
814  while (pEdge->m_pos < pPrev->m_pos)
815  {
816  Handle* pHandlePrev = getHandle(pPrev->m_handle);
817 
818  if (pPrev->IsMax())
819  {
820  // if previous edge is a maximum check the bounds and add an overlap if necessary
821  const int axis1 = (1 << axis) & 3;
822  const int axis2 = (1 << axis1) & 3;
823  if (updateOverlaps && testOverlap2D(pHandleEdge, pHandlePrev,axis1,axis2))
824  {
825  m_pairCache->addOverlappingPair(pHandleEdge,pHandlePrev);
826  if (m_userPairCallback)
827  m_userPairCallback->addOverlappingPair(pHandleEdge,pHandlePrev);
828 
829  //AddOverlap(pEdge->m_handle, pPrev->m_handle);
830 
831  }
832 
833  // update edge reference in other handle
834  pHandlePrev->m_maxEdges[axis]++;
835  }
836  else
837  pHandlePrev->m_minEdges[axis]++;
838 
839  pHandleEdge->m_minEdges[axis]--;
840 
841  // swap the edges
842  Edge swap = *pEdge;
843  *pEdge = *pPrev;
844  *pPrev = swap;
845 
846  // decrement
847  pEdge--;
848  pPrev--;
849  }
850 
851 #ifdef DEBUG_BROADPHASE
852  debugPrintAxis(axis);
853 #endif //DEBUG_BROADPHASE
854 
855 }
856 
857 // sorting a min edge upwards can only ever *remove* overlaps
858 template <typename BP_FP_INT_TYPE>
859 void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
860 {
861  Edge* pEdge = m_pEdges[axis] + edge;
862  Edge* pNext = pEdge + 1;
863  Handle* pHandleEdge = getHandle(pEdge->m_handle);
864 
865  while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
866  {
867  Handle* pHandleNext = getHandle(pNext->m_handle);
868 
869  if (pNext->IsMax())
870  {
871  Handle* handle0 = getHandle(pEdge->m_handle);
872  Handle* handle1 = getHandle(pNext->m_handle);
873  const int axis1 = (1 << axis) & 3;
874  const int axis2 = (1 << axis1) & 3;
875 
876  // if next edge is maximum remove any overlap between the two handles
877  if (updateOverlaps
879  && testOverlap2D(handle0,handle1,axis1,axis2)
880 #endif //USE_OVERLAP_TEST_ON_REMOVES
881  )
882  {
883 
884 
885  m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher);
886  if (m_userPairCallback)
887  m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher);
888 
889  }
890 
891 
892  // update edge reference in other handle
893  pHandleNext->m_maxEdges[axis]--;
894  }
895  else
896  pHandleNext->m_minEdges[axis]--;
897 
898  pHandleEdge->m_minEdges[axis]++;
899 
900  // swap the edges
901  Edge swap = *pEdge;
902  *pEdge = *pNext;
903  *pNext = swap;
904 
905  // increment
906  pEdge++;
907  pNext++;
908  }
909 
910 
911 }
912 
913 // sorting a max edge downwards can only ever *remove* overlaps
914 template <typename BP_FP_INT_TYPE>
915 void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
916 {
917 
918  Edge* pEdge = m_pEdges[axis] + edge;
919  Edge* pPrev = pEdge - 1;
920  Handle* pHandleEdge = getHandle(pEdge->m_handle);
921 
922  while (pEdge->m_pos < pPrev->m_pos)
923  {
924  Handle* pHandlePrev = getHandle(pPrev->m_handle);
925 
926  if (!pPrev->IsMax())
927  {
928  // if previous edge was a minimum remove any overlap between the two handles
929  Handle* handle0 = getHandle(pEdge->m_handle);
930  Handle* handle1 = getHandle(pPrev->m_handle);
931  const int axis1 = (1 << axis) & 3;
932  const int axis2 = (1 << axis1) & 3;
933 
934  if (updateOverlaps
936  && testOverlap2D(handle0,handle1,axis1,axis2)
937 #endif //USE_OVERLAP_TEST_ON_REMOVES
938  )
939  {
940  //this is done during the overlappingpairarray iteration/narrowphase collision
941 
942 
943  m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher);
944  if (m_userPairCallback)
945  m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher);
946 
947 
948 
949  }
950 
951  // update edge reference in other handle
952  pHandlePrev->m_minEdges[axis]++;;
953  }
954  else
955  pHandlePrev->m_maxEdges[axis]++;
956 
957  pHandleEdge->m_maxEdges[axis]--;
958 
959  // swap the edges
960  Edge swap = *pEdge;
961  *pEdge = *pPrev;
962  *pPrev = swap;
963 
964  // decrement
965  pEdge--;
966  pPrev--;
967  }
968 
969 
970 #ifdef DEBUG_BROADPHASE
971  debugPrintAxis(axis);
972 #endif //DEBUG_BROADPHASE
973 
974 }
975 
976 // sorting a max edge upwards can only ever *add* overlaps
977 template <typename BP_FP_INT_TYPE>
978 void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps)
979 {
980  Edge* pEdge = m_pEdges[axis] + edge;
981  Edge* pNext = pEdge + 1;
982  Handle* pHandleEdge = getHandle(pEdge->m_handle);
983 
984  while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
985  {
986  Handle* pHandleNext = getHandle(pNext->m_handle);
987 
988  const int axis1 = (1 << axis) & 3;
989  const int axis2 = (1 << axis1) & 3;
990 
991  if (!pNext->IsMax())
992  {
993  // if next edge is a minimum check the bounds and add an overlap if necessary
994  if (updateOverlaps && testOverlap2D(pHandleEdge, pHandleNext,axis1,axis2))
995  {
996  Handle* handle0 = getHandle(pEdge->m_handle);
997  Handle* handle1 = getHandle(pNext->m_handle);
998  m_pairCache->addOverlappingPair(handle0,handle1);
999  if (m_userPairCallback)
1000  m_userPairCallback->addOverlappingPair(handle0,handle1);
1001  }
1002 
1003  // update edge reference in other handle
1004  pHandleNext->m_minEdges[axis]--;
1005  }
1006  else
1007  pHandleNext->m_maxEdges[axis]--;
1008 
1009  pHandleEdge->m_maxEdges[axis]++;
1010 
1011  // swap the edges
1012  Edge swap = *pEdge;
1013  *pEdge = *pNext;
1014  *pNext = swap;
1015 
1016  // increment
1017  pEdge++;
1018  pNext++;
1019  }
1020 
1021 }
1022 
1023 
1024 
1026 
1027 
1031 class btAxisSweep3 : public btAxisSweep3Internal<unsigned short int>
1032 {
1033 public:
1034 
1035  btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
1036 
1037 };
1038 
1042 class bt32BitAxisSweep3 : public btAxisSweep3Internal<unsigned int>
1043 {
1044 public:
1045 
1046  bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
1047 
1048 };
1049 
1050 #endif
1051 
virtual void resetPool(btDispatcher *dispatcher)
reset broadphase internal structures, to ensure determinism/reproducability
Definition: btAxisSweep3.h:618
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: btAxisSweep3.h:270
virtual void getAabb(btBroadphaseProxy *proxy, btVector3 &aabbMin, btVector3 &aabbMax) const
Definition: btAxisSweep3.h:318
virtual btBroadphaseProxy * createProxy(const btVector3 &aabbMin, const btVector3 &aabbMax, int shapeType, void *userPtr, short int collisionFilterGroup, short int collisionFilterMask, btDispatcher *dispatcher, void *multiSapProxy)
Definition: btAxisSweep3.h:231
bt32BitAxisSweep3(const btVector3 &worldAabbMin, const btVector3 &worldAabbMax, unsigned int maxHandles=1500000, btOverlappingPairCache *pairCache=0, bool disableRaycastAccelerator=false)
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:640
The btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase.
Handle * getHandle(BP_FP_INT_TYPE index) const
Definition: btAxisSweep3.h:140
btBroadphaseProxy * m_dbvtProxy
Definition: btAxisSweep3.h:65
btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing...
BP_FP_INT_TYPE getNumHandles() const
Definition: btAxisSweep3.h:130
short int m_collisionFilterGroup
void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher *dispatcher, bool updateOverlaps)
Definition: btAxisSweep3.h:978
#define USE_OVERLAP_TEST_ON_REMOVES
Definition: btAxisSweep3.h:30
virtual void printStats()
Definition: btAxisSweep3.h:188
void freeHandle(BP_FP_INT_TYPE handle)
Definition: btAxisSweep3.h:493
#define btAssert(x)
Definition: btScalar.h:101
#define SIMD_FORCE_INLINE
Definition: btScalar.h:58
The btDbvtBroadphase implements a broadphase using two dynamic AABB bounding volume hierarchies/trees...
btVector3 m_worldAabbMin
Definition: btAxisSweep3.h:74
BP_FP_INT_TYPE m_handleSentinel
Definition: btAxisSweep3.h:41
void processAllOverlappingPairs(btOverlapCallback *callback)
BP_FP_INT_TYPE m_firstFreeHandle
Definition: btAxisSweep3.h:83
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
void removeHandle(BP_FP_INT_TYPE handle, btDispatcher *dispatcher)
Definition: btAxisSweep3.h:561
BP_FP_INT_TYPE m_minEdges[3]
Definition: btAxisSweep3.h:63
BP_FP_INT_TYPE addHandle(const btVector3 &aabbMin, const btVector3 &aabbMax, void *pOwner, short int collisionFilterGroup, short int collisionFilterMask, btDispatcher *dispatcher, void *multiSapProxy)
Definition: btAxisSweep3.h:505
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:565
The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
void unQuantize(btBroadphaseProxy *proxy, btVector3 &aabbMin, btVector3 &aabbMax) const
unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result ...
Definition: btAxisSweep3.h:327
bool testAabbOverlap(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
Definition: btAxisSweep3.h:722
int size() const
return the number of elements in the array
const btOverlappingPairCallback * getOverlappingPairUserCallback() const
Definition: btAxisSweep3.h:175
BP_FP_INT_TYPE m_maxHandles
Definition: btAxisSweep3.h:80
virtual void calculateOverlappingPairs(btDispatcher *dispatcher)
calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during th...
Definition: btAxisSweep3.h:636
static float max(float a, float b)
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
Definition: btAxisSweep3.h:249
int gOverlappingPairs
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:563
void updateHandle(BP_FP_INT_TYPE handle, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)
Definition: btAxisSweep3.h:756
#define btAlignedFree(ptr)
BP_FP_INT_TYPE m_maxEdges[3]
Definition: btAxisSweep3.h:63
void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher *dispatcher, bool updateOverlaps)
Definition: btAxisSweep3.h:859
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)
Definition: btAxisSweep3.h:258
void setOverlappingPairUserCallback(btOverlappingPairCallback *pairCallback)
Definition: btAxisSweep3.h:171
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:561
bool testOverlap2D(const Handle *pHandleA, const Handle *pHandleB, int axis0, int axis1)
Definition: btAxisSweep3.h:741
BP_FP_INT_TYPE m_bpHandleMask
Definition: btAxisSweep3.h:40
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs...
virtual void getBroadphaseAabb(btVector3 &aabbMin, btVector3 &aabbMax) const
getAabb returns the axis aligned bounding box in the 'global' coordinate frame will add some transfor...
Definition: btAxisSweep3.h:182
BP_FP_INT_TYPE GetNextFree() const
Definition: btAxisSweep3.h:69
static float min(float a, float b)
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
btBroadphaseProxy * m_pProxy1
void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher *dispatcher, bool updateOverlaps)
Definition: btAxisSweep3.h:807
btCollisionAlgorithm * m_algorithm
btOverlappingPairCache * m_nullPairCache
Definition: btAxisSweep3.h:100
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
virtual bool process(const btBroadphaseProxy *proxy)=0
btOverlappingPairCache * m_pairCache
Definition: btAxisSweep3.h:88
btBroadphaseProxy * m_pProxy0
void * m_pEdgesRawPtr[3]
Definition: btAxisSweep3.h:86
btDbvtBroadphase * m_raycastAccelerator
additional dynamic aabb structure, used to accelerate ray cast queries.
Definition: btAxisSweep3.h:99
BP_FP_INT_TYPE IsMax() const
Definition: btAxisSweep3.h:53
btVector3 m_worldAabbMax
Definition: btAxisSweep3.h:75
const btOverlappingPairCache * getOverlappingPairCache() const
Definition: btAxisSweep3.h:166
BP_FP_INT_TYPE allocHandle()
Definition: btAxisSweep3.h:481
void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher *dispatcher, bool updateOverlaps)
Definition: btAxisSweep3.h:915
void resize(int newsize, const T &fillData=T())
The internal templace class btAxisSweep3Internal implements the sweep and prune broadphase.
Definition: btAxisSweep3.h:36
The bt32BitAxisSweep3 allows higher precision quantization and more objects compared to the btAxisSwe...
btOverlappingPairCache * getOverlappingPairCache()
Definition: btAxisSweep3.h:162
void SetNextFree(BP_FP_INT_TYPE next)
Definition: btAxisSweep3.h:68
void quantize(BP_FP_INT_TYPE *out, const btVector3 &point, int isMax) const
Definition: btAxisSweep3.h:459
#define btAlignedAlloc(size, alignment)
short int m_collisionFilterMask
BP_FP_INT_TYPE m_numHandles
Definition: btAxisSweep3.h:79
btAxisSweep3(const btVector3 &worldAabbMin, const btVector3 &worldAabbMax, unsigned short int maxHandles=16384, btOverlappingPairCache *pairCache=0, bool disableRaycastAccelerator=false)
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
Definition: btVector3.h:609
virtual ~btAxisSweep3Internal()
Definition: btAxisSweep3.h:435
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:69
btAxisSweep3Internal(const btVector3 &worldAabbMin, const btVector3 &worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles=16384, btOverlappingPairCache *pairCache=0, bool disableRaycastAccelerator=false)
Definition: btAxisSweep3.h:352
Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman...
The btOverlappingPairCallback class is an additional optional broadphase user callback for adding/rem...
void setMin(const btVector3 &other)
Set each element to the min of the current values and the values of another btVector3.
Definition: btVector3.h:626
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:266
void quickSort(const L &CompareFunc)
virtual void aabbTest(const btVector3 &aabbMin, const btVector3 &aabbMax, btBroadphaseAabbCallback &callback)
Definition: btAxisSweep3.h:291
btOverlappingPairCallback * m_userPairCallback
btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pai...
Definition: btAxisSweep3.h:91
The btBroadphasePair class contains a pair of aabb-overlapping objects.