removed collision template, some code style cleanup, added btDbvhBroadphase to BenchmarkDemo

This commit is contained in:
erwin.coumans
2008-05-06 02:45:56 +00:00
parent 1d5050f584
commit b9acc820d6
7 changed files with 369 additions and 249 deletions

View File

@@ -25,7 +25,7 @@ subject to the following restrictions:
#include <stdio.h> //printf debugging #include <stdio.h> //printf debugging
#include "Taru.mdl" #include "Taru.mdl"
#include "landscape.mdl" #include "landscape.mdl"
#include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h"
@@ -272,7 +272,9 @@ void BenchmarkDemo::initPhysics()
///Don't make the world AABB size too large, it will harm simulation quality and performance ///Don't make the world AABB size too large, it will harm simulation quality and performance
btVector3 worldAabbMin(-10000,-10000,-10000); btVector3 worldAabbMin(-10000,-10000,-10000);
btVector3 worldAabbMax(10000,10000,10000); btVector3 worldAabbMax(10000,10000,10000);
m_overlappingPairCache = new btAxisSweep3(worldAabbMin,worldAabbMax,3500); //m_overlappingPairCache = new btAxisSweep3(worldAabbMin,worldAabbMax,3500);
m_overlappingPairCache = new btDbvtBroadphase();
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;

View File

@@ -26,13 +26,13 @@ int main(int argc,char** argv)
{ {
GLDebugDrawer gDebugDrawer; GLDebugDrawer gDebugDrawer;
// BenchmarkDemo1 benchmarkDemo; BenchmarkDemo1 benchmarkDemo;
// BenchmarkDemo2 benchmarkDemo; // BenchmarkDemo2 benchmarkDemo;
// BenchmarkDemo3 benchmarkDemo; // BenchmarkDemo3 benchmarkDemo;
// BenchmarkDemo4 benchmarkDemo; // BenchmarkDemo4 benchmarkDemo;
// BenchmarkDemo5 benchmarkDemo; // BenchmarkDemo5 benchmarkDemo;
// BenchmarkDemo6 benchmarkDemo; // BenchmarkDemo6 benchmarkDemo;
BenchmarkDemo7 benchmarkDemo; // BenchmarkDemo7 benchmarkDemo;
benchmarkDemo.initPhysics(); benchmarkDemo.initPhysics();

View File

@@ -279,7 +279,7 @@ static btDbvt::Node* topdown(btDbvt* pdbvt,
{ {
if((splitcount[i][0]>0)&&(splitcount[i][1]>0)) if((splitcount[i][0]>0)&&(splitcount[i][1]>0))
{ {
const int midp=abs(splitcount[i][0]-splitcount[i][1]); const int midp=btFabs(splitcount[i][0]-splitcount[i][1]);
if(midp<bestmidp) if(midp<bestmidp)
{ {
bestaxis=i; bestaxis=i;
@@ -470,25 +470,25 @@ void btDbvt::remove(Node* leaf)
void btDbvt::collide(btDbvt* tree, void btDbvt::collide(btDbvt* tree,
ICollide* icollide) const ICollide* icollide) const
{ {
collideGeneric(tree,GCollide(icollide)); collideGeneric(tree,icollide);
} }
// //
void btDbvt::collide(btDbvt::Node* node, void btDbvt::collide(btDbvt::Node* node,
ICollide* icollide) const ICollide* icollide) const
{ {
collideGeneric(node,GCollide(icollide)); collideGeneric(node,icollide);
} }
// //
void btDbvt::collide(const Volume& volume, void btDbvt::collide(const Volume& volume,
ICollide* icollide) const ICollide* icollide) const
{ {
collideGeneric(volume,GCollide(icollide)); collideGeneric(volume,icollide);
} }
// //
void btDbvt::collide(ICollide* icollide) const void btDbvt::collide(ICollide* icollide) const
{ {
collideGeneric(GCollide(icollide)); collideGeneric(icollide);
} }

View File

@@ -87,18 +87,9 @@ struct btDbvt
/* ICollide */ /* ICollide */
struct ICollide struct ICollide
{ {
virtual void Process(const Node*,const Node*) {} virtual void Process(const Node*,const Node*)=0;
virtual void Process(const Node*) {} virtual void Process(const Node*)=0;
virtual bool Descent(const Node*) { return(false); } virtual bool Descent(const Node*)=0;
};
/* GCollide */
struct GCollide
{
ICollide* icollide;
GCollide(ICollide* ic) : icollide(ic) {}
void Process(const Node* a,const Node* b) { icollide->Process(a,b); }
void Process(const Node* a) { icollide->Process(a); }
bool Descent(const Node* a) { return(icollide->Descent(a)); }
}; };
// Constants // Constants
@@ -137,14 +128,14 @@ struct btDbvt
ICollide* icollide) const; ICollide* icollide) const;
void collide(ICollide* icollide) const; void collide(ICollide* icollide) const;
// Generics : T must implement ICollide // Generics : T must implement ICollide
template <typename T>
void collideGeneric( btDbvt* tree,T& policy) const; void collideGeneric( btDbvt* tree,ICollide* policy) const;
template <typename T>
void collideGeneric( btDbvt::Node* node,T& policy) const; void collideGeneric( btDbvt::Node* node,ICollide* policy) const;
template <typename T>
void collideGeneric(const Volume& volume,T& policy) const; void collideGeneric(const Volume& volume,ICollide* policy) const;
template <typename T>
void collideGeneric(T& policy) const; void collideGeneric(ICollide* policy) const;
// //
private: private:
btDbvt(const btDbvt&) {} btDbvt(const btDbvt&) {}
@@ -300,8 +291,7 @@ inline bool NotEqual( const btDbvtAabbMm& a,
// //
// //
template <typename T> inline void btDbvt::collideGeneric( btDbvt::Node* node,ICollide* policy) const
inline void btDbvt::collideGeneric( btDbvt::Node* node,T& policy) const
{ {
if(m_root&&node) if(m_root&&node)
{ {
@@ -346,7 +336,7 @@ inline void btDbvt::collideGeneric( btDbvt::Node* node,T& policy) const
} }
else else
{ {
policy.Process(p.a,p.b); policy->Process(p.a,p.b);
} }
} }
} }
@@ -355,15 +345,13 @@ inline void btDbvt::collideGeneric( btDbvt::Node* node,T& policy) const
} }
// //
template <typename T> inline void btDbvt::collideGeneric( btDbvt* tree,ICollide* policy) const
inline void btDbvt::collideGeneric( btDbvt* tree,T& policy) const
{ {
collideGeneric<T>(tree->m_root,policy); collideGeneric(tree->m_root,policy);
} }
// //
template <typename T> inline void btDbvt::collideGeneric(const Volume& volume,ICollide* policy) const
inline void btDbvt::collideGeneric(const Volume& volume,T& policy) const
{ {
if(m_root) if(m_root)
{ {
@@ -382,7 +370,7 @@ inline void btDbvt::collideGeneric(const Volume& volume,T& policy) const
} }
else else
{ {
policy.Process(n); policy->Process(n);
} }
} }
} while(stack.size()>0); } while(stack.size()>0);
@@ -390,8 +378,8 @@ inline void btDbvt::collideGeneric(const Volume& volume,T& policy) const
} }
// //
template <typename T>
inline void btDbvt::collideGeneric(T& policy) const inline void btDbvt::collideGeneric(ICollide* policy) const
{ {
if(m_root) if(m_root)
{ {
@@ -401,12 +389,12 @@ inline void btDbvt::collideGeneric(T& policy) const
do { do {
const Node* n=stack[stack.size()-1]; const Node* n=stack[stack.size()-1];
stack.pop_back(); stack.pop_back();
if(policy.Descent(n)) if(policy->Descent(n))
{ {
if(n->isinternal()) if(n->isinternal())
{ stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); } { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
else else
{ policy.Process(n); } { policy->Process(n); }
} }
} while(stack.size()>0); } while(stack.size()>0);
} }

View File

@@ -23,21 +23,21 @@ subject to the following restrictions:
#if DBVT_BP_PROFILE #if DBVT_BP_PROFILE
#include <stdio.h> #include <stdio.h>
struct ProfileScope struct ProfileScope
{ {
ProfileScope(btClock& clock,unsigned long& value) ProfileScope(btClock& clock,unsigned long& value)
{ {
m_clock=&clock; m_clock=&clock;
m_value=&value; m_value=&value;
m_base=clock.getTimeMicroseconds(); m_base=clock.getTimeMicroseconds();
} }
~ProfileScope() ~ProfileScope()
{ {
(*m_value)+=m_clock->getTimeMicroseconds()-m_base; (*m_value)+=m_clock->getTimeMicroseconds()-m_base;
} }
btClock* m_clock; btClock* m_clock;
unsigned long* m_value; unsigned long* m_value;
unsigned long m_base; unsigned long m_base;
}; };
#define SPC(_value_) ProfileScope spc_scope(m_clock,_value_) #define SPC(_value_) ProfileScope spc_scope(m_clock,_value_)
#else #else
#define SPC(_value_) #define SPC(_value_)
@@ -50,49 +50,49 @@ struct ProfileScope
// //
static inline int hash(unsigned int i,unsigned int j) static inline int hash(unsigned int i,unsigned int j)
{ {
int key=((unsigned int)i)|(((unsigned int)j)<<16); int key=((unsigned int)i)|(((unsigned int)j)<<16);
key+=~(key<<15); key+=~(key<<15);
key^= (key>>10); key^= (key>>10);
key+= (key<<3); key+= (key<<3);
key^= (key>>6); key^= (key>>6);
key+=~(key<<11); key+=~(key<<11);
key^= (key>>16); key^= (key>>16);
return(key); return(key);
} }
// //
template <typename T> template <typename T>
static inline void listappend(T* item,T*& list) static inline void listappend(T* item,T*& list)
{ {
item->links[0]=0; item->links[0]=0;
item->links[1]=list; item->links[1]=list;
if(list) list->links[0]=item; if(list) list->links[0]=item;
list=item; list=item;
} }
// //
template <typename T> template <typename T>
static inline void listremove(T* item,T*& list) static inline void listremove(T* item,T*& list)
{ {
if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1]; if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1];
if(item->links[1]) item->links[1]->links[0]=item->links[0]; if(item->links[1]) item->links[1]->links[0]=item->links[0];
} }
// //
template <typename T> template <typename T>
static inline int listcount(T* root) static inline int listcount(T* root)
{ {
int n=0; int n=0;
while(root) { ++n;root=root->links[1]; } while(root) { ++n;root=root->links[1]; }
return(n); return(n);
} }
// //
template <typename T> template <typename T>
static inline void clear(T& value) static inline void clear(T& value)
{ {
static const T zerodummy; static const T zerodummy;
value=zerodummy; value=zerodummy;
} }
// //
@@ -100,19 +100,29 @@ value=zerodummy;
// //
struct btDbvtBroadphaseCollider : btDbvt::ICollide struct btDbvtBroadphaseCollider : btDbvt::ICollide
{ {
btDbvtBroadphase* pbp; btDbvtBroadphase* pbp;
int pid; int pid;
btDbvtBroadphaseCollider(btDbvtBroadphase* p,int id) : pbp(p),pid(id) {} btDbvtBroadphaseCollider(btDbvtBroadphase* p,int id) : pbp(p),pid(id) {}
void Process(const btDbvt::Node* na,const btDbvt::Node* nb)
virtual void Process(const btDbvt::Node* na)
{ {
btDbvtProxy* pa=(btDbvtProxy*)na->data; }
btDbvtProxy* pb=(btDbvtProxy*)nb->data; virtual bool Descent(const btDbvt::Node*)
#if DBVT_BP_DISCRETPAIRS {
if(Intersect(pa->aabb,pb->aabb)) return false;
#endif }
virtual void Process(const btDbvt::Node* na,const btDbvt::Node* nb)
{
btDbvtProxy* pa=(btDbvtProxy*)na->data;
btDbvtProxy* pb=(btDbvtProxy*)nb->data;
#if DBVT_BP_DISCRETPAIRS
if(Intersect(pa->aabb,pb->aabb))
#endif
{ {
btBroadphasePair* pp=pbp->m_paircache->addOverlappingPair(pa,pb); btBroadphasePair* pp=pbp->m_paircache->addOverlappingPair(pa,pb);
if(pp) pp->m_userInfo=*(void**)&pid; if(pp)
pp->m_userInfo=*(void**)&pid;
} }
} }
}; };
@@ -124,107 +134,110 @@ void Process(const btDbvt::Node* na,const btDbvt::Node* nb)
// //
btDbvtBroadphase::btDbvtBroadphase() btDbvtBroadphase::btDbvtBroadphase()
{ {
m_fcursor = 0; m_invalidPair = 0;
m_dcursor = 0; m_fcursor = 0;
m_stageCurrent = 0; m_dcursor = 0;
m_fupdates = 1; m_stageCurrent = 0;
m_dupdates = 0; m_fupdates = 1;
m_paircache = new btHashedOverlappingPairCache(); m_dupdates = 0;
m_gid = 0; //m_paircache = new btSortedOverlappingPairCache();
m_pid = 0; m_paircache = new btHashedOverlappingPairCache();
for(int i=0;i<=STAGECOUNT;++i)
m_gid = 0;
m_pid = 0;
for(int i=0;i<=STAGECOUNT;++i)
{ {
m_stageRoots[i]=0; m_stageRoots[i]=0;
} }
#if DBVT_BP_PROFILE #if DBVT_BP_PROFILE
clear(m_profiling); clear(m_profiling);
#endif #endif
} }
// //
btDbvtBroadphase::~btDbvtBroadphase() btDbvtBroadphase::~btDbvtBroadphase()
{ {
delete m_paircache; delete m_paircache;
} }
// //
btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin, btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin,
const btVector3& aabbMax, const btVector3& aabbMax,
int shapeType, int shapeType,
void* userPtr, void* userPtr,
short int collisionFilterGroup, short int collisionFilterGroup,
short int collisionFilterMask, short int collisionFilterMask,
btDispatcher* dispatcher, btDispatcher* dispatcher,
void* multiSapProxy) void* multiSapProxy)
{ {
btDbvtProxy* proxy=new btDbvtProxy(userPtr,collisionFilterGroup,collisionFilterMask); btDbvtProxy* proxy=new btDbvtProxy(userPtr,collisionFilterGroup,collisionFilterMask);
proxy->aabb = btDbvtAabbMm::FromMM(aabbMin,aabbMax); proxy->aabb = btDbvtAabbMm::FromMM(aabbMin,aabbMax);
proxy->leaf = m_sets[0].insert(proxy->aabb,proxy); proxy->leaf = m_sets[0].insert(proxy->aabb,proxy);
proxy->stage = m_stageCurrent; proxy->stage = m_stageCurrent;
proxy->m_uniqueId = ++m_gid; proxy->m_uniqueId = ++m_gid;
listappend(proxy,m_stageRoots[m_stageCurrent]); listappend(proxy,m_stageRoots[m_stageCurrent]);
return(proxy); return(proxy);
} }
// //
void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy, void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy,
btDispatcher* dispatcher) btDispatcher* dispatcher)
{ {
btDbvtProxy* proxy=(btDbvtProxy*)absproxy; btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
if(proxy->stage==STAGECOUNT) if(proxy->stage==STAGECOUNT)
m_sets[1].remove(proxy->leaf); m_sets[1].remove(proxy->leaf);
else else
m_sets[0].remove(proxy->leaf); m_sets[0].remove(proxy->leaf);
listremove(proxy,m_stageRoots[proxy->stage]); listremove(proxy,m_stageRoots[proxy->stage]);
m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher); m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher);
delete proxy; delete proxy;
} }
// //
void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy, void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy,
const btVector3& aabbMin, const btVector3& aabbMin,
const btVector3& aabbMax, const btVector3& aabbMax,
btDispatcher* dispatcher) btDispatcher* dispatcher)
{ {
btDbvtProxy* proxy=(btDbvtProxy*)absproxy; btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
btDbvtAabbMm aabb=btDbvtAabbMm::FromMM(aabbMin,aabbMax); btDbvtAabbMm aabb=btDbvtAabbMm::FromMM(aabbMin,aabbMax);
if(proxy->stage==STAGECOUNT) if(proxy->stage==STAGECOUNT)
{/* fixed -> dynamic set */ {/* fixed -> dynamic set */
m_sets[1].remove(proxy->leaf); m_sets[1].remove(proxy->leaf);
proxy->leaf=m_sets[0].insert(aabb,proxy); proxy->leaf=m_sets[0].insert(aabb,proxy);
m_fcursor=0; m_fcursor=0;
} }
else else
{/* dynamic set */ {/* dynamic set */
const btVector3 delta=(aabbMin+aabbMax)/2-proxy->aabb.Center(); const btVector3 delta=(aabbMin+aabbMax)/2-proxy->aabb.Center();
m_sets[0].update(proxy->leaf,aabb,delta*PREDICTED_FRAMES,DBVT_BP_MARGIN); m_sets[0].update(proxy->leaf,aabb,delta*PREDICTED_FRAMES,DBVT_BP_MARGIN);
} }
listremove(proxy,m_stageRoots[proxy->stage]); listremove(proxy,m_stageRoots[proxy->stage]);
proxy->aabb = aabb; proxy->aabb = aabb;
proxy->stage = m_stageCurrent; proxy->stage = m_stageCurrent;
listappend(proxy,m_stageRoots[m_stageCurrent]); listappend(proxy,m_stageRoots[m_stageCurrent]);
} }
// //
void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
{ {
collide(dispatcher); collide(dispatcher);
#if DBVT_BP_PROFILE #if DBVT_BP_PROFILE
if(0==(m_pid%DBVT_BP_PROFILING_RATE)) if(0==(m_pid%DBVT_BP_PROFILING_RATE))
{ {
printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leafs,m_sets[0].m_leafs,m_paircache->getNumOverlappingPairs()); printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leafs,m_sets[0].m_leafs,m_paircache->getNumOverlappingPairs());
unsigned int total=m_profiling.m_total; unsigned int total=m_profiling.m_total;
if(total<=0) total=1; if(total<=0) total=1;
printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE); printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE);
printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE); printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE);
printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE); printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE);
printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE); printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE);
const unsigned long sum=m_profiling.m_ddcollide+ const unsigned long sum=m_profiling.m_ddcollide+
m_profiling.m_fdcollide+ m_profiling.m_fdcollide+
m_profiling.m_cleanup; m_profiling.m_cleanup;
printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE); printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE);
clear(m_profiling); clear(m_profiling);
m_clock.reset(); m_clock.reset();
} }
#endif #endif
} }
@@ -232,105 +245,194 @@ if(0==(m_pid%DBVT_BP_PROFILING_RATE))
// //
void btDbvtBroadphase::collide(btDispatcher* dispatcher) void btDbvtBroadphase::collide(btDispatcher* dispatcher)
{ {
SPC(m_profiling.m_total); SPC(m_profiling.m_total);
/* refine dynamic */ /* refine dynamic */
if(m_stageRoots[m_stageCurrent]&&(m_dupdates>0)) if(m_stageRoots[m_stageCurrent]&&(m_dupdates>0))
{ {
const int count=1+(m_sets[0].m_leafs*m_dupdates)/100; const int count=1+(m_sets[0].m_leafs*m_dupdates)/100;
for(int i=0;i<count;++i) for(int i=0;i<count;++i)
{ {
if(!m_dcursor) m_dcursor=m_stageRoots[m_stageCurrent]; if(!m_dcursor)
m_sets[0].update(m_dcursor->leaf); m_dcursor=m_stageRoots[m_stageCurrent];
m_dcursor=m_dcursor->links[1]; m_sets[0].update(m_dcursor->leaf);
m_dcursor=m_dcursor->links[1];
} }
} }
/* dynamic -> fixed set */ /* dynamic -> fixed set */
m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT;
btDbvtProxy* current=m_stageRoots[m_stageCurrent]; btDbvtProxy* current=m_stageRoots[m_stageCurrent];
if(current) if(current)
{ {
btDbvtBroadphaseCollider collider(this,m_pid); btDbvtBroadphaseCollider collider(this,m_pid);
do { do {
btDbvtProxy* next=current->links[1]; btDbvtProxy* next=current->links[1];
if(m_dcursor==current) m_dcursor=0; if(m_dcursor==current) m_dcursor=0;
listremove(current,m_stageRoots[current->stage]); listremove(current,m_stageRoots[current->stage]);
listappend(current,m_stageRoots[STAGECOUNT]); listappend(current,m_stageRoots[STAGECOUNT]);
m_sets[1].collideGeneric(current->leaf,collider); m_sets[1].collideGeneric(current->leaf,&collider);
m_sets[0].remove(current->leaf); m_sets[0].remove(current->leaf);
current->leaf = m_sets[1].insert(current->aabb,current); current->leaf = m_sets[1].insert(current->aabb,current);
current->stage = STAGECOUNT; current->stage = STAGECOUNT;
current = next; current = next;
} while(current); } while(current);
} }
/* refine fixed */ /* refine fixed */
if(m_stageRoots[STAGECOUNT]&&(m_fupdates>0)) if(m_stageRoots[STAGECOUNT]&&(m_fupdates>0))
{ {
const int count=1+(m_sets[1].m_leafs*m_fupdates)/100; const int count=1+(m_sets[1].m_leafs*m_fupdates)/100;
for(int i=0;i<count;++i) for(int i=0;i<count;++i)
{ {
if(!m_fcursor) m_fcursor=m_stageRoots[STAGECOUNT]; if(!m_fcursor) m_fcursor=m_stageRoots[STAGECOUNT];
m_sets[1].update(m_fcursor->leaf); m_sets[1].update(m_fcursor->leaf);
m_fcursor=m_fcursor->links[1]; m_fcursor=m_fcursor->links[1];
} }
} }
/* collide dynamics */ /* collide dynamics */
btDbvtBroadphaseCollider collider(this,m_pid); btDbvtBroadphaseCollider collider(this,m_pid);
{ {
SPC(m_profiling.m_fdcollide); SPC(m_profiling.m_fdcollide);
m_sets[0].collideGeneric(&m_sets[1],collider); m_sets[0].collideGeneric(&m_sets[1],&collider);
} }
{ {
SPC(m_profiling.m_ddcollide); SPC(m_profiling.m_ddcollide);
m_sets[0].collideGeneric(&m_sets[0],collider); m_sets[0].collideGeneric(&m_sets[0],&collider);
} }
/* clean up */ /* clean up */
///m_paircache->processAllOverlappingPairs(0,dispatcher);
{ {
SPC(m_profiling.m_cleanup); SPC(m_profiling.m_cleanup);
btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); if (!m_paircache->hasDeferredRemoval())
for(int i=0,ni=pairs.size();i<ni;++i)
{ {
btBroadphasePair& p=pairs[i]; btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray();
if(m_pid!=(*(int*)&p.m_userInfo)) for(int i=0,ni=pairs.size();i<ni;++i)
{ {
btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0; btBroadphasePair& p=pairs[i];
btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1; if(m_pid!=(*(int*)&p.m_userInfo))
if(!Intersect(pa->aabb,pb->aabb))
{ {
m_paircache->removeOverlappingPair(pa,pb,dispatcher); btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0;
--ni;--i; btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1;
if(!Intersect(pa->aabb,pb->aabb))
{
m_paircache->removeOverlappingPair(pa,pb,dispatcher);
--ni;--i;
}
} }
} }
} else
{
if ( m_paircache->hasDeferredRemoval())
{
btBroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray();
//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;
btBroadphasePair previousPair;
previousPair.m_pProxy0 = 0;
previousPair.m_pProxy1 = 0;
previousPair.m_algorithm = 0;
int i;
for (i=0;i<overlappingPairArray.size();i++)
{
btBroadphasePair& pair = overlappingPairArray[i];
bool isDuplicate = (pair == previousPair);
previousPair = pair;
bool needsRemoval = false;
if (!isDuplicate)
{
btDbvtProxy* pa=(btDbvtProxy*)pair.m_pProxy0;
btDbvtProxy* pb=(btDbvtProxy*)pair.m_pProxy1;
bool hasOverlap = Intersect(pa->aabb,pb->aabb);
if (hasOverlap)
{
needsRemoval = false;//callback->processOverlap(pair);
} else
{
needsRemoval = true;
}
} else
{
//remove duplicate
needsRemoval = true;
//should have no algorithm
btAssert(!pair.m_algorithm);
}
if (needsRemoval)
{
m_paircache->cleanOverlappingPair(pair,dispatcher);
// m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
// m_overlappingPairArray.pop_back();
pair.m_pProxy0 = 0;
pair.m_pProxy1 = 0;
m_invalidPair++;
}
}
///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
//perform a sort, to sort 'invalid' pairs to the end
overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
m_invalidPair = 0;
#endif//CLEAN_INVALID_PAIRS
}
} }
} }
++m_pid;
++m_pid;
} }
// //
btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache()
{ {
return(m_paircache); return(m_paircache);
} }
// //
const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const
{ {
return(m_paircache); return(m_paircache);
} }
// //
void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
{ {
btDbvtAabbMm bounds; btDbvtAabbMm bounds;
if(!m_sets[0].empty()) if(!m_sets[0].empty())
if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume, if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume,
m_sets[1].m_root->volume,bounds); m_sets[1].m_root->volume,bounds);
else else
bounds=m_sets[0].m_root->volume; bounds=m_sets[0].m_root->volume;
else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume; else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume;
else else
bounds=btDbvtAabbMm::FromCR(btVector3(0,0,0),0); bounds=btDbvtAabbMm::FromCR(btVector3(0,0,0),0);
aabbMin=bounds.Mins(); aabbMin=bounds.Mins();
aabbMax=bounds.Maxs(); aabbMax=bounds.Maxs();
} }
// //

View File

@@ -30,13 +30,14 @@ subject to the following restrictions:
// Compile time config // Compile time config
// //
#define DBVT_BP_PROFILE 1 //#define DBVT_BP_PROFILE 1
#define DBVT_BP_DISCRETPAIRS 0 #define DBVT_BP_DISCRETPAIRS 0
#define DBVT_BP_MARGIN (btScalar)0.05 #define DBVT_BP_MARGIN (btScalar)0.05
#if DBVT_BP_PROFILE #if DBVT_BP_PROFILE
#define DBVT_BP_PROFILING_RATE 50 #define DBVT_BP_PROFILING_RATE 50
#include "LinearMath/btQuickprof.h" #include "LinearMath/btQuickprof.h"
#endif #endif
// //
@@ -44,16 +45,16 @@ subject to the following restrictions:
// //
struct btDbvtProxy : btBroadphaseProxy struct btDbvtProxy : btBroadphaseProxy
{ {
/* Fields */ /* Fields */
btDbvtAabbMm aabb; btDbvtAabbMm aabb;
btDbvt::Node* leaf; btDbvt::Node* leaf;
btDbvtProxy* links[2]; btDbvtProxy* links[2];
int stage; int stage;
/* ctor */ /* ctor */
btDbvtProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) : btDbvtProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :
btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask) btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask)
{ {
links[0]=links[1]=0; links[0]=links[1]=0;
} }
}; };
@@ -62,46 +63,48 @@ btDbvtProxy(void* userPtr,short int collisionFilterGroup, short int collisionFil
// //
struct btDbvtBroadphase : btBroadphaseInterface struct btDbvtBroadphase : btBroadphaseInterface
{ {
/* Config */ /* Config */
enum { enum {
DYNAMIC_SET = 0, /* Dynamic set index */ DYNAMIC_SET = 0, /* Dynamic set index */
FIXED_SET = 1, /* Fixed set index */ FIXED_SET = 1, /* Fixed set index */
STAGECOUNT = 2, /* Number of stages */ STAGECOUNT = 2, /* Number of stages */
PREDICTED_FRAMES = 2, /* Frames prediction */ PREDICTED_FRAMES = 2, /* Frames prediction */
}; };
/* Fields */ /* Fields */
btDbvt m_sets[2]; // Dbvt sets btDbvt m_sets[2]; // Dbvt sets
btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list
int m_stageCurrent; // Current stage int m_stageCurrent; // Current stage
btOverlappingPairCache* m_paircache; // Pair cache btOverlappingPairCache* m_paircache; // Pair cache
btDbvtProxy* m_fcursor; // Current fixed cursor btDbvtProxy* m_fcursor; // Current fixed cursor
btDbvtProxy* m_dcursor; // Current dynamic cursor btDbvtProxy* m_dcursor; // Current dynamic cursor
int m_fupdates; // % of fixed updates per frame int m_fupdates; // % of fixed updates per frame
int m_dupdates; // % of dynamic updates per frame int m_dupdates; // % of dynamic updates per frame
int m_pid; // Parse id int m_pid; // Parse id
int m_gid; // Gen id int m_gid; // Gen id
int m_invalidPair;
#if DBVT_BP_PROFILE #if DBVT_BP_PROFILE
btClock m_clock; btClock m_clock;
struct { struct {
unsigned long m_total; unsigned long m_total;
unsigned long m_ddcollide; unsigned long m_ddcollide;
unsigned long m_fdcollide; unsigned long m_fdcollide;
unsigned long m_cleanup; unsigned long m_cleanup;
} m_profiling; } m_profiling;
#endif #endif
/* Methods */ /* Methods */
btDbvtBroadphase(); btDbvtBroadphase();
~btDbvtBroadphase(); ~btDbvtBroadphase();
void collide(btDispatcher* dispatcher); void collide(btDispatcher* dispatcher);
/* btBroadphaseInterface Implementation */ /* btBroadphaseInterface Implementation */
btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy); btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
void calculateOverlappingPairs(btDispatcher* dispatcher); void calculateOverlappingPairs(btDispatcher* dispatcher);
btOverlappingPairCache* getOverlappingPairCache(); btOverlappingPairCache* getOverlappingPairCache();
const btOverlappingPairCache* getOverlappingPairCache() const; const btOverlappingPairCache* getOverlappingPairCache() const;
void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const; void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
void printStats(); void printStats();
}; };
#endif #endif

View File

@@ -622,7 +622,13 @@ struct RayCaster : public btDbvt::ICollide
face = 0; face = 0;
tests = 0; tests = 0;
} }
void Process(const btDbvt::Node* leaf)
virtual void Process(const btDbvt::Node* a,const btDbvt::Node* b)
{
}
virtual void Process(const btDbvt::Node* leaf)
{ {
btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data; btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data;
const btScalar t=RayTriangle( o,d, const btScalar t=RayTriangle( o,d,
@@ -637,7 +643,7 @@ struct RayCaster : public btDbvt::ICollide
} }
++tests; ++tests;
} }
bool Descent(const btDbvt::Node* node) virtual bool Descent(const btDbvt::Node* node)
{ {
const btVector3 ctr=node->volume.Center()-o; const btVector3 ctr=node->volume.Center()-o;
const btScalar sqr=node->volume.Lengths().length2()/4; const btScalar sqr=node->volume.Lengths().length2()/4;
@@ -715,7 +721,7 @@ static int RaycastInternal(const btSoftBody* psb,
else else
{/* Use dbvt */ {/* Use dbvt */
RayCaster collider(org,dir,mint); RayCaster collider(org,dir,mint);
psb->m_fdbvt.collideGeneric(collider); psb->m_fdbvt.collideGeneric(&collider);
if(collider.face) if(collider.face)
{ {
mint=collider.mint; mint=collider.mint;
@@ -2533,7 +2539,17 @@ switch(m_cfg.collisions&fCollision::RVSmask)
{ {
struct DoCollide : btDbvt::ICollide struct DoCollide : btDbvt::ICollide
{ {
void Process(const btDbvt::Node* leaf)
virtual void Process(const btDbvt::Node* a,const btDbvt::Node* b)
{
}
virtual bool Descent(const btDbvt::Node*)
{
return false;
}
virtual void Process(const btDbvt::Node* leaf)
{ {
Node* node=(Node*)leaf->data; Node* node=(Node*)leaf->data;
DoNode(*node); DoNode(*node);
@@ -2608,6 +2624,15 @@ switch(cf&fCollision::SVSmask)
{ {
struct DoCollide : btDbvt::ICollide struct DoCollide : btDbvt::ICollide
{ {
virtual bool Descent(const btDbvt::Node*)
{
return false;
}
virtual void Process(const btDbvt::Node* leaf)
{
}
void Process(const btDbvt::Node* lnode, void Process(const btDbvt::Node* lnode,
const btDbvt::Node* lface) const btDbvt::Node* lface)
{ {