public override void UpdateAfterSimulation100() { //Debug.Assert(MyExternalReplicable.FindByObject(this) != null, "Planet replicable not found, but it should be there"); base.UpdateAfterSimulation100(); if (m_physicsShapes != null) { ProfilerShort.Begin("Study shapes to remove"); foreach (var physicsShape in m_physicsShapes) { BoundingBoxD box; if (physicsShape.Value != null) { box = physicsShape.Value.PositionComp.WorldAABB; box.Min -= box.HalfExtents; box.Max += box.HalfExtents; } else { Vector3 min = (Vector3)physicsShape.Key * PHYSICS_SECTOR_SIZE_METERS + PositionLeftBottomCorner; box = new BoundingBoxD(min, min + PHYSICS_SECTOR_SIZE_METERS); } m_entities.Clear(); MyGamePruningStructure.GetTopMostEntitiesInBox(ref box, m_entities); bool keep = false; foreach (var entity in m_entities) { if (entity.Physics != null && !entity.Physics.IsStatic) { keep = true; } } if (!keep) { m_sectorsPhysicsToRemove.Add(physicsShape.Key); } } foreach (var shapeToRemove in m_sectorsPhysicsToRemove) { MyVoxelPhysics physics; if (m_physicsShapes.TryGetValue(shapeToRemove, out physics)) { if (physics != null) { physics.Close(); } } m_physicsShapes.Remove(shapeToRemove); } m_sectorsPhysicsToRemove.Clear(); ProfilerShort.End(); } }
private bool TestPlacement() { if (MySession.Static.ControlledEntity != null && (MySession.Static.GetCameraControllerEnum() == MyCameraControllerEnum.Entity || MySession.Static.GetCameraControllerEnum() == MyCameraControllerEnum.ThirdPersonSpectator || MySession.Static.GetCameraControllerEnum() == MyCameraControllerEnum.Spectator)) { for (int i = 0; i < m_previewVoxelMaps.Count; ++i) { var aabb = m_previewVoxelMaps[i].PositionComp.WorldAABB; using (m_tmpResultList.GetClearToken()) { MyGamePruningStructure.GetTopMostEntitiesInBox(ref aabb, m_tmpResultList); if (TestPlacement(m_tmpResultList) == false) { return(false); } } } if (m_planetMode) { for (int i = 0; i < m_copiedVoxelMaps.Count; ++i) { MyObjectBuilder_Planet builder = m_copiedVoxelMaps[i] as MyObjectBuilder_Planet; if (builder != null) { using (m_tmpResultList.GetClearToken()) { BoundingSphereD sphere = new BoundingSphereD(m_pastePosition, builder.Radius * 1.1f); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref sphere, m_tmpResultList); if (TestPlacement(m_tmpResultList) == false) { return(false); } } } } } } return(true); }
/** * Scan sectors arround entities in planet and update them accordingly. */ private void UpdateSectors(bool serial, ref BoundingBoxD box) { // Prepare sectors for update foreach (var sp in m_planetEnvironmentSectors) { sp.Value.PrepareForUpdate(); } // Find all entities, spawn physics arround ships and players, spawn graphics arround cameras ProfilerShort.Begin("Update Sectors"); MyGamePruningStructure.GetTopMostEntitiesInBox(ref box, m_entities, MyEntityQueryType.Dynamic); foreach (var entity in m_entities) { // entity is MyPlanet || entity is MyVoxelMap || entity is MyEnvironmentItems should all be static // If any of that changes keep in mind they must be skipped // It is also important to avoid adding physics where there are no clusters, otherwise the entities won't get activated properly. if (entity.MarkedForClose || entity.Physics == null || entity.Physics.IsStatic) { continue; } Vector3 position = entity.PositionComp.GetPosition() - WorldMatrix.Translation; double distanceSq = position.LengthSquared(); var predictionOffset = ComputePredictionOffset(entity); if (CanSpawnFlora && RUN_SECTORS && distanceSq >= Ranges.PLANET_PHYSICS_SCAN_MIN && distanceSq <= Ranges.PLANET_PHYSICS_SCAN_MAX) { ProfilerShort.Begin("EntitySpawn"); position += predictionOffset; MyPlanetSectorId sectId; GetSectorIdAt(position, out sectId); MyPlanetEnvironmentSector sector; if (!m_planetEnvironmentSectors.TryGetValue(sectId, out sector) || !sector.HasEntity) { ForEachSector(position, SECTOR_PHYSICS_EXTENT + SECTOR_KEEP_INFLATE, SectorPhysicsDelegate); } if ((sector != null || m_planetEnvironmentSectors.TryGetValue(sectId, out sector)) && !sector.ShouldClose) { // Make sure other entities in same sector do not cause new scans. sector.HasEntity = true; } ProfilerShort.End(); } } if (CanSpawnFlora && RUN_SECTORS) { ProfilerShort.Begin("MainCameraSpawn"); Vector3D position = MySector.MainCamera.Position - WorldMatrix.Translation; double distanceSq = position.LengthSquared(); if (distanceSq > Ranges.PLANET_GRAPHICS_SCAN_MIN && distanceSq < Ranges.PLANET_GRAPHICS_SCAN_MAX) { ForEachSector(position, SECTOR_LOD1_EXTENT + SECTOR_KEEP_INFLATE, SectorGraphicsDelegate); } ProfilerShort.End(); // Remove sectors marked for removal and enqueue sectors with pending operations. ProfilerShort.Begin("Recycle Sectors"); m_sectorsToRemove.Clear(); foreach (var sp in m_planetEnvironmentSectors) { var sector = sp.Value; using (sector.AcquireStatusLock()) { sector.EvaluateOperations(); if (sector.ShouldClose) { if ((sector.PendingOperations & MyPlanetEnvironmentSector.SERIAL_OPERATIONS_MASK) != 0) { // This will close the sector here if necessary. sector.DoSerialWork(false); } Debug.Assert(sector.IsClosed); m_planetSectorsPool.Deallocate(sector); m_sectorsToRemove.Add(sp.Key); } else if (sector.ParallelPending) { if (!sector.IsQueuedParallel && sector.ParallelPending) { sector.IsQueuedParallel = true; SectorsToWorkParallel.Enqueue(sector); } } else if (sector.SerialPending && !sector.IsQueuedSerial) { SectorsToWorkSerial.Enqueue(sector); sector.IsQueuedSerial = true; } } } // Remove from the dictionary all the sectors that were closed foreach (var sector in m_sectorsToRemove) { m_planetEnvironmentSectors.Remove(sector); } ProfilerShort.End(); ProfilerShort.Begin("Schedule Tasks"); // Lastly we start the sectors worker if any work is left in the queue. if (!m_sectorsWorking) { if (SectorsToWorkParallel.Count > 0) { m_sectorsWorking = true; if (serial) { ParallelWorkCallback(); SerialWorkCallback(); } else { Parallel.Start(m_parallelWorkDelegate, m_serialWorkDelegate); } } else { SerialWorkCallback(); } } ProfilerShort.End(); } ProfilerShort.End(); WrapCounters(); }