コード例 #1
0
        public override void Close()
        {
            base.Close();
            m_workTracker.CancelAll();
            if (RunningBatchTask != null)
            {
                RunningBatchTask.Cancel();
                RunningBatchTask = null;
            }

            if (ENABLE_AABB_PHANTOM)
            {
                m_aabbPhantom.Dispose();
                m_aabbPhantom = null;
            }
        }
コード例 #2
0
        public override void UpdateBeforeSimulation()
        {
            if (m_highPriorityJobs.Count > 0)
            { // no upper bound on these, as there should be just a few high priority jobs
                for (int i = 0; i < Parallel.Scheduler.ThreadCount; ++i)
                {
                    var work = m_workPool.Allocate();
                    work.Queue          = m_highPriorityJobs;
                    work.Priority       = WorkPriority.Low;
                    work.MaxPrecalcTime = (long)MyFakes.MAX_PRECALC_TIME_IN_MILLIS;
                    Parallel.Start(work, work.CompletionCallback);
                }
            }

            if (m_lowPriorityJobs.Count > 0 && m_worksInUse < 2 * Parallel.Scheduler.ThreadCount)
            {
                for (int i = 0; i < Parallel.Scheduler.ThreadCount; ++i)
                {
                    var work = m_workPool.Allocate();
                    work.Queue          = m_lowPriorityJobs;
                    work.Priority       = WorkPriority.VeryLow;
                    work.MaxPrecalcTime = (long)MyFakes.MAX_PRECALC_TIME_IN_MILLIS;
                    ++m_worksInUse;
                    Parallel.Start(work, work.CompletionCallback);
                }
            }

            foreach (var physics in PhysicsWithInvalidCells)
            {
                MyPrecalcJobPhysicsBatch.Start(physics, ref physics.InvalidCells);
            }
            PhysicsWithInvalidCells.Clear();

            Stats.Generic.Write("Precalc jobs in queue (low)", m_lowPriorityJobs.Count, VRage.Stats.MyStatTypeEnum.CurrentValue, 100, 0);
            Stats.Generic.Write("Precalc jobs in queue (high)", m_highPriorityJobs.Count, VRage.Stats.MyStatTypeEnum.CurrentValue, 100, 0);

            if (!MySandboxGame.IsGameReady)
            {
                var work = m_workPool.Allocate();
                work.Queue          = m_lowPriorityJobs;
                work.MaxPrecalcTime = (long)MyFakes.MAX_PRECALC_TIME_IN_MILLIS;
                (work as IWork).DoWork();
                work.CompletionCallback();
            }

            base.UpdateAfterSimulation();
        }
コード例 #3
0
        public override void Close()
        {
            base.Close();
            m_workTracker.CancelAll();
            if (RunningBatchTask != null)
            {
                RunningBatchTask.Cancel();
                RunningBatchTask = null;
            }

            if (ENABLE_AABB_PHANTOM && m_aabbPhantom != null)
            {
                m_aabbPhantom.Dispose();
                m_aabbPhantom = null;
            }
        }
コード例 #4
0
        public override void UpdateBeforeSimulation()
        {
            m_sortedJobs.Lock();
            m_sortedJobs.List.AddList(m_addedJobs);
            m_sortedJobs.Unlock();
            m_addedJobs.Clear();
            m_counter++;
            if (m_counter % 30 == 0)
            {
                SortJobs();
                //m_sortedJobs.Sort(m_comparer);
            }

            if (MyDebugDrawSettings.DEBUG_DRAW_SORTED_JOBS)
            {
                try
                {
                    const float max         = 255;
                    float       shade       = m_sortedJobs.Count > 0 ? m_sortedJobs.ListUnsafe.ItemAt((int)Math.Min(m_sortedJobs.ListUnsafe.Count - 1, max)).Priority : 1;
                    float       minPriority = m_sortedJobs.Count > 0 ? m_sortedJobs.ListUnsafe.ItemAt(0).Priority : 1;
                    shade -= minPriority;
                    for (int xi = 0; xi < max; xi++)
                    {
                        if (xi + 5 > m_sortedJobs.Count)
                        {
                            break;
                        }
                        var job = m_sortedJobs.ListUnsafe.ItemAt(xi);
                        var p   = job.Priority - minPriority;
                        job.DebugDraw(new Color((shade - p) / shade, 0.0f, p / shade, (max - xi) / max));
                    }
                }
                catch (Exception e)
                { }
            }

            if (m_sortedJobs.Count > 0)
            {
                while (m_workPool.Count > 0)
                {
                    var work = m_workPool.Allocate();
                    work.Queue          = m_sortedJobs;
                    work.Priority       = WorkPriority.Low;
                    work.MaxPrecalcTime = (long)MyFakes.MAX_PRECALC_TIME_IN_MILLIS;

                    if (MULTITHREADED)
                    {
                        Parallel.Start(work, work.CompletionCallback);
                    }
                    else
                    {
                        ((IWork)work).DoWork();
                        work.CompletionCallback();
                    }
                }
            }

            foreach (var physics in PhysicsWithInvalidCells)
            {
                for (int lod = 0; lod < physics.InvalidCells.Length; lod++)
                {
                    if (physics.InvalidCells[lod].Count > 0 && physics.RunningBatchTask[lod] == null)
                    {
                        MyPrecalcJobPhysicsBatch.Start(physics, ref physics.InvalidCells[lod], lod);
                    }
                }
            }
            PhysicsWithInvalidCells.Clear();

            Stats.Generic.Write("Precalc jobs in sorted", m_sortedJobs.Count, VRage.Stats.MyStatTypeEnum.CurrentValue, 100, 0);
            Stats.Generic.Write("Clipmap triangle cache", MyClipmap.CellsCache.Usage, VRage.Stats.MyStatTypeEnum.CurrentValue, 100, 2);

            base.UpdateAfterSimulation();
        }
コード例 #5
0
        /// <param name="minVoxelChanged">Inclusive min.</param>
        /// <param name="maxVoxelChanged">Inclusive max.</param>
        internal void InvalidateRange(Vector3I minVoxelChanged, Vector3I maxVoxelChanged)
        {
            MyPrecalcComponent.AssertUpdateThread();
            ProfilerShort.Begin("MyVoxelPhysicsBody.InvalidateRange");

            minVoxelChanged -= MyPrecalcComponent.InvalidatedRangeInflate;
            maxVoxelChanged += MyPrecalcComponent.InvalidatedRangeInflate;
            m_voxelMap.Storage.ClampVoxelCoord(ref minVoxelChanged);
            m_voxelMap.Storage.ClampVoxelCoord(ref maxVoxelChanged);

            Vector3I minCellChanged, maxCellChanged;
            MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref minVoxelChanged, out minCellChanged);
            MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref maxVoxelChanged, out maxCellChanged);

            Vector3I minCellChangedVoxelMap, maxCellChangedVoxelMap;
            minCellChangedVoxelMap = minCellChanged - m_cellsOffset;
            maxCellChangedVoxelMap = maxCellChanged - m_cellsOffset;

            Debug.Assert(RigidBody != null, "RigidBody in voxel physics is null! This must not happen.");
            if (RigidBody != null)
            {
                var shape = (HkUniformGridShape)RigidBody.GetShape();
                var tmpBuffer = m_cellsToGenerateBuffer;
                int invalidCount = shape.InvalidateRange(ref minCellChangedVoxelMap, ref maxCellChangedVoxelMap, tmpBuffer);
                if (invalidCount > tmpBuffer.Length)
                {
                    // Not storing this new buffer in static variable since this is just temporary and potentially large.
                    // Static variable could be potentially the same as leak.
                    tmpBuffer = new Vector3I[invalidCount];
                    int invalidCount2 = shape.InvalidateRange(ref minCellChangedVoxelMap, ref maxCellChangedVoxelMap, tmpBuffer);
                    Debug.Assert(invalidCount == invalidCount2);
                    invalidCount = invalidCount2;
                }

                Debug.Assert(invalidCount <= tmpBuffer.Length);
                for (int i = 0; i < invalidCount; i++)
                {
                    InvalidCells.Add(tmpBuffer[i]);
                }
                if (RunningBatchTask != null)
                {
                    RunningBatchTask.Cancel();
                    foreach (var oldInvalidCell in RunningBatchTask.CellBatch)
                    {
                        InvalidCells.Add(oldInvalidCell);
                    }
                    RunningBatchTask = null;
                }
                if (InvalidCells.Count != 0)
                    MyPrecalcComponent.PhysicsWithInvalidCells.Add(this);
            }

            var cell = minCellChanged;
            for (var it = new Vector3I.RangeIterator(ref minCellChanged, ref maxCellChanged);
                it.IsValid(); it.GetNext(out cell))
            {
                m_workTracker.Cancel(cell);
            }

            m_needsShapeUpdate = true;

            ProfilerShort.End();
        }
コード例 #6
0
        /// <param name="minVoxelChanged">Inclusive min.</param>
        /// <param name="maxVoxelChanged">Inclusive max.</param>
        internal void InvalidateRange(Vector3I minVoxelChanged, Vector3I maxVoxelChanged)
        {
            MyPrecalcComponent.AssertUpdateThread();
            ProfilerShort.Begin("MyVoxelPhysicsBody.InvalidateRange");

            minVoxelChanged -= MyPrecalcComponent.InvalidatedRangeInflate;
            maxVoxelChanged += MyPrecalcComponent.InvalidatedRangeInflate;
            m_voxelMap.Storage.ClampVoxelCoord(ref minVoxelChanged);
            m_voxelMap.Storage.ClampVoxelCoord(ref maxVoxelChanged);

            Vector3I minCellChanged, maxCellChanged;

            MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref minVoxelChanged, out minCellChanged);
            MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref maxVoxelChanged, out maxCellChanged);

            Vector3I minCellChangedVoxelMap, maxCellChangedVoxelMap;

            minCellChangedVoxelMap = minCellChanged - m_cellsOffset;
            maxCellChangedVoxelMap = maxCellChanged - m_cellsOffset;

            Debug.Assert(RigidBody != null, "RigidBody in voxel physics is null! This must not happen.");
            if (RigidBody != null)
            {
                var shape        = (HkUniformGridShape)RigidBody.GetShape();
                var tmpBuffer    = m_cellsToGenerateBuffer;
                int invalidCount = shape.InvalidateRange(ref minCellChangedVoxelMap, ref maxCellChangedVoxelMap, tmpBuffer);
                if (invalidCount > tmpBuffer.Length)
                {
                    // Not storing this new buffer in static variable since this is just temporary and potentially large.
                    // Static variable could be potentially the same as leak.
                    tmpBuffer = new Vector3I[invalidCount];
                    int invalidCount2 = shape.InvalidateRange(ref minCellChangedVoxelMap, ref maxCellChangedVoxelMap, tmpBuffer);
                    Debug.Assert(invalidCount == invalidCount2);
                    invalidCount = invalidCount2;
                }

                Debug.Assert(invalidCount <= tmpBuffer.Length);
                for (int i = 0; i < invalidCount; i++)
                {
                    InvalidCells.Add(tmpBuffer[i]);
                }
                if (RunningBatchTask != null)
                {
                    RunningBatchTask.Cancel();
                    foreach (var oldInvalidCell in RunningBatchTask.CellBatch)
                    {
                        InvalidCells.Add(oldInvalidCell);
                    }
                    RunningBatchTask = null;
                }
                if (InvalidCells.Count != 0)
                {
                    MyPrecalcComponent.PhysicsWithInvalidCells.Add(this);
                }
            }

            var cell = minCellChanged;

            for (var it = new Vector3I.RangeIterator(ref minCellChanged, ref maxCellChanged);
                 it.IsValid(); it.GetNext(out cell))
            {
                m_workTracker.Cancel(cell);
            }

            m_needsShapeUpdate = true;

            ProfilerShort.End();
        }
コード例 #7
0
        public override void UpdateBeforeSimulation()
        {
            m_sortedJobs.Lock();
            m_sortedJobs.List.AddList(m_addedJobs);
            m_sortedJobs.Unlock();
            m_addedJobs.Clear();
            m_counter++;
            if (m_counter % 60 == 0)
            {
                SortJobs();
                //m_sortedJobs.Sort(m_comparer);
            }

            if (MyDebugDrawSettings.DEBUG_DRAW_SORTED_JOBS)
            {
                try
                {
                    const float max         = 255;
                    float       shade       = m_sortedJobs.Count > 0 ? m_sortedJobs.ListUnsafe.ItemAt((int)Math.Min(m_sortedJobs.ListUnsafe.Count - 1, max)).Priority : 1;
                    float       minPriority = m_sortedJobs.Count > 0 ? m_sortedJobs.ListUnsafe.ItemAt(0).Priority : 1;
                    shade -= minPriority;
                    for (int xi = 0; xi < max; xi++)
                    {
                        if (xi + 5 > m_sortedJobs.Count)
                        {
                            break;
                        }
                        var job = m_sortedJobs.ListUnsafe.ItemAt(xi);
                        var p   = job.Priority - minPriority;
                        job.DebugDraw(new Color((shade - p) / shade, 0.0f, p / shade, (max - xi) / max));
                    }
                }
                catch (Exception e)
                { }
            }

            if (m_sortedJobs.Count > 0 && m_worksInUse < 2 * Parallel.Scheduler.ThreadCount)
            { // no upper bound on these, as there should be just a few high priority jobs
                for (int i = 0; i < Parallel.Scheduler.ThreadCount; ++i)
                {
                    var work = m_workPool.Allocate();
                    work.Queue          = m_sortedJobs;
                    work.Priority       = WorkPriority.Low;
                    work.MaxPrecalcTime = (long)MyFakes.MAX_PRECALC_TIME_IN_MILLIS;
                    ++m_worksInUse;

                    if (MULTITHREADED)
                    {
                        Parallel.Start(work, work.CompletionCallback);
                    }
                    else
                    {
                        ((IWork)work).DoWork();
                        work.CompletionCallback();
                    }
                }
            }

            if (m_highPriorityJobs.Count > 0)
            { // no upper bound on these, as there should be just a few high priority jobs
                for (int i = 0; i < Parallel.Scheduler.ThreadCount; ++i)
                {
                    var work = m_workPool.Allocate();
                    work.Queue          = m_highPriorityJobs;
                    work.Priority       = WorkPriority.Low;
                    work.MaxPrecalcTime = (long)MyFakes.MAX_PRECALC_TIME_IN_MILLIS;
                    ++m_worksInUse;

                    if (MULTITHREADED)
                    {
                        Parallel.Start(work, work.CompletionCallback);
                    }
                    else
                    {
                        ((IWork)work).DoWork();
                        work.CompletionCallback();
                    }
                }
            }

            if (m_lowPriorityJobs.Count > 0 && m_worksInUse < 2 * Parallel.Scheduler.ThreadCount)
            {
                for (int i = 0; i < Parallel.Scheduler.ThreadCount; ++i)
                {
                    var work = m_workPool.Allocate();
                    work.Queue          = m_lowPriorityJobs;
                    work.Priority       = WorkPriority.VeryLow;
                    work.MaxPrecalcTime = (long)MyFakes.MAX_PRECALC_TIME_IN_MILLIS;
                    ++m_worksInUse;

                    if (MULTITHREADED)
                    {
                        Parallel.Start(work, work.CompletionCallback);
                    }
                    else
                    {
                        ((IWork)work).DoWork();
                        work.CompletionCallback();
                    }
                }
            }

            foreach (var physics in PhysicsWithInvalidCells)
            {
                MyPrecalcJobPhysicsBatch.Start(physics, ref physics.InvalidCells);
            }
            PhysicsWithInvalidCells.Clear();

            Stats.Generic.Write("Precalc jobs in sorted", m_sortedJobs.Count, VRage.Stats.MyStatTypeEnum.CurrentValue, 100, 0);
            Stats.Generic.Write("Precalc jobs in queue (low)", m_lowPriorityJobs.Count, VRage.Stats.MyStatTypeEnum.CurrentValue, 100, 0);
            Stats.Generic.Write("Precalc jobs in queue (high)", m_highPriorityJobs.Count, VRage.Stats.MyStatTypeEnum.CurrentValue, 100, 0);

            if (!MySandboxGame.IsGameReady)
            {
                var work = m_workPool.Allocate();
                work.Queue          = m_lowPriorityJobs;
                work.MaxPrecalcTime = (long)MyFakes.MAX_PRECALC_TIME_IN_MILLIS;
                (work as IWork).DoWork();
                work.CompletionCallback();
            }

            base.UpdateAfterSimulation();
        }