Ejemplo n.º 1
0
        internal override void OnUpdate(bool forceRebuild, HashSet <T> addedItems, HashSet <T> removedItems, HashSet <T> invalidItems)
        {
            if (forceRebuild)
            {
                // Total rebuild. Re-Add all Items.
                _edges[0].Clear();
                _edges[1].Clear();
                _edges[2].Clear();
                _itemInfos.Clear();
                if (_broadPhase != null)
                {
                    _broadPhase.Clear();
                }
                if (EnableSelfOverlaps)
                {
                    SelfOverlaps.Clear();
                }

                foreach (var item in Items)
                {
                    AddItem(item);
                }
            }
            else
            {
                // Refit - the default case.
                // First, remove all old items.
                foreach (T removedItem in removedItems)
                {
                    RemoveItem(removedItem);
                }

                // Second, update all invalid items before we add the new items.
                if (invalidItems == null)
                {
                    // Update all items.
                    foreach (ItemInfo itemInfo in _itemInfos)
                    {
                        UpdateItem(itemInfo);
                    }
                }
                else
                {
                    // Update items marked as invalid.
                    foreach (T invalidItem in invalidItems)
                    {
                        UpdateItem(invalidItem);
                    }
                }

                // Third, add all the new items.
                foreach (var addedItem in addedItems)
                {
                    AddItem(addedItem);
                }
            }

            // Update AABB of whole space.
            UpdateAabb();
        }
Ejemplo n.º 2
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);
                //  }
                //}
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Recomputes the self-overlaps.
        /// </summary>
        private void UpdateSelfOverlaps()
        {
            if (!EnableSelfOverlaps)
            {
                return;
            }

            SelfOverlaps.Clear();

            // Get intra-overlaps from static partition.
            AddSelfOverlaps(StaticPartition.GetOverlaps());

            // Get intra-overlaps from dynamic partition.
            AddSelfOverlaps(DynamicPartition.GetOverlaps());

            // Get inter-overlaps between static and dynamic partition.
            AddSelfOverlaps(StaticPartition.GetOverlaps(DynamicPartition));
        }
Ejemplo n.º 4
0
        /// <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);
                    }
                }
            }
        }
Ejemplo n.º 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);
                //    }
                //  }
                //}
            }
        }
Ejemplo n.º 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);
                            }
                        }
                    }
                }
            }
        }