public void Collide(IDispatcher dispatcher) { Stopwatch totalStopwatch = new Stopwatch(); totalStopwatch.Start(); //SPC(m_profiling.m_total); /* optimize */ m_sets[0].OptimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100); if(m_fixedleft > 0) { 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=System.Math.Max(0,m_fixedleft-count); } /* dynamic . fixed set */ m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; DbvtProxy current = m_stageRoots[m_stageCurrent]; if(current != null) { DbvtTreeCollider collider = new DbvtTreeCollider (this); do { DbvtProxy next =current.links[1]; ListRemove(current,ref m_stageRoots[current.stage]); ListAppend(current,ref m_stageRoots[STAGECOUNT]); #if DBVT_BP_ACCURATESLEEPING m_paircache.removeOverlappingPairsContainingProxy(current,dispatcher); collider.proxy=current; btDbvt::collideTV(m_sets[0].m_root,current.aabb,collider); btDbvt::collideTV(m_sets[1].m_root,current.aabb,collider); #endif m_sets[0].Remove(current.leaf); DbvtAabbMm curAabb=DbvtAabbMm.FromMM(ref current.m_aabbMin,ref current.m_aabbMax); current.leaf = m_sets[1].Insert(ref curAabb,current); current.stage = STAGECOUNT; current = next; } while(current != null); m_fixedleft=m_sets[1].m_leaves; m_needcleanup=true; } /* collide dynamics */ { DbvtTreeCollider collider = new DbvtTreeCollider (this); if(m_deferedcollide) { Stopwatch fdCollideStopwatch = new Stopwatch(); fdCollideStopwatch.Start(); //SPC(m_profiling.m_fdcollide); Dbvt.CollideTTpersistentStack(m_sets[0].m_root,m_sets[1].m_root,collider); fdCollideStopwatch.Stop(); m_profiling.m_fdcollide += (ulong)fdCollideStopwatch.ElapsedMilliseconds; } if(m_deferedcollide) { Stopwatch ddCollideStopwatch = new Stopwatch(); ddCollideStopwatch.Start(); //SPC(m_profiling.m_ddcollide); Dbvt.CollideTTpersistentStack(m_sets[0].m_root,m_sets[0].m_root,collider); ddCollideStopwatch.Stop(); m_profiling.m_ddcollide += (ulong)ddCollideStopwatch.ElapsedMilliseconds; } } /* clean up */ if(m_needcleanup) { Stopwatch cleanupStopwatch = new Stopwatch(); cleanupStopwatch.Start(); //SPC(m_profiling.m_cleanup); IList<BroadphasePair> pairs=m_paircache.GetOverlappingPairArray(); if(pairs.Count>0) { int ni= System.Math.Min(pairs.Count,System.Math.Max(m_newpairs,(pairs.Count*m_cupdates)/100)); for(int i=0;i<ni;++i) { BroadphasePair p=pairs[(m_cid+i)%pairs.Count]; DbvtProxy pa=(DbvtProxy)p.m_pProxy0; DbvtProxy pb=(DbvtProxy)p.m_pProxy1; if (!DbvtAabbMm.Intersect(ref pa.leaf.volume, ref pb.leaf.volume)) { #if DBVT_BP_SORTPAIRS if(pa.m_uniqueId>pb.m_uniqueId) btSwap(pa,pb); #endif m_paircache.RemoveOverlappingPair(pa,pb,dispatcher); --ni;--i; } } if(pairs.Count>0) { m_cid=(m_cid+ni)%pairs.Count; } else { m_cid=0; } } cleanupStopwatch.Stop(); m_profiling.m_cleanup += (ulong)cleanupStopwatch.ElapsedMilliseconds; } ++m_pid; m_newpairs=1; m_needcleanup=false; if(m_updates_call>0) { m_updates_ratio=m_updates_done/(float)m_updates_call; } else { m_updates_ratio=0; } m_updates_done/=2; m_updates_call/=2; totalStopwatch.Stop(); m_profiling.m_total += (ulong)totalStopwatch.ElapsedMilliseconds; }
public virtual void SetAabb(BroadphaseProxy absproxy, ref Vector3 aabbMin, ref Vector3 aabbMax, IDispatcher dispatcher) { DbvtProxy proxy=(DbvtProxy)absproxy; DbvtAabbMm aabb = DbvtAabbMm.FromMM(ref aabbMin,ref aabbMax); #if DBVT_BP_PREVENTFALSEUPDATE if(NotEqual(ref 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(ref aabb,proxy); docollide=true; } else {/* dynamic set */ ++m_updates_call; if (DbvtAabbMm.Intersect(ref proxy.leaf.volume, ref aabb)) {/* Moving */ Vector3 delta=aabbMin-proxy.m_aabbMin; Vector3 velocity = (((proxy.m_aabbMax-proxy.m_aabbMin)/2f)*m_prediction); if(delta.X<0) velocity.X = -velocity.X; if(delta.Y<0) velocity.Y = -velocity.Y; if(delta.Z<0) velocity.Z = -velocity.Z; if ( #if DBVT_BP_MARGIN m_sets[0].Update(proxy.leaf,ref aabb,ref velocity,DBVT_BP_MARGIN) #else m_sets[0].update(proxy.leaf,aabb,ref velocity) #endif ) { ++m_updates_done; docollide=true; } } else {/* Teleporting */ m_sets[0].Update(proxy.leaf,ref aabb); ++m_updates_done; docollide=true; } } ListRemove(proxy,ref m_stageRoots[proxy.stage]); proxy.m_aabbMin = aabbMin; proxy.m_aabbMax = aabbMax; proxy.stage = m_stageCurrent; ListAppend(proxy,ref m_stageRoots[m_stageCurrent]); if(docollide) { m_needcleanup=true; if(!m_deferedcollide) { DbvtTreeCollider collider = new DbvtTreeCollider(this); Dbvt.CollideTTpersistentStack(m_sets[1].m_root,proxy.leaf,collider); Dbvt.CollideTTpersistentStack(m_sets[0].m_root, proxy.leaf, collider); } } } }
///this setAabbForceUpdate is similar to setAabb but always forces the aabb update. ///it is not part of the btBroadphaseInterface but specific to btDbvtBroadphase. ///it bypasses certain optimizations that prevent aabb updates (when the aabb shrinks), see ///http://code.google.com/p/bullet/issues/detail?id=223 public void setAabbForceUpdate(BroadphaseProxy absproxy, ref Vector3 aabbMin, ref Vector3 aabbMax, IDispatcher dispatcher) { DbvtProxy proxy=(DbvtProxy)absproxy; DbvtAabbMm bounds=DbvtAabbMm.FromMM(ref aabbMin,ref aabbMax); bool docollide=false; if(proxy.stage==STAGECOUNT) {/* fixed . dynamic set */ m_sets[1].Remove(proxy.leaf); proxy.leaf=m_sets[0].Insert(ref bounds,proxy); docollide=true; } else {/* dynamic set */ ++m_updates_call; /* Teleporting */ m_sets[0].Update(proxy.leaf,ref bounds); ++m_updates_done; docollide=true; } ListRemove(proxy,ref m_stageRoots[proxy.stage]); proxy.m_aabbMin = aabbMin; proxy.m_aabbMax = aabbMax; proxy.stage = m_stageCurrent; ListAppend(proxy,ref m_stageRoots[m_stageCurrent]); if(docollide) { m_needcleanup=true; if(!m_deferedcollide) { DbvtTreeCollider collider = new DbvtTreeCollider(this); Dbvt.CollideTTpersistentStack(m_sets[1].m_root, proxy.leaf, collider); Dbvt.CollideTTpersistentStack(m_sets[0].m_root, proxy.leaf, collider); } } }
public virtual BroadphaseProxy CreateProxy(ref Vector3 aabbMin, ref Vector3 aabbMax, BroadphaseNativeTypes shapeType, Object userPtr, CollisionFilterGroups collisionFilterGroup, CollisionFilterGroups collisionFilterMask, IDispatcher dispatcher, Object multiSapProxy) { DbvtProxy proxy=new DbvtProxy(ref aabbMin,ref aabbMax,userPtr,collisionFilterGroup,collisionFilterMask); DbvtAabbMm aabb = DbvtAabbMm.FromMM(ref aabbMin,ref aabbMax); //bproxy.aabb = btDbvtAabbMm::FromMM(aabbMin,aabbMax); proxy.stage = m_stageCurrent; proxy.m_uniqueId = ++m_gid; proxy.leaf = m_sets[0].Insert(ref aabb,proxy); ListAppend(proxy,ref m_stageRoots[m_stageCurrent]); if(!m_deferedcollide) { DbvtTreeCollider collider = new DbvtTreeCollider(this); collider.proxy=proxy; Dbvt.CollideTV(m_sets[0].m_root,ref aabb,collider); Dbvt.CollideTV(m_sets[1].m_root,ref aabb,collider); } return(proxy); }