19#ifndef BT_AXIS_SWEEP_3_INTERNAL_H
20#define BT_AXIS_SWEEP_3_INTERNAL_H
30#define USE_OVERLAP_TEST_ON_REMOVES 1
35template <
typename BP_FP_INT_TYPE>
51 BP_FP_INT_TYPE
IsMax()
const {
return static_cast<BP_FP_INT_TYPE
>(
m_pos & 1); }
55 class Handle :
public btBroadphaseProxy
103 bool testOverlap2D(
const Handle* pHandleA,
const Handle* pHandleB,
int axis0,
int axis1);
105#ifdef DEBUG_BROADPHASE
106 void debugPrintAxis(
int axis,
bool checkCardinality =
true);
118 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);
129 BP_FP_INT_TYPE
addHandle(
const btVector3& aabbMin,
const btVector3& aabbMax,
void* pOwner,
int collisionFilterGroup,
int collisionFilterMask,
btDispatcher* dispatcher);
139 virtual btBroadphaseProxy*
createProxy(
const btVector3& aabbMin,
const btVector3& aabbMax,
int shapeType,
void* userPtr,
int collisionFilterGroup,
int collisionFilterMask,
btDispatcher* dispatcher);
141 virtual void setAabb(btBroadphaseProxy* proxy,
const btVector3& aabbMin,
const btVector3& aabbMax,
btDispatcher* dispatcher);
142 virtual void getAabb(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax)
const;
147 void quantize(BP_FP_INT_TYPE* out,
const btVector3& point,
int isMax)
const;
149 void unQuantize(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax)
const;
191#ifdef DEBUG_BROADPHASE
194template <
typename BP_FP_INT_TYPE>
197 int numEdges = m_pHandles[0].
m_maxEdges[axis];
198 printf(
"SAP Axis %d, numEdges=%d\n", axis, numEdges);
201 for (i = 0; i < numEdges + 1; i++)
203 Edge* pEdge = m_pEdges[axis] + i;
204 Handle* pHandlePrev = getHandle(pEdge->m_handle);
205 int handleIndex = pEdge->IsMax() ? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis];
207 beginOrEnd = pEdge->IsMax() ?
'E' :
'B';
208 printf(
" [%c,h=%d,p=%x,i=%d]\n", beginOrEnd, pEdge->m_handle, pEdge->m_pos, handleIndex);
211 if (checkCardinality)
212 btAssert(numEdges == m_numHandles * 2 + 1);
216template <
typename BP_FP_INT_TYPE>
220 BP_FP_INT_TYPE handleId = addHandle(aabbMin, aabbMax, userPtr, collisionFilterGroup, collisionFilterMask, dispatcher);
222 Handle* handle = getHandle(handleId);
224 if (m_raycastAccelerator)
226 btBroadphaseProxy* rayProxy = m_raycastAccelerator->
createProxy(aabbMin, aabbMax, shapeType, userPtr, collisionFilterGroup, collisionFilterMask, dispatcher);
227 handle->m_dbvtProxy = rayProxy;
232template <
typename BP_FP_INT_TYPE>
236 if (m_raycastAccelerator)
237 m_raycastAccelerator->
destroyProxy(handle->m_dbvtProxy, dispatcher);
238 removeHandle(
static_cast<BP_FP_INT_TYPE
>(handle->m_uniqueId), dispatcher);
241template <
typename BP_FP_INT_TYPE>
245 handle->m_aabbMin = aabbMin;
246 handle->m_aabbMax = aabbMax;
247 updateHandle(
static_cast<BP_FP_INT_TYPE
>(handle->m_uniqueId), aabbMin, aabbMax, dispatcher);
248 if (m_raycastAccelerator)
249 m_raycastAccelerator->
setAabb(handle->m_dbvtProxy, aabbMin, aabbMax, dispatcher);
252template <
typename BP_FP_INT_TYPE>
255 if (m_raycastAccelerator)
257 m_raycastAccelerator->
rayTest(rayFrom, rayTo, rayCallback, aabbMin, aabbMax);
262 BP_FP_INT_TYPE axis = 0;
264 for (BP_FP_INT_TYPE i = 1; i < m_numHandles * 2 + 1; i++)
266 if (m_pEdges[axis][i].IsMax())
268 rayCallback.
process(getHandle(m_pEdges[axis][i].m_handle));
274template <
typename BP_FP_INT_TYPE>
277 if (m_raycastAccelerator)
284 BP_FP_INT_TYPE axis = 0;
286 for (BP_FP_INT_TYPE i = 1; i < m_numHandles * 2 + 1; i++)
288 if (m_pEdges[axis][i].IsMax())
290 Handle* handle = getHandle(m_pEdges[axis][i].m_handle);
300template <
typename BP_FP_INT_TYPE>
304 aabbMin = pHandle->m_aabbMin;
305 aabbMax = pHandle->m_aabbMax;
308template <
typename BP_FP_INT_TYPE>
313 unsigned short vecInMin[3];
314 unsigned short vecInMax[3];
323 aabbMin.setValue((
btScalar)(vecInMin[0]) / (m_quantize.getX()), (
btScalar)(vecInMin[1]) / (m_quantize.getY()), (
btScalar)(vecInMin[2]) / (m_quantize.getZ()));
324 aabbMin += m_worldAabbMin;
326 aabbMax.setValue((
btScalar)(vecInMax[0]) / (m_quantize.getX()), (
btScalar)(vecInMax[1]) / (m_quantize.getY()), (
btScalar)(vecInMax[2]) / (m_quantize.getZ()));
327 aabbMax += m_worldAabbMin;
330template <
typename BP_FP_INT_TYPE>
332 : m_bpHandleMask(handleMask),
333 m_handleSentinel(handleSentinel),
334 m_pairCache(pairCache),
335 m_userPairCallback(0),
336 m_ownsPairCache(
false),
338 m_raycastAccelerator(0)
340 BP_FP_INT_TYPE maxHandles =
static_cast<BP_FP_INT_TYPE
>(userMaxHandles + 1);
349 if (!disableRaycastAccelerator)
378 m_pHandles[i].SetNextFree(
static_cast<BP_FP_INT_TYPE
>(i + 1));
384 for (
int i = 0; i < 3; i++)
396 for (
int axis = 0; axis < 3; axis++)
405#ifdef DEBUG_BROADPHASE
406 debugPrintAxis(axis);
411template <
typename BP_FP_INT_TYPE>
414 if (m_raycastAccelerator)
422 for (
int i = 2; i >= 0; i--)
435template <
typename BP_FP_INT_TYPE>
438#ifdef OLD_CLAMPING_METHOD
441 btVector3 clampedPoint(point);
442 clampedPoint.setMax(m_worldAabbMin);
443 clampedPoint.setMin(m_worldAabbMax);
444 btVector3
v = (clampedPoint - m_worldAabbMin) * m_quantize;
445 out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)
v.getX() & m_bpHandleMask) | isMax);
446 out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)
v.getY() & m_bpHandleMask) | isMax);
447 out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)
v.getZ() & m_bpHandleMask) | isMax);
449 btVector3
v = (point - m_worldAabbMin) * m_quantize;
450 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);
451 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);
452 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);
456template <
typename BP_FP_INT_TYPE>
461 BP_FP_INT_TYPE handle = m_firstFreeHandle;
462 m_firstFreeHandle = getHandle(handle)->GetNextFree();
468template <
typename BP_FP_INT_TYPE>
471 btAssert(handle > 0 && handle < m_maxHandles);
473 getHandle(handle)->SetNextFree(m_firstFreeHandle);
474 m_firstFreeHandle = handle;
479template <
typename BP_FP_INT_TYPE>
483 BP_FP_INT_TYPE
min[3], max[3];
488 BP_FP_INT_TYPE handle = allocHandle();
490 Handle* pHandle = getHandle(handle);
492 pHandle->m_uniqueId =
static_cast<int>(handle);
494 pHandle->m_clientObject = pOwner;
495 pHandle->m_collisionFilterGroup = collisionFilterGroup;
496 pHandle->m_collisionFilterMask = collisionFilterMask;
499 BP_FP_INT_TYPE limit =
static_cast<BP_FP_INT_TYPE
>(m_numHandles * 2);
502 for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++)
506 m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1];
508 m_pEdges[axis][limit - 1].
m_pos =
min[axis];
509 m_pEdges[axis][limit - 1].
m_handle = handle;
511 m_pEdges[axis][limit].
m_pos = max[axis];
512 m_pEdges[axis][limit].
m_handle = handle;
514 pHandle->
m_minEdges[axis] =
static_cast<BP_FP_INT_TYPE
>(limit - 1);
519 sortMinDown(0, pHandle->
m_minEdges[0], dispatcher,
false);
520 sortMaxDown(0, pHandle->
m_maxEdges[0], dispatcher,
false);
521 sortMinDown(1, pHandle->
m_minEdges[1], dispatcher,
false);
522 sortMaxDown(1, pHandle->
m_maxEdges[1], dispatcher,
false);
523 sortMinDown(2, pHandle->
m_minEdges[2], dispatcher,
true);
524 sortMaxDown(2, pHandle->
m_maxEdges[2], dispatcher,
true);
529template <
typename BP_FP_INT_TYPE>
532 Handle* pHandle = getHandle(handle);
543 int limit =
static_cast<int>(m_numHandles * 2);
547 for (axis = 0; axis < 3; axis++)
553 for (axis = 0; axis < 3; axis++)
555 Edge* pEdges = m_pEdges[axis];
556 BP_FP_INT_TYPE max = pHandle->
m_maxEdges[axis];
557 pEdges[
max].
m_pos = m_handleSentinel;
559 sortMaxUp(axis, max, dispatcher,
false);
562 pEdges[i].
m_pos = m_handleSentinel;
564 sortMinUp(axis, i, dispatcher,
false);
567 pEdges[limit - 1].
m_pos = m_handleSentinel;
569#ifdef DEBUG_BROADPHASE
570 debugPrintAxis(axis,
false);
578template <
typename BP_FP_INT_TYPE>
581 if (m_numHandles == 0)
583 m_firstFreeHandle = 1;
585 for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < m_maxHandles; i++)
586 m_pHandles[i].SetNextFree(
static_cast<BP_FP_INT_TYPE
>(i + 1));
594template <
typename BP_FP_INT_TYPE>
604 overlappingPairArray.
resize(overlappingPairArray.
size() - m_invalidPair);
610 previousPair.m_pProxy0 = 0;
611 previousPair.m_pProxy1 = 0;
612 previousPair.m_algorithm = 0;
614 for (i = 0; i < overlappingPairArray.
size(); i++)
618 bool isDuplicate = (pair == previousPair);
622 bool needsRemoval =
false;
627 bool hasOverlap = testAabbOverlap(pair.m_pProxy0, pair.m_pProxy1);
631 needsRemoval =
false;
659#define CLEAN_INVALID_PAIRS 1
660#ifdef CLEAN_INVALID_PAIRS
665 overlappingPairArray.
resize(overlappingPairArray.
size() - m_invalidPair);
673template <
typename BP_FP_INT_TYPE>
681 for (
int axis = 0; axis < 3; axis++)
692template <
typename BP_FP_INT_TYPE>
707template <
typename BP_FP_INT_TYPE>
713 Handle* pHandle = getHandle(handle);
716 BP_FP_INT_TYPE
min[3], max[3];
721 for (
int axis = 0; axis < 3; axis++)
723 BP_FP_INT_TYPE emin = pHandle->
m_minEdges[axis];
724 BP_FP_INT_TYPE emax = pHandle->
m_maxEdges[axis];
726 int dmin = (
int)
min[axis] - (
int)m_pEdges[axis][emin].
m_pos;
727 int dmax = (
int)max[axis] - (
int)m_pEdges[axis][emax].
m_pos;
729 m_pEdges[axis][emin].
m_pos =
min[axis];
730 m_pEdges[axis][emax].
m_pos = max[axis];
734 sortMinDown(axis, emin, dispatcher,
true);
737 sortMaxUp(axis, emax, dispatcher,
true);
741 sortMinUp(axis, emin, dispatcher,
true);
744 sortMaxDown(axis, emax, dispatcher,
true);
746#ifdef DEBUG_BROADPHASE
747 debugPrintAxis(axis);
753template <
typename BP_FP_INT_TYPE>
756 Edge* pEdge = m_pEdges[axis] + edge;
757 Edge* pPrev = pEdge - 1;
767 const int axis1 = (1 << axis) & 3;
768 const int axis2 = (1 << axis1) & 3;
769 if (updateOverlaps && testOverlap2D(pHandleEdge, pHandlePrev, axis1, axis2))
772 if (m_userPairCallback)
796#ifdef DEBUG_BROADPHASE
797 debugPrintAxis(axis);
802template <
typename BP_FP_INT_TYPE>
805 Edge* pEdge = m_pEdges[axis] + edge;
806 Edge* pNext = pEdge + 1;
817 const int axis1 = (1 << axis) & 3;
818 const int axis2 = (1 << axis1) & 3;
823 && testOverlap2D(handle0, handle1, axis1, axis2)
828 if (m_userPairCallback)
852template <
typename BP_FP_INT_TYPE>
855 Edge* pEdge = m_pEdges[axis] + edge;
856 Edge* pPrev = pEdge - 1;
868 const int axis1 = (1 << axis) & 3;
869 const int axis2 = (1 << axis1) & 3;
873 && testOverlap2D(handle0, handle1, axis1, axis2)
880 if (m_userPairCallback)
903#ifdef DEBUG_BROADPHASE
904 debugPrintAxis(axis);
909template <
typename BP_FP_INT_TYPE>
912 Edge* pEdge = m_pEdges[axis] + edge;
913 Edge* pNext = pEdge + 1;
920 const int axis1 = (1 << axis) & 3;
921 const int axis2 = (1 << axis1) & 3;
926 if (updateOverlaps && testOverlap2D(pHandleEdge, pHandleNext, axis1, axis2))
931 if (m_userPairCallback)
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, const btVector3 &aabbMin2, const btVector3 &aabbMax2)
conservative test for overlap between two aabbs
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
#define USE_OVERLAP_TEST_ON_REMOVES
btHashedOverlappingPairCache()
SIMD_FORCE_INLINE void quantize(unsigned short *out, const btVector3 &point, int isMax) const
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
#define SIMD_FORCE_INLINE
btVector3
btVector3 can be used to represent 3D points and vectors. It has an un-used w component to suit 16-by...
SIMD_FORCE_INLINE int size() const
return the number of elements in the array
SIMD_FORCE_INLINE void resize(int newsize, const T &fillData=T())
void quickSort(const L &CompareFunc)
BP_FP_INT_TYPE IsMax() const
SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next)
btBroadphaseProxy * m_dbvtProxy
SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const
BP_FP_INT_TYPE m_maxEdges[3]
BT_DECLARE_ALIGNED_ALLOCATOR()
BP_FP_INT_TYPE m_minEdges[3]
virtual void getAabb(btBroadphaseProxy *proxy, btVector3 &aabbMin, btVector3 &aabbMax) const
btOverlappingPairCache * m_pairCache
BP_FP_INT_TYPE m_handleSentinel
bool testAabbOverlap(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
SIMD_FORCE_INLINE Handle * getHandle(BP_FP_INT_TYPE index) const
void unQuantize(btBroadphaseProxy *proxy, btVector3 &aabbMin, btVector3 &aabbMax) const
unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result
void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher *dispatcher, bool updateOverlaps)
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))
BP_FP_INT_TYPE m_bpHandleMask
BP_FP_INT_TYPE allocHandle()
BP_FP_INT_TYPE m_numHandles
bool testOverlap2D(const Handle *pHandleA, const Handle *pHandleB, int axis0, int axis1)
const btOverlappingPairCallback * getOverlappingPairUserCallback() const
BP_FP_INT_TYPE addHandle(const btVector3 &aabbMin, const btVector3 &aabbMax, void *pOwner, int collisionFilterGroup, int collisionFilterMask, btDispatcher *dispatcher)
void removeHandle(BP_FP_INT_TYPE handle, btDispatcher *dispatcher)
virtual btBroadphaseProxy * createProxy(const btVector3 &aabbMin, const btVector3 &aabbMax, int shapeType, void *userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher *dispatcher)
virtual void printStats()
const btOverlappingPairCache * getOverlappingPairCache() const
void quantize(BP_FP_INT_TYPE *out, const btVector3 &point, int isMax) const
BP_FP_INT_TYPE getNumHandles() const
btDbvtBroadphase * m_raycastAccelerator
btOverlappingPairCache * getOverlappingPairCache()
BP_FP_INT_TYPE m_maxHandles
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)
virtual void calculateOverlappingPairs(btDispatcher *dispatcher)
calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during th...
void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher *dispatcher, bool updateOverlaps)
void freeHandle(BP_FP_INT_TYPE handle)
virtual void aabbTest(const btVector3 &aabbMin, const btVector3 &aabbMax, btBroadphaseAabbCallback &callback)
void updateHandle(BP_FP_INT_TYPE handle, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)
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)
virtual ~btAxisSweep3Internal()
virtual void getBroadphaseAabb(btVector3 &aabbMin, btVector3 &aabbMax) const
btOverlappingPairCallback * m_userPairCallback
btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pai...
BT_DECLARE_ALIGNED_ALLOCATOR()
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
void processAllOverlappingPairs(btOverlapCallback *callback)
BP_FP_INT_TYPE m_firstFreeHandle
void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher *dispatcher, bool updateOverlaps)
void setOverlappingPairUserCallback(btOverlappingPairCallback *pairCallback)
virtual void resetPool(btDispatcher *dispatcher)
reset broadphase internal structures, to ensure determinism/reproducability
btOverlappingPairCache * m_nullPairCache
void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher *dispatcher, bool updateOverlaps)
virtual btBroadphasePairArray & getOverlappingPairArray()=0
virtual void cleanOverlappingPair(btBroadphasePair &pair, btDispatcher *dispatcher)=0
virtual ~btOverlappingPairCache()
virtual bool hasDeferredRemoval()=0
The btOverlappingPairCallback class is an additional optional broadphase user callback for adding/rem...
virtual void * removeOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1, btDispatcher *dispatcher)=0
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy *proxy0, btDispatcher *dispatcher)=0
virtual btBroadphasePair * addOverlappingPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
DEGForeachIDComponentCallback callback
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
virtual bool process(const btBroadphaseProxy *proxy)=0
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)
btBroadphaseProxy * createProxy(const btVector3 &aabbMin, const btVector3 &aabbMax, int shapeType, void *userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher *dispatcher)
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 aabbTest(const btVector3 &aabbMin, const btVector3 &aabbMax, btBroadphaseAabbCallback &callback)
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)