/// <summary> /// Gets the leaf nodes that touch the given AABB. (Same as /// <see cref="GetOverlaps(Shapes.Aabb)"/> except we directly return the AABB tree node. /// </summary> /// <param name="aabb">The axis-aligned bounding box.</param> /// <returns>All items that touch the given AABB.</returns> /// <remarks> /// Filtering (see <see cref="Filter"/>) is not applied. /// </remarks> private IEnumerable <Node> GetLeafNodes(Aabb aabb) { // Note: This methods is the same as GetOverlaps(Aabb), but instead of returning items we // return the nodes directly. This is used in tree vs. tree tests, so we do not have to // recompute the AABBs of each leaf node. Update(false); #if !POOL_ENUMERABLES if (_numberOfItems == 0) { yield break; } // Stackless traversal of tree. // The AABB tree nodes are stored in preorder traversal order. We can visit them in linear // order. The EscapeOffset of each node can be used to skip a subtree. int index = 0; while (index < _nodes.Length) { Node node = _nodes[index]; bool haveContact = GeometryHelper.HaveContact(GetAabb(node), aabb); if (haveContact && node.IsLeaf) { yield return(node); } if (haveContact || node.IsLeaf) { // Given AABB intersects the internal AABB tree node or the node is a leaf. // Continue with next item in preorder traversal order. index++; } else { // Given AABB does not touch the internal AABB tree node. // --> Skip the subtree. index += node.EscapeOffset; } } #else // Avoiding garbage: return(GetLeafNodesWork.Create(this, ref aabb)); #endif }
///// <summary> ///// Gets the items that touch the given leaf node. ///// </summary> ///// <param name="leaf">The axis-aligned bounding box.</param> ///// <returns>All items that touch the given AABB.</returns> ///// <remarks> ///// Filtering (see <see cref="BasePartition{T}.Filter"/>) is not applied. ///// </remarks> //private IEnumerable<T> GetOverlaps(Node leaf) //{ // // Note: This method is the same as GetOverlaps(Aabb), except that before checking // // the AABBs we compare the nodes. This removes some unnecessary AABB checks when // // computing self-overlaps. // Debug.Assert(leaf.IsLeaf); // Update(false); // if (_root == null) // yield break; // var stack = DigitalRune.ResourcePools<Node>.Stacks.Obtain(); // stack.Push(_root); // while (stack.Count > 0) // { // Node node = stack.Pop(); // node.IsActive = true; // if (node != leaf && GeometryHelper.HaveContact(node.Aabb, leaf.Aabb)) // { // if (node.IsLeaf) // { // yield return node.Item; // } // else // { // SplitIfNecessary(node); // stack.Push(node.RightChild); // stack.Push(node.LeftChild); // } // } // } // DigitalRune.ResourcePools<Node>.Stacks.Recycle(stack); //} /// <summary> /// Gets the leaf nodes that touch the given AABB. (Same as <see cref="GetOverlaps(Aabb)"/> /// except we directly return the AABB tree node.) /// </summary> /// <param name="aabb">The axis-aligned bounding box.</param> /// <returns>All leaf nodes that touch the given AABB.</returns> /// <remarks> /// Filtering (see <see cref="BasePartition{T}.Filter"/>) is not applied. /// </remarks> private IEnumerable <Node> GetLeafNodes(Aabb aabb) { // Note: This methods is the same as GetOverlaps(Aabb), but instead of returning items we // return the nodes directly. This is used in tree vs. tree tests, so we do not have to // recompute the AABBs of each leaf node. UpdateInternal(); #if !POOL_ENUMERABLES if (_root == null) { yield break; } var stack = DigitalRune.ResourcePools <Node> .Stacks.Obtain(); stack.Push(_root); while (stack.Count > 0) { Node node = stack.Pop(); node.IsActive = true; if (GeometryHelper.HaveContact(node.Aabb, aabb)) { if (node.IsLeaf) { yield return(node); } else { SplitIfNecessary(node); stack.Push(node.RightChild); stack.Push(node.LeftChild); } } } DigitalRune.ResourcePools <Node> .Stacks.Recycle(stack); #else // Avoiding garbage: return(GetLeafNodesWork.Create(this, ref aabb)); #endif }