Exemple #1
0
        public AABBTreeRayTestResult rayTest(AABBTree[] trees,
                                             AABBTreeRay ray,
                                             Func <AABBTree, AABBExternalNode, AABBTreeRay, double, double, AABBTreeRayTestResult> callback)
        {
            //
            //
            // we traverse both trees at once
            // keeping a priority list of nodes to check next.

            // TODO: possibly implement priority list more effeciently?
            //       binary heap probably too much overhead in typical case.
            List <PriorityNode> priorityList = new List <PriorityNode>();
            //current upperBound on distance to first intersection
            //and current closest object properties
            AABBTreeRayTestResult minimumResult = null;

            var upperBound = ray.maxFactor;

            for (int i = 0; i < trees.Length; i += 1)
            {
                AABBTree tree = trees[i];
                if (tree.getNodeCount() != 0)
                {
                    upperBound = processNode(tree, ray, 0, upperBound, callback, ref priorityList, ref minimumResult);
                }
            }

            while (priorityList.Count != 0)
            {
                var nodeObj = priorityList.Last();
                priorityList.RemoveAt(priorityList.Count - 1);
                // A node inserted into priority list after this one may have
                // moved the upper bound.
                if (nodeObj.distance >= upperBound)
                {
                    continue;
                }

                var      nodeIndex = nodeObj.nodeIndex;
                AABBTree tree      = nodeObj.tree;
                var      nodes     = tree.getNodes();

                var node     = nodes[nodeIndex];
                var maxIndex = nodeIndex + node.escapeNodeOffset;

                var childIndex = nodeIndex + 1;
                do
                {
                    upperBound  = processNode(tree, ray, childIndex, upperBound, callback, ref priorityList, ref minimumResult);
                    childIndex += nodes[childIndex].escapeNodeOffset;
                }while (childIndex < maxIndex);
            }

            return(minimumResult);
        }