public void WalkStacklessTree(OptimizedBvhNode[] rootNodeArray, INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax) { int escapeIndex, curIndex = 0; int walkIterations = 0; bool aabbOverlap, isLeafNode; int rootNodeIndex = 0; OptimizedBvhNode rootNode = rootNodeArray[rootNodeIndex]; while (curIndex < _curNodeIndex) { //catch bugs in tree data if (walkIterations >= _curNodeIndex) { throw new BulletException(); } walkIterations++; aabbOverlap = MathHelper.TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode.AabbMin, rootNode.AabbMax); isLeafNode = (rootNode.LeftChild == null && rootNode.RightChild == null); if (isLeafNode && aabbOverlap) { nodeCallback.ProcessNode(rootNode); } if (aabbOverlap || isLeafNode) { rootNodeIndex++; // this curIndex++; if (rootNodeIndex < rootNodeArray.Length) { rootNode = rootNodeArray[rootNodeIndex]; } } else { escapeIndex = rootNode.EscapeIndex; rootNodeIndex += escapeIndex; // and this curIndex += escapeIndex; if (rootNodeIndex < rootNodeArray.Length) { rootNode = rootNodeArray[rootNodeIndex]; } } } if (_maxIterations < walkIterations) { _maxIterations = walkIterations; } }
public void Build(StridingMeshInterface triangles) { NodeTriangleCallback callback = new NodeTriangleCallback(_leafNodes); Vector3 aabbMin = new Vector3(-1e30f, -1e30f, -1e30f); Vector3 aabbMax = new Vector3(1e30f, 1e30f, 1e30f); triangles.InternalProcessAllTriangles(callback, aabbMin, aabbMax); //now we have an array of leafnodes in m_leafNodes _contiguousNodes = new OptimizedBvhNode[2 * _leafNodes.Count]; for (int i = 0; i < _contiguousNodes.Length; i++) _contiguousNodes[i] = new OptimizedBvhNode(); _curNodeIndex = 0; _rootNode = BuildTree(_leafNodes, 0, _leafNodes.Count); }
public void ProcessNode(OptimizedBvhNode node) { List<Vector3> verts; List<int> indicies; int numtriangles; _meshInterface.GetLockedReadOnlyVertexIndexBase(out verts, out indicies, out numtriangles, node.SubPart); Vector3 meshScaling = _meshInterface.Scaling; for (int j = 0; j < 3; j++) { _triangle[j] = verts[indicies[j + node.TriangleIndex * 3]] * meshScaling; } _callback.ProcessTriangle(_triangle, node.SubPart, node.TriangleIndex); _meshInterface.UnLockReadOnlyVertexBase(node.SubPart); }
public void ProcessNode(OptimizedBvhNode node) { List <Vector3> verts; List <int> indicies; int numtriangles; _meshInterface.GetLockedReadOnlyVertexIndexBase(out verts, out indicies, out numtriangles, node.SubPart); Vector3 meshScaling = _meshInterface.Scaling; for (int j = 0; j < 3; j++) { _triangle[j] = verts[indicies[j + node.TriangleIndex * 3]] * meshScaling; } _callback.ProcessTriangle(_triangle, node.SubPart, node.TriangleIndex); _meshInterface.UnLockReadOnlyVertexBase(node.SubPart); }
public void WalkTree(OptimizedBvhNode rootNode, INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax) { bool isLeafNode, aabbOverlap = MathHelper.TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode.AabbMin, rootNode.AabbMax); if (aabbOverlap) { isLeafNode = (rootNode.LeftChild == null && rootNode.RightChild == null); if (isLeafNode) { nodeCallback.ProcessNode(rootNode); } else { WalkTree(rootNode.LeftChild, nodeCallback, aabbMin, aabbMax); WalkTree(rootNode.RightChild, nodeCallback, aabbMin, aabbMax); } } }
public void Build(StridingMeshInterface triangles) { NodeTriangleCallback callback = new NodeTriangleCallback(_leafNodes); Vector3 aabbMin = new Vector3(-1e30f, -1e30f, -1e30f); Vector3 aabbMax = new Vector3(1e30f, 1e30f, 1e30f); triangles.InternalProcessAllTriangles(callback, aabbMin, aabbMax); //now we have an array of leafnodes in m_leafNodes _contiguousNodes = new OptimizedBvhNode[2 * _leafNodes.Count]; for (int i = 0; i < _contiguousNodes.Length; i++) { _contiguousNodes[i] = new OptimizedBvhNode(); } _curNodeIndex = 0; _rootNode = BuildTree(_leafNodes, 0, _leafNodes.Count); }
public void ProcessTriangleIndex(Vector3[] triangle, int partId, int triangleIndex) { OptimizedBvhNode node = new OptimizedBvhNode(); node.AabbMin = new Vector3(1e30f, 1e30f, 1e30f); node.AabbMax = new Vector3(-1e30f, -1e30f, -1e30f); node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[0]); node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[0]); node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[1]); node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[1]); node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[2]); node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[2]); node.EscapeIndex = -1; node.LeftChild = null; node.RightChild = null; //for child nodes node.SubPart = partId; node.TriangleIndex = triangleIndex; _triangleNodes.Add(node); }
public void WalkStacklessTree(OptimizedBvhNode[] rootNodeArray, INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax) { int escapeIndex, curIndex = 0; int walkIterations = 0; bool aabbOverlap, isLeafNode; int rootNodeIndex = 0; OptimizedBvhNode rootNode = rootNodeArray[rootNodeIndex]; while (curIndex < _curNodeIndex) { //catch bugs in tree data if (walkIterations >= _curNodeIndex) throw new BulletException(); walkIterations++; aabbOverlap = MathHelper.TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode.AabbMin, rootNode.AabbMax); isLeafNode = (rootNode.LeftChild == null && rootNode.RightChild == null); if (isLeafNode && aabbOverlap) { nodeCallback.ProcessNode(rootNode); } if (aabbOverlap || isLeafNode) { rootNodeIndex++; // this curIndex++; if (rootNodeIndex < rootNodeArray.Length) rootNode = rootNodeArray[rootNodeIndex]; } else { escapeIndex = rootNode.EscapeIndex; rootNodeIndex += escapeIndex; // and this curIndex += escapeIndex; if (rootNodeIndex < rootNodeArray.Length) rootNode = rootNodeArray[rootNodeIndex]; } } if (_maxIterations < walkIterations) _maxIterations = walkIterations; }
public int SortAndCalculateSplittingIndex(List <OptimizedBvhNode> leafNodes, int startIndex, int endIndex, int splitAxis) { int splitIndex = startIndex; int numIndices = endIndex - startIndex; float splitValue; Vector3 means = new Vector3(); for (int i = startIndex; i < endIndex; i++) { Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin); means += center; } means *= (1f / (float)numIndices); if (splitAxis == 0) { splitValue = means.X; } else if (splitAxis == 1) { splitValue = means.Y; } else if (splitAxis == 2) { splitValue = means.Z; } else { throw new ArgumentException(); } //sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'. for (int i = startIndex; i < endIndex; i++) { Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin); float centerSplit; if (splitAxis == 0) { centerSplit = means.X; } else if (splitAxis == 1) { centerSplit = means.Y; } else if (splitAxis == 2) { centerSplit = means.Z; } else { throw new ArgumentException(); } if (centerSplit > splitValue) { //swap OptimizedBvhNode tmp = leafNodes[i]; leafNodes[i] = leafNodes[splitIndex]; leafNodes[splitIndex] = tmp; splitIndex++; } } if ((splitIndex == startIndex) || (splitIndex == (endIndex - 1))) { splitIndex = startIndex + (numIndices >> 1); } return(splitIndex); }