// Can only add overlapping pairs.
        // Sort edge up and add overlapping pairs
        private void SortMaxEdgeUp(List<Edge> edgeList, int axisIndex, int edgeIndex)
        {
            int maxIndex = edgeList.Count - 1;
              if (edgeIndex == maxIndex)
            return;

              var edge = edgeList[edgeIndex];
              var itemInfo = edge.Info;

              int nextEdgeIndex = edgeIndex + 1;
              var nextEdge = edgeList[nextEdgeIndex];

              while (edge.Position >= nextEdge.Position)
              {
            var nextItemInfo = nextEdge.Info;

            if (nextEdge.IsMax == false)
            {
              // New overlapping pair!
              if (_broadPhase != null || EnableSelfOverlaps)
              {
            if (AreOverlapping(itemInfo, nextItemInfo, axisIndex))
            {
              var overlap = new Pair<T>(itemInfo.Item, nextItemInfo.Item);
              if (Filter == null || Filter.Filter(overlap))
              {
                if (_broadPhase != null)
                  _broadPhase.Add(overlap);

                if (EnableSelfOverlaps)
                  SelfOverlaps.Add(overlap);
              }
            }
              }

              nextItemInfo.MinEdgeIndices[axisIndex] = edgeIndex; // Min edge was swapped down.
            }
            else
            {
              nextItemInfo.MaxEdgeIndices[axisIndex] = edgeIndex; // Max edge was swapped down.
            }

            itemInfo.MaxEdgeIndices[axisIndex] = nextEdgeIndex;   // Max edge was swapped up.

            // Swap edges in edge list.
            edgeList[edgeIndex] = nextEdge;
            edgeList[nextEdgeIndex] = edge;

            edgeIndex++;
            if (edgeIndex == maxIndex)
              return;

            nextEdgeIndex++;
            nextEdge = edgeList[nextEdgeIndex];
              }
        }
        // Can only add overlapping pairs.
        // Sort edge down and add overlapping pairs.
        private void SortMinEdgeDown(List<Edge> edgeList, int axisIndex, int edgeIndex)
        {
            if (edgeIndex == 0)
            return;

              var edge = edgeList[edgeIndex];
              var itemInfo = edge.Info;

              int previousEdgeIndex = edgeIndex - 1;
              Edge previousEdge = edgeList[previousEdgeIndex];

              while (edge.Position <= previousEdge.Position)
              {
            var previousItemInfo = previousEdge.Info;

            if (previousEdge.IsMax)
            {
              // New overlapping pair!
              if (_broadPhase != null || EnableSelfOverlaps)
              {
            if (AreOverlapping(itemInfo, previousItemInfo, axisIndex))
            {
              var overlap = new Pair<T>(itemInfo.Item, previousItemInfo.Item);
              if (Filter == null || Filter.Filter(overlap))
              {
                if (_broadPhase != null)
                  _broadPhase.Add(overlap);

                if (EnableSelfOverlaps)
                  SelfOverlaps.Add(overlap);
              }
            }
              }

              previousItemInfo.MaxEdgeIndices[axisIndex] = edgeIndex; // Max edge was swapped up.
            }
            else
            {
              previousItemInfo.MinEdgeIndices[axisIndex] = edgeIndex; // Min edge was swapped up.
            }

            itemInfo.MinEdgeIndices[axisIndex] = previousEdgeIndex;   // Min edge was swapped down.

            // Swap edges in edge list.
            edgeList[edgeIndex] = previousEdge;
            edgeList[previousEdgeIndex] = edge;

            edgeIndex--;
            if (edgeIndex == 0)
              return;

            previousEdgeIndex--;
            previousEdge = edgeList[previousEdgeIndex];
              }
        }
示例#3
0
        /// <inheritdoc/>
        internal override void OnUpdate(bool forceRebuild, HashSet <T> addedItems, HashSet <T> removedItems, HashSet <T> invalidItems)
        {
            if (EnableSelfOverlaps)
            {
                // Need to find all self-overlaps.
                SelfOverlaps.Clear();

                // Test all items against all items.
                HashSet <T> .Enumerator outerEnumerator = Items.GetEnumerator();
                while (outerEnumerator.MoveNext())
                {
                    T    item = outerEnumerator.Current;
                    Aabb aabb = GetAabbForItem(item);

                    // Duplicate struct enumerator at current position.
                    HashSet <T> .Enumerator innerEnumerator = outerEnumerator;
                    while (innerEnumerator.MoveNext())
                    {
                        T    otherItem = innerEnumerator.Current;
                        Aabb otherAabb = GetAabbForItem(otherItem);

                        Pair <T> overlap = new Pair <T>(item, otherItem);
                        if (Filter == null || Filter.Filter(overlap))
                        {
                            if (GeometryHelper.HaveContact(aabb, otherAabb))
                            {
                                SelfOverlaps.Add(overlap);
                            }
                        }
                    }
                }

                // If Items is a IList<T>, which has an indexer, we can use the following code.
                //for (int i = 0; i < Items.Count; i++)
                //{
                //  var itemI = Items[i];
                //  var aabbI = GetAabbForItem(itemI);

                //  for (int j = i + 1; j < Items.Count; j++)
                //  {
                //    var itemJ = Items[j];
                //    var aabbJ = GetAabbForItem(itemJ);

                //    var overlap = new Pair<T>(itemI, itemJ);
                //    if (Filter == null || Filter.Filter(overlap))
                //      if (GeometryHelper.HaveContact(aabbI, aabbJ))
                //        SelfOverlaps.Add(overlap);
                //  }
                //}
            }
        }
        /// <summary>
        /// Updates the self-overlaps.
        /// </summary>
        private void UpdateSelfOverlaps()
        {
            if (EnableSelfOverlaps)
            {
                // Recompute all self-overlaps by making a tree vs. tree test.
                SelfOverlaps.Clear();

                if (_root != null)
                {
                    // Important: Do not call GetOverlaps(this) because this would lead to recursive
                    // Update() calls!
                    foreach (var overlap in GetOverlapsImpl(this))
                    {
                        Debug.Assert(FilterSelfOverlap(overlap), "Filtering should have been applied.");
                        SelfOverlaps.Add(overlap);
                    }
                }
            }
        }
示例#5
0
        private void UpdateSelfOverlaps()
        {
            if (EnableSelfOverlaps)
            {
                // Update self-overlaps.
                SelfOverlaps.Clear();

                // ----- Compute self-overlaps using tree vs. tree test.

                if (_root == null)
                {
                    return;
                }

                // Important: Do not call GetOverlaps(this) because this would lead to recursive
                // Update() calls!
                foreach (var overlap in GetOverlapsImpl(this))
                {
                    Debug.Assert(FilterSelfOverlap(overlap), "Filtering should have been applied.");
                    SelfOverlaps.Add(overlap);
                }

                // ----- Compute self-overlaps using leaf vs. tree test.
                //if (_root != null)
                //{
                //  foreach (var leave in _leaves)
                //  {
                //    foreach (var touchedItem in GetOverlaps(leave.Aabb))
                //    {
                //      var overlap = new Pair<T>(leave.Item, touchedItem);

                //      if (FilterSelfOverlap(overlap))
                //        SelfOverlaps.Add(overlap);
                //    }
                //  }
                //}
            }
        }
示例#6
0
        private void UpdateSelfOverlaps(HashSet <T> addedItems, HashSet <T> removedItems, HashSet <T> invalidItems, List <Node> invalidNodes)
        {
            if (!EnableSelfOverlaps)
            {
                return;
            }

            // If the entire partition or a substantial amount of nodes is invalid use a tree vs. tree
            // checks. (Faster than leaf vs. tree checks. However, we need to determine the exact
            // threshold at which tree vs. tree is cheaper. The current threshold of Count / 2 is just
            // a guess.)
            if (invalidItems == null || addedItems.Count + invalidItems.Count > Count / 2)
            {
                // Recompute all self-overlaps by making a tree vs. tree test.
                SelfOverlaps.Clear();

                if (_root != null)
                {
                    // Important: Do not call GetOverlaps(this) because this would lead to recursive
                    // Update() calls!
                    // Note: Filtering is applied in GetOverlapsImpl(this).
                    foreach (var overlap in GetOverlapsImpl(this))
                    {
                        SelfOverlaps.Add(overlap);
                    }
                }
            }
            else
            {
                // Merge invalid and removed items into single set.
                // Store result in invalidItems.
                if (invalidItems.Count > 0 && removedItems.Count > 0)
                {
                    // Merge smaller set into larger set.
                    if (invalidItems.Count < removedItems.Count)
                    {
                        MathHelper.Swap(ref invalidItems, ref removedItems);
                    }

                    foreach (var item in removedItems)
                    {
                        invalidItems.Add(item);
                    }
                }
                else if (removedItems.Count > 0)
                {
                    invalidItems = removedItems;
                }

                // Remove invalid entries from self-overlaps.
                if (invalidItems.Count > 0)
                {
                    var invalidOverlaps = DigitalRune.ResourcePools <Pair <T> > .Lists.Obtain();

                    foreach (var overlap in SelfOverlaps)
                    {
                        if (invalidItems.Contains(overlap.First) || invalidItems.Contains(overlap.Second))
                        {
                            invalidOverlaps.Add(overlap);
                        }
                    }

                    foreach (var overlap in invalidOverlaps)
                    {
                        SelfOverlaps.Remove(overlap);
                    }

                    DigitalRune.ResourcePools <Pair <T> > .Lists.Recycle(invalidOverlaps);
                }

                // Compute new overlaps for all nodes that were updated in this frame.
                if (invalidNodes != null)
                {
                    foreach (var node in invalidNodes)
                    {
                        foreach (var touchedItem in GetOverlapsImpl(node))
                        {
                            var overlap = new Pair <T>(node.Item, touchedItem);
                            if (Filter == null || Filter.Filter(overlap))
                            {
                                SelfOverlaps.Add(overlap);
                            }
                        }
                    }
                }
            }
        }
示例#7
0
 private void AddSelfOverlap(Pair <T> overlap)
 {
     Debug.Assert(FilterSelfOverlap(overlap), "Filtering should have been applied.");
     SelfOverlaps.Add(overlap);
 }