2017-08-01 14:30:58 +02:00
//Bullet Continuous Collision Detection and Physics Library
//Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
//
// btAxisSweep3.h
//
// Copyright (c) 2006 Simon Hobbs
//
// 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.
//
// 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:
//
// 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.
//
// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
# ifndef BT_AXIS_SWEEP_3_INTERNAL_H
# define BT_AXIS_SWEEP_3_INTERNAL_H
# include "LinearMath/btVector3.h"
# include "btOverlappingPairCache.h"
# include "btBroadphaseInterface.h"
# include "btBroadphaseProxy.h"
# include "btOverlappingPairCallback.h"
# include "btDbvtBroadphase.h"
//#define DEBUG_BROADPHASE 1
# define USE_OVERLAP_TEST_ON_REMOVES 1
/// The internal templace class btAxisSweep3Internal implements the sweep and prune broadphase.
/// It uses quantized integers to represent the begin and end points for each of the 3 axis.
/// Dont use this class directly, use btAxisSweep3 or bt32BitAxisSweep3 instead.
template < typename BP_FP_INT_TYPE >
class btAxisSweep3Internal : public btBroadphaseInterface
{
protected :
2019-01-03 14:26:51 +01:00
BP_FP_INT_TYPE m_bpHandleMask ;
BP_FP_INT_TYPE m_handleSentinel ;
2017-08-01 14:30:58 +02:00
public :
2019-01-03 14:26:51 +01:00
BT_DECLARE_ALIGNED_ALLOCATOR ( ) ;
2017-08-01 14:30:58 +02:00
class Edge
{
public :
2019-01-03 14:26:51 +01:00
BP_FP_INT_TYPE m_pos ; // low bit is min/max
2017-08-01 14:30:58 +02:00
BP_FP_INT_TYPE m_handle ;
2019-01-03 14:26:51 +01:00
BP_FP_INT_TYPE IsMax ( ) const { return static_cast < BP_FP_INT_TYPE > ( m_pos & 1 ) ; }
2017-08-01 14:30:58 +02:00
} ;
public :
2019-01-03 14:26:51 +01:00
class Handle : public btBroadphaseProxy
2017-08-01 14:30:58 +02:00
{
public :
2019-01-03 14:26:51 +01:00
BT_DECLARE_ALIGNED_ALLOCATOR ( ) ;
2017-08-01 14:30:58 +02:00
// indexes into the edge arrays
2019-01-03 14:26:51 +01:00
BP_FP_INT_TYPE m_minEdges [ 3 ] , m_maxEdges [ 3 ] ; // 6 * 2 = 12
// BP_FP_INT_TYPE m_uniqueId;
btBroadphaseProxy * m_dbvtProxy ; //for faster raycast
2017-08-01 14:30:58 +02:00
//void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
2019-01-03 14:26:51 +01:00
SIMD_FORCE_INLINE void SetNextFree ( BP_FP_INT_TYPE next ) { m_minEdges [ 0 ] = next ; }
SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree ( ) const { return m_minEdges [ 0 ] ; }
} ; // 24 bytes + 24 for Edge structures = 44 bytes total per entry
2017-08-01 14:30:58 +02:00
protected :
2019-01-03 14:26:51 +01:00
btVector3 m_worldAabbMin ; // overall system bounds
btVector3 m_worldAabbMax ; // overall system bounds
btVector3 m_quantize ; // scaling factor for quantization
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
BP_FP_INT_TYPE m_numHandles ; // number of active handles
BP_FP_INT_TYPE m_maxHandles ; // max number of handles
Handle * m_pHandles ; // handles pool
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
BP_FP_INT_TYPE m_firstFreeHandle ; // free handles list
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
Edge * m_pEdges [ 3 ] ; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries)
2017-08-01 14:30:58 +02:00
void * m_pEdgesRawPtr [ 3 ] ;
btOverlappingPairCache * m_pairCache ;
///btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache.
btOverlappingPairCallback * m_userPairCallback ;
2019-01-03 14:26:51 +01:00
bool m_ownsPairCache ;
int m_invalidPair ;
2017-08-01 14:30:58 +02:00
///additional dynamic aabb structure, used to accelerate ray cast queries.
///can be disabled using a optional argument in the constructor
2019-01-03 14:26:51 +01:00
btDbvtBroadphase * m_raycastAccelerator ;
btOverlappingPairCache * m_nullPairCache ;
2017-08-01 14:30:58 +02:00
// allocation/deallocation
BP_FP_INT_TYPE allocHandle ( ) ;
void freeHandle ( BP_FP_INT_TYPE handle ) ;
2019-01-03 14:26:51 +01:00
bool testOverlap2D ( const Handle * pHandleA , const Handle * pHandleB , int axis0 , int axis1 ) ;
2017-08-01 14:30:58 +02:00
# ifdef DEBUG_BROADPHASE
2019-01-03 14:26:51 +01:00
void debugPrintAxis ( int axis , bool checkCardinality = true ) ;
# endif //DEBUG_BROADPHASE
2017-08-01 14:30:58 +02:00
//Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
//void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
2019-01-03 14:26:51 +01:00
void sortMinDown ( int axis , BP_FP_INT_TYPE edge , btDispatcher * dispatcher , bool updateOverlaps ) ;
void sortMinUp ( int axis , BP_FP_INT_TYPE edge , btDispatcher * dispatcher , bool updateOverlaps ) ;
void sortMaxDown ( int axis , BP_FP_INT_TYPE edge , btDispatcher * dispatcher , bool updateOverlaps ) ;
void sortMaxUp ( int axis , BP_FP_INT_TYPE edge , btDispatcher * dispatcher , bool updateOverlaps ) ;
2017-08-01 14:30:58 +02:00
public :
2019-01-03 14:26:51 +01:00
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 ) ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
virtual ~ btAxisSweep3Internal ( ) ;
2017-08-01 14:30:58 +02:00
BP_FP_INT_TYPE getNumHandles ( ) const
{
return m_numHandles ;
}
2019-01-03 14:26:51 +01:00
virtual void calculateOverlappingPairs ( btDispatcher * dispatcher ) ;
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 ) ;
void updateHandle ( BP_FP_INT_TYPE handle , const btVector3 & aabbMin , const btVector3 & aabbMax , btDispatcher * dispatcher ) ;
SIMD_FORCE_INLINE Handle * getHandle ( BP_FP_INT_TYPE index ) const { return m_pHandles + index ; }
2017-08-01 14:30:58 +02:00
virtual void resetPool ( btDispatcher * dispatcher ) ;
2019-01-03 14:26:51 +01:00
void processAllOverlappingPairs ( btOverlapCallback * callback ) ;
2017-08-01 14:30:58 +02:00
//Broadphase Interface
2019-01-03 14:26:51 +01:00
virtual btBroadphaseProxy * createProxy ( const btVector3 & aabbMin , const btVector3 & aabbMax , int shapeType , void * userPtr , int collisionFilterGroup , int collisionFilterMask , btDispatcher * dispatcher ) ;
virtual void destroyProxy ( btBroadphaseProxy * proxy , btDispatcher * dispatcher ) ;
virtual void setAabb ( btBroadphaseProxy * proxy , const btVector3 & aabbMin , const btVector3 & aabbMax , btDispatcher * dispatcher ) ;
virtual void getAabb ( btBroadphaseProxy * proxy , btVector3 & aabbMin , btVector3 & aabbMax ) const ;
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 ) ;
2017-08-01 14:30:58 +02:00
void quantize ( BP_FP_INT_TYPE * out , const btVector3 & point , int isMax ) const ;
///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result
2019-01-03 14:26:51 +01:00
void unQuantize ( btBroadphaseProxy * proxy , btVector3 & aabbMin , btVector3 & aabbMax ) const ;
bool testAabbOverlap ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 ) ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
btOverlappingPairCache * getOverlappingPairCache ( )
2017-08-01 14:30:58 +02:00
{
return m_pairCache ;
}
2019-01-03 14:26:51 +01:00
const btOverlappingPairCache * getOverlappingPairCache ( ) const
2017-08-01 14:30:58 +02:00
{
return m_pairCache ;
}
2019-01-03 14:26:51 +01:00
void setOverlappingPairUserCallback ( btOverlappingPairCallback * pairCallback )
2017-08-01 14:30:58 +02:00
{
m_userPairCallback = pairCallback ;
}
2019-01-03 14:26:51 +01:00
const btOverlappingPairCallback * getOverlappingPairUserCallback ( ) const
2017-08-01 14:30:58 +02:00
{
return m_userPairCallback ;
}
///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
///will add some transform later
2019-01-03 14:26:51 +01:00
virtual void getBroadphaseAabb ( btVector3 & aabbMin , btVector3 & aabbMax ) const
2017-08-01 14:30:58 +02:00
{
aabbMin = m_worldAabbMin ;
aabbMax = m_worldAabbMax ;
}
2019-01-03 14:26:51 +01:00
virtual void printStats ( )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
/* printf("btAxisSweep3.h\n");
2017-08-01 14:30:58 +02:00
printf ( " numHandles = %d, maxHandles = %d \n " , m_numHandles , m_maxHandles ) ;
printf ( " aabbMin=%f,%f,%f,aabbMax=%f,%f,%f \n " , m_worldAabbMin . getX ( ) , m_worldAabbMin . getY ( ) , m_worldAabbMin . getZ ( ) ,
m_worldAabbMax . getX ( ) , m_worldAabbMax . getY ( ) , m_worldAabbMax . getZ ( ) ) ;
*/
}
} ;
////////////////////////////////////////////////////////////////////
# ifdef DEBUG_BROADPHASE
# include <stdio.h>
template < typename BP_FP_INT_TYPE >
void btAxisSweep3 < BP_FP_INT_TYPE > : : debugPrintAxis ( int axis , bool checkCardinality )
{
int numEdges = m_pHandles [ 0 ] . m_maxEdges [ axis ] ;
2019-01-03 14:26:51 +01:00
printf ( " SAP Axis %d, numEdges=%d \n " , axis , numEdges ) ;
2017-08-01 14:30:58 +02:00
int i ;
2019-01-03 14:26:51 +01:00
for ( i = 0 ; i < numEdges + 1 ; i + + )
2017-08-01 14:30:58 +02:00
{
Edge * pEdge = m_pEdges [ axis ] + i ;
Handle * pHandlePrev = getHandle ( pEdge - > m_handle ) ;
2019-01-03 14:26:51 +01:00
int handleIndex = pEdge - > IsMax ( ) ? pHandlePrev - > m_maxEdges [ axis ] : pHandlePrev - > m_minEdges [ axis ] ;
2017-08-01 14:30:58 +02:00
char beginOrEnd ;
2019-01-03 14:26:51 +01:00
beginOrEnd = pEdge - > IsMax ( ) ? ' E ' : ' B ' ;
printf ( " [%c,h=%d,p=%x,i=%d] \n " , beginOrEnd , pEdge - > m_handle , pEdge - > m_pos , handleIndex ) ;
2017-08-01 14:30:58 +02:00
}
if ( checkCardinality )
2019-01-03 14:26:51 +01:00
btAssert ( numEdges = = m_numHandles * 2 + 1 ) ;
2017-08-01 14:30:58 +02:00
}
2019-01-03 14:26:51 +01:00
# endif //DEBUG_BROADPHASE
2017-08-01 14:30:58 +02:00
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
btBroadphaseProxy * btAxisSweep3Internal < BP_FP_INT_TYPE > : : createProxy ( const btVector3 & aabbMin , const btVector3 & aabbMax , int shapeType , void * userPtr , int collisionFilterGroup , int collisionFilterMask , btDispatcher * dispatcher )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
( void ) shapeType ;
BP_FP_INT_TYPE handleId = addHandle ( aabbMin , aabbMax , userPtr , collisionFilterGroup , collisionFilterMask , dispatcher ) ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
Handle * handle = getHandle ( handleId ) ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
if ( m_raycastAccelerator )
{
btBroadphaseProxy * rayProxy = m_raycastAccelerator - > createProxy ( aabbMin , aabbMax , shapeType , userPtr , collisionFilterGroup , collisionFilterMask , dispatcher ) ;
handle - > m_dbvtProxy = rayProxy ;
}
return handle ;
}
2017-08-01 14:30:58 +02:00
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : destroyProxy ( btBroadphaseProxy * proxy , btDispatcher * dispatcher )
2017-08-01 14:30:58 +02:00
{
Handle * handle = static_cast < Handle * > ( proxy ) ;
if ( m_raycastAccelerator )
2019-01-03 14:26:51 +01:00
m_raycastAccelerator - > destroyProxy ( handle - > m_dbvtProxy , dispatcher ) ;
2017-08-01 14:30:58 +02:00
removeHandle ( static_cast < BP_FP_INT_TYPE > ( handle - > m_uniqueId ) , dispatcher ) ;
}
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : setAabb ( btBroadphaseProxy * proxy , const btVector3 & aabbMin , const btVector3 & aabbMax , btDispatcher * dispatcher )
2017-08-01 14:30:58 +02:00
{
Handle * handle = static_cast < Handle * > ( proxy ) ;
handle - > m_aabbMin = aabbMin ;
handle - > m_aabbMax = aabbMax ;
2019-01-03 14:26:51 +01:00
updateHandle ( static_cast < BP_FP_INT_TYPE > ( handle - > m_uniqueId ) , aabbMin , aabbMax , dispatcher ) ;
2017-08-01 14:30:58 +02:00
if ( m_raycastAccelerator )
2019-01-03 14:26:51 +01:00
m_raycastAccelerator - > setAabb ( handle - > m_dbvtProxy , aabbMin , aabbMax , dispatcher ) ;
2017-08-01 14:30:58 +02:00
}
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : rayTest ( const btVector3 & rayFrom , const btVector3 & rayTo , btBroadphaseRayCallback & rayCallback , const btVector3 & aabbMin , const btVector3 & aabbMax )
2017-08-01 14:30:58 +02:00
{
if ( m_raycastAccelerator )
{
2019-01-03 14:26:51 +01:00
m_raycastAccelerator - > rayTest ( rayFrom , rayTo , rayCallback , aabbMin , aabbMax ) ;
}
else
2017-08-01 14:30:58 +02:00
{
//choose axis?
BP_FP_INT_TYPE axis = 0 ;
//for each proxy
2019-01-03 14:26:51 +01:00
for ( BP_FP_INT_TYPE i = 1 ; i < m_numHandles * 2 + 1 ; i + + )
2017-08-01 14:30:58 +02:00
{
if ( m_pEdges [ axis ] [ i ] . IsMax ( ) )
{
rayCallback . process ( getHandle ( m_pEdges [ axis ] [ i ] . m_handle ) ) ;
}
}
}
}
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : aabbTest ( const btVector3 & aabbMin , const btVector3 & aabbMax , btBroadphaseAabbCallback & callback )
2017-08-01 14:30:58 +02:00
{
if ( m_raycastAccelerator )
{
2019-01-03 14:26:51 +01:00
m_raycastAccelerator - > aabbTest ( aabbMin , aabbMax , callback ) ;
}
else
2017-08-01 14:30:58 +02:00
{
//choose axis?
BP_FP_INT_TYPE axis = 0 ;
//for each proxy
2019-01-03 14:26:51 +01:00
for ( BP_FP_INT_TYPE i = 1 ; i < m_numHandles * 2 + 1 ; i + + )
2017-08-01 14:30:58 +02:00
{
if ( m_pEdges [ axis ] [ i ] . IsMax ( ) )
{
Handle * handle = getHandle ( m_pEdges [ axis ] [ i ] . m_handle ) ;
2019-01-03 14:26:51 +01:00
if ( TestAabbAgainstAabb2 ( aabbMin , aabbMax , handle - > m_aabbMin , handle - > m_aabbMax ) )
2017-08-01 14:30:58 +02:00
{
callback . process ( handle ) ;
}
}
}
}
}
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : getAabb ( btBroadphaseProxy * proxy , btVector3 & aabbMin , btVector3 & aabbMax ) const
2017-08-01 14:30:58 +02:00
{
Handle * pHandle = static_cast < Handle * > ( proxy ) ;
aabbMin = pHandle - > m_aabbMin ;
aabbMax = pHandle - > m_aabbMax ;
}
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : unQuantize ( btBroadphaseProxy * proxy , btVector3 & aabbMin , btVector3 & aabbMax ) const
2017-08-01 14:30:58 +02:00
{
Handle * pHandle = static_cast < Handle * > ( proxy ) ;
unsigned short vecInMin [ 3 ] ;
unsigned short vecInMax [ 3 ] ;
2019-01-03 14:26:51 +01:00
vecInMin [ 0 ] = m_pEdges [ 0 ] [ pHandle - > m_minEdges [ 0 ] ] . m_pos ;
vecInMax [ 0 ] = m_pEdges [ 0 ] [ pHandle - > m_maxEdges [ 0 ] ] . m_pos + 1 ;
vecInMin [ 1 ] = m_pEdges [ 1 ] [ pHandle - > m_minEdges [ 1 ] ] . m_pos ;
vecInMax [ 1 ] = m_pEdges [ 1 ] [ pHandle - > m_maxEdges [ 1 ] ] . m_pos + 1 ;
vecInMin [ 2 ] = m_pEdges [ 2 ] [ pHandle - > m_minEdges [ 2 ] ] . m_pos ;
vecInMax [ 2 ] = m_pEdges [ 2 ] [ pHandle - > m_maxEdges [ 2 ] ] . m_pos + 1 ;
aabbMin . setValue ( ( btScalar ) ( vecInMin [ 0 ] ) / ( m_quantize . getX ( ) ) , ( btScalar ) ( vecInMin [ 1 ] ) / ( m_quantize . getY ( ) ) , ( btScalar ) ( vecInMin [ 2 ] ) / ( m_quantize . getZ ( ) ) ) ;
2017-08-01 14:30:58 +02:00
aabbMin + = m_worldAabbMin ;
2019-01-03 14:26:51 +01:00
aabbMax . setValue ( ( btScalar ) ( vecInMax [ 0 ] ) / ( m_quantize . getX ( ) ) , ( btScalar ) ( vecInMax [ 1 ] ) / ( m_quantize . getY ( ) ) , ( btScalar ) ( vecInMax [ 2 ] ) / ( m_quantize . getZ ( ) ) ) ;
2017-08-01 14:30:58 +02:00
aabbMax + = m_worldAabbMin ;
}
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
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 )
: m_bpHandleMask ( handleMask ) ,
m_handleSentinel ( handleSentinel ) ,
m_pairCache ( pairCache ) ,
m_userPairCallback ( 0 ) ,
m_ownsPairCache ( false ) ,
m_invalidPair ( 0 ) ,
m_raycastAccelerator ( 0 )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
BP_FP_INT_TYPE maxHandles = static_cast < BP_FP_INT_TYPE > ( userMaxHandles + 1 ) ; //need to add one sentinel handle
2017-08-01 14:30:58 +02:00
if ( ! m_pairCache )
{
2019-01-03 14:26:51 +01:00
void * ptr = btAlignedAlloc ( sizeof ( btHashedOverlappingPairCache ) , 16 ) ;
m_pairCache = new ( ptr ) btHashedOverlappingPairCache ( ) ;
2017-08-01 14:30:58 +02:00
m_ownsPairCache = true ;
}
if ( ! disableRaycastAccelerator )
{
2019-01-03 14:26:51 +01:00
m_nullPairCache = new ( btAlignedAlloc ( sizeof ( btNullPairCache ) , 16 ) ) btNullPairCache ( ) ;
m_raycastAccelerator = new ( btAlignedAlloc ( sizeof ( btDbvtBroadphase ) , 16 ) ) btDbvtBroadphase ( m_nullPairCache ) ; //m_pairCache);
m_raycastAccelerator - > m_deferedcollide = true ; //don't add/remove pairs
2017-08-01 14:30:58 +02:00
}
//btAssert(bounds.HasVolume());
// init bounds
m_worldAabbMin = worldAabbMin ;
m_worldAabbMax = worldAabbMax ;
btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin ;
2019-01-03 14:26:51 +01:00
BP_FP_INT_TYPE maxInt = m_handleSentinel ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
m_quantize = btVector3 ( btScalar ( maxInt ) , btScalar ( maxInt ) , btScalar ( maxInt ) ) / aabbSize ;
2017-08-01 14:30:58 +02:00
// allocate handles buffer, using btAlignedAlloc, and put all handles on free list
m_pHandles = new Handle [ maxHandles ] ;
2019-01-03 14:26:51 +01:00
2017-08-01 14:30:58 +02:00
m_maxHandles = maxHandles ;
m_numHandles = 0 ;
// handle 0 is reserved as the null index, and is also used as the sentinel
m_firstFreeHandle = 1 ;
{
for ( BP_FP_INT_TYPE i = m_firstFreeHandle ; i < maxHandles ; i + + )
m_pHandles [ i ] . SetNextFree ( static_cast < BP_FP_INT_TYPE > ( i + 1 ) ) ;
m_pHandles [ maxHandles - 1 ] . SetNextFree ( 0 ) ;
}
{
// allocate edge buffers
for ( int i = 0 ; i < 3 ; i + + )
{
2019-01-03 14:26:51 +01:00
m_pEdgesRawPtr [ i ] = btAlignedAlloc ( sizeof ( Edge ) * maxHandles * 2 , 16 ) ;
m_pEdges [ i ] = new ( m_pEdgesRawPtr [ i ] ) Edge [ maxHandles * 2 ] ;
2017-08-01 14:30:58 +02:00
}
}
//removed overlap management
// make boundary sentinels
2019-01-03 14:26:51 +01:00
2017-08-01 14:30:58 +02:00
m_pHandles [ 0 ] . m_clientObject = 0 ;
for ( int axis = 0 ; axis < 3 ; axis + + )
{
m_pHandles [ 0 ] . m_minEdges [ axis ] = 0 ;
m_pHandles [ 0 ] . m_maxEdges [ axis ] = 1 ;
m_pEdges [ axis ] [ 0 ] . m_pos = 0 ;
m_pEdges [ axis ] [ 0 ] . m_handle = 0 ;
m_pEdges [ axis ] [ 1 ] . m_pos = m_handleSentinel ;
m_pEdges [ axis ] [ 1 ] . m_handle = 0 ;
# ifdef DEBUG_BROADPHASE
debugPrintAxis ( axis ) ;
2019-01-03 14:26:51 +01:00
# endif //DEBUG_BROADPHASE
2017-08-01 14:30:58 +02:00
}
}
template < typename BP_FP_INT_TYPE >
btAxisSweep3Internal < BP_FP_INT_TYPE > : : ~ btAxisSweep3Internal ( )
{
if ( m_raycastAccelerator )
{
m_nullPairCache - > ~ btOverlappingPairCache ( ) ;
btAlignedFree ( m_nullPairCache ) ;
m_raycastAccelerator - > ~ btDbvtBroadphase ( ) ;
2019-01-03 14:26:51 +01:00
btAlignedFree ( m_raycastAccelerator ) ;
2017-08-01 14:30:58 +02:00
}
for ( int i = 2 ; i > = 0 ; i - - )
{
btAlignedFree ( m_pEdgesRawPtr [ i ] ) ;
}
2019-01-03 14:26:51 +01:00
delete [ ] m_pHandles ;
2017-08-01 14:30:58 +02:00
if ( m_ownsPairCache )
{
m_pairCache - > ~ btOverlappingPairCache ( ) ;
btAlignedFree ( m_pairCache ) ;
}
}
template < typename BP_FP_INT_TYPE >
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : quantize ( BP_FP_INT_TYPE * out , const btVector3 & point , int isMax ) const
{
# ifdef OLD_CLAMPING_METHOD
///problem with this clamping method is that the floating point during quantization might still go outside the range [(0|isMax) .. (m_handleSentinel&m_bpHandleMask]|isMax]
///see http://code.google.com/p/bullet/issues/detail?id=87
btVector3 clampedPoint ( point ) ;
clampedPoint . setMax ( m_worldAabbMin ) ;
clampedPoint . setMin ( m_worldAabbMax ) ;
btVector3 v = ( clampedPoint - m_worldAabbMin ) * m_quantize ;
out [ 0 ] = ( BP_FP_INT_TYPE ) ( ( ( BP_FP_INT_TYPE ) v . getX ( ) & m_bpHandleMask ) | isMax ) ;
out [ 1 ] = ( BP_FP_INT_TYPE ) ( ( ( BP_FP_INT_TYPE ) v . getY ( ) & m_bpHandleMask ) | isMax ) ;
out [ 2 ] = ( BP_FP_INT_TYPE ) ( ( ( BP_FP_INT_TYPE ) v . getZ ( ) & m_bpHandleMask ) | isMax ) ;
# else
btVector3 v = ( point - m_worldAabbMin ) * m_quantize ;
2019-01-03 14:26:51 +01:00
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 ) ;
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 ) ;
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 ) ;
# endif //OLD_CLAMPING_METHOD
2017-08-01 14:30:58 +02:00
}
template < typename BP_FP_INT_TYPE >
BP_FP_INT_TYPE btAxisSweep3Internal < BP_FP_INT_TYPE > : : allocHandle ( )
{
btAssert ( m_firstFreeHandle ) ;
BP_FP_INT_TYPE handle = m_firstFreeHandle ;
m_firstFreeHandle = getHandle ( handle ) - > GetNextFree ( ) ;
m_numHandles + + ;
return handle ;
}
template < typename BP_FP_INT_TYPE >
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : freeHandle ( BP_FP_INT_TYPE handle )
{
btAssert ( handle > 0 & & handle < m_maxHandles ) ;
getHandle ( handle ) - > SetNextFree ( m_firstFreeHandle ) ;
m_firstFreeHandle = handle ;
m_numHandles - - ;
}
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
BP_FP_INT_TYPE btAxisSweep3Internal < BP_FP_INT_TYPE > : : addHandle ( const btVector3 & aabbMin , const btVector3 & aabbMax , void * pOwner , int collisionFilterGroup , int collisionFilterMask , btDispatcher * dispatcher )
2017-08-01 14:30:58 +02:00
{
// quantize the bounds
BP_FP_INT_TYPE min [ 3 ] , max [ 3 ] ;
quantize ( min , aabbMin , 0 ) ;
quantize ( max , aabbMax , 1 ) ;
// allocate a handle
BP_FP_INT_TYPE handle = allocHandle ( ) ;
Handle * pHandle = getHandle ( handle ) ;
2019-01-03 14:26:51 +01:00
2017-08-01 14:30:58 +02:00
pHandle - > m_uniqueId = static_cast < int > ( handle ) ;
//pHandle->m_pOverlaps = 0;
pHandle - > m_clientObject = pOwner ;
pHandle - > m_collisionFilterGroup = collisionFilterGroup ;
pHandle - > m_collisionFilterMask = collisionFilterMask ;
// compute current limit of edge arrays
BP_FP_INT_TYPE limit = static_cast < BP_FP_INT_TYPE > ( m_numHandles * 2 ) ;
// insert new edges just inside the max boundary edge
for ( BP_FP_INT_TYPE axis = 0 ; axis < 3 ; axis + + )
{
m_pHandles [ 0 ] . m_maxEdges [ axis ] + = 2 ;
m_pEdges [ axis ] [ limit + 1 ] = m_pEdges [ axis ] [ limit - 1 ] ;
m_pEdges [ axis ] [ limit - 1 ] . m_pos = min [ axis ] ;
m_pEdges [ axis ] [ limit - 1 ] . m_handle = handle ;
m_pEdges [ axis ] [ limit ] . m_pos = max [ axis ] ;
m_pEdges [ axis ] [ limit ] . m_handle = handle ;
pHandle - > m_minEdges [ axis ] = static_cast < BP_FP_INT_TYPE > ( limit - 1 ) ;
pHandle - > m_maxEdges [ axis ] = limit ;
}
// now sort the new edges to their correct position
2019-01-03 14:26:51 +01:00
sortMinDown ( 0 , pHandle - > m_minEdges [ 0 ] , dispatcher , false ) ;
sortMaxDown ( 0 , pHandle - > m_maxEdges [ 0 ] , dispatcher , false ) ;
sortMinDown ( 1 , pHandle - > m_minEdges [ 1 ] , dispatcher , false ) ;
sortMaxDown ( 1 , pHandle - > m_maxEdges [ 1 ] , dispatcher , false ) ;
sortMinDown ( 2 , pHandle - > m_minEdges [ 2 ] , dispatcher , true ) ;
sortMaxDown ( 2 , pHandle - > m_maxEdges [ 2 ] , dispatcher , true ) ;
2017-08-01 14:30:58 +02:00
return handle ;
}
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : removeHandle ( BP_FP_INT_TYPE handle , btDispatcher * dispatcher )
2017-08-01 14:30:58 +02:00
{
Handle * pHandle = getHandle ( handle ) ;
//explicitly remove the pairs containing the proxy
//we could do it also in the sortMinUp (passing true)
///@todo: compare performance
if ( ! m_pairCache - > hasDeferredRemoval ( ) )
{
2019-01-03 14:26:51 +01:00
m_pairCache - > removeOverlappingPairsContainingProxy ( pHandle , dispatcher ) ;
2017-08-01 14:30:58 +02:00
}
// compute current limit of edge arrays
int limit = static_cast < int > ( m_numHandles * 2 ) ;
2019-01-03 14:26:51 +01:00
2017-08-01 14:30:58 +02:00
int axis ;
2019-01-03 14:26:51 +01:00
for ( axis = 0 ; axis < 3 ; axis + + )
2017-08-01 14:30:58 +02:00
{
m_pHandles [ 0 ] . m_maxEdges [ axis ] - = 2 ;
}
// remove the edges by sorting them up to the end of the list
2019-01-03 14:26:51 +01:00
for ( axis = 0 ; axis < 3 ; axis + + )
2017-08-01 14:30:58 +02:00
{
Edge * pEdges = m_pEdges [ axis ] ;
BP_FP_INT_TYPE max = pHandle - > m_maxEdges [ axis ] ;
pEdges [ max ] . m_pos = m_handleSentinel ;
2019-01-03 14:26:51 +01:00
sortMaxUp ( axis , max , dispatcher , false ) ;
2017-08-01 14:30:58 +02:00
BP_FP_INT_TYPE i = pHandle - > m_minEdges [ axis ] ;
pEdges [ i ] . m_pos = m_handleSentinel ;
2019-01-03 14:26:51 +01:00
sortMinUp ( axis , i , dispatcher , false ) ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
pEdges [ limit - 1 ] . m_handle = 0 ;
pEdges [ limit - 1 ] . m_pos = m_handleSentinel ;
2017-08-01 14:30:58 +02:00
# ifdef DEBUG_BROADPHASE
2019-01-03 14:26:51 +01:00
debugPrintAxis ( axis , false ) ;
# endif //DEBUG_BROADPHASE
2017-08-01 14:30:58 +02:00
}
// free the handle
freeHandle ( handle ) ;
}
template < typename BP_FP_INT_TYPE >
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : resetPool ( btDispatcher * /*dispatcher*/ )
{
if ( m_numHandles = = 0 )
{
m_firstFreeHandle = 1 ;
{
for ( BP_FP_INT_TYPE i = m_firstFreeHandle ; i < m_maxHandles ; i + + )
m_pHandles [ i ] . SetNextFree ( static_cast < BP_FP_INT_TYPE > ( i + 1 ) ) ;
m_pHandles [ m_maxHandles - 1 ] . SetNextFree ( 0 ) ;
}
}
2019-01-03 14:26:51 +01:00
}
2017-08-01 14:30:58 +02:00
//#include <stdio.h>
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : calculateOverlappingPairs ( btDispatcher * dispatcher )
2017-08-01 14:30:58 +02:00
{
if ( m_pairCache - > hasDeferredRemoval ( ) )
{
2019-01-03 14:26:51 +01:00
btBroadphasePairArray & overlappingPairArray = m_pairCache - > getOverlappingPairArray ( ) ;
2017-08-01 14:30:58 +02:00
//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
overlappingPairArray . quickSort ( btBroadphasePairSortPredicate ( ) ) ;
overlappingPairArray . resize ( overlappingPairArray . size ( ) - m_invalidPair ) ;
m_invalidPair = 0 ;
int i ;
btBroadphasePair previousPair ;
previousPair . m_pProxy0 = 0 ;
previousPair . m_pProxy1 = 0 ;
previousPair . m_algorithm = 0 ;
2019-01-03 14:26:51 +01:00
for ( i = 0 ; i < overlappingPairArray . size ( ) ; i + + )
2017-08-01 14:30:58 +02:00
{
btBroadphasePair & pair = overlappingPairArray [ i ] ;
bool isDuplicate = ( pair = = previousPair ) ;
previousPair = pair ;
bool needsRemoval = false ;
if ( ! isDuplicate )
{
///important to use an AABB test that is consistent with the broadphase
2019-01-03 14:26:51 +01:00
bool hasOverlap = testAabbOverlap ( pair . m_pProxy0 , pair . m_pProxy1 ) ;
2017-08-01 14:30:58 +02:00
if ( hasOverlap )
{
2019-01-03 14:26:51 +01:00
needsRemoval = false ; //callback->processOverlap(pair);
}
else
2017-08-01 14:30:58 +02:00
{
needsRemoval = true ;
}
2019-01-03 14:26:51 +01:00
}
else
2017-08-01 14:30:58 +02:00
{
//remove duplicate
needsRemoval = true ;
//should have no algorithm
btAssert ( ! pair . m_algorithm ) ;
}
2019-01-03 14:26:51 +01:00
2017-08-01 14:30:58 +02:00
if ( needsRemoval )
{
2019-01-03 14:26:51 +01:00
m_pairCache - > cleanOverlappingPair ( pair , dispatcher ) ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
// m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
// m_overlappingPairArray.pop_back();
2017-08-01 14:30:58 +02:00
pair . m_pProxy0 = 0 ;
pair . m_pProxy1 = 0 ;
m_invalidPair + + ;
2019-01-03 14:26:51 +01:00
}
}
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
///if you don't like to skip the invalid pairs in the array, execute following code:
# define CLEAN_INVALID_PAIRS 1
# ifdef CLEAN_INVALID_PAIRS
2017-08-01 14:30:58 +02:00
//perform a sort, to sort 'invalid' pairs to the end
overlappingPairArray . quickSort ( btBroadphasePairSortPredicate ( ) ) ;
overlappingPairArray . resize ( overlappingPairArray . size ( ) - m_invalidPair ) ;
m_invalidPair = 0 ;
2019-01-03 14:26:51 +01:00
# endif //CLEAN_INVALID_PAIRS
2017-08-01 14:30:58 +02:00
//printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
}
}
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
bool btAxisSweep3Internal < BP_FP_INT_TYPE > : : testAabbOverlap ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 )
2017-08-01 14:30:58 +02:00
{
const Handle * pHandleA = static_cast < Handle * > ( proxy0 ) ;
const Handle * pHandleB = static_cast < Handle * > ( proxy1 ) ;
2019-01-03 14:26:51 +01:00
2017-08-01 14:30:58 +02:00
//optimization 1: check the array index (memory address), instead of the m_pos
for ( int axis = 0 ; axis < 3 ; axis + + )
2019-01-03 14:26:51 +01:00
{
if ( pHandleA - > m_maxEdges [ axis ] < pHandleB - > m_minEdges [ axis ] | |
pHandleB - > m_maxEdges [ axis ] < pHandleA - > m_minEdges [ axis ] )
{
return false ;
}
}
2017-08-01 14:30:58 +02:00
return true ;
}
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
bool btAxisSweep3Internal < BP_FP_INT_TYPE > : : testOverlap2D ( const Handle * pHandleA , const Handle * pHandleB , int axis0 , int axis1 )
2017-08-01 14:30:58 +02:00
{
//optimization 1: check the array index (memory address), instead of the m_pos
2019-01-03 14:26:51 +01:00
if ( pHandleA - > m_maxEdges [ axis0 ] < pHandleB - > m_minEdges [ axis0 ] | |
2017-08-01 14:30:58 +02:00
pHandleB - > m_maxEdges [ axis0 ] < pHandleA - > m_minEdges [ axis0 ] | |
pHandleA - > m_maxEdges [ axis1 ] < pHandleB - > m_minEdges [ axis1 ] | |
2019-01-03 14:26:51 +01:00
pHandleB - > m_maxEdges [ axis1 ] < pHandleA - > m_minEdges [ axis1 ] )
{
return false ;
}
2017-08-01 14:30:58 +02:00
return true ;
}
template < typename BP_FP_INT_TYPE >
2019-01-03 14:26:51 +01:00
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : updateHandle ( BP_FP_INT_TYPE handle , const btVector3 & aabbMin , const btVector3 & aabbMax , btDispatcher * dispatcher )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
// btAssert(bounds.IsFinite());
2017-08-01 14:30:58 +02:00
//btAssert(bounds.HasVolume());
Handle * pHandle = getHandle ( handle ) ;
// quantize the new bounds
BP_FP_INT_TYPE min [ 3 ] , max [ 3 ] ;
quantize ( min , aabbMin , 0 ) ;
quantize ( max , aabbMax , 1 ) ;
// update changed edges
for ( int axis = 0 ; axis < 3 ; axis + + )
{
BP_FP_INT_TYPE emin = pHandle - > m_minEdges [ axis ] ;
BP_FP_INT_TYPE emax = pHandle - > m_maxEdges [ axis ] ;
int dmin = ( int ) min [ axis ] - ( int ) m_pEdges [ axis ] [ emin ] . m_pos ;
int dmax = ( int ) max [ axis ] - ( int ) m_pEdges [ axis ] [ emax ] . m_pos ;
m_pEdges [ axis ] [ emin ] . m_pos = min [ axis ] ;
m_pEdges [ axis ] [ emax ] . m_pos = max [ axis ] ;
// expand (only adds overlaps)
if ( dmin < 0 )
2019-01-03 14:26:51 +01:00
sortMinDown ( axis , emin , dispatcher , true ) ;
2017-08-01 14:30:58 +02:00
if ( dmax > 0 )
2019-01-03 14:26:51 +01:00
sortMaxUp ( axis , emax , dispatcher , true ) ;
2017-08-01 14:30:58 +02:00
// shrink (only removes overlaps)
if ( dmin > 0 )
2019-01-03 14:26:51 +01:00
sortMinUp ( axis , emin , dispatcher , true ) ;
2017-08-01 14:30:58 +02:00
if ( dmax < 0 )
2019-01-03 14:26:51 +01:00
sortMaxDown ( axis , emax , dispatcher , true ) ;
2017-08-01 14:30:58 +02:00
# ifdef DEBUG_BROADPHASE
2019-01-03 14:26:51 +01:00
debugPrintAxis ( axis ) ;
# endif //DEBUG_BROADPHASE
2017-08-01 14:30:58 +02:00
}
}
// sorting a min edge downwards can only ever *add* overlaps
template < typename BP_FP_INT_TYPE >
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : sortMinDown ( int axis , BP_FP_INT_TYPE edge , btDispatcher * /* dispatcher */ , bool updateOverlaps )
{
Edge * pEdge = m_pEdges [ axis ] + edge ;
Edge * pPrev = pEdge - 1 ;
Handle * pHandleEdge = getHandle ( pEdge - > m_handle ) ;
while ( pEdge - > m_pos < pPrev - > m_pos )
{
Handle * pHandlePrev = getHandle ( pPrev - > m_handle ) ;
if ( pPrev - > IsMax ( ) )
{
// if previous edge is a maximum check the bounds and add an overlap if necessary
2019-01-03 14:26:51 +01:00
const int axis1 = ( 1 < < axis ) & 3 ;
const int axis2 = ( 1 < < axis1 ) & 3 ;
if ( updateOverlaps & & testOverlap2D ( pHandleEdge , pHandlePrev , axis1 , axis2 ) )
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
m_pairCache - > addOverlappingPair ( pHandleEdge , pHandlePrev ) ;
2017-08-01 14:30:58 +02:00
if ( m_userPairCallback )
2019-01-03 14:26:51 +01:00
m_userPairCallback - > addOverlappingPair ( pHandleEdge , pHandlePrev ) ;
2017-08-01 14:30:58 +02:00
//AddOverlap(pEdge->m_handle, pPrev->m_handle);
}
// update edge reference in other handle
pHandlePrev - > m_maxEdges [ axis ] + + ;
}
else
pHandlePrev - > m_minEdges [ axis ] + + ;
pHandleEdge - > m_minEdges [ axis ] - - ;
// swap the edges
Edge swap = * pEdge ;
* pEdge = * pPrev ;
* pPrev = swap ;
// decrement
pEdge - - ;
pPrev - - ;
}
# ifdef DEBUG_BROADPHASE
debugPrintAxis ( axis ) ;
2019-01-03 14:26:51 +01:00
# endif //DEBUG_BROADPHASE
2017-08-01 14:30:58 +02:00
}
// sorting a min edge upwards can only ever *remove* overlaps
template < typename BP_FP_INT_TYPE >
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : sortMinUp ( int axis , BP_FP_INT_TYPE edge , btDispatcher * dispatcher , bool updateOverlaps )
{
Edge * pEdge = m_pEdges [ axis ] + edge ;
Edge * pNext = pEdge + 1 ;
Handle * pHandleEdge = getHandle ( pEdge - > m_handle ) ;
while ( pNext - > m_handle & & ( pEdge - > m_pos > = pNext - > m_pos ) )
{
Handle * pHandleNext = getHandle ( pNext - > m_handle ) ;
if ( pNext - > IsMax ( ) )
{
Handle * handle0 = getHandle ( pEdge - > m_handle ) ;
Handle * handle1 = getHandle ( pNext - > m_handle ) ;
2019-01-03 14:26:51 +01:00
const int axis1 = ( 1 < < axis ) & 3 ;
const int axis2 = ( 1 < < axis1 ) & 3 ;
2017-08-01 14:30:58 +02:00
// if next edge is maximum remove any overlap between the two handles
2019-01-03 14:26:51 +01:00
if ( updateOverlaps
2017-08-01 14:30:58 +02:00
# ifdef USE_OVERLAP_TEST_ON_REMOVES
2019-01-03 14:26:51 +01:00
& & testOverlap2D ( handle0 , handle1 , axis1 , axis2 )
# endif //USE_OVERLAP_TEST_ON_REMOVES
)
2017-08-01 14:30:58 +02:00
{
2019-01-03 14:26:51 +01:00
m_pairCache - > removeOverlappingPair ( handle0 , handle1 , dispatcher ) ;
2017-08-01 14:30:58 +02:00
if ( m_userPairCallback )
2019-01-03 14:26:51 +01:00
m_userPairCallback - > removeOverlappingPair ( handle0 , handle1 , dispatcher ) ;
2017-08-01 14:30:58 +02:00
}
// update edge reference in other handle
pHandleNext - > m_maxEdges [ axis ] - - ;
}
else
pHandleNext - > m_minEdges [ axis ] - - ;
pHandleEdge - > m_minEdges [ axis ] + + ;
// swap the edges
Edge swap = * pEdge ;
* pEdge = * pNext ;
* pNext = swap ;
// increment
pEdge + + ;
pNext + + ;
}
}
// sorting a max edge downwards can only ever *remove* overlaps
template < typename BP_FP_INT_TYPE >
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : sortMaxDown ( int axis , BP_FP_INT_TYPE edge , btDispatcher * dispatcher , bool updateOverlaps )
{
Edge * pEdge = m_pEdges [ axis ] + edge ;
Edge * pPrev = pEdge - 1 ;
Handle * pHandleEdge = getHandle ( pEdge - > m_handle ) ;
while ( pEdge - > m_pos < pPrev - > m_pos )
{
Handle * pHandlePrev = getHandle ( pPrev - > m_handle ) ;
if ( ! pPrev - > IsMax ( ) )
{
// if previous edge was a minimum remove any overlap between the two handles
Handle * handle0 = getHandle ( pEdge - > m_handle ) ;
Handle * handle1 = getHandle ( pPrev - > m_handle ) ;
2019-01-03 14:26:51 +01:00
const int axis1 = ( 1 < < axis ) & 3 ;
const int axis2 = ( 1 < < axis1 ) & 3 ;
2017-08-01 14:30:58 +02:00
2019-01-03 14:26:51 +01:00
if ( updateOverlaps
2017-08-01 14:30:58 +02:00
# ifdef USE_OVERLAP_TEST_ON_REMOVES
2019-01-03 14:26:51 +01:00
& & testOverlap2D ( handle0 , handle1 , axis1 , axis2 )
# endif //USE_OVERLAP_TEST_ON_REMOVES
)
2017-08-01 14:30:58 +02:00
{
//this is done during the overlappingpairarray iteration/narrowphase collision
2019-01-03 14:26:51 +01:00
m_pairCache - > removeOverlappingPair ( handle0 , handle1 , dispatcher ) ;
2017-08-01 14:30:58 +02:00
if ( m_userPairCallback )
2019-01-03 14:26:51 +01:00
m_userPairCallback - > removeOverlappingPair ( handle0 , handle1 , dispatcher ) ;
2017-08-01 14:30:58 +02:00
}
// update edge reference in other handle
2019-01-03 14:26:51 +01:00
pHandlePrev - > m_minEdges [ axis ] + + ;
;
2017-08-01 14:30:58 +02:00
}
else
pHandlePrev - > m_maxEdges [ axis ] + + ;
pHandleEdge - > m_maxEdges [ axis ] - - ;
// swap the edges
Edge swap = * pEdge ;
* pEdge = * pPrev ;
* pPrev = swap ;
// decrement
pEdge - - ;
pPrev - - ;
}
# ifdef DEBUG_BROADPHASE
debugPrintAxis ( axis ) ;
2019-01-03 14:26:51 +01:00
# endif //DEBUG_BROADPHASE
2017-08-01 14:30:58 +02:00
}
// sorting a max edge upwards can only ever *add* overlaps
template < typename BP_FP_INT_TYPE >
void btAxisSweep3Internal < BP_FP_INT_TYPE > : : sortMaxUp ( int axis , BP_FP_INT_TYPE edge , btDispatcher * /* dispatcher */ , bool updateOverlaps )
{
Edge * pEdge = m_pEdges [ axis ] + edge ;
Edge * pNext = pEdge + 1 ;
Handle * pHandleEdge = getHandle ( pEdge - > m_handle ) ;
while ( pNext - > m_handle & & ( pEdge - > m_pos > = pNext - > m_pos ) )
{
Handle * pHandleNext = getHandle ( pNext - > m_handle ) ;
2019-01-03 14:26:51 +01:00
const int axis1 = ( 1 < < axis ) & 3 ;
const int axis2 = ( 1 < < axis1 ) & 3 ;
2017-08-01 14:30:58 +02:00
if ( ! pNext - > IsMax ( ) )
{
// if next edge is a minimum check the bounds and add an overlap if necessary
2019-01-03 14:26:51 +01:00
if ( updateOverlaps & & testOverlap2D ( pHandleEdge , pHandleNext , axis1 , axis2 ) )
2017-08-01 14:30:58 +02:00
{
Handle * handle0 = getHandle ( pEdge - > m_handle ) ;
Handle * handle1 = getHandle ( pNext - > m_handle ) ;
2019-01-03 14:26:51 +01:00
m_pairCache - > addOverlappingPair ( handle0 , handle1 ) ;
2017-08-01 14:30:58 +02:00
if ( m_userPairCallback )
2019-01-03 14:26:51 +01:00
m_userPairCallback - > addOverlappingPair ( handle0 , handle1 ) ;
2017-08-01 14:30:58 +02:00
}
// update edge reference in other handle
pHandleNext - > m_minEdges [ axis ] - - ;
}
else
pHandleNext - > m_maxEdges [ axis ] - - ;
pHandleEdge - > m_maxEdges [ axis ] + + ;
// swap the edges
Edge swap = * pEdge ;
* pEdge = * pNext ;
* pNext = swap ;
// increment
pEdge + + ;
pNext + + ;
}
}
# endif