2017-08-01 12:30:58 +00:00
/*
Bullet Continuous Collision Detection and Physics Library
Copyright ( c ) 2003 - 2006 Erwin Coumans http : //continuousphysics.com/Bullet/
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_OVERLAPPING_PAIR_CACHE_H
# define BT_OVERLAPPING_PAIR_CACHE_H
# include "btBroadphaseInterface.h"
# include "btBroadphaseProxy.h"
# include "btOverlappingPairCallback.h"
# include "LinearMath/btAlignedObjectArray.h"
class btDispatcher ;
2019-01-03 13:26:51 +00:00
typedef btAlignedObjectArray < btBroadphasePair > btBroadphasePairArray ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
struct btOverlapCallback
2017-08-01 12:30:58 +00:00
{
virtual ~ btOverlapCallback ( )
2019-01-03 13:26:51 +00:00
{
}
2017-08-01 12:30:58 +00:00
//return true for deletion of the pair
2019-01-03 13:26:51 +00:00
virtual bool processOverlap ( btBroadphasePair & pair ) = 0 ;
2017-08-01 12:30:58 +00:00
} ;
struct btOverlapFilterCallback
{
virtual ~ btOverlapFilterCallback ( )
2019-01-03 13:26:51 +00:00
{
}
2017-08-01 12:30:58 +00:00
// return true when pairs need collision
2019-01-03 13:26:51 +00:00
virtual bool needBroadphaseCollision ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 ) const = 0 ;
2017-08-01 12:30:58 +00:00
} ;
2019-01-03 13:26:51 +00:00
const int BT_NULL_PAIR = 0xffffffff ;
2017-08-01 12:30:58 +00:00
///The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
///The btHashedOverlappingPairCache and btSortedOverlappingPairCache classes are two implementations.
class btOverlappingPairCache : public btOverlappingPairCallback
{
public :
2019-01-03 13:26:51 +00:00
virtual ~ btOverlappingPairCache ( ) { } // this is needed so we can get to the derived class destructor
virtual btBroadphasePair * getOverlappingPairArrayPtr ( ) = 0 ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual const btBroadphasePair * getOverlappingPairArrayPtr ( ) const = 0 ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual btBroadphasePairArray & getOverlappingPairArray ( ) = 0 ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual void cleanOverlappingPair ( btBroadphasePair & pair , btDispatcher * dispatcher ) = 0 ;
2017-08-01 12:30:58 +00:00
virtual int getNumOverlappingPairs ( ) const = 0 ;
2019-01-03 13:26:51 +00:00
virtual void cleanProxyFromPairs ( btBroadphaseProxy * proxy , btDispatcher * dispatcher ) = 0 ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual void setOverlapFilterCallback ( btOverlapFilterCallback * callback ) = 0 ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual void processAllOverlappingPairs ( btOverlapCallback * , btDispatcher * dispatcher ) = 0 ;
2017-08-01 12:30:58 +00:00
2020-01-08 17:05:43 +00:00
virtual void processAllOverlappingPairs ( btOverlapCallback * callback , btDispatcher * dispatcher , const struct btDispatcherInfo & /*dispatchInfo*/ )
2018-09-07 14:11:04 +00:00
{
processAllOverlappingPairs ( callback , dispatcher ) ;
}
2017-08-01 12:30:58 +00:00
virtual btBroadphasePair * findPair ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 ) = 0 ;
2019-01-03 13:26:51 +00:00
virtual bool hasDeferredRemoval ( ) = 0 ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual void setInternalGhostPairCallback ( btOverlappingPairCallback * ghostPairCallback ) = 0 ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual void sortOverlappingPairs ( btDispatcher * dispatcher ) = 0 ;
2017-08-01 12:30:58 +00:00
} ;
/// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com
2019-01-03 13:26:51 +00:00
ATTRIBUTE_ALIGNED16 ( class )
btHashedOverlappingPairCache : public btOverlappingPairCache
2017-08-01 12:30:58 +00:00
{
2019-01-03 13:26:51 +00:00
btBroadphasePairArray m_overlappingPairArray ;
2017-08-01 12:30:58 +00:00
btOverlapFilterCallback * m_overlapFilterCallback ;
protected :
2019-01-03 13:26:51 +00:00
btAlignedObjectArray < int > m_hashTable ;
btAlignedObjectArray < int > m_next ;
btOverlappingPairCallback * m_ghostPairCallback ;
2017-08-01 12:30:58 +00:00
public :
BT_DECLARE_ALIGNED_ALLOCATOR ( ) ;
2019-01-03 13:26:51 +00:00
2017-08-01 12:30:58 +00:00
btHashedOverlappingPairCache ( ) ;
virtual ~ btHashedOverlappingPairCache ( ) ;
2019-01-03 13:26:51 +00:00
void removeOverlappingPairsContainingProxy ( btBroadphaseProxy * proxy , btDispatcher * dispatcher ) ;
virtual void * removeOverlappingPair ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 , btDispatcher * dispatcher ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
SIMD_FORCE_INLINE bool needsBroadphaseCollision ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 ) const
2017-08-01 12:30:58 +00:00
{
if ( m_overlapFilterCallback )
2019-01-03 13:26:51 +00:00
return m_overlapFilterCallback - > needBroadphaseCollision ( proxy0 , proxy1 ) ;
2017-08-01 12:30:58 +00:00
bool collides = ( proxy0 - > m_collisionFilterGroup & proxy1 - > m_collisionFilterMask ) ! = 0 ;
collides = collides & & ( proxy1 - > m_collisionFilterGroup & proxy0 - > m_collisionFilterMask ) ;
2019-01-03 13:26:51 +00:00
2017-08-01 12:30:58 +00:00
return collides ;
}
// Add a pair and return the new pair. If the pair already exists,
// no new pair is created and the old one is returned.
2019-01-03 13:26:51 +00:00
virtual btBroadphasePair * addOverlappingPair ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 )
2017-08-01 12:30:58 +00:00
{
2019-01-03 13:26:51 +00:00
if ( ! needsBroadphaseCollision ( proxy0 , proxy1 ) )
2017-08-01 12:30:58 +00:00
return 0 ;
2019-01-03 13:26:51 +00:00
return internalAddPair ( proxy0 , proxy1 ) ;
2017-08-01 12:30:58 +00:00
}
2019-01-03 13:26:51 +00:00
void cleanProxyFromPairs ( btBroadphaseProxy * proxy , btDispatcher * dispatcher ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual void processAllOverlappingPairs ( btOverlapCallback * , btDispatcher * dispatcher ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual void processAllOverlappingPairs ( btOverlapCallback * callback , btDispatcher * dispatcher , const struct btDispatcherInfo & dispatchInfo ) ;
2018-09-07 14:11:04 +00:00
2019-01-03 13:26:51 +00:00
virtual btBroadphasePair * getOverlappingPairArrayPtr ( )
2017-08-01 12:30:58 +00:00
{
return & m_overlappingPairArray [ 0 ] ;
}
2019-01-03 13:26:51 +00:00
const btBroadphasePair * getOverlappingPairArrayPtr ( ) const
2017-08-01 12:30:58 +00:00
{
return & m_overlappingPairArray [ 0 ] ;
}
2019-01-03 13:26:51 +00:00
btBroadphasePairArray & getOverlappingPairArray ( )
2017-08-01 12:30:58 +00:00
{
return m_overlappingPairArray ;
}
2019-01-03 13:26:51 +00:00
const btBroadphasePairArray & getOverlappingPairArray ( ) const
2017-08-01 12:30:58 +00:00
{
return m_overlappingPairArray ;
}
2019-01-03 13:26:51 +00:00
void cleanOverlappingPair ( btBroadphasePair & pair , btDispatcher * dispatcher ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
btBroadphasePair * findPair ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 ) ;
2017-08-01 12:30:58 +00:00
int GetCount ( ) const { return m_overlappingPairArray . size ( ) ; }
2019-01-03 13:26:51 +00:00
// btBroadphasePair* GetPairs() { return m_pairs; }
2017-08-01 12:30:58 +00:00
btOverlapFilterCallback * getOverlapFilterCallback ( )
{
return m_overlapFilterCallback ;
}
2019-01-03 13:26:51 +00:00
void setOverlapFilterCallback ( btOverlapFilterCallback * callback )
2017-08-01 12:30:58 +00:00
{
m_overlapFilterCallback = callback ;
}
2019-01-03 13:26:51 +00:00
int getNumOverlappingPairs ( ) const
2017-08-01 12:30:58 +00:00
{
return m_overlappingPairArray . size ( ) ;
}
2019-01-03 13:26:51 +00:00
2017-08-01 12:30:58 +00:00
private :
2019-01-03 13:26:51 +00:00
btBroadphasePair * internalAddPair ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
void growTables ( ) ;
2017-08-01 12:30:58 +00:00
SIMD_FORCE_INLINE bool equalsPair ( const btBroadphasePair & pair , int proxyId1 , int proxyId2 )
2019-01-03 13:26:51 +00:00
{
2017-08-01 12:30:58 +00:00
return pair . m_pProxy0 - > getUid ( ) = = proxyId1 & & pair . m_pProxy1 - > getUid ( ) = = proxyId2 ;
}
/*
// Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm
// This assumes proxyId1 and proxyId2 are 16-bit.
SIMD_FORCE_INLINE int getHash ( int proxyId1 , int proxyId2 )
{
int key = ( proxyId2 < < 16 ) | proxyId1 ;
key = ~ key + ( key < < 15 ) ;
key = key ^ ( key > > 12 ) ;
key = key + ( key < < 2 ) ;
key = key ^ ( key > > 4 ) ;
key = key * 2057 ;
key = key ^ ( key > > 16 ) ;
return key ;
}
*/
SIMD_FORCE_INLINE unsigned int getHash ( unsigned int proxyId1 , unsigned int proxyId2 )
{
unsigned int key = proxyId1 | ( proxyId2 < < 16 ) ;
// Thomas Wang's hash
key + = ~ ( key < < 15 ) ;
2019-01-03 13:26:51 +00:00
key ^ = ( key > > 10 ) ;
key + = ( key < < 3 ) ;
key ^ = ( key > > 6 ) ;
2017-08-01 12:30:58 +00:00
key + = ~ ( key < < 11 ) ;
2019-01-03 13:26:51 +00:00
key ^ = ( key > > 16 ) ;
2017-08-01 12:30:58 +00:00
return key ;
}
2019-01-03 13:26:51 +00:00
SIMD_FORCE_INLINE btBroadphasePair * internalFindPair ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 , int hash )
2017-08-01 12:30:58 +00:00
{
int proxyId1 = proxy0 - > getUid ( ) ;
int proxyId2 = proxy1 - > getUid ( ) ;
2019-01-03 13:26:51 +00:00
#if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat.
2017-08-01 12:30:58 +00:00
if ( proxyId1 > proxyId2 )
btSwap ( proxyId1 , proxyId2 ) ;
2019-01-03 13:26:51 +00:00
# endif
2017-08-01 12:30:58 +00:00
int index = m_hashTable [ hash ] ;
2019-01-03 13:26:51 +00:00
while ( index ! = BT_NULL_PAIR & & equalsPair ( m_overlappingPairArray [ index ] , proxyId1 , proxyId2 ) = = false )
2017-08-01 12:30:58 +00:00
{
index = m_next [ index ] ;
}
2019-01-03 13:26:51 +00:00
if ( index = = BT_NULL_PAIR )
2017-08-01 12:30:58 +00:00
{
return NULL ;
}
btAssert ( index < m_overlappingPairArray . size ( ) ) ;
return & m_overlappingPairArray [ index ] ;
}
2019-01-03 13:26:51 +00:00
virtual bool hasDeferredRemoval ( )
2017-08-01 12:30:58 +00:00
{
return false ;
}
2019-01-03 13:26:51 +00:00
virtual void setInternalGhostPairCallback ( btOverlappingPairCallback * ghostPairCallback )
2017-08-01 12:30:58 +00:00
{
m_ghostPairCallback = ghostPairCallback ;
}
2019-01-03 13:26:51 +00:00
virtual void sortOverlappingPairs ( btDispatcher * dispatcher ) ;
2017-08-01 12:30:58 +00:00
} ;
///btSortedOverlappingPairCache maintains the objects with overlapping AABB
///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
2019-01-03 13:26:51 +00:00
class btSortedOverlappingPairCache : public btOverlappingPairCache
2017-08-01 12:30:58 +00:00
{
2019-01-03 13:26:51 +00:00
protected :
//avoid brute-force finding all the time
btBroadphasePairArray m_overlappingPairArray ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
//during the dispatch, check that user doesn't destroy/create proxy
bool m_blockedForChanges ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
///by default, do the removal during the pair traversal
bool m_hasDeferredRemoval ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
//if set, use the callback instead of the built in filter in needBroadphaseCollision
btOverlapFilterCallback * m_overlapFilterCallback ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
btOverlappingPairCallback * m_ghostPairCallback ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
public :
btSortedOverlappingPairCache ( ) ;
virtual ~ btSortedOverlappingPairCache ( ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual void processAllOverlappingPairs ( btOverlapCallback * , btDispatcher * dispatcher ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
void * removeOverlappingPair ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 , btDispatcher * dispatcher ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
void cleanOverlappingPair ( btBroadphasePair & pair , btDispatcher * dispatcher ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
btBroadphasePair * addOverlappingPair ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
btBroadphasePair * findPair ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
void cleanProxyFromPairs ( btBroadphaseProxy * proxy , btDispatcher * dispatcher ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
void removeOverlappingPairsContainingProxy ( btBroadphaseProxy * proxy , btDispatcher * dispatcher ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
inline bool needsBroadphaseCollision ( btBroadphaseProxy * proxy0 , btBroadphaseProxy * proxy1 ) const
{
if ( m_overlapFilterCallback )
return m_overlapFilterCallback - > needBroadphaseCollision ( proxy0 , proxy1 ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
bool collides = ( proxy0 - > m_collisionFilterGroup & proxy1 - > m_collisionFilterMask ) ! = 0 ;
collides = collides & & ( proxy1 - > m_collisionFilterGroup & proxy0 - > m_collisionFilterMask ) ;
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
return collides ;
}
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
btBroadphasePairArray & getOverlappingPairArray ( )
{
return m_overlappingPairArray ;
}
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
const btBroadphasePairArray & getOverlappingPairArray ( ) const
{
return m_overlappingPairArray ;
}
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
btBroadphasePair * getOverlappingPairArrayPtr ( )
{
return & m_overlappingPairArray [ 0 ] ;
}
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
const btBroadphasePair * getOverlappingPairArrayPtr ( ) const
{
return & m_overlappingPairArray [ 0 ] ;
}
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
int getNumOverlappingPairs ( ) const
{
return m_overlappingPairArray . size ( ) ;
}
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
btOverlapFilterCallback * getOverlapFilterCallback ( )
{
return m_overlapFilterCallback ;
}
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
void setOverlapFilterCallback ( btOverlapFilterCallback * callback )
{
m_overlapFilterCallback = callback ;
}
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual bool hasDeferredRemoval ( )
{
return m_hasDeferredRemoval ;
}
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual void setInternalGhostPairCallback ( btOverlappingPairCallback * ghostPairCallback )
{
m_ghostPairCallback = ghostPairCallback ;
}
2017-08-01 12:30:58 +00:00
2019-01-03 13:26:51 +00:00
virtual void sortOverlappingPairs ( btDispatcher * dispatcher ) ;
} ;
2017-08-01 12:30:58 +00:00
///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing.
class btNullPairCache : public btOverlappingPairCache
{
2019-01-03 13:26:51 +00:00
btBroadphasePairArray m_overlappingPairArray ;
2017-08-01 12:30:58 +00:00
public :
2019-01-03 13:26:51 +00:00
virtual btBroadphasePair * getOverlappingPairArrayPtr ( )
2017-08-01 12:30:58 +00:00
{
return & m_overlappingPairArray [ 0 ] ;
}
2019-01-03 13:26:51 +00:00
const btBroadphasePair * getOverlappingPairArrayPtr ( ) const
2017-08-01 12:30:58 +00:00
{
return & m_overlappingPairArray [ 0 ] ;
}
2019-01-03 13:26:51 +00:00
btBroadphasePairArray & getOverlappingPairArray ( )
2017-08-01 12:30:58 +00:00
{
return m_overlappingPairArray ;
}
2019-01-03 13:26:51 +00:00
virtual void cleanOverlappingPair ( btBroadphasePair & /*pair*/ , btDispatcher * /*dispatcher*/ )
{
2017-08-01 12:30:58 +00:00
}
virtual int getNumOverlappingPairs ( ) const
{
return 0 ;
}
2019-01-03 13:26:51 +00:00
virtual void cleanProxyFromPairs ( btBroadphaseProxy * /*proxy*/ , btDispatcher * /*dispatcher*/ )
2017-08-01 12:30:58 +00:00
{
}
2019-01-03 13:26:51 +00:00
virtual void setOverlapFilterCallback ( btOverlapFilterCallback * /*callback*/ )
2017-08-01 12:30:58 +00:00
{
}
2019-01-03 13:26:51 +00:00
virtual void processAllOverlappingPairs ( btOverlapCallback * , btDispatcher * /*dispatcher*/ )
2017-08-01 12:30:58 +00:00
{
}
virtual btBroadphasePair * findPair ( btBroadphaseProxy * /*proxy0*/ , btBroadphaseProxy * /*proxy1*/ )
{
return 0 ;
}
2019-01-03 13:26:51 +00:00
virtual bool hasDeferredRemoval ( )
2017-08-01 12:30:58 +00:00
{
return true ;
}
2019-01-03 13:26:51 +00:00
virtual void setInternalGhostPairCallback ( btOverlappingPairCallback * /* ghostPairCallback */ )
2017-08-01 12:30:58 +00:00
{
}
2019-01-03 13:26:51 +00:00
virtual btBroadphasePair * addOverlappingPair ( btBroadphaseProxy * /*proxy0*/ , btBroadphaseProxy * /*proxy1*/ )
2017-08-01 12:30:58 +00:00
{
return 0 ;
}
2019-01-03 13:26:51 +00:00
virtual void * removeOverlappingPair ( btBroadphaseProxy * /*proxy0*/ , btBroadphaseProxy * /*proxy1*/ , btDispatcher * /*dispatcher*/ )
2017-08-01 12:30:58 +00:00
{
return 0 ;
}
2019-01-03 13:26:51 +00:00
virtual void removeOverlappingPairsContainingProxy ( btBroadphaseProxy * /*proxy0*/ , btDispatcher * /*dispatcher*/ )
2017-08-01 12:30:58 +00:00
{
}
2019-01-03 13:26:51 +00:00
virtual void sortOverlappingPairs ( btDispatcher * dispatcher )
2017-08-01 12:30:58 +00:00
{
2019-01-03 13:26:51 +00:00
( void ) dispatcher ;
2017-08-01 12:30:58 +00:00
}
} ;
2019-01-03 13:26:51 +00:00
# endif //BT_OVERLAPPING_PAIR_CACHE_H