/// <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);
        }
예제 #2
0
        /// <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;
        }