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); } }
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 CollideRAY(DbvtNode root, ref Vector3 origin, ref Vector3 direction, Collide collideable) { if (root != null) { Vector3 normal = direction; normal.Normalize(); Vector3 invdir = new Vector3(1 / normal.X, 1 / normal.Y, 1 / normal.Z); int[] signs = new int[] { direction.X < 0f ? 1 : 0, direction.Y < 0f ? 1 : 0, direction.Z < 0f ? 1 : 0 }; Stack<DbvtNode> stack = new Stack<DbvtNode>(SIMPLE_STACKSIZE); stack.Push(root); do { DbvtNode node = stack.Pop(); if (Intersect(ref node.volume, ref origin, ref invdir, signs)) { if (node.IsInternal()) { stack.Push(node._children[0]); stack.Push(node._children[1]); } else { collideable.Process(node); } } } while (stack.Count > 0); } }
public static void CollideKDOP(DbvtNode root, Vector3[] normals, float[] offsets, int count, Collide collideable) { if (root != null) { int inside = (1 << count) - 1; Stack<sStkNP> stack = new Stack<sStkNP>(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.Push(new sStkNP(root, 0)); do { sStkNP se = stack.Pop(); 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) { if ((se.mask != inside) && (se.node.IsInternal())) { stack.Push(new sStkNP(se.node._children[0], se.mask)); stack.Push(new sStkNP(se.node._children[1], se.mask)); } else { if (collideable.AllLeaves(se.node)) { EnumLeafs(se.node, collideable); } } } } while (stack.Count > 0); } }
public static void CollideTV(DbvtNode root, ref DbvtAabbMm volume, Collide collideable) { if (root != null) { Stack<DbvtNode> stack = new Stack<DbvtNode>(SIMPLE_STACKSIZE); stack.Push(root); do { DbvtNode n = stack.Pop(); if (DbvtAabbMm.Intersect(ref n.volume, ref volume)) { if (n.IsInternal()) { stack.Push(n._children[0]); stack.Push(n._children[1]); } else { collideable.Process(n); } } } while (stack.Count > 0); } }
public void RayTestInternal(DbvtNode root, ref Vector3 rayFrom, ref Vector3 rayTo, ref Vector3 rayDirectionInverse, bool[] signs, float lambda_max, ref Vector3 aabbMin, ref Vector3 aabbMax, Collide policy) { // (void) rayTo; //DBVT_CHECKTYPE if(root != null) { Vector3 resultNormal = Vector3.Up; int depth=1; int treshold=DOUBLE_STACKSIZE-2; ObjectArray<DbvtNode> stack = new ObjectArray<DbvtNode>(DOUBLE_STACKSIZE); stack[0]=root; Vector3[] bounds = new Vector3[2]; do { DbvtNode node=stack[--depth]; bounds[0] = node.volume.Mins()-aabbMax; bounds[1] = node.volume.Maxs()-aabbMin; float tmin=1.0f,lambda_min=0.0f; bool result1 = AabbUtil2.RayAabb2(ref rayFrom,ref rayDirectionInverse,signs,bounds,ref tmin,lambda_min,lambda_max); if(result1) { if(node.IsInternal()) { //if(depth>treshold) //{ // stack.resize(stack.size()*2); // treshold=stack.size()-2; //} stack[depth++]=node._children[0]; stack[depth++]=node._children[1]; } else { policy.Process(node); } } } while(depth != 0); } }
public static void CollideTT(DbvtNode root0, DbvtNode root1, Collide collideable) { if (root0 != null && root1 != null) { Stack<sStkNN> stack = new Stack<sStkNN>(DOUBLE_STACKSIZE); stack.Push(new sStkNN(root0, root1)); do { sStkNN p = stack.Pop(); if (p.a == p.b) { if (p.a.IsInternal()) { stack.Push(new sStkNN(p.a._children[0], p.a._children[0])); stack.Push(new sStkNN(p.a._children[1], p.a._children[1])); stack.Push(new sStkNN(p.a._children[0], p.a._children[1])); } } else if (DbvtAabbMm.Intersect(ref p.a.volume, ref p.b.volume)) { if (p.a.IsInternal()) { if (p.b.IsInternal()) { stack.Push(new sStkNN(p.a._children[0], p.b._children[0])); stack.Push(new sStkNN(p.a._children[1], p.b._children[0])); stack.Push(new sStkNN(p.a._children[0], p.b._children[1])); stack.Push(new sStkNN(p.a._children[1], p.b._children[1])); } else { stack.Push(new sStkNN(p.a._children[0], p.b)); stack.Push(new sStkNN(p.a._children[1], p.b)); } } else { if (p.b.IsInternal()) { stack.Push(new sStkNN(p.a, p.b._children[0])); stack.Push(new sStkNN(p.a, p.b._children[1])); } else { collideable.Process(p.a, p.b); } } } } while (stack.Count > 0); } }
public static void CollideTTpersistentStack(DbvtNode m_root0, DbvtNode m_root1, Collide collider) { CollideTT(m_root0, m_root1, collider); }
public static void EnumLeafs(DbvtNode root, Collide collideable) { if (root.IsInternal()) { EnumLeafs(root._children[0], collideable); EnumLeafs(root._children[1], collideable); } else { collideable.Process(root); } }