b3BroadphaseProxy* b3DynamicBvhBroadphase::createProxy( const b3Vector3& aabbMin, const b3Vector3& aabbMax, int objectId, void* userPtr, short int collisionFilterGroup, short int collisionFilterMask) { b3DbvtProxy* mem = &m_proxies[objectId]; b3DbvtProxy* proxy=new(mem) b3DbvtProxy( aabbMin,aabbMax,userPtr, collisionFilterGroup, collisionFilterMask); b3DbvtAabbMm aabb = b3DbvtVolume::FromMM(aabbMin,aabbMax); //bproxy->aabb = b3DbvtVolume::FromMM(aabbMin,aabbMax); proxy->stage = m_stageCurrent; proxy->m_uniqueId = objectId; proxy->leaf = m_sets[0].insert(aabb,proxy); b3ListAppend(proxy,m_stageRoots[m_stageCurrent]); if(!m_deferedcollide) { b3DbvtTreeCollider collider(this); collider.proxy=proxy; m_sets[0].collideTV(m_sets[0].m_root,aabb,collider); m_sets[1].collideTV(m_sets[1].m_root,aabb,collider); } return(proxy); }
void b3DynamicBvhBroadphase::setAabbForceUpdate(b3BroadphaseProxy* absproxy, const b3Vector3& aabbMin, const b3Vector3& aabbMax, b3Dispatcher* /*dispatcher*/) { b3DbvtProxy* proxy = (b3DbvtProxy*)absproxy; B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) aabb = b3DbvtVolume::FromMM(aabbMin, aabbMax); bool docollide = false; if (proxy->stage == STAGECOUNT) { /* fixed -> dynamic set */ m_sets[1].remove(proxy->leaf); proxy->leaf = m_sets[0].insert(aabb, proxy); docollide = true; } else { /* dynamic set */ ++m_updates_call; /* Teleporting */ m_sets[0].update(proxy->leaf, aabb); ++m_updates_done; docollide = true; } b3ListRemove(proxy, m_stageRoots[proxy->stage]); proxy->m_aabbMin = aabbMin; proxy->m_aabbMax = aabbMax; proxy->stage = m_stageCurrent; b3ListAppend(proxy, m_stageRoots[m_stageCurrent]); if (docollide) { m_needcleanup = true; if (!m_deferedcollide) { b3DbvtTreeCollider collider(this); m_sets[1].collideTTpersistentStack(m_sets[1].m_root, proxy->leaf, collider); m_sets[0].collideTTpersistentStack(m_sets[0].m_root, proxy->leaf, collider); } } }
void b3DynamicBvhBroadphase::collide(b3Dispatcher* dispatcher) { /*printf("---------------------------------------------------------\n"); printf("m_sets[0].m_leaves=%d\n",m_sets[0].m_leaves); printf("m_sets[1].m_leaves=%d\n",m_sets[1].m_leaves); printf("numPairs = %d\n",getOverlappingPairCache()->getNumOverlappingPairs()); { int i; for (i=0;i<getOverlappingPairCache()->getNumOverlappingPairs();i++) { printf("pair[%d]=(%d,%d),",i,getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy0->getUid(), getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy1->getUid()); } printf("\n"); } */ b3SPC(m_profiling.m_total); /* optimize */ m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/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=b3Max<int>(0,m_fixedleft-count); } /* dynamic -> fixed set */ m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; b3DbvtProxy* current=m_stageRoots[m_stageCurrent]; if(current) { b3DbvtTreeCollider collider(this); do { b3DbvtProxy* next=current->links[1]; b3ListRemove(current,m_stageRoots[current->stage]); b3ListAppend(current,m_stageRoots[STAGECOUNT]); #if B3_DBVT_BP_ACCURATESLEEPING m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher); collider.proxy=current; b3DynamicBvh::collideTV(m_sets[0].m_root,current->aabb,collider); b3DynamicBvh::collideTV(m_sets[1].m_root,current->aabb,collider); #endif m_sets[0].remove(current->leaf); B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) curAabb=b3DbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax); current->leaf = m_sets[1].insert(curAabb,current); current->stage = STAGECOUNT; current = next; } while(current); m_fixedleft=m_sets[1].m_leaves; m_needcleanup=true; } /* collide dynamics */ { b3DbvtTreeCollider collider(this); if(m_deferedcollide) { b3SPC(m_profiling.m_fdcollide); m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[1].m_root,collider); } if(m_deferedcollide) { b3SPC(m_profiling.m_ddcollide); m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[0].m_root,collider); } } /* clean up */ if(m_needcleanup) { b3SPC(m_profiling.m_cleanup); b3BroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); if(pairs.size()>0) { int ni=b3Min(pairs.size(),b3Max<int>(m_newpairs,(pairs.size()*m_cupdates)/100)); for(int i=0;i<ni;++i) { b3BroadphasePair& p=pairs[(m_cid+i)%pairs.size()]; b3DbvtProxy* pa=&m_proxies[p.x]; b3DbvtProxy* pb=&m_proxies[p.y]; if(!b3Intersect(pa->leaf->volume,pb->leaf->volume)) { #if B3_DBVT_BP_SORTPAIRS if(pa->m_uniqueId>pb->m_uniqueId) b3Swap(pa,pb); #endif m_paircache->removeOverlappingPair(pa->getUid(),pb->getUid(),dispatcher); --ni;--i; } } if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0; } } ++m_pid; m_newpairs=1; m_needcleanup=false; if(m_updates_call>0) { m_updates_ratio=m_updates_done/(b3Scalar)m_updates_call; } else { m_updates_ratio=0; } m_updates_done/=2; m_updates_call/=2; }
void b3DynamicBvhBroadphase::setAabb( b3BroadphaseProxy* absproxy, const b3Vector3& aabbMin, const b3Vector3& aabbMax, b3Dispatcher* /*dispatcher*/) { b3DbvtProxy* proxy=(b3DbvtProxy*)absproxy; B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) aabb=b3DbvtVolume::FromMM(aabbMin,aabbMax); #if B3_DBVT_BP_PREVENTFALSEUPDATE if(b3NotEqual(aabb,proxy->leaf->volume)) #endif { bool docollide=false; if(proxy->stage==STAGECOUNT) {/* fixed -> dynamic set */ m_sets[1].remove(proxy->leaf); proxy->leaf=m_sets[0].insert(aabb,proxy); docollide=true; } else {/* dynamic set */ ++m_updates_call; if(b3Intersect(proxy->leaf->volume,aabb)) {/* Moving */ const b3Vector3 delta=aabbMin-proxy->m_aabbMin; b3Vector3 velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*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 ( #ifdef B3_DBVT_BP_MARGIN m_sets[0].update(proxy->leaf,aabb,velocity,B3_DBVT_BP_MARGIN) #else m_sets[0].update(proxy->leaf,aabb,velocity) #endif ) { ++m_updates_done; docollide=true; } } else {/* Teleporting */ m_sets[0].update(proxy->leaf,aabb); ++m_updates_done; docollide=true; } } b3ListRemove(proxy,m_stageRoots[proxy->stage]); proxy->m_aabbMin = aabbMin; proxy->m_aabbMax = aabbMax; proxy->stage = m_stageCurrent; b3ListAppend(proxy,m_stageRoots[m_stageCurrent]); if(docollide) { m_needcleanup=true; if(!m_deferedcollide) { b3DbvtTreeCollider collider(this); m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider); m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider); } } } }