internal void ProcessTriangles(TriangleFunctor tf) { Triangle tri; int stackIdx = 0, stackSize = tf.Stack.Length; int bufIdx = 0, bufSize = tf.Buffer.Length; var box = tf.BoundingBox; if (AlignedBox.Intersect(ref box, ref _nodes[0].BoundingBox) == BoxIntersectType.None) { return; } tf.Stack[0] = 0; while (stackIdx >= 0) { int nodeIdx = tf.Stack[stackIdx]; if (AlignedBox.Intersect(ref box, ref _nodes[nodeIdx].BoundingBox) != BoxIntersectType.None) { for (int i = 0; i < _nodes[nodeIdx].Triangles.Length; i++) { if (AlignedBox.Intersect(ref box, ref _triangleBoxes[_nodes[nodeIdx].Triangles[i]]) != BoxIntersectType.None) { int[] vertices = _triangles[_nodes[nodeIdx].Triangles[i]]; tri.V1 = _body[vertices[0]]; tri.V2 = _body[vertices[1]]; tri.V3 = _body[vertices[2]]; tri.Normal = _normals[_nodes[nodeIdx].Triangles[i]]; tf.Buffer[bufIdx++] = tri; if (bufIdx == bufSize) { tf.Process(bufSize); bufIdx = 0; } } } } stackIdx--; for (int i = 0; i < _nodes[nodeIdx].Children.Length; i++) { if (stackIdx == stackSize - 2) { stackSize = tf.GrowStack(); } tf.Stack[++stackIdx] = _nodes[nodeIdx].Children[i]; } } if (bufIdx > 0) { tf.Process(bufIdx); } }
private void BuildOctree() { var tempNodes = new List <TempNode>(); var root = new TempNode(); tempNodes.Add(root); // create bounding boxes for all triangles _triangleBoxes = new AlignedBox[_triangles.Length]; for (int i = 0; i < _triangles.Length; i++) { AlignedBox.Fit(ref _body[_triangles[i][0]], ref _body[_triangles[i][1]], ref _body[_triangles[i][2]], out _triangleBoxes[i]); AlignedBox.Merge(ref root.BoundingBox, ref _triangleBoxes[i], out root.BoundingBox); } var subBoxes = new AlignedBox[8]; // add each triangle to the bounding box for (int i = 0; i < _triangles.Length; i++) { int idx = 0; var box = root.BoundingBox; while (AlignedBox.Intersect(ref tempNodes[idx].BoundingBox, ref _triangleBoxes[i]) == BoxIntersectType.AContainsB) { int sector = -1; for (int j = 0; j < 8; j++) { CreateChildBox(ref tempNodes[idx].BoundingBox, j, out subBoxes[j]); if (AlignedBox.Intersect(ref subBoxes[j], ref _triangleBoxes[i]) == BoxIntersectType.AContainsB) { sector = j; break; } } if (sector == -1) { tempNodes[idx].Triangles.Add(i); break; } else { if (tempNodes[idx].Children[sector] > 0) { idx = tempNodes[idx].Children[sector]; } else { var child = new TempNode(); child.BoundingBox = subBoxes[sector]; tempNodes.Add(child); idx = tempNodes[idx].Children[sector] = tempNodes.Count - 1; } } } } _nodes = (from node in tempNodes select new Node() { Children = (from i in node.Children where i > 0 select(ushort) i).ToArray(), Triangles = (from i in node.Triangles select(ushort) i).ToArray(), BoundingBox = node.BoundingBox }).ToArray(); }