19 #ifndef BT_AXIS_SWEEP_3_H
20 #define BT_AXIS_SWEEP_3_H
30 #define USE_OVERLAP_TEST_ON_REMOVES 1
35 template <
typename BP_FP_INT_TYPE>
53 BP_FP_INT_TYPE
IsMax()
const {
return static_cast<BP_FP_INT_TYPE
>(
m_pos & 1);}
108 bool testOverlap2D(
const Handle* pHandleA,
const Handle* pHandleB,
int axis0,
int axis1);
110 #ifdef DEBUG_BROADPHASE
111 void debugPrintAxis(
int axis,
bool checkCardinality=
true);
112 #endif //DEBUG_BROADPHASE
137 BP_FP_INT_TYPE
addHandle(
const btVector3& aabbMin,
const btVector3& aabbMax,
void* pOwner,
short int collisionFilterGroup,
short int collisionFilterMask,
btDispatcher* dispatcher,
void* multiSapProxy);
205 #ifdef DEBUG_BROADPHASE
208 template <
typename BP_FP_INT_TYPE>
211 int numEdges = m_pHandles[0].m_maxEdges[axis];
212 printf(
"SAP Axis %d, numEdges=%d\n",axis,numEdges);
215 for (i=0;i<numEdges+1;i++)
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];
221 beginOrEnd=pEdge->IsMax()?
'E':
'B';
222 printf(
" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex);
225 if (checkCardinality)
226 btAssert(numEdges == m_numHandles*2+1);
228 #endif //DEBUG_BROADPHASE
230 template <
typename BP_FP_INT_TYPE>
234 BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,multiSapProxy);
236 Handle* handle = getHandle(handleId);
238 if (m_raycastAccelerator)
240 btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,0);
248 template <
typename BP_FP_INT_TYPE>
252 if (m_raycastAccelerator)
253 m_raycastAccelerator->destroyProxy(handle->
m_dbvtProxy,dispatcher);
254 removeHandle(static_cast<BP_FP_INT_TYPE>(handle->
m_uniqueId), dispatcher);
257 template <
typename BP_FP_INT_TYPE>
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);
269 template <
typename BP_FP_INT_TYPE>
272 if (m_raycastAccelerator)
274 m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback,aabbMin,aabbMax);
278 BP_FP_INT_TYPE axis = 0;
280 for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++)
282 if (m_pEdges[axis][i].IsMax())
284 rayCallback.
process(getHandle(m_pEdges[axis][i].m_handle));
290 template <
typename BP_FP_INT_TYPE>
293 if (m_raycastAccelerator)
295 m_raycastAccelerator->aabbTest(aabbMin,aabbMax,callback);
299 BP_FP_INT_TYPE axis = 0;
301 for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++)
303 if (m_pEdges[axis][i].IsMax())
305 Handle* handle = getHandle(m_pEdges[axis][i].m_handle);
317 template <
typename BP_FP_INT_TYPE>
326 template <
typename BP_FP_INT_TYPE>
331 unsigned short vecInMin[3];
332 unsigned short vecInMax[3];
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 ;
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;
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;
351 template <
typename BP_FP_INT_TYPE>
353 :m_bpHandleMask(handleMask),
354 m_handleSentinel(handleSentinel),
355 m_pairCache(pairCache),
356 m_userPairCallback(0),
357 m_ownsPairCache(false),
359 m_raycastAccelerator(0)
361 BP_FP_INT_TYPE maxHandles =
static_cast<BP_FP_INT_TYPE
>(userMaxHandles+1);
370 if (!disableRaycastAccelerator)
399 m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
405 for (
int i = 0; i < 3; i++)
417 for (
int axis = 0; axis < 3; axis++)
426 #ifdef DEBUG_BROADPHASE
427 debugPrintAxis(axis);
428 #endif //DEBUG_BROADPHASE
434 template <
typename BP_FP_INT_TYPE>
437 if (m_raycastAccelerator)
439 m_nullPairCache->~btOverlappingPairCache();
441 m_raycastAccelerator->~btDbvtBroadphase();
445 for (
int i = 2; i >= 0; i--)
449 delete [] m_pHandles;
453 m_pairCache->~btOverlappingPairCache();
458 template <
typename BP_FP_INT_TYPE>
461 #ifdef OLD_CLAMPING_METHOD
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);
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
480 template <
typename BP_FP_INT_TYPE>
485 BP_FP_INT_TYPE handle = m_firstFreeHandle;
486 m_firstFreeHandle = getHandle(handle)->GetNextFree();
492 template <
typename BP_FP_INT_TYPE>
495 btAssert(handle > 0 && handle < m_maxHandles);
497 getHandle(handle)->SetNextFree(m_firstFreeHandle);
498 m_firstFreeHandle = handle;
504 template <
typename BP_FP_INT_TYPE>
508 BP_FP_INT_TYPE
min[3],
max[3];
509 quantize(min, aabbMin, 0);
510 quantize(max, aabbMax, 1);
513 BP_FP_INT_TYPE handle = allocHandle();
516 Handle* pHandle = getHandle(handle);
518 pHandle->
m_uniqueId =
static_cast<int>(handle);
526 BP_FP_INT_TYPE limit =
static_cast<BP_FP_INT_TYPE
>(m_numHandles * 2);
530 for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++)
533 m_pHandles[0].m_maxEdges[axis] += 2;
535 m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1];
537 m_pEdges[axis][limit - 1].m_pos = min[axis];
538 m_pEdges[axis][limit - 1].m_handle = handle;
540 m_pEdges[axis][limit].m_pos = max[axis];
541 m_pEdges[axis][limit].m_handle = handle;
543 pHandle->
m_minEdges[axis] =
static_cast<BP_FP_INT_TYPE
>(limit - 1);
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);
560 template <
typename BP_FP_INT_TYPE>
564 Handle* pHandle = getHandle(handle);
569 if (!m_pairCache->hasDeferredRemoval())
571 m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher);
575 int limit =
static_cast<int>(m_numHandles * 2);
579 for (axis = 0;axis<3;axis++)
581 m_pHandles[0].m_maxEdges[axis] -= 2;
585 for ( axis = 0; axis < 3; axis++)
587 Edge* pEdges = m_pEdges[axis];
589 pEdges[
max].
m_pos = m_handleSentinel;
591 sortMaxUp(axis,max,dispatcher,
false);
595 pEdges[i].
m_pos = m_handleSentinel;
598 sortMinUp(axis,i,dispatcher,
false);
601 pEdges[limit-1].
m_pos = m_handleSentinel;
603 #ifdef DEBUG_BROADPHASE
604 debugPrintAxis(axis,
false);
605 #endif //DEBUG_BROADPHASE
617 template <
typename BP_FP_INT_TYPE>
620 if (m_numHandles == 0)
622 m_firstFreeHandle = 1;
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);
635 template <
typename BP_FP_INT_TYPE>
639 if (m_pairCache->hasDeferredRemoval())
647 overlappingPairArray.
resize(overlappingPairArray.
size() - m_invalidPair);
659 for (i=0;i<overlappingPairArray.
size();i++)
664 bool isDuplicate = (pair == previousPair);
668 bool needsRemoval =
false;
677 needsRemoval =
false;
692 m_pairCache->cleanOverlappingPair(pair,dispatcher);
705 #define CLEAN_INVALID_PAIRS 1
706 #ifdef CLEAN_INVALID_PAIRS
711 overlappingPairArray.
resize(overlappingPairArray.
size() - m_invalidPair);
713 #endif//CLEAN_INVALID_PAIRS
721 template <
typename BP_FP_INT_TYPE>
729 for (
int axis = 0; axis < 3; axis++)
740 template <
typename BP_FP_INT_TYPE>
755 template <
typename BP_FP_INT_TYPE>
761 Handle* pHandle = getHandle(handle);
764 BP_FP_INT_TYPE
min[3],
max[3];
765 quantize(min, aabbMin, 0);
766 quantize(max, aabbMax, 1);
769 for (
int axis = 0; axis < 3; axis++)
771 BP_FP_INT_TYPE emin = pHandle->
m_minEdges[axis];
772 BP_FP_INT_TYPE emax = pHandle->
m_maxEdges[axis];
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;
777 m_pEdges[axis][emin].m_pos = min[axis];
778 m_pEdges[axis][emax].m_pos = max[axis];
782 sortMinDown(axis, emin,dispatcher,
true);
785 sortMaxUp(axis, emax,dispatcher,
true);
789 sortMinUp(axis, emin,dispatcher,
true);
792 sortMaxDown(axis, emax,dispatcher,
true);
794 #ifdef DEBUG_BROADPHASE
795 debugPrintAxis(axis);
796 #endif //DEBUG_BROADPHASE
806 template <
typename BP_FP_INT_TYPE>
810 Edge* pEdge = m_pEdges[axis] + edge;
811 Edge* pPrev = pEdge - 1;
821 const int axis1 = (1 << axis) & 3;
822 const int axis2 = (1 << axis1) & 3;
823 if (updateOverlaps && testOverlap2D(pHandleEdge, pHandlePrev,axis1,axis2))
825 m_pairCache->addOverlappingPair(pHandleEdge,pHandlePrev);
826 if (m_userPairCallback)
827 m_userPairCallback->addOverlappingPair(pHandleEdge,pHandlePrev);
851 #ifdef DEBUG_BROADPHASE
852 debugPrintAxis(axis);
853 #endif //DEBUG_BROADPHASE
858 template <
typename BP_FP_INT_TYPE>
861 Edge* pEdge = m_pEdges[axis] + edge;
862 Edge* pNext = pEdge + 1;
873 const int axis1 = (1 << axis) & 3;
874 const int axis2 = (1 << axis1) & 3;
879 && testOverlap2D(handle0,handle1,axis1,axis2)
880 #endif //USE_OVERLAP_TEST_ON_REMOVES
885 m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher);
886 if (m_userPairCallback)
887 m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher);
914 template <
typename BP_FP_INT_TYPE>
918 Edge* pEdge = m_pEdges[axis] + edge;
919 Edge* pPrev = pEdge - 1;
931 const int axis1 = (1 << axis) & 3;
932 const int axis2 = (1 << axis1) & 3;
936 && testOverlap2D(handle0,handle1,axis1,axis2)
937 #endif //USE_OVERLAP_TEST_ON_REMOVES
943 m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher);
944 if (m_userPairCallback)
945 m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher);
970 #ifdef DEBUG_BROADPHASE
971 debugPrintAxis(axis);
972 #endif //DEBUG_BROADPHASE
977 template <
typename BP_FP_INT_TYPE>
980 Edge* pEdge = m_pEdges[axis] + edge;
981 Edge* pNext = pEdge + 1;
988 const int axis1 = (1 << axis) & 3;
989 const int axis2 = (1 << axis1) & 3;
994 if (updateOverlaps && testOverlap2D(pHandleEdge, pHandleNext,axis1,axis2))
998 m_pairCache->addOverlappingPair(handle0,handle1);
999 if (m_userPairCallback)
1000 m_userPairCallback->addOverlappingPair(handle0,handle1);
virtual void resetPool(btDispatcher *dispatcher)
reset broadphase internal structures, to ensure determinism/reproducability
void * m_multiSapParentProxy
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 void getAabb(btBroadphaseProxy *proxy, btVector3 &aabbMin, btVector3 &aabbMax) const
virtual btBroadphaseProxy * createProxy(const btVector3 &aabbMin, const btVector3 &aabbMax, int shapeType, void *userPtr, short int collisionFilterGroup, short int collisionFilterMask, btDispatcher *dispatcher, void *multiSapProxy)
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)
The btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase.
Handle * getHandle(BP_FP_INT_TYPE index) const
btBroadphaseProxy * m_dbvtProxy
btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing...
BP_FP_INT_TYPE getNumHandles() const
short int m_collisionFilterGroup
void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher *dispatcher, bool updateOverlaps)
#define USE_OVERLAP_TEST_ON_REMOVES
virtual void printStats()
void freeHandle(BP_FP_INT_TYPE handle)
#define SIMD_FORCE_INLINE
The btDbvtBroadphase implements a broadphase using two dynamic AABB bounding volume hierarchies/trees...
BP_FP_INT_TYPE m_handleSentinel
void processAllOverlappingPairs(btOverlapCallback *callback)
BP_FP_INT_TYPE m_firstFreeHandle
bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, const btVector3 &aabbMin2, const btVector3 &aabbMax2)
conservative test for overlap between two aabbs
void removeHandle(BP_FP_INT_TYPE handle, btDispatcher *dispatcher)
BP_FP_INT_TYPE m_minEdges[3]
BP_FP_INT_TYPE addHandle(const btVector3 &aabbMin, const btVector3 &aabbMax, void *pOwner, short int collisionFilterGroup, short int collisionFilterMask, btDispatcher *dispatcher, void *multiSapProxy)
BT_DECLARE_ALIGNED_ALLOCATOR()
const btScalar & getZ() const
Return the z value.
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 ...
bool testAabbOverlap(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
int size() const
return the number of elements in the array
const btOverlappingPairCallback * getOverlappingPairUserCallback() const
BP_FP_INT_TYPE m_maxHandles
virtual void calculateOverlappingPairs(btDispatcher *dispatcher)
calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during th...
static float max(float a, float b)
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
const btScalar & getY() const
Return the y value.
void updateHandle(BP_FP_INT_TYPE handle, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)
#define btAlignedFree(ptr)
BP_FP_INT_TYPE m_maxEdges[3]
void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher *dispatcher, bool updateOverlaps)
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)
void setOverlappingPairUserCallback(btOverlappingPairCallback *pairCallback)
const btScalar & getX() const
Return the x value.
bool testOverlap2D(const Handle *pHandleA, const Handle *pHandleB, int axis0, int axis1)
BP_FP_INT_TYPE m_bpHandleMask
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...
BP_FP_INT_TYPE GetNextFree() const
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)
btCollisionAlgorithm * m_algorithm
btOverlappingPairCache * m_nullPairCache
btVector3 can be used to represent 3D points and vectors.
virtual bool process(const btBroadphaseProxy *proxy)=0
btOverlappingPairCache * m_pairCache
btBroadphaseProxy * m_pProxy0
btDbvtBroadphase * m_raycastAccelerator
additional dynamic aabb structure, used to accelerate ray cast queries.
BP_FP_INT_TYPE IsMax() const
const btOverlappingPairCache * getOverlappingPairCache() const
BP_FP_INT_TYPE allocHandle()
void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher *dispatcher, bool updateOverlaps)
void resize(int newsize, const T &fillData=T())
The internal templace class btAxisSweep3Internal implements the sweep and prune broadphase.
The bt32BitAxisSweep3 allows higher precision quantization and more objects compared to the btAxisSwe...
btOverlappingPairCache * getOverlappingPairCache()
void SetNextFree(BP_FP_INT_TYPE next)
void quantize(BP_FP_INT_TYPE *out, const btVector3 &point, int isMax) const
#define btAlignedAlloc(size, alignment)
short int m_collisionFilterMask
BP_FP_INT_TYPE m_numHandles
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.
virtual ~btAxisSweep3Internal()
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
BT_DECLARE_ALIGNED_ALLOCATOR()
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)
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.
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
void quickSort(const L &CompareFunc)
virtual void aabbTest(const btVector3 &aabbMin, const btVector3 &aabbMax, btBroadphaseAabbCallback &callback)
btOverlappingPairCallback * m_userPairCallback
btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pai...
The btBroadphasePair class contains a pair of aabb-overlapping objects.