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); }