Esempio n. 1
0
        /// <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
        }
Esempio n. 2
0
        ///// <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
        }