public static void CollideTV(DbvtNode root, ref DbvtAabbMm volume, ICollide collideable) { CollideTVCount++; Debug.Assert(CollideTVCount < 2); CollideTVStack.Clear(); if (root != null) { CollideTVStack.Push(root); do { DbvtNode n = CollideTVStack.Pop(); if (DbvtAabbMm.Intersect(ref n.volume, ref volume)) { if (n.IsInternal()) { CollideTVStack.Push(n._children[0]); CollideTVStack.Push(n._children[1]); } else { collideable.Process(n); } } } while (CollideTVStack.Count > 0); } CollideTVCount--; }
public void OptimizeIncremental(int passes) { if (passes < 0) { passes = m_leaves; } if (Root != null && (passes > 0)) { int sizeOfUnsigned = 4; int computedValue = (sizeOfUnsigned * 8 - 1); do { DbvtNode node = Root; int bit = 0; while (node.IsInternal()) { node = Sort(node, m_root)._children[(m_opath >> bit) & 1]; bit = (bit + 1) & (sizeof(UInt32) * 8 - 1); } Update(node); ++m_opath; } while (--passes > 0); } }
public static void EnumNodes(DbvtNode root, ICollide collideable) { collideable.Process(root); if (root.IsInternal()) { EnumNodes(root._children[0], collideable); EnumNodes(root._children[1], collideable); } }
public static void GetMaxDepth(DbvtNode node, int depth, ref int maxDepth) { if (node.IsInternal()) { GetMaxDepth(node._children[0], depth + 1, ref maxDepth); GetMaxDepth(node._children[1], depth + 1, ref maxDepth); } else { maxDepth = Math.Max(depth, maxDepth); } }
public static void FetchLeafs(Dbvt pdbvt, DbvtNode root, ObjectArray <DbvtNode> leafs, int depth) { if (root.IsInternal() && depth != 0) { FetchLeafs(pdbvt, root._children[0], leafs, depth - 1); FetchLeafs(pdbvt, root._children[1], leafs, depth - 1); DeleteNode(pdbvt, root); } else { leafs.Add(root); } }
public void RayTestInternal(DbvtNode root, ref IndexedVector3 rayFrom, ref IndexedVector3 rayTo, ref IndexedVector3 rayDirectionInverse, bool[] signs, float lambda_max, ref IndexedVector3 aabbMin, ref IndexedVector3 aabbMax, ICollide policy) { using (DbvtStackDataBlock stackDataBlock = BulletGlobals.DbvtStackDataBlockPool.Get()) { // (void) rayTo; //DBVT_CHECKTYPE if (root != null) { IndexedVector3 resultNormal = new IndexedVector3(0, 1, 0); int depth = 1; int treshold = DOUBLE_STACKSIZE - 2; stackDataBlock.stack[0] = root; do { DbvtNode node = stackDataBlock.stack[--depth]; stackDataBlock.bounds[0] = node.volume.Mins() - aabbMax; stackDataBlock.bounds[1] = node.volume.Maxs() - aabbMin; float tmin = 1.0f, lambda_min = 0.0f; bool result1 = AabbUtil2.RayAabb2(ref rayFrom, ref rayDirectionInverse, signs, stackDataBlock.bounds, out tmin, lambda_min, lambda_max); if (result1) { if (node.IsInternal()) { if (depth > treshold) { stackDataBlock.stack.Resize(stackDataBlock.stack.Count * 2); treshold = stackDataBlock.stack.Count - 2; } stackDataBlock.stack[depth++] = node._children[0]; stackDataBlock.stack[depth++] = node._children[1]; } else { policy.Process(node); } } } while (depth != 0); } } }
public static DbvtNode Sort(DbvtNode n, DbvtNode r) { DbvtNode p = n.parent; Debug.Assert(n.IsInternal()); if (p != null && (p.id > n.id)) { int i = IndexOf(n); int j = 1 - i; DbvtNode s = p._children[j]; DbvtNode q = p.parent; Debug.Assert(n == p._children[i]); if (q != null) { q._children[IndexOf(p)] = n; } else { r = n; } s.parent = n; p.parent = n; n.parent = q; p._children[0] = n._children[0]; p._children[1] = n._children[1]; n._children[0].parent = p; n._children[1].parent = p; n._children[i] = p; n._children[j] = s; // swap id's? as well - probably not. Swap(ref p.volume, ref n.volume); return(p); } return(n); }
public static void RayTest(DbvtNode root, ref IndexedVector3 rayFrom, ref IndexedVector3 rayTo, ICollide policy) { using (DbvtStackDataBlock stackDataBlock = BulletGlobals.DbvtStackDataBlockPool.Get()) { if (root != null) { IndexedVector3 rayDir = (rayTo - rayFrom); rayDir.Normalize(); ///what about division by zero? -. just set rayDirection[i] to INF/BT_LARGE_FLOAT IndexedVector3 rayDirectionInverse = new IndexedVector3( rayDir.X == 0.0f ? MathUtil.BT_LARGE_FLOAT : 1.0f / rayDir.X, rayDir.Y == 0.0f ? MathUtil.BT_LARGE_FLOAT : 1.0f / rayDir.Y, rayDir.Z == 0.0f ? MathUtil.BT_LARGE_FLOAT : 1.0f / rayDir.Z); stackDataBlock.signs[0] = rayDirectionInverse.X < 0.0f; stackDataBlock.signs[1] = rayDirectionInverse.Y < 0.0f; stackDataBlock.signs[2] = rayDirectionInverse.Z < 0.0f; float lambda_max = IndexedVector3.Dot(rayDir, (rayTo - rayFrom)); int depth = 1; int treshold = DOUBLE_STACKSIZE - 2; stackDataBlock.stack.Resize(DOUBLE_STACKSIZE); stackDataBlock.stack[0] = root; do { DbvtNode node = stackDataBlock.stack[--depth]; stackDataBlock.bounds[0] = node.volume.Mins(); stackDataBlock.bounds[1] = node.volume.Maxs(); float tmin = 1.0f, lambda_min = 0.0f; bool result1 = AabbUtil2.RayAabb2(ref rayFrom, ref rayDirectionInverse, stackDataBlock.signs, stackDataBlock.bounds, out tmin, lambda_min, lambda_max); #if COMPARE_BTRAY_AABB2 float param = 1.0f; bool result2 = AabbUtil.RayAabb(ref rayFrom, ref rayTo, node.volume.Mins(), node.volume.Maxs(), param, resultNormal); Debug.Assert(result1 == result2); #endif //TEST_BTRAY_AABB2 if (result1) { if (node.IsInternal()) { if (depth > treshold) { stackDataBlock.stack.Resize(stackDataBlock.stack.Count * 2); treshold = stackDataBlock.stack.Count - 2; } stackDataBlock.stack[depth++] = node._children[0]; stackDataBlock.stack[depth++] = node._children[1]; } else { policy.Process(node); } } } while (depth != 0); } } }