Ejemplo n.º 1
0
    /// <inheritdoc/>
    public override IEnumerable<T> GetOverlaps(Aabb aabb)
    {
      UpdateInternal();


      if (_root == null)
        yield break;

      var stack = DigitalRune.ResourcePools<Node>.Stacks.Obtain();
      stack.Push(_root);
      while (stack.Count > 0)
      {
        Node node = stack.Pop();

        if (GeometryHelper.HaveContact(node.Aabb, aabb))
        {
          if (node.IsLeaf)
          {
            yield return node.Item;
          }
          else
          {
            stack.Push(node.RightChild);
            stack.Push(node.LeftChild);
          }
        }
      }

      DigitalRune.ResourcePools<Node>.Stacks.Recycle(stack);
#else
      // Avoiding garbage:
      return GetOverlapsWork.Create(this, ref aabb);

    }
Ejemplo n.º 2
0
        private IEnumerable <int> GetOverlapsImpl(Aabb aabb)
        {
            // This method avoids the Update() call!

#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.Item);
                }

                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(GetOverlapsWork.Create(this, ref aabb));
#endif
        }
Ejemplo n.º 3
0
        /// <inheritdoc/>
        public override IEnumerable <T> GetOverlaps(Aabb aabb)
        {
            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.Item);
                    }
                    else
                    {
                        SplitIfNecessary(node);
                        stack.Push(node.RightChild);
                        stack.Push(node.LeftChild);
                    }
                }
            }

            DigitalRune.ResourcePools <Node> .Stacks.Recycle(stack);
#else
            // Avoiding garbage:
            return(GetOverlapsWork.Create(this, ref aabb));
#endif
        }
Ejemplo n.º 4
0
    /// <inheritdoc/>
    public override IEnumerable<T> GetOverlaps(Aabb aabb)
    {
      // Make sure we are up-to-date.
      UpdateInternal();

      // TODO: This could be vastly improved with stabbing numbers!
      // TODO: Choose better sweep direction.
      // TODO: Sweep along all 3 axis instead only x.
      // TODO: Add special support for ray collision objects vs the AABB.
      // Currently we sweep up along the x-axis. We could check the AABB center
      // versus the full SAP space to choose a better sweep axis and direction (up vs. down).

      var overlapCandidates = DigitalRune.ResourcePools<ItemInfo>.HashSets.Obtain();

      // The x-axis edge list.
      List<Edge> edgesX = _edges[0];
      int numberOfEdgesPerAxis = edgesX.Count;

      // First, sort max x position up.
      for (int i = 0; i < numberOfEdgesPerAxis; i++)
      {
        var edge = edgesX[i];
        if (edge.Position <= aabb.Maximum.X)
        {
          if (!edge.IsMax)                    // Crossed Min edge --> new overlap.
            overlapCandidates.Add(edge.Info);
        }
        else
        {
          // Search finished.
          break;
        }
      }

      // Next, sort min x position up and remove candidates.
      for (int i = 0; i < numberOfEdgesPerAxis; i++)
      {
        var edge = edgesX[i];
        if (edge.Position < aabb.Minimum.X)
        {
          if (edge.IsMax)                       // Crossed Max edge --> remove overlap.
            overlapCandidates.Remove(edge.Info);
        }
        else
        {
          // Search finished.
          break;
        }
      }


      foreach (var candidate in overlapCandidates)
      {
        if (GeometryHelper.HaveContact(candidate.Aabb, aabb))
          yield return candidate.Item;
      }

      DigitalRune.ResourcePools<ItemInfo>.HashSets.Recycle(overlapCandidates);        
#else
      // Avoiding garbage:
      return GetOverlapsWork.Create(overlapCandidates, ref aabb);

    }