/// <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 JBBox 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) != JBBox.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 JBBox[tris.Length]; // create an infinite size root box rootNodeBox = new JBBox(new JVector(double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity), new JVector(double.NegativeInfinity, double.NegativeInfinity, double.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; }