public static void CollideTU(DbvtNode root, Collide collideable) { if (root != null) { Stack<DbvtNode> stack = new Stack<DbvtNode>(SIMPLE_STACKSIZE); stack.Push(root); do { DbvtNode n = stack.Pop(); if (collideable.Descent(n)) { if (n.IsInternal()) { stack.Push(n._children[0]); stack.Push(n._children[1]); } else { collideable.Process(n); } } } while (stack.Count > 0); } }
public static void CollideOCL(DbvtNode root, Vector3[] normals, float[] offsets, ref Vector3 sortaxis, int count, Collide collideable) { if (root != null) { uint srtsgns = (uint)((sortaxis.X >= 0 ? 1 : 0) + (sortaxis.Y >= 0 ? 2 : 0) + (sortaxis.Z >= 0 ? 4 : 0)); int inside = (1 << count) - 1; //Stack<sStkNPS> stack = new Stack<sStkNPS>(SIMPLE_STACKSIZE); List<sStkNPS> stack = new List<sStkNPS>(SIMPLE_STACKSIZE); int[] signs = new int[count]; for (int i = 0; i < count; ++i) { signs[i] = ((normals[i].X >= 0) ? 1 : 0) + ((normals[i].Y >= 0) ? 2 : 0) + ((normals[i].Z >= 0) ? 4 : 0); } stack.Insert(0, new sStkNPS(root, 0, root.volume.ProjectMinimum(ref sortaxis, srtsgns))); do { sStkNPS se = stack[0]; stack.RemoveAt(0); if (se.mask != inside) { bool outp = false; for (int i = 0, j = 1; (!outp) && (i < count); ++i, j <<= 1) { if (0 == (se.mask & j)) { int side = se.node.volume.Classify(ref normals[i], offsets[i], signs[i]); switch (side) { case -1: outp = true; break; case +1: se.mask |= (uint)j; break; } } } if (outp) { continue; } } if (collideable.Descent(se.node)) { if (se.node.IsInternal()) { for (int i = 0; i < 2; ++i) { DbvtNode n = se.node._children[i]; int j = stack.Count; sStkNPS ne = new sStkNPS(n, se.mask, n.volume.ProjectMinimum(ref sortaxis, srtsgns)); stack.Insert(0, ne); while ((j > 0) && (ne.value > stack[j - 1].value)) { sStkNPS left = stack[j]; sStkNPS right = stack[j - 1]; stack[j] = right; stack[j - 1] = left; --j; //btSwap(stack[j],stack[j-1]);--j; } } } else { collideable.Process(se.node); } } } while (stack.Count > 0); } }