/// <summary> /// Builds the octree. /// </summary> #region public void BuildOctree() public void BuildOctree() { // create tri and tri bounding box arrays triBoxes = new JBBox[tris.Length]; // create an infinite size root box rootNodeBox = new JBBox(new JVector(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity), new JVector(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity)); for (int i = 0; i < tris.Length; i++) { JVector.Min(ref positions[tris[i].I1], ref positions[tris[i].I2], out triBoxes[i].Min); JVector.Min(ref positions[tris[i].I0], ref triBoxes[i].Min, out triBoxes[i].Min); JVector.Max(ref positions[tris[i].I1], ref positions[tris[i].I2], out triBoxes[i].Max); JVector.Max(ref positions[tris[i].I0], ref triBoxes[i].Max, out triBoxes[i].Max); // get size of the root box JVector.Min(ref rootNodeBox.Min, ref triBoxes[i].Min, out rootNodeBox.Min); JVector.Max(ref rootNodeBox.Max, ref triBoxes[i].Max, out rootNodeBox.Max); } List<BuildNode> buildNodes = new List<BuildNode>(); buildNodes.Add(new BuildNode()); buildNodes[0].box = rootNodeBox; JBBox[] children = new JBBox[8]; for (int triNum = 0; triNum < tris.Length; triNum++) { int nodeIndex = 0; JBBox box = rootNodeBox; while (box.Contains(ref triBoxes[triNum]) == JBBox.ContainmentType.Contains) { int childCon = -1; for (int i = 0; i < 8; ++i) { CreateAABox(ref box, (EChild)i,out children[i]); if (children[i].Contains(ref triBoxes[triNum]) == JBBox.ContainmentType.Contains) { // this box contains the tri, it can be the only one that does, // so we can stop our child search now and recurse into it childCon = i; break; } } // no child contains this tri completely, so it belong in this node if (childCon == -1) { buildNodes[nodeIndex].triIndices.Add(triNum); break; } else { // do we already have this child int childIndex = -1; for (int index = 0; index < buildNodes[nodeIndex].nodeIndices.Count; ++index) { if (buildNodes[buildNodes[nodeIndex].nodeIndices[index]].childType == childCon) { childIndex = index; break; } } if (childIndex == -1) { // nope create child BuildNode parentNode = buildNodes[nodeIndex]; BuildNode newNode = new BuildNode(); newNode.childType = childCon; newNode.box = children[childCon]; buildNodes.Add(newNode); nodeIndex = buildNodes.Count - 1; box = children[childCon]; parentNode.nodeIndices.Add(nodeIndex); } else { nodeIndex = buildNodes[nodeIndex].nodeIndices[childIndex]; box = children[childCon]; } } } } // now convert to the tighter Node from BuildNodes nodes = new Node[buildNodes.Count]; nodeStackPool = new ArrayResourcePool<ushort>(buildNodes.Count); //nodeStack = new UInt16[buildNodes.Count]; for (int i = 0; i < nodes.Length; i++) { nodes[i].nodeIndices = new UInt16[buildNodes[i].nodeIndices.Count]; for (int index = 0; index < nodes[i].nodeIndices.Length; ++index) { nodes[i].nodeIndices[index] = (UInt16)buildNodes[i].nodeIndices[index]; } nodes[i].triIndices = new int[buildNodes[i].triIndices.Count]; buildNodes[i].triIndices.CopyTo(nodes[i].triIndices); nodes[i].box = buildNodes[i].box; } buildNodes.Clear(); buildNodes = null; }
/// <summary> /// Builds the octree. /// </summary> #region public void BuildOctree() public void BuildOctree() { // create tri and tri bounding box arrays triBoxes = new TSBBox[tris.Length]; // create an infinite size root box rootNodeBox = new TSBBox(new TSVector(FP.PositiveInfinity, FP.PositiveInfinity, FP.PositiveInfinity), new TSVector(FP.NegativeInfinity, FP.NegativeInfinity, FP.NegativeInfinity)); for (int i = 0; i < tris.Length; i++) { TSVector.Min(ref positions[tris[i].I1], ref positions[tris[i].I2], out triBoxes[i].min); TSVector.Min(ref positions[tris[i].I0], ref triBoxes[i].min, out triBoxes[i].min); TSVector.Max(ref positions[tris[i].I1], ref positions[tris[i].I2], out triBoxes[i].max); TSVector.Max(ref positions[tris[i].I0], ref triBoxes[i].max, out triBoxes[i].max); // get size of the root box TSVector.Min(ref rootNodeBox.min, ref triBoxes[i].min, out rootNodeBox.min); TSVector.Max(ref rootNodeBox.max, ref triBoxes[i].max, out rootNodeBox.max); } List <BuildNode> buildNodes = new List <BuildNode>(); buildNodes.Add(new BuildNode()); buildNodes[0].box = rootNodeBox; TSBBox[] children = new TSBBox[8]; for (int triNum = 0; triNum < tris.Length; triNum++) { int nodeIndex = 0; TSBBox box = rootNodeBox; while (box.Contains(ref triBoxes[triNum]) == TSBBox.ContainmentType.Contains) { int childCon = -1; for (int i = 0; i < 8; ++i) { CreateAABox(ref box, (EChild)i, out children[i]); if (children[i].Contains(ref triBoxes[triNum]) == TSBBox.ContainmentType.Contains) { // this box contains the tri, it can be the only one that does, // so we can stop our child search now and recurse into it childCon = i; break; } } // no child contains this tri completely, so it belong in this node if (childCon == -1) { buildNodes[nodeIndex].triIndices.Add(triNum); break; } else { // do we already have this child int childIndex = -1; for (int index = 0; index < buildNodes[nodeIndex].nodeIndices.Count; ++index) { if (buildNodes[buildNodes[nodeIndex].nodeIndices[index]].childType == childCon) { childIndex = index; break; } } if (childIndex == -1) { // nope create child BuildNode parentNode = buildNodes[nodeIndex]; BuildNode newNode = new BuildNode(); newNode.childType = childCon; newNode.box = children[childCon]; buildNodes.Add(newNode); nodeIndex = buildNodes.Count - 1; box = children[childCon]; parentNode.nodeIndices.Add(nodeIndex); } else { nodeIndex = buildNodes[nodeIndex].nodeIndices[childIndex]; box = children[childCon]; } } } } // now convert to the tighter Node from BuildNodes nodes = new Node[buildNodes.Count]; nodeStackPool = new ArrayResourcePool <ushort>(buildNodes.Count); //nodeStack = new UInt16[buildNodes.Count]; for (int i = 0; i < nodes.Length; i++) { nodes[i].nodeIndices = new UInt16[buildNodes[i].nodeIndices.Count]; for (int index = 0; index < nodes[i].nodeIndices.Length; ++index) { nodes[i].nodeIndices[index] = (UInt16)buildNodes[i].nodeIndices[index]; } nodes[i].triIndices = new int[buildNodes[i].triIndices.Count]; buildNodes[i].triIndices.CopyTo(nodes[i].triIndices); nodes[i].box = buildNodes[i].box; } buildNodes.Clear(); buildNodes = null; }
public void BuildOctree() { triBoxes = new JBBox[tris.Length]; rootNodeBox = new JBBox(new JVector(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity), new JVector(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity)); for (int i = 0; i < tris.Length; i++) { var min = JVector.Min(positions[tris[i].I1], positions[tris[i].I2]); min = JVector.Min(positions[tris[i].I0], min); var max = JVector.Max(positions[tris[i].I1], positions[tris[i].I2]); max = JVector.Max(positions[tris[i].I0], max); min = JVector.Min(rootNodeBox.Min, min); max = JVector.Max(rootNodeBox.Max, max); triBoxes[i] = new JBBox(min, max); } var buildNodes = new List <BuildNode> { new BuildNode() }; buildNodes[0].box = rootNodeBox; var children = new JBBox[8]; for (int triNum = 0; triNum < tris.Length; triNum++) { int nodeIndex = 0; var box = rootNodeBox; while (box.Contains(triBoxes[triNum]) == JBBox.ContainmentType.Contains) { int childCon = -1; for (int i = 0; i < 8; ++i) { CreateAABox(box, (EChild)i, out children[i]); if (children[i].Contains(triBoxes[triNum]) == JBBox.ContainmentType.Contains) { childCon = i; break; } } if (childCon == -1) { buildNodes[nodeIndex].triIndices.Add(triNum); break; } else { int childIndex = -1; for (int index = 0; index < buildNodes[nodeIndex].nodeIndices.Count; ++index) { if (buildNodes[buildNodes[nodeIndex].nodeIndices[index]].childType == childCon) { childIndex = index; break; } } if (childIndex == -1) { var parentNode = buildNodes[nodeIndex]; var newNode = new BuildNode { childType = childCon, box = children[childCon] }; buildNodes.Add(newNode); nodeIndex = buildNodes.Count - 1; box = children[childCon]; parentNode.nodeIndices.Add(nodeIndex); } else { nodeIndex = buildNodes[nodeIndex].nodeIndices[childIndex]; box = children[childCon]; } } } } nodes = new Node[buildNodes.Count]; nodeStackPool = new ArrayResourcePool <ushort>(buildNodes.Count); for (int i = 0; i < nodes.Length; i++) { nodes[i].nodeIndices = new ushort[buildNodes[i].nodeIndices.Count]; for (int index = 0; index < nodes[i].nodeIndices.Length; ++index) { nodes[i].nodeIndices[index] = (ushort)buildNodes[i].nodeIndices[index]; } nodes[i].triIndices = new int[buildNodes[i].triIndices.Count]; buildNodes[i].triIndices.CopyTo(nodes[i].triIndices); nodes[i].box = buildNodes[i].box; } buildNodes.Clear(); }