public void collideTV(Node root, Dispatcher dispatcher, DbvtAabbMm volume, short collisionFilterGroup, short collisionFilterMask, ICollide policy) { if (root != null) { List <Node> stack = new List <Node>(SIMPLE_STACKSIZE); stack.Add(root); do { Node n = stack[stack.Count - 1]; stack.RemoveAt(stack.Count - 1); if (DbvtAabbMm.Intersect(n.volume, volume)) { if (n.isinternal()) { stack.Add(n.childs[0]); stack.Add(n.childs[1]); } else { if (!dispatcher.needsCollision(collisionFilterGroup, collisionFilterMask, n.data.collisionFilterGroup, n.data.collisionFilterMask)) { continue; } policy.Process(n); } } } while (stack.Count > 0); } }
public static void collideTT(Node root0, Node root1, Dispatcher dispatcher, ICollide policy) { if (root0 != null && root1 != null) { List <sStkNN> stack = new List <sStkNN>(DOUBLE_STACKSIZE); stack.Add(new sStkNN(root0, root1)); do { sStkNN p = stack[stack.Count - 1]; stack.RemoveAt(stack.Count - 1); if (p.a == p.b) { if (p.a.isinternal()) { stack.Add(new sStkNN(p.a.childs[0], p.a.childs[0])); stack.Add(new sStkNN(p.a.childs[1], p.a.childs[1])); stack.Add(new sStkNN(p.a.childs[0], p.a.childs[1])); } } else if (DbvtAabbMm.Intersect(p.a.volume, p.b.volume)) { if (p.a.isinternal()) { if (p.b.isinternal()) { stack.Add(new sStkNN(p.a.childs[0], p.b.childs[0])); stack.Add(new sStkNN(p.a.childs[1], p.b.childs[0])); stack.Add(new sStkNN(p.a.childs[0], p.b.childs[1])); stack.Add(new sStkNN(p.a.childs[1], p.b.childs[1])); } else { stack.Add(new sStkNN(p.a.childs[0], p.b)); stack.Add(new sStkNN(p.a.childs[1], p.b)); } } else { if (p.b.isinternal()) { stack.Add(new sStkNN(p.a, p.b.childs[0])); stack.Add(new sStkNN(p.a, p.b.childs[1])); } else { if (!dispatcher.needsCollision(p.a.data.collisionFilterGroup, p.a.data.collisionFilterMask, p.b.data.collisionFilterGroup, p.b.data.collisionFilterMask)) { continue; } policy.Process(p.a, p.b); } } } }while (stack.Count > 0); } }
public void collide(Dispatcher dispatcher) { DbvtTreeCollider collider = new DbvtTreeCollider(this); //collide dynamics: { Dbvt.collideTT(sets[DYNAMIC_SET].root, sets[FIXED_SET].root, dispatcher, collider); Dbvt.collideTT(sets[DYNAMIC_SET].root, sets[DYNAMIC_SET].root, dispatcher, collider); } //dynamic -> fixed set: DbvtProxy current = stageRoots[DYNAMIC_SET]; while (current != null) { stageRoots[DYNAMIC_SET] = listremove(current, stageRoots[DYNAMIC_SET]); stageRoots[FIXED_SET] = listappend(current, stageRoots[FIXED_SET]); DbvtAabbMm volume = current.leaf.volume; sets[DYNAMIC_SET].remove(current.leaf); current.leaf = sets[FIXED_SET].insert(volume, current); current.stage = FIXED_SET; current = stageRoots[DYNAMIC_SET]; } // clean up: { List <BroadphasePair> pairs = paircache.getOverlappingPairArray(); if (pairs.Count > 0) { for (int i = 0, ni = pairs.Count; i < ni; i++) { BroadphasePair p = pairs[i]; DbvtProxy pa = (DbvtProxy)p.pProxy0; DbvtProxy pb = (DbvtProxy)p.pProxy1; if (!DbvtAabbMm.Intersect(pa.leaf.volume, pb.leaf.volume)) { if (pa.getUid() > pb.getUid()) { DbvtProxy tmp = pa; pa = pb; pb = tmp; } paircache.removeOverlappingPair(pa, pb); ni--; i--; } } } } }