/// <summary> /// Query an AABB for overlapping proxies. The callback class /// is called for each proxy that overlaps the supplied AABB. /// </summary> /// <param name="callback">The callback.</param> /// <param name="aabb">The aabb.</param> public void Query(List <int> my, ref TSBBox aabb) { //Stack<int> _stack = new Stack<int>(256); Stack <int> _stack = stackPool.GetNew(); _stack.Push(_root); while (_stack.Count > 0) { int nodeId = _stack.Pop(); if (nodeId == NullNode) { continue; } DynamicTreeNode <T> node = _nodes[nodeId]; //if (JBBox.TestOverlap(ref node.AABB, ref aabb)) if (aabb.Contains(ref node.AABB) != TSBBox.ContainmentType.Disjoint) { if (node.IsLeaf()) { my.Add(nodeId); //bool proceed = callback(nodeId); //if (proceed == false) //{ // return; //} } else { _stack.Push(node.Child1); _stack.Push(node.Child2); } } } stackPool.GiveBack(_stack); }
/// <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; }