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; ++m_worksInUse; 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(); }
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 && m_worksInUse < 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(); } } } 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("Clipmap triangle cache", MyClipmap.CellsCache.Usage, VRage.Stats.MyStatTypeEnum.CurrentValue, 100, 2); base.UpdateAfterSimulation(); }
public override void UpdateAfterSimulation10() { base.UpdateAfterSimulation10(); if (!Sync.IsServer || !IsWorking) { return; } if (!ResourceSink.IsPoweredByType(MyResourceDistributorComponent.ElectricityId)) { if (ResourceSink.IsPowerAvailable(MyResourceDistributorComponent.ElectricityId, BlockDefinition.RequiredPowerInput)) { float origInput = ResourceSink.RequiredInputByType(MyResourceDistributorComponent.ElectricityId); ResourceSink.SetRequiredInputByType(MyResourceDistributorComponent.ElectricityId, 0); ResourceSink.SetRequiredInputByType(MyResourceDistributorComponent.ElectricityId, origInput); } else { return; } } var rotation1 = Quaternion.CreateFromForwardUp(WorldMatrix.Forward, WorldMatrix.Up); var position1 = PositionComp.GetPosition() + Vector3D.Transform(PositionComp.LocalVolume.Center + (m_fieldMax.Value + m_fieldMin.Value) * 0.5f, rotation1); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Recreate Field"); if (m_recreateField) { m_recreateField = false; m_fieldShape.RemoveReference(); m_fieldShape = GetHkShape(); ResourceSink.Update(); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); var boundingBox = new BoundingBoxD(m_fieldMin.Value, m_fieldMax.Value).Translate(PositionComp.LocalVolume.Center).TransformFast(WorldMatrix.GetOrientation()).Translate(PositionComp.GetPosition()); m_potentialPenetrations.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref boundingBox, m_potentialPenetrations); m_potentialVoxelPenetrations.Clear(); MyGamePruningStructure.GetAllVoxelMapsInBox(ref boundingBox, m_potentialVoxelPenetrations);//disabled until heightmap queries are finished VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Sensor Physics"); LastDetectedEntity = null; bool empty = true; m_detectedEntities.Clear(); //foreach (var entity in m_potentialPenetrations) Parallel.ForEach(m_potentialPenetrations, entity => { if (entity is MyVoxelBase) { //voxels are handled in different loop (becaose of planets) return; } if (ShouldDetect(entity)) { Quaternion rotation2; Vector3 posDiff; HkShape?shape2; if (GetPropertiesFromEntity(entity, ref position1, out rotation2, out posDiff, out shape2)) { if (entity.GetPhysicsBody().HavokWorld.IsPenetratingShapeShape(m_fieldShape, ref Vector3.Zero, ref rotation1, shape2.Value, ref posDiff, ref rotation2)) { if (LastDetectedEntity == null) { LastDetectedEntity = entity; } empty = false; //entities.Add(entity); var inf = MyDetectedEntityInfoHelper.Create(entity, this.OwnerId); m_detectedEntities.Add(inf); } } } }); if (DetectAsteroids) { //foreach (var entity in m_potentialVoxelPenetrations) Parallel.ForEach(m_potentialVoxelPenetrations, entity => { var voxel = entity as MyVoxelPhysics; if (voxel != null) { Vector3D localPositionMin, localPositionMax; MyVoxelCoordSystems.WorldPositionToLocalPosition(boundingBox.Min, voxel.PositionComp.WorldMatrix, voxel.PositionComp.WorldMatrixInvScaled, voxel.SizeInMetresHalf, out localPositionMin); MyVoxelCoordSystems.WorldPositionToLocalPosition(boundingBox.Max, voxel.PositionComp.WorldMatrix, voxel.PositionComp.WorldMatrixInvScaled, voxel.SizeInMetresHalf, out localPositionMax); var aabb = new BoundingBox(localPositionMin, localPositionMax); aabb.Translate(voxel.StorageMin); if (voxel.Storage.Intersect(ref aabb) != ContainmentType.Disjoint) { if (LastDetectedEntity == null) { LastDetectedEntity = entity; } empty = false; //entities.Add(entity); var inf = MyDetectedEntityInfoHelper.Create(entity, this.OwnerId); m_detectedEntities.Add(inf); } } else { Quaternion rotation2; Vector3 posDiff; HkShape?shape2; if (GetPropertiesFromEntity(entity, ref position1, out rotation2, out posDiff, out shape2)) { if (entity.GetPhysicsBody().HavokWorld.IsPenetratingShapeShape(m_fieldShape, ref Vector3.Zero, ref rotation1, shape2.Value, ref posDiff, ref rotation2)) { if (LastDetectedEntity == null) { LastDetectedEntity = entity; } empty = false; //entities.Add(entity); var inf = MyDetectedEntityInfoHelper.Create(entity, this.OwnerId); m_detectedEntities.Add(inf); } } } }); } IsActive = !empty; m_potentialPenetrations.Clear(); m_potentialVoxelPenetrations.Clear(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); }