示例#1
0
        protected override void UpdateMultithreaded()
        {
            if (backbuffer.Count != entries.Count)
            {
                backbuffer.Capacity = entries.Capacity;
                backbuffer.Count    = entries.Count;
            }
            Overlaps.Clear();
            //Sort along x axis using insertion sort; the list will be nearly sorted, so very few swaps are necessary.
            for (int i = 1; i < entries.Count; i++)
            {
                var entry = entries.Elements[i];
                for (int j = i - 1; j >= 0; j--)
                {
                    if (entry.boundingBox.Min.X < entries.Elements[j].boundingBox.Min.X)
                    {
                        entries.Elements[j + 1] = entries.Elements[j];
                        entries.Elements[j]     = entry;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            //TODO: Multithreaded sorting could help in some large cases.
            //The overhead involved in this implementation is way too high for reasonable object counts.
            //for (int i = 0; i < sortSegmentCount; i++)
            //    SortSection(i);

            ////MergeSections(0, 1);
            ////MergeSections(2, 3);
            ////MergeSections(0, 2);
            ////MergeSections(1, 3);

            //MergeSections(0, 1);
            //MergeSections(2, 3);
            //MergeSections(4, 5);
            //MergeSections(6, 7);

            //MergeSections(0, 2);
            //MergeSections(1, 3);
            //MergeSections(4, 6);
            //MergeSections(5, 7);

            //MergeSections(0, 4);
            //MergeSections(1, 5);
            //MergeSections(2, 6);
            //MergeSections(3, 7);

            //var temp = backbuffer;
            //backbuffer = entries;
            //entries = temp;

            ParallelLooper.ForLoop(0, sweepSegmentCount, sweepSegment);
        }
        protected override void UpdateSingleThreaded()
        {
            lock (Locker)
            {
                Overlaps.Clear();
                //Update the placement of objects.
                for (int i = 0; i < entries.Count; i++)
                {
                    //Compute the current cells occupied by the entry.
                    var  entry = entries.Elements[i];
                    Int2 min, max;
                    ComputeCell(ref entry.item.boundingBox.Min, out min);
                    ComputeCell(ref entry.item.boundingBox.Max, out max);
                    //For any cell that used to be occupied (defined by the previous min/max),
                    //remove the entry.
                    for (int j = entry.previousMin.Y; j <= entry.previousMax.Y; j++)
                    {
                        for (int k = entry.previousMin.Z; k <= entry.previousMax.Z; k++)
                        {
                            if (j >= min.Y && j <= max.Y && k >= min.Z && k <= max.Z)
                            {
                                continue; //This cell is currently occupied, do not remove.
                            }
                            var index = new Int2 {
                                Y = j, Z = k
                            };
                            cellSet.Remove(ref index, entry);
                        }
                    }
                    //For any cell that is newly occupied (was not previously contained),
                    //add the entry.
                    for (int j = min.Y; j <= max.Y; j++)
                    {
                        for (int k = min.Z; k <= max.Z; k++)
                        {
                            if (j >= entry.previousMin.Y && j <= entry.previousMax.Y && k >= entry.previousMin.Z && k <= entry.previousMax.Z)
                            {
                                continue; //This cell is already occupied, do not add.
                            }
                            var index = new Int2 {
                                Y = j, Z = k
                            };
                            cellSet.Add(ref index, entry);
                        }
                    }
                    entry.previousMin = min;
                    entry.previousMax = max;
                }

                //Update each cell to find the overlaps.
                for (int i = 0; i < cellSet.count; i++)
                {
                    cellSet.cells.Elements[i].UpdateOverlaps(this);
                }
            }
        }
示例#3
0
 // Inherited
 public override void Clear()
 {
     Layering.Clear();
     EventTriggers.Clear();
     ExitTriggers.Clear();
     NPCObjects.Clear();
     Overlaps.Clear();
     TileSwitches.Clear();
     CollisionSwitches.Clear();
 }
 protected override void UpdateMultithreaded()
 {
     lock (Locker)
     {
         Overlaps.Clear();
         //Update the entries!
         ParallelLooper.ForLoop(0, entries.Count, updateEntry);
         //Update the cells!
         ParallelLooper.ForLoop(0, cellSet.count, updateCell);
     }
 }
示例#5
0
 protected override void UpdateSingleThreaded()
 {
     Overlaps.Clear();
     for (int i = 0; i < entries.Count; i++)
     {
         for (int j = i + 1; j < entries.Count; j++)
         {
             if (entries[i].boundingBox.Intersects(entries[j].boundingBox))
             {
                 base.TryToAddOverlap(entries[i], entries[j]);
             }
         }
     }
 }
示例#6
0
        protected override void UpdateSingleThreaded()
        {
            lock (Locker)
            {
                Overlaps.Clear();
                if (root != null)
                {
                    root.Refit();

                    if (!root.IsLeaf) //If the root is a leaf, it's alone- nothing to collide against! This test is required by the assumptions of the leaf-leaf test.
                    {
                        root.GetOverlaps(root, this);
                    }
                }
            }
        }
示例#7
0
        /// <summary>
        /// Calculate a list of which views overlap this handle.
        /// </summary>
        /// <param name="group">The parent texture group, used to find a view's base CPU VA offset</param>
        /// <param name="views">The list of views to search for overlaps</param>
        public void RecalculateOverlaps(TextureGroup group, List <Texture> views)
        {
            // Overlaps can be accessed from the memory tracking signal handler, so access must be atomic.
            lock (Overlaps)
            {
                int endOffset = Offset + Size;

                Overlaps.Clear();

                foreach (Texture view in views)
                {
                    int viewOffset = group.FindOffset(view);
                    if (viewOffset < endOffset && Offset < viewOffset + (int)view.Size)
                    {
                        Overlaps.Add(view);
                    }
                }
            }
        }
示例#8
0
        protected override void UpdateSingleThreaded()
        {
            lock (Locker)
            {
                Overlaps.Clear();
                if (root != null)
                {
#if PROFILE
                    startRefit = Stopwatch.GetTimestamp();
#endif
                    SingleThreadedRefitPhase();
#if PROFILE
                    endRefit = Stopwatch.GetTimestamp();
#endif
                    SingleThreadedOverlapPhase();
#if PROFILE
                    endOverlap = Stopwatch.GetTimestamp();
#endif
                }
            }
        }
示例#9
0
        protected override void UpdateMultithreaded()
        {
            lock (Locker)
            {
                Overlaps.Clear();
                if (root != null)
                {
                    int splitDepth = GetSplitDepth();
#if PROFILE
                    startRefit = Stopwatch.GetTimestamp();
#endif
                    MultithreadedRefitPhase(splitDepth);
#if PROFILE
                    endRefit = Stopwatch.GetTimestamp();
#endif
                    MultithreadedOverlapPhase(splitDepth);
#if PROFILE
                    endOverlap = Stopwatch.GetTimestamp();
#endif
                }
            }
        }
示例#10
0
        protected override void UpdateSingleThreaded()
        {
            Overlaps.Clear();
            //Sort along x axis using insertion sort; the list will be nearly sorted, so very few swaps are necessary.
            for (int i = 1; i < entries.Count; i++)
            {
                BroadPhaseEntry entry = entries.Elements[i];
                for (int j = i - 1; j >= 0; j--)
                {
                    if (entry.boundingBox.Min.X < entries.Elements[j].boundingBox.Min.X)
                    {
                        entries.Elements[j + 1] = entries.Elements[j];
                        entries.Elements[j]     = entry;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            //Sweep the list looking for overlaps.
            for (int i = 0; i < entries.Count; i++)
            {
                BoundingBox a = entries.Elements[i].boundingBox;
                for (int j = i + 1; j < entries.Count && a.Max.X >= entries.Elements[j].boundingBox.Min.X; j++)
                {
                    if (!(a.Min.Y > entries.Elements[j].boundingBox.Max.Y ||
                          a.Max.Y <entries.Elements[j].boundingBox.Min.Y ||
                                   a.Min.Z> entries.Elements[j].boundingBox.Max.Z ||
                          a.Max.Z < entries.Elements[j].boundingBox.Min.Z))
                    {
                        TryToAddOverlap(entries.Elements[i], entries.Elements[j]);
                    }
                }
            }
        }
示例#11
0
        protected override void UpdateSingleThreaded()
        {
            overlapCandidatesX.Clear();
            overlapCandidatesY.Clear();
            Overlaps.Clear();

            //Sort along x axis using insertion sort; the list will be nearly sorted, so very few swaps are necessary.
            for (int i = 1; i < entriesX.count; i++)
            {
                var entry = entriesX.Elements[i];
                for (int j = i - 1; j >= 0; j--)
                {
                    if (entry.boundingBox.Min.X < entriesX.Elements[j].boundingBox.Min.X)
                    {
                        entriesX.Elements[j + 1] = entriesX.Elements[j];
                        entriesX.Elements[j]     = entry;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            //Sort along y axis using insertion sort; the list will be nearly sorted, so very few swaps are necessary.
            for (int i = 1; i < entriesY.count; i++)
            {
                var entry = entriesY.Elements[i];
                for (int j = i - 1; j >= 0; j--)
                {
                    if (entry.boundingBox.Min.Y < entriesY.Elements[j].boundingBox.Min.Y)
                    {
                        entriesY.Elements[j + 1] = entriesY.Elements[j];
                        entriesY.Elements[j]     = entry;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            //Sort along z axis using insertion sort; the list will be nearly sorted, so very few swaps are necessary.
            for (int i = 1; i < entriesZ.count; i++)
            {
                var entry = entriesZ.Elements[i];
                for (int j = i - 1; j >= 0; j--)
                {
                    if (entry.boundingBox.Min.Z < entriesZ.Elements[j].boundingBox.Min.Z)
                    {
                        entriesZ.Elements[j + 1] = entriesZ.Elements[j];
                        entriesZ.Elements[j]     = entry;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            //Hash-set based sweeping is way too slow.  3D sap is really best suited to an incremental approach.

            //Sweep the list looking for overlaps.
            //Sweep the X axis first; in this phase, add overlaps to the hash set if they exist.
            for (int i = 0; i < entriesX.count; i++)
            {
                BoundingBox a = entriesX.Elements[i].boundingBox;
                for (int j = i + 1; j < entriesX.count && a.Max.X > entriesX.Elements[j].boundingBox.Min.X; j++)
                {
                    overlapCandidatesX.Add(new BroadPhaseOverlap(entriesX.Elements[i], entriesX.Elements[j]));
                }
            }
            //Sweep the Y axis second; same thing
            for (int i = 0; i < entriesY.count; i++)
            {
                BoundingBox a = entriesY.Elements[i].boundingBox;
                for (int j = i + 1; j < entriesY.count && a.Max.Y > entriesY.Elements[j].boundingBox.Min.Y; j++)
                {
                    overlapCandidatesY.Add(new BroadPhaseOverlap(entriesY.Elements[i], entriesY.Elements[j]));
                }
            }
            //Sweep the Z axis last
            for (int i = 0; i < entriesZ.count; i++)
            {
                BoundingBox a = entriesZ.Elements[i].boundingBox;
                for (int j = i + 1; j < entriesZ.count && a.Max.Z > entriesZ.Elements[j].boundingBox.Min.Z; j++)
                {
                    var overlap = new BroadPhaseOverlap(entriesZ.Elements[i], entriesZ.Elements[j]);
                    if (overlapCandidatesX.Contains(overlap) && overlapCandidatesY.Contains(overlap))
                    {
                        TryToAddOverlap(entriesZ.Elements[i], entriesZ.Elements[j]);
                    }
                }
            }
        }