Exemple #1
0
        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();
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        /**
         * 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();
        }