private static Node createnode(Dbvt pdbvt, Node parent, DbvtAabbMm volume, DbvtProxy data) { Node node = new Node(); node.parent = parent; node.volume = volume; node.data = data; node.height = 0; return(node); }
public VFixedPoint predictedframes; // Frames predicted public DbvtBroadphase(OverlappingPairCache paircache) { predictedframes = VFixedPoint.Two; this.paircache = paircache != null ? paircache : new HashedOverlappingPairCache(); for (int i = 0; i < STAGECOUNT; i++) { sets[i] = new Dbvt(); stageRoots[i] = null; } }
private static void deletenode(Dbvt pdbvt, Node node) { node.childs[0] = null; node.childs[1] = null; node.data = null; node.parent = null; node.volume = null; node.height = -1; pdbvt.leaves--; }
private static void insertleaf(Dbvt pdbvt, Node leaf) { if (pdbvt.root == null) { pdbvt.root = leaf; leaf.parent = null; } else { Node node = pdbvt.root; while (!node.isleaf()) { if (DbvtAabbMm.Proximity(node.childs[0].volume, leaf.volume) < DbvtAabbMm.Proximity(node.childs[1].volume, leaf.volume)) { node = node.childs[0]; } else { node = node.childs[1]; } } Node sibling = node; Node oldParent = node.parent; Node newParent = createnode(pdbvt, oldParent, merge(leaf.volume, sibling.volume, new DbvtAabbMm()), null); if (oldParent != null) { oldParent.childs[indexof(sibling)] = newParent; newParent.childs[0] = sibling; newParent.childs[1] = leaf; sibling.parent = newParent; leaf.parent = newParent; } else { newParent.childs[0] = sibling; newParent.childs[1] = leaf; sibling.parent = newParent; leaf.parent = newParent; pdbvt.root = newParent; } node = leaf.parent; while (node != null) { node = Balance(pdbvt, node); Node child0 = node.childs[0]; Node child1 = node.childs[1]; node.height = Math.Max(child0.height, child1.height) + 1; node.volume = merge(child0.volume, child1.volume, new DbvtAabbMm()); node = node.parent; } } }
private static void recursedeletenode(Dbvt pdbvt, Node node) { if (!node.isleaf()) { recursedeletenode(pdbvt, node.childs[0]); recursedeletenode(pdbvt, node.childs[1]); } if (node == pdbvt.root) { pdbvt.root = null; } deletenode(pdbvt, node); }
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--; } } } } }
private static void removeleaf(Dbvt pdbvt, Node leaf) { if (leaf == pdbvt.root) { pdbvt.root = null; return; } else { Node parent = leaf.parent; Node grandParent = parent != null ? parent.parent : null; Node sibling = parent.childs[1 - indexof(leaf)]; if (grandParent != null) { grandParent.childs[indexof(parent)] = sibling; sibling.parent = grandParent; deletenode(pdbvt, parent); Node node = grandParent; while (node != null) { node = Balance(pdbvt, node); Node child0 = node.childs[0]; Node child1 = node.childs[1]; node.height = Math.Max(child0.height, child1.height) + 1; node.volume = merge(child0.volume, child1.volume, new DbvtAabbMm()); node = node.parent; } } else { pdbvt.root = sibling; sibling.parent = null; deletenode(pdbvt, parent); } } }
private static Node Balance(Dbvt pdbvt, Node A) { if (A.isleaf() || A.height < 2) { return(A); } Node B = A.childs[0]; Node C = A.childs[1]; int balance = C.height - B.height; if (balance > 1) { Node F = C.childs[0]; Node G = C.childs[1]; // Swap A and C C.childs[0] = A; C.parent = A.parent; // A's old parent should point to C if (A.parent != null) { A.parent.childs[indexof(A)] = C; } else { pdbvt.root = C; } A.parent = C; // Rotate if (F.height > G.height) { C.childs[1] = F; A.childs[1] = G; G.parent = A; A.volume = merge(B.volume, G.volume, new DbvtAabbMm()); C.volume = merge(A.volume, F.volume, new DbvtAabbMm()); A.height = 1 + Math.Max(B.height, G.height); C.height = 1 + Math.Max(A.height, F.height); } else { C.childs[1] = G; A.childs[1] = F; F.parent = A; A.volume = merge(B.volume, F.volume, new DbvtAabbMm()); C.volume = merge(A.volume, G.volume, new DbvtAabbMm()); A.height = 1 + Math.Max(B.height, F.height); C.height = 1 + Math.Max(A.height, G.height); } return(C); } if (balance < -1) { Node D = B.childs[0]; Node E = B.childs[1]; // Swap A andB B.childs[0] = A; B.parent = A.parent; // A's old parent should point to B if (A.parent != null) { A.parent.childs[indexof(A)] = B; } else { pdbvt.root = B; } A.parent = B; // Rotate if (D.height > E.height) { B.childs[1] = D; A.childs[0] = E; E.parent = A; A.volume = merge(C.volume, E.volume, new DbvtAabbMm()); B.volume = merge(A.volume, D.volume, new DbvtAabbMm()); A.height = 1 + Math.Max(C.height, E.height); B.height = 1 + Math.Max(A.height, D.height); } else { B.childs[1] = E; A.childs[0] = D; D.parent = A; A.volume = merge(C.volume, D.volume, new DbvtAabbMm()); B.volume = merge(A.volume, E.volume, new DbvtAabbMm()); A.height = 1 + Math.Max(C.height, D.height); B.height = 1 + Math.Max(A.height, E.height); } return(B); } return(A); }