diff --git a/Demos/Benchmarks/BenchmarkDemo.cpp b/Demos/Benchmarks/BenchmarkDemo.cpp index 3a1955f81..1bb60a73c 100644 --- a/Demos/Benchmarks/BenchmarkDemo.cpp +++ b/Demos/Benchmarks/BenchmarkDemo.cpp @@ -25,7 +25,7 @@ subject to the following restrictions: #include //printf debugging #include "Taru.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 btVector3 worldAabbMin(-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) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; diff --git a/Demos/Benchmarks/main.cpp b/Demos/Benchmarks/main.cpp index 74ba5db8b..d038f76fd 100644 --- a/Demos/Benchmarks/main.cpp +++ b/Demos/Benchmarks/main.cpp @@ -26,13 +26,13 @@ int main(int argc,char** argv) { GLDebugDrawer gDebugDrawer; -// BenchmarkDemo1 benchmarkDemo; + BenchmarkDemo1 benchmarkDemo; // BenchmarkDemo2 benchmarkDemo; // BenchmarkDemo3 benchmarkDemo; // BenchmarkDemo4 benchmarkDemo; // BenchmarkDemo5 benchmarkDemo; // BenchmarkDemo6 benchmarkDemo; - BenchmarkDemo7 benchmarkDemo; +// BenchmarkDemo7 benchmarkDemo; benchmarkDemo.initPhysics(); diff --git a/src/BulletCollision/BroadphaseCollision/btDbvt.cpp b/src/BulletCollision/BroadphaseCollision/btDbvt.cpp index c96640fc8..19c63e461 100644 --- a/src/BulletCollision/BroadphaseCollision/btDbvt.cpp +++ b/src/BulletCollision/BroadphaseCollision/btDbvt.cpp @@ -279,7 +279,7 @@ static btDbvt::Node* topdown(btDbvt* pdbvt, { 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(midpProcess(a,b); } - void Process(const Node* a) { icollide->Process(a); } - bool Descent(const Node* a) { return(icollide->Descent(a)); } - }; - + // Constants enum { TREETREE_STACKSIZE = 128, @@ -137,14 +128,14 @@ struct btDbvt ICollide* icollide) const; void collide(ICollide* icollide) const; // Generics : T must implement ICollide - template - void collideGeneric( btDbvt* tree,T& policy) const; - template - void collideGeneric( btDbvt::Node* node,T& policy) const; - template - void collideGeneric(const Volume& volume,T& policy) const; - template - void collideGeneric(T& policy) const; + + void collideGeneric( btDbvt* tree,ICollide* policy) const; + + void collideGeneric( btDbvt::Node* node,ICollide* policy) const; + + void collideGeneric(const Volume& volume,ICollide* policy) const; + + void collideGeneric(ICollide* policy) const; // private: btDbvt(const btDbvt&) {} @@ -300,8 +291,7 @@ inline bool NotEqual( const btDbvtAabbMm& a, // // -template -inline void btDbvt::collideGeneric( btDbvt::Node* node,T& policy) const +inline void btDbvt::collideGeneric( btDbvt::Node* node,ICollide* policy) const { if(m_root&&node) { @@ -346,7 +336,7 @@ inline void btDbvt::collideGeneric( btDbvt::Node* node,T& policy) const } 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 -inline void btDbvt::collideGeneric( btDbvt* tree,T& policy) const +inline void btDbvt::collideGeneric( btDbvt* tree,ICollide* policy) const { - collideGeneric(tree->m_root,policy); + collideGeneric(tree->m_root,policy); } // -template -inline void btDbvt::collideGeneric(const Volume& volume,T& policy) const +inline void btDbvt::collideGeneric(const Volume& volume,ICollide* policy) const { if(m_root) { @@ -382,7 +370,7 @@ inline void btDbvt::collideGeneric(const Volume& volume,T& policy) const } else { - policy.Process(n); + policy->Process(n); } } } while(stack.size()>0); @@ -390,8 +378,8 @@ inline void btDbvt::collideGeneric(const Volume& volume,T& policy) const } // -template -inline void btDbvt::collideGeneric(T& policy) const + +inline void btDbvt::collideGeneric(ICollide* policy) const { if(m_root) { @@ -401,12 +389,12 @@ inline void btDbvt::collideGeneric(T& policy) const do { const Node* n=stack[stack.size()-1]; stack.pop_back(); - if(policy.Descent(n)) + if(policy->Descent(n)) { if(n->isinternal()) { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); } else - { policy.Process(n); } + { policy->Process(n); } } } while(stack.size()>0); } diff --git a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp index d3dfaa9af..a55a91319 100644 --- a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp +++ b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp @@ -23,21 +23,21 @@ subject to the following restrictions: #if DBVT_BP_PROFILE #include struct ProfileScope - { +{ ProfileScope(btClock& clock,unsigned long& value) - { + { m_clock=&clock; m_value=&value; m_base=clock.getTimeMicroseconds(); - } + } ~ProfileScope() - { + { (*m_value)+=m_clock->getTimeMicroseconds()-m_base; - } + } btClock* m_clock; unsigned long* m_value; unsigned long m_base; - }; +}; #define SPC(_value_) ProfileScope spc_scope(m_clock,_value_) #else #define SPC(_value_) @@ -50,49 +50,49 @@ struct ProfileScope // static inline int hash(unsigned int i,unsigned int j) { -int key=((unsigned int)i)|(((unsigned int)j)<<16); -key+=~(key<<15); -key^= (key>>10); -key+= (key<<3); -key^= (key>>6); -key+=~(key<<11); -key^= (key>>16); -return(key); + int key=((unsigned int)i)|(((unsigned int)j)<<16); + key+=~(key<<15); + key^= (key>>10); + key+= (key<<3); + key^= (key>>6); + key+=~(key<<11); + key^= (key>>16); + return(key); } // template static inline void listappend(T* item,T*& list) { -item->links[0]=0; -item->links[1]=list; -if(list) list->links[0]=item; -list=item; + item->links[0]=0; + item->links[1]=list; + if(list) list->links[0]=item; + list=item; } // template 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[1]) item->links[1]->links[0]=item->links[0]; + 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]; } // template static inline int listcount(T* root) { -int n=0; -while(root) { ++n;root=root->links[1]; } -return(n); + int n=0; + while(root) { ++n;root=root->links[1]; } + return(n); } // template static inline void clear(T& value) { -static const T zerodummy; -value=zerodummy; + static const T zerodummy; + value=zerodummy; } // @@ -100,19 +100,29 @@ value=zerodummy; // struct btDbvtBroadphaseCollider : btDbvt::ICollide { -btDbvtBroadphase* pbp; -int pid; - btDbvtBroadphaseCollider(btDbvtBroadphase* p,int id) : pbp(p),pid(id) {} -void Process(const btDbvt::Node* na,const btDbvt::Node* nb) + btDbvtBroadphase* pbp; + int pid; + btDbvtBroadphaseCollider(btDbvtBroadphase* p,int id) : pbp(p),pid(id) {} + + virtual void Process(const btDbvt::Node* na) { - btDbvtProxy* pa=(btDbvtProxy*)na->data; - btDbvtProxy* pb=(btDbvtProxy*)nb->data; - #if DBVT_BP_DISCRETPAIRS - if(Intersect(pa->aabb,pb->aabb)) - #endif + } + virtual bool Descent(const btDbvt::Node*) + { + return false; + } + + 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); - if(pp) pp->m_userInfo=*(void**)&pid; + btBroadphasePair* pp=pbp->m_paircache->addOverlappingPair(pa,pb); + if(pp) + pp->m_userInfo=*(void**)&pid; } } }; @@ -124,107 +134,110 @@ void Process(const btDbvt::Node* na,const btDbvt::Node* nb) // btDbvtBroadphase::btDbvtBroadphase() { -m_fcursor = 0; -m_dcursor = 0; -m_stageCurrent = 0; -m_fupdates = 1; -m_dupdates = 0; -m_paircache = new btHashedOverlappingPairCache(); -m_gid = 0; -m_pid = 0; -for(int i=0;i<=STAGECOUNT;++i) + m_invalidPair = 0; + m_fcursor = 0; + m_dcursor = 0; + m_stageCurrent = 0; + m_fupdates = 1; + m_dupdates = 0; + //m_paircache = new btSortedOverlappingPairCache(); + m_paircache = new btHashedOverlappingPairCache(); + + 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 -clear(m_profiling); + clear(m_profiling); #endif } // btDbvtBroadphase::~btDbvtBroadphase() { -delete m_paircache; + delete m_paircache; } // btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin, - const btVector3& aabbMax, - int shapeType, - void* userPtr, - short int collisionFilterGroup, - short int collisionFilterMask, - btDispatcher* dispatcher, - void* multiSapProxy) + const btVector3& aabbMax, + int shapeType, + void* userPtr, + short int collisionFilterGroup, + short int collisionFilterMask, + btDispatcher* dispatcher, + void* multiSapProxy) { -btDbvtProxy* proxy=new btDbvtProxy(userPtr,collisionFilterGroup,collisionFilterMask); -proxy->aabb = btDbvtAabbMm::FromMM(aabbMin,aabbMax); -proxy->leaf = m_sets[0].insert(proxy->aabb,proxy); -proxy->stage = m_stageCurrent; -proxy->m_uniqueId = ++m_gid; -listappend(proxy,m_stageRoots[m_stageCurrent]); -return(proxy); + btDbvtProxy* proxy=new btDbvtProxy(userPtr,collisionFilterGroup,collisionFilterMask); + proxy->aabb = btDbvtAabbMm::FromMM(aabbMin,aabbMax); + proxy->leaf = m_sets[0].insert(proxy->aabb,proxy); + proxy->stage = m_stageCurrent; + proxy->m_uniqueId = ++m_gid; + listappend(proxy,m_stageRoots[m_stageCurrent]); + return(proxy); } // void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy, - btDispatcher* dispatcher) + btDispatcher* dispatcher) { -btDbvtProxy* proxy=(btDbvtProxy*)absproxy; -if(proxy->stage==STAGECOUNT) - m_sets[1].remove(proxy->leaf); + btDbvtProxy* proxy=(btDbvtProxy*)absproxy; + if(proxy->stage==STAGECOUNT) + m_sets[1].remove(proxy->leaf); else - m_sets[0].remove(proxy->leaf); -listremove(proxy,m_stageRoots[proxy->stage]); -m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher); -delete proxy; + m_sets[0].remove(proxy->leaf); + listremove(proxy,m_stageRoots[proxy->stage]); + m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher); + delete proxy; } // void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy, - const btVector3& aabbMin, - const btVector3& aabbMax, - btDispatcher* dispatcher) + const btVector3& aabbMin, + const btVector3& aabbMax, + btDispatcher* dispatcher) { -btDbvtProxy* proxy=(btDbvtProxy*)absproxy; -btDbvtAabbMm aabb=btDbvtAabbMm::FromMM(aabbMin,aabbMax); -if(proxy->stage==STAGECOUNT) + btDbvtProxy* proxy=(btDbvtProxy*)absproxy; + btDbvtAabbMm aabb=btDbvtAabbMm::FromMM(aabbMin,aabbMax); + if(proxy->stage==STAGECOUNT) {/* fixed -> dynamic set */ - m_sets[1].remove(proxy->leaf); - proxy->leaf=m_sets[0].insert(aabb,proxy); - m_fcursor=0; + m_sets[1].remove(proxy->leaf); + proxy->leaf=m_sets[0].insert(aabb,proxy); + m_fcursor=0; } else {/* dynamic set */ - const btVector3 delta=(aabbMin+aabbMax)/2-proxy->aabb.Center(); - m_sets[0].update(proxy->leaf,aabb,delta*PREDICTED_FRAMES,DBVT_BP_MARGIN); + const btVector3 delta=(aabbMin+aabbMax)/2-proxy->aabb.Center(); + m_sets[0].update(proxy->leaf,aabb,delta*PREDICTED_FRAMES,DBVT_BP_MARGIN); } -listremove(proxy,m_stageRoots[proxy->stage]); -proxy->aabb = aabb; -proxy->stage = m_stageCurrent; -listappend(proxy,m_stageRoots[m_stageCurrent]); + listremove(proxy,m_stageRoots[proxy->stage]); + proxy->aabb = aabb; + proxy->stage = m_stageCurrent; + listappend(proxy,m_stageRoots[m_stageCurrent]); } // void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) { -collide(dispatcher); + collide(dispatcher); #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()); - unsigned int total=m_profiling.m_total; - 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("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("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE); - const unsigned long sum=m_profiling.m_ddcollide+ - m_profiling.m_fdcollide+ - m_profiling.m_cleanup; - printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE); - clear(m_profiling); - m_clock.reset(); + 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; + 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("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("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE); + const unsigned long sum=m_profiling.m_ddcollide+ + m_profiling.m_fdcollide+ + m_profiling.m_cleanup; + printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE); + clear(m_profiling); + m_clock.reset(); } #endif } @@ -232,105 +245,194 @@ if(0==(m_pid%DBVT_BP_PROFILING_RATE)) // void btDbvtBroadphase::collide(btDispatcher* dispatcher) { -SPC(m_profiling.m_total); -/* refine dynamic */ -if(m_stageRoots[m_stageCurrent]&&(m_dupdates>0)) + SPC(m_profiling.m_total); + /* refine dynamic */ + if(m_stageRoots[m_stageCurrent]&&(m_dupdates>0)) { - const int count=1+(m_sets[0].m_leafs*m_dupdates)/100; - for(int i=0;ileaf); - m_dcursor=m_dcursor->links[1]; + if(!m_dcursor) + m_dcursor=m_stageRoots[m_stageCurrent]; + m_sets[0].update(m_dcursor->leaf); + m_dcursor=m_dcursor->links[1]; } } -/* dynamic -> fixed set */ -m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; -btDbvtProxy* current=m_stageRoots[m_stageCurrent]; -if(current) + /* dynamic -> fixed set */ + m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; + btDbvtProxy* current=m_stageRoots[m_stageCurrent]; + if(current) { - btDbvtBroadphaseCollider collider(this,m_pid); - do { - btDbvtProxy* next=current->links[1]; - if(m_dcursor==current) m_dcursor=0; - listremove(current,m_stageRoots[current->stage]); - listappend(current,m_stageRoots[STAGECOUNT]); - m_sets[1].collideGeneric(current->leaf,collider); - m_sets[0].remove(current->leaf); - current->leaf = m_sets[1].insert(current->aabb,current); - current->stage = STAGECOUNT; - current = next; + btDbvtBroadphaseCollider collider(this,m_pid); + do { + btDbvtProxy* next=current->links[1]; + if(m_dcursor==current) m_dcursor=0; + listremove(current,m_stageRoots[current->stage]); + listappend(current,m_stageRoots[STAGECOUNT]); + m_sets[1].collideGeneric(current->leaf,&collider); + m_sets[0].remove(current->leaf); + current->leaf = m_sets[1].insert(current->aabb,current); + current->stage = STAGECOUNT; + current = next; } while(current); } -/* refine fixed */ -if(m_stageRoots[STAGECOUNT]&&(m_fupdates>0)) + /* refine fixed */ + if(m_stageRoots[STAGECOUNT]&&(m_fupdates>0)) { - const int count=1+(m_sets[1].m_leafs*m_fupdates)/100; - for(int i=0;ileaf); - m_fcursor=m_fcursor->links[1]; + if(!m_fcursor) m_fcursor=m_stageRoots[STAGECOUNT]; + m_sets[1].update(m_fcursor->leaf); + m_fcursor=m_fcursor->links[1]; } } -/* collide dynamics */ -btDbvtBroadphaseCollider collider(this,m_pid); + /* collide dynamics */ + btDbvtBroadphaseCollider collider(this,m_pid); { - SPC(m_profiling.m_fdcollide); - m_sets[0].collideGeneric(&m_sets[1],collider); + SPC(m_profiling.m_fdcollide); + m_sets[0].collideGeneric(&m_sets[1],&collider); } { - SPC(m_profiling.m_ddcollide); - m_sets[0].collideGeneric(&m_sets[0],collider); + SPC(m_profiling.m_ddcollide); + m_sets[0].collideGeneric(&m_sets[0],&collider); } -/* clean up */ + /* clean up */ + ///m_paircache->processAllOverlappingPairs(0,dispatcher); { - SPC(m_profiling.m_cleanup); - btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); - for(int i=0,ni=pairs.size();ihasDeferredRemoval()) { - btBroadphasePair& p=pairs[i]; - if(m_pid!=(*(int*)&p.m_userInfo)) + btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); + for(int i=0,ni=pairs.size();iaabb,pb->aabb)) + btBroadphasePair& p=pairs[i]; + if(m_pid!=(*(int*)&p.m_userInfo)) { - m_paircache->removeOverlappingPair(pa,pb,dispatcher); - --ni;--i; + btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0; + 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;iaabb,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() { -return(m_paircache); + return(m_paircache); } // const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const { -return(m_paircache); + return(m_paircache); } // void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const { -btDbvtAabbMm bounds; -if(!m_sets[0].empty()) - if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume, - m_sets[1].m_root->volume,bounds); - else - bounds=m_sets[0].m_root->volume; -else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume; - else - bounds=btDbvtAabbMm::FromCR(btVector3(0,0,0),0); -aabbMin=bounds.Mins(); -aabbMax=bounds.Maxs(); + btDbvtAabbMm bounds; + if(!m_sets[0].empty()) + if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume, + m_sets[1].m_root->volume,bounds); + else + bounds=m_sets[0].m_root->volume; + else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume; + else + bounds=btDbvtAabbMm::FromCR(btVector3(0,0,0),0); + aabbMin=bounds.Mins(); + aabbMax=bounds.Maxs(); } // diff --git a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h index 9a37fe466..c39976115 100644 --- a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h +++ b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h @@ -30,13 +30,14 @@ subject to the following restrictions: // Compile time config // -#define DBVT_BP_PROFILE 1 +//#define DBVT_BP_PROFILE 1 + #define DBVT_BP_DISCRETPAIRS 0 #define DBVT_BP_MARGIN (btScalar)0.05 #if DBVT_BP_PROFILE - #define DBVT_BP_PROFILING_RATE 50 - #include "LinearMath/btQuickprof.h" +#define DBVT_BP_PROFILING_RATE 50 +#include "LinearMath/btQuickprof.h" #endif // @@ -44,16 +45,16 @@ subject to the following restrictions: // struct btDbvtProxy : btBroadphaseProxy { -/* Fields */ -btDbvtAabbMm aabb; -btDbvt::Node* leaf; -btDbvtProxy* links[2]; -int stage; -/* ctor */ -btDbvtProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) : + /* Fields */ + btDbvtAabbMm aabb; + btDbvt::Node* leaf; + btDbvtProxy* links[2]; + int stage; + /* ctor */ + btDbvtProxy(void* userPtr,short int collisionFilterGroup, short int 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 { -/* Config */ -enum { + /* Config */ + enum { DYNAMIC_SET = 0, /* Dynamic set index */ FIXED_SET = 1, /* Fixed set index */ STAGECOUNT = 2, /* Number of stages */ PREDICTED_FRAMES = 2, /* Frames prediction */ - }; -/* Fields */ -btDbvt m_sets[2]; // Dbvt sets -btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list -int m_stageCurrent; // Current stage -btOverlappingPairCache* m_paircache; // Pair cache -btDbvtProxy* m_fcursor; // Current fixed cursor -btDbvtProxy* m_dcursor; // Current dynamic cursor -int m_fupdates; // % of fixed updates per frame -int m_dupdates; // % of dynamic updates per frame -int m_pid; // Parse id -int m_gid; // Gen id + }; + /* Fields */ + btDbvt m_sets[2]; // Dbvt sets + btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list + int m_stageCurrent; // Current stage + btOverlappingPairCache* m_paircache; // Pair cache + btDbvtProxy* m_fcursor; // Current fixed cursor + btDbvtProxy* m_dcursor; // Current dynamic cursor + int m_fupdates; // % of fixed updates per frame + int m_dupdates; // % of dynamic updates per frame + int m_pid; // Parse id + int m_gid; // Gen id + int m_invalidPair; + #if DBVT_BP_PROFILE -btClock m_clock; -struct { + btClock m_clock; + struct { unsigned long m_total; unsigned long m_ddcollide; unsigned long m_fdcollide; unsigned long m_cleanup; - } m_profiling; + } m_profiling; #endif -/* Methods */ -btDbvtBroadphase(); -~btDbvtBroadphase(); -void collide(btDispatcher* dispatcher); -/* btBroadphaseInterface Implementation */ -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 setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); -void calculateOverlappingPairs(btDispatcher* dispatcher); -btOverlappingPairCache* getOverlappingPairCache(); -const btOverlappingPairCache* getOverlappingPairCache() const; -void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const; -void printStats(); + /* Methods */ + btDbvtBroadphase(); + ~btDbvtBroadphase(); + void collide(btDispatcher* dispatcher); + /* btBroadphaseInterface Implementation */ + 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 setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); + void calculateOverlappingPairs(btDispatcher* dispatcher); + btOverlappingPairCache* getOverlappingPairCache(); + const btOverlappingPairCache* getOverlappingPairCache() const; + void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const; + void printStats(); }; #endif diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index 3faa01264..4efea03b4 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -622,7 +622,13 @@ struct RayCaster : public btDbvt::ICollide face = 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; const btScalar t=RayTriangle( o,d, @@ -637,7 +643,7 @@ struct RayCaster : public btDbvt::ICollide } ++tests; } - bool Descent(const btDbvt::Node* node) + virtual bool Descent(const btDbvt::Node* node) { const btVector3 ctr=node->volume.Center()-o; const btScalar sqr=node->volume.Lengths().length2()/4; @@ -715,7 +721,7 @@ static int RaycastInternal(const btSoftBody* psb, else {/* Use dbvt */ RayCaster collider(org,dir,mint); - psb->m_fdbvt.collideGeneric(collider); + psb->m_fdbvt.collideGeneric(&collider); if(collider.face) { mint=collider.mint; @@ -2533,7 +2539,17 @@ switch(m_cfg.collisions&fCollision::RVSmask) { 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; DoNode(*node); @@ -2608,6 +2624,15 @@ switch(cf&fCollision::SVSmask) { 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, const btDbvt::Node* lface) {