Improved DbvtBroadphase performance for sleeping world (when no bodies are moving).

Improved DbvtBroadphase velocity prediction.
This commit is contained in:
id0x1234
2008-09-11 15:20:55 +00:00
parent afcfcb0a5d
commit fe0e2cd266
2 changed files with 51 additions and 28 deletions

View File

@@ -116,11 +116,13 @@ btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache)
{ {
m_initialize = true; m_initialize = true;
m_deferedcollide = true; m_deferedcollide = true;
m_needcleanup = true;
m_releasepaircache = (paircache!=0)?false:true; m_releasepaircache = (paircache!=0)?false:true;
m_predictedframes = 15; m_prediction = 1/(btScalar)2;
m_stageCurrent = 0; m_stageCurrent = 0;
m_fixedleft = 0;
m_fupdates = 1; m_fupdates = 1;
m_dupdates = 1; m_dupdates = 0;
m_cupdates = 10; m_cupdates = 10;
m_newpairs = 1; m_newpairs = 1;
m_updates_call = 0; m_updates_call = 0;
@@ -170,6 +172,7 @@ 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]);
setAabb(proxy,aabbMin,aabbMax,dispatcher); setAabb(proxy,aabbMin,aabbMax,dispatcher);
m_needcleanup=true;
return(proxy); return(proxy);
} }
@@ -185,6 +188,7 @@ if(proxy->stage==STAGECOUNT)
listremove(proxy,m_stageRoots[proxy->stage]); listremove(proxy,m_stageRoots[proxy->stage]);
m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher); m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher);
btAlignedFree(proxy); btAlignedFree(proxy);
m_needcleanup=true;
} }
// //
@@ -195,7 +199,9 @@ void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy,
{ {
btDbvtProxy* proxy=(btDbvtProxy*)absproxy; btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
btDbvtVolume aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); btDbvtVolume aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
//if(NotEqual(aabb,proxy->leaf->volume)) #if DBVT_BP_PREVENTFALSEUPDATE
if(NotEqual(aabb,proxy->leaf->volume))
#endif
{ {
bool docollide=false; bool docollide=false;
if(proxy->stage==STAGECOUNT) if(proxy->stage==STAGECOUNT)
@@ -209,12 +215,16 @@ btDbvtVolume aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
++m_updates_call; ++m_updates_call;
if(Intersect(proxy->leaf->volume,aabb)) if(Intersect(proxy->leaf->volume,aabb))
{/* Moving */ {/* Moving */
const btVector3 delta=(aabbMin+aabbMax)/2-proxy->aabb.Center(); const btVector3 delta=aabbMin-proxy->aabb.Mins();
btVector3 velocity(aabb.Extents()*m_prediction);
if(delta[0]<0) velocity[0]=-velocity[0];
if(delta[1]<0) velocity[1]=-velocity[1];
if(delta[2]<0) velocity[2]=-velocity[2];
if ( if (
#ifdef DBVT_BP_MARGIN #ifdef DBVT_BP_MARGIN
m_sets[0].update(proxy->leaf,aabb,delta*m_predictedframes,DBVT_BP_MARGIN) m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN)
#else #else
m_sets[0].update(proxy->leaf,aabb,delta*m_predictedframes) m_sets[0].update(proxy->leaf,aabb,velocity)
#endif #endif
) )
{ {
@@ -233,11 +243,15 @@ btDbvtVolume aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
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]);
if(docollide&&(!m_deferedcollide)) if(docollide)
{ {
btDbvtTreeCollider collider(this); m_needcleanup=true;
btDbvt::collideTT(m_sets[1].m_root,proxy->leaf,collider); if(!m_deferedcollide)
btDbvt::collideTT(m_sets[0].m_root,proxy->leaf,collider); {
btDbvtTreeCollider collider(this);
btDbvt::collideTT(m_sets[1].m_root,proxy->leaf,collider);
btDbvt::collideTT(m_sets[0].m_root,proxy->leaf,collider);
}
} }
} }
} }
@@ -273,7 +287,12 @@ void btDbvtBroadphase::collide(btDispatcher* dispatcher)
SPC(m_profiling.m_total); SPC(m_profiling.m_total);
/* optimize */ /* optimize */
m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100); m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100);
m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100); if(m_fixedleft)
{
const int count=1+(m_sets[1].m_leaves*m_fupdates)/100;
m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100);
m_fixedleft=btMax<int>(0,m_fixedleft-count);
}
/* 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];
@@ -290,6 +309,8 @@ if(current)
current->stage = STAGECOUNT; current->stage = STAGECOUNT;
current = next; current = next;
} while(current); } while(current);
m_fixedleft=m_sets[1].m_leaves;
m_needcleanup=true;
} }
/* collide dynamics */ /* collide dynamics */
{ {
@@ -306,6 +327,7 @@ if(current)
} }
} }
/* clean up */ /* clean up */
if(m_needcleanup)
{ {
SPC(m_profiling.m_cleanup); SPC(m_profiling.m_cleanup);
btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray();
@@ -318,16 +340,13 @@ if(current)
btBroadphasePair& p=pairs[(m_cid+i)%ci]; btBroadphasePair& p=pairs[(m_cid+i)%ci];
btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0; btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0;
btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1; btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1;
//if((pa->stage==0)||(pb->stage==0)) if(!Intersect(pa->leaf->volume,pb->leaf->volume))
{ {
if(!Intersect(pa->leaf->volume,pb->leaf->volume)) #if DBVT_BP_SORTPAIRS
{ if(pa>pb) btSwap(pa,pb);
#if DBVT_BP_SORTPAIRS #endif
if(pa>pb) btSwap(pa,pb); m_paircache->removeOverlappingPair(pa,pb,dispatcher);
#endif --ni;--i;
m_paircache->removeOverlappingPair(pa,pb,dispatcher);
--ni;--i;
}
} }
} }
if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0; if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0;
@@ -335,6 +354,7 @@ if(current)
} }
++m_pid; ++m_pid;
m_newpairs=1; m_newpairs=1;
m_needcleanup=false;
if(m_updates_call>0) if(m_updates_call>0)
{ m_updates_ratio=m_updates_done/(btScalar)m_updates_call; } { m_updates_ratio=m_updates_done/(btScalar)m_updates_call; }
else else

View File

@@ -23,10 +23,11 @@ subject to the following restrictions:
// Compile time config // Compile time config
// //
#define DBVT_BP_PROFILE 0 #define DBVT_BP_PROFILE 0
#define DBVT_BP_SORTPAIRS 1 #define DBVT_BP_SORTPAIRS 1
#define DBVT_BP_ENABLE_BENCHMARK 0 #define DBVT_BP_PREVENTFALSEUPDATE 0
#define DBVT_BP_MARGIN (btScalar)0.05 #define DBVT_BP_ENABLE_BENCHMARK 0
#define DBVT_BP_MARGIN (btScalar)0.05
#if DBVT_BP_PROFILE #if DBVT_BP_PROFILE
#define DBVT_BP_PROFILING_RATE 256 #define DBVT_BP_PROFILING_RATE 256
@@ -68,12 +69,13 @@ enum {
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
btOverlappingPairCache* m_paircache; // Pair cache btOverlappingPairCache* m_paircache; // Pair cache
btScalar m_predictedframes; // Frames predicted btScalar m_prediction; // Velocity prediction
int m_stageCurrent; // Current stage int m_stageCurrent; // Current stage
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_cupdates; // % of cleanup updates per frame int m_cupdates; // % of cleanup updates per frame
int m_newpairs; // Number of pairs created int m_newpairs; // Number of pairs created
int m_fixedleft; // Fixed optimization left
unsigned m_updates_call; // Number of updates call unsigned m_updates_call; // Number of updates call
unsigned m_updates_done; // Number of updates done unsigned m_updates_done; // Number of updates done
btScalar m_updates_ratio; // m_updates_done/m_updates_call btScalar m_updates_ratio; // m_updates_done/m_updates_call
@@ -82,6 +84,7 @@ int m_cid; // Cleanup index
int m_gid; // Gen id int m_gid; // Gen id
bool m_releasepaircache; // Release pair cache on delete bool m_releasepaircache; // Release pair cache on delete
bool m_deferedcollide; // Defere dynamic/static collision to collide call bool m_deferedcollide; // Defere dynamic/static collision to collide call
bool m_needcleanup; // Need to run cleanup?
bool m_initialize; // Initialization bool m_initialize; // Initialization
#if DBVT_BP_PROFILE #if DBVT_BP_PROFILE
btClock m_clock; btClock m_clock;