- removed STL from the Bullet library: replace std::vector by btAlignedObjectArray. Also removed the std::set for overlapping pair set, and turned it into an overlapping pair array. The SAP only adds objects, never removed. Removal is postponed for during traversal of overlapping pairs (duplicates and non-overlapping pairs are removed during that traversal).
- added heap sort and binary search/linear search to btAlignedObjectArray - fixed wrong cast, thanks Hamstray, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1015
This commit is contained in:
@@ -50,6 +50,7 @@ void btAxisSweep3::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,con
|
||||
btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles)
|
||||
:btOverlappingPairCache()
|
||||
{
|
||||
m_invalidPair = 0;
|
||||
//assert(bounds.HasVolume());
|
||||
|
||||
// 1 handle is reserved as sentinel
|
||||
@@ -249,6 +250,97 @@ void btAxisSweep3::removeHandle(unsigned short handle)
|
||||
|
||||
}
|
||||
|
||||
extern int gOverlappingPairs;
|
||||
|
||||
void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback)
|
||||
{
|
||||
|
||||
//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
|
||||
m_overlappingPairArray.heapSort(btBroadphasePairSortPredicate());
|
||||
|
||||
//remove the 'invalid' ones
|
||||
#ifdef USE_POPBACK_REMOVAL
|
||||
while (m_invalidPair>0)
|
||||
{
|
||||
m_invalidPair--;
|
||||
m_overlappingPairArray.pop_back();
|
||||
}
|
||||
#else
|
||||
m_overlappingPairArray.resize(m_overlappingPairArray.size() - m_invalidPair);
|
||||
m_invalidPair = 0;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
btBroadphasePair previousPair;
|
||||
previousPair.m_pProxy0 = 0;
|
||||
previousPair.m_pProxy1 = 0;
|
||||
previousPair.m_algorithm = 0;
|
||||
|
||||
|
||||
for (i=0;i<m_overlappingPairArray.size();i++)
|
||||
{
|
||||
|
||||
btBroadphasePair& pair = m_overlappingPairArray[i];
|
||||
|
||||
bool isDuplicate = (pair == previousPair);
|
||||
|
||||
previousPair = pair;
|
||||
|
||||
bool needsRemoval = false;
|
||||
|
||||
if (!isDuplicate)
|
||||
{
|
||||
bool hasOverlap = testOverlap(pair.m_pProxy0,pair.m_pProxy1);
|
||||
|
||||
if (hasOverlap)
|
||||
{
|
||||
needsRemoval = callback->processOverlap(pair);
|
||||
} else
|
||||
{
|
||||
needsRemoval = true;
|
||||
}
|
||||
} else
|
||||
{
|
||||
//remove duplicate
|
||||
needsRemoval = true;
|
||||
//should have no algorithm
|
||||
btAssert(!pair.m_algorithm);
|
||||
}
|
||||
|
||||
if (needsRemoval)
|
||||
{
|
||||
cleanOverlappingPair(pair);
|
||||
|
||||
// m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
|
||||
// m_overlappingPairArray.pop_back();
|
||||
pair.m_pProxy0 = 0;
|
||||
pair.m_pProxy1 = 0;
|
||||
m_invalidPair++;
|
||||
gOverlappingPairs--;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool btAxisSweep3::testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
|
||||
{
|
||||
const Handle* pHandleA = static_cast<Handle*>(proxy0);
|
||||
const Handle* pHandleB = static_cast<Handle*>(proxy1);
|
||||
|
||||
//optimization 1: check the array index (memory address), instead of the m_pos
|
||||
|
||||
for (int axis = 0; axis < 3; axis++)
|
||||
{
|
||||
if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] ||
|
||||
pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB)
|
||||
{
|
||||
//optimization 1: check the array index (memory address), instead of the m_pos
|
||||
@@ -379,10 +471,12 @@ void btAxisSweep3::sortMinUp(int axis, unsigned short edge, bool updateOverlaps)
|
||||
// if next edge is maximum remove any overlap between the two handles
|
||||
if (updateOverlaps)
|
||||
{
|
||||
/*
|
||||
Handle* handle0 = getHandle(pEdge->m_handle);
|
||||
Handle* handle1 = getHandle(pNext->m_handle);
|
||||
btBroadphasePair tmpPair(*handle0,*handle1);
|
||||
removeOverlappingPair(tmpPair);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -421,6 +515,8 @@ void btAxisSweep3::sortMaxDown(int axis, unsigned short edge, bool updateOverlap
|
||||
// if previous edge was a minimum remove any overlap between the two handles
|
||||
if (updateOverlaps)
|
||||
{
|
||||
//this is done during the overlappingpairarray iteration/narrowphase collision
|
||||
/*
|
||||
Handle* handle0 = getHandle(pEdge->m_handle);
|
||||
Handle* handle1 = getHandle(pPrev->m_handle);
|
||||
btBroadphasePair* pair = findPair(handle0,handle1);
|
||||
@@ -430,6 +526,8 @@ void btAxisSweep3::sortMaxDown(int axis, unsigned short edge, bool updateOverlap
|
||||
{
|
||||
removeOverlappingPair(*pair);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
// update edge reference in other handle
|
||||
|
||||
@@ -72,6 +72,7 @@ private:
|
||||
|
||||
Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries)
|
||||
|
||||
int m_invalidPair;
|
||||
|
||||
// allocation/deallocation
|
||||
unsigned short allocHandle();
|
||||
@@ -80,6 +81,7 @@ private:
|
||||
|
||||
bool testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB);
|
||||
|
||||
|
||||
//Overlap* AddOverlap(unsigned short handleA, unsigned short handleB);
|
||||
//void RemoveOverlap(unsigned short handleA, unsigned short handleB);
|
||||
|
||||
@@ -96,7 +98,7 @@ public:
|
||||
|
||||
virtual void refreshOverlappingPairs()
|
||||
{
|
||||
//this is replace by sweep and prune
|
||||
//this is performed incrementally by sweep and prune (add pair), and during pair traversal (remove pair)
|
||||
}
|
||||
|
||||
unsigned short addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask);
|
||||
@@ -104,11 +106,13 @@ public:
|
||||
void updateHandle(unsigned short handle, const btPoint3& aabbMin,const btPoint3& aabbMax);
|
||||
inline Handle* getHandle(unsigned short index) const {return m_pHandles + index;}
|
||||
|
||||
void processAllOverlappingPairs(btOverlapCallback* callback);
|
||||
|
||||
//Broadphase Interface
|
||||
virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask);
|
||||
virtual void destroyProxy(btBroadphaseProxy* proxy);
|
||||
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax);
|
||||
bool testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ subject to the following restrictions:
|
||||
#ifndef BROADPHASE_PROXY_H
|
||||
#define BROADPHASE_PROXY_H
|
||||
|
||||
#include "../../LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
|
||||
|
||||
|
||||
/// btDispatcher uses these types
|
||||
@@ -164,13 +165,33 @@ struct btBroadphasePair
|
||||
mutable btCollisionAlgorithm* m_algorithm;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
//comparison for set operation, see Solid DT_Encounter
|
||||
inline bool operator<(const btBroadphasePair& a, const btBroadphasePair& b)
|
||||
SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePair& b)
|
||||
{
|
||||
return a.m_pProxy0 < b.m_pProxy0 ||
|
||||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 < b.m_pProxy1);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
class btBroadphasePairSortPredicate
|
||||
{
|
||||
public:
|
||||
|
||||
bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b )
|
||||
{
|
||||
return a.m_pProxy0 > b.m_pProxy0 ||
|
||||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 > b.m_pProxy1) ||
|
||||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphasePair& b)
|
||||
{
|
||||
return (a.m_pProxy0 == b.m_pProxy0) && (a.m_pProxy1 == b.m_pProxy1);
|
||||
}
|
||||
|
||||
|
||||
#endif //BROADPHASE_PROXY_H
|
||||
|
||||
@@ -39,15 +39,15 @@ btOverlappingPairCache::~btOverlappingPairCache()
|
||||
void btOverlappingPairCache::removeOverlappingPair(btBroadphasePair& findPair)
|
||||
{
|
||||
|
||||
std::set<btBroadphasePair>::iterator it = m_overlappingPairSet.find(findPair);
|
||||
// assert(it != m_overlappingPairSet.end());
|
||||
|
||||
if (it != m_overlappingPairSet.end())
|
||||
int findIndex = m_overlappingPairArray.findLinearSearch(findPair);
|
||||
if (findIndex < m_overlappingPairArray.size())
|
||||
{
|
||||
gOverlappingPairs--;
|
||||
btBroadphasePair* pair = (btBroadphasePair*)(&(*it));
|
||||
cleanOverlappingPair(*pair);
|
||||
m_overlappingPairSet.erase(it);
|
||||
btBroadphasePair& pair = m_overlappingPairArray[findIndex];
|
||||
cleanOverlappingPair(pair);
|
||||
|
||||
m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.size()-1);
|
||||
m_overlappingPairArray.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroa
|
||||
|
||||
btBroadphasePair pair(*proxy0,*proxy1);
|
||||
|
||||
m_overlappingPairSet.insert(pair);
|
||||
m_overlappingPairArray.push_back(pair);
|
||||
gOverlappingPairs++;
|
||||
|
||||
}
|
||||
@@ -93,13 +93,15 @@ void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroa
|
||||
return 0;
|
||||
|
||||
btBroadphasePair tmpPair(*proxy0,*proxy1);
|
||||
std::set<btBroadphasePair>::iterator it = m_overlappingPairSet.find(tmpPair);
|
||||
if ((it == m_overlappingPairSet.end()))
|
||||
return 0;
|
||||
int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair);
|
||||
|
||||
//assert(it != m_overlappingPairSet.end());
|
||||
btBroadphasePair* pair = (btBroadphasePair*)(&(*it));
|
||||
return pair;
|
||||
if (findIndex < m_overlappingPairArray.size())
|
||||
{
|
||||
//assert(it != m_overlappingPairSet.end());
|
||||
btBroadphasePair* pair = &m_overlappingPairArray[findIndex];
|
||||
return pair;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,6 +145,8 @@ void btOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy)
|
||||
void btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy)
|
||||
{
|
||||
|
||||
assert(0);
|
||||
//todo, implement more efficient
|
||||
class RemovePairCallback : public btOverlapCallback
|
||||
{
|
||||
btBroadphaseProxy* m_obsoleteProxy;
|
||||
@@ -170,30 +174,23 @@ void btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseP
|
||||
|
||||
void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback)
|
||||
{
|
||||
std::set<btBroadphasePair>::iterator it = m_overlappingPairSet.begin();
|
||||
for (; !(it==m_overlappingPairSet.end());)
|
||||
|
||||
int i;
|
||||
|
||||
for (i=0;i<m_overlappingPairArray.size();)
|
||||
{
|
||||
|
||||
btBroadphasePair* pair = (btBroadphasePair*)(&(*it));
|
||||
btBroadphasePair* pair = &m_overlappingPairArray[i];
|
||||
if (callback->processOverlap(*pair))
|
||||
{
|
||||
cleanOverlappingPair(*pair);
|
||||
|
||||
std::set<btBroadphasePair>::iterator it2 = it;
|
||||
//why does next line not compile under OS X??
|
||||
#ifdef MAC_OSX_FIXED_STL_SET
|
||||
it2++;
|
||||
it = m_overlappingPairSet.erase(it);
|
||||
assert(it == it2);
|
||||
#else
|
||||
it++;
|
||||
m_overlappingPairSet.erase(it2);
|
||||
#endif //MAC_OSX_FIXED_STL_SET
|
||||
|
||||
m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
|
||||
m_overlappingPairArray.pop_back();
|
||||
gOverlappingPairs--;
|
||||
} else
|
||||
{
|
||||
it++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ subject to the following restrictions:
|
||||
#include "btBroadphaseInterface.h"
|
||||
#include "btBroadphaseProxy.h"
|
||||
#include "../../LinearMath/btPoint3.h"
|
||||
#include <set>
|
||||
#include "../../LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
|
||||
struct btOverlapCallback
|
||||
@@ -37,8 +37,9 @@ virtual ~btOverlapCallback()
|
||||
///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
|
||||
class btOverlappingPairCache : public btBroadphaseInterface
|
||||
{
|
||||
protected:
|
||||
//avoid brute-force finding all the time
|
||||
std::set<btBroadphasePair> m_overlappingPairSet;
|
||||
btAlignedObjectArray<btBroadphasePair> m_overlappingPairArray;
|
||||
|
||||
//during the dispatch, check that user doesn't destroy/create proxy
|
||||
bool m_blockedForChanges;
|
||||
@@ -48,7 +49,7 @@ class btOverlappingPairCache : public btBroadphaseInterface
|
||||
btOverlappingPairCache();
|
||||
virtual ~btOverlappingPairCache();
|
||||
|
||||
void processAllOverlappingPairs(btOverlapCallback*);
|
||||
virtual void processAllOverlappingPairs(btOverlapCallback*);
|
||||
|
||||
void removeOverlappingPair(btBroadphasePair& pair);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "LinearMath/btMatrix3x3.h"
|
||||
#include <vector>
|
||||
#include <new.h>
|
||||
|
||||
|
||||
void btSimpleBroadphase::validate()
|
||||
|
||||
Reference in New Issue
Block a user