示例#1
0
        public List <MyVoxelBase> GetAllOverlappingWithSphere(ref BoundingSphereD sphere)
        {
            List <MyVoxelBase> voxels = new List <MyVoxelBase>();

            MyGamePruningStructure.GetAllVoxelMapsInSphere(ref sphere, voxels);
            return(voxels);
        }
        bool IMyShipController.TryGetPlanetElevation(MyPlanetElevation detail, out double elevation)
        {
            var blockPosition = this.PositionComp.GetPosition();

            if (!MyGravityProviderSystem.IsPositionInNaturalGravity(blockPosition))
            {
                elevation = double.PositiveInfinity;
                return(false);
            }
            var boundingBox   = PositionComp.WorldAABB;
            var nearestPlanet = MyGamePruningStructure.GetClosestPlanet(ref boundingBox);

            if (nearestPlanet == null)
            {
                elevation = double.PositiveInfinity;
                return(false);
            }

            switch (detail)
            {
            case MyPlanetElevation.Sealevel:
                elevation = ((boundingBox.Center - nearestPlanet.PositionComp.GetPosition()).Length() - nearestPlanet.AverageRadius);
                return(true);

            case MyPlanetElevation.Surface:
                var      controlledEntityPosition = CubeGrid.Physics.CenterOfMassWorld;
                Vector3D closestPoint             = nearestPlanet.GetClosestSurfacePointGlobal(ref controlledEntityPosition);
                elevation = Vector3D.Distance(closestPoint, controlledEntityPosition);
                return(true);

            default:
                throw new ArgumentOutOfRangeException("detail", detail, null);
            }
        }
示例#3
0
 public void AddToGamePruningStructure()
 {
     MyGamePruningStructure.Add(this);
     foreach (var child in Hierarchy.Children)
     {
         child.Entity.AddToGamePruningStructure();
     }
 }
示例#4
0
 public void UpdateGamePruningStructure()
 {
     MyGamePruningStructure.Move(this);
     foreach (var child in Hierarchy.Children)
     {
         child.Entity.UpdateGamePruningStructure();
     }
 }
示例#5
0
 public void RemoveFromGamePruningStructure()
 {
     MyGamePruningStructure.Remove(this);
     foreach (var child in Hierarchy.Children)
     {
         child.Entity.RemoveFromGamePruningStructure();
     }
 }
示例#6
0
            public override void UpdateBeforeSimulation100()
            {
                base.UpdateBeforeSimulation100();
                if (m_particleVectorUp == Vector3.Zero)
                {
                    if (Entity.Physics.LinearVelocity != Vector3.Zero)
                    {
                        m_particleVectorUp = -Vector3.Normalize(Entity.Physics.LinearVelocity);
                    }
                    else
                    {
                        m_particleVectorUp = Vector3.Up;
                    }
                    m_particleVectorUp.CalculatePerpendicularVector(out m_particleVectorForward);
                }

                Vector3D pos    = Entity.PositionComp.GetPosition();
                var      planet = MyGamePruningStructure.GetClosestPlanet(pos);

                MeteorStatus orig = m_meteorStatus;

                if (planet != null && planet.HasAtmosphere && planet.GetAirDensity(pos) > 0.5f)
                {
                    m_meteorStatus = MeteorStatus.InAtmosphere;
                }
                else
                {
                    m_meteorStatus = MeteorStatus.InSpace;
                }

                if (orig != m_meteorStatus && m_dustEffect != null)
                {
                    m_dustEffect.Stop();
                    m_dustEffect = null;
                }

                if (m_dustEffect != null && !InParticleVisibleRange)
                {
                    m_dustEffect.Stop();
                    m_dustEffect = null;
                }

                if (m_dustEffect == null && InParticleVisibleRange)
                {
                    if (MyParticlesManager.TryCreateParticleEffect(m_particleEffectNames[(int)m_meteorStatus], out m_dustEffect))
                    {
                        UpdateParticlePosition();
                        m_dustEffect.UserScale = Entity.PositionComp.Scale.Value;
                    }
                }

                m_soundEmitter.Update();

                if (Sync.IsServer && MySandboxGame.TotalGamePlayTimeInMilliseconds - m_timeCreated > Math.Min(MAX_TRAJECTORY_LENGTH / SPEED, MAX_TRAJECTORY_LENGTH / Entity.Physics.LinearVelocity.Length()) * 1000)
                {
                    CloseMeteorInternal();
                }
            }
示例#7
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();
            }
        }
示例#8
0
 public static void UpdateGamePruningStructure(this MyEntity thisEntity)
 {
     if (thisEntity.Parent == null && thisEntity.InScene)
     {
         //Debug.Assert(thisEntity.Parent == null, "Only top most entity should be in prunning structure");
         MyGamePruningStructure.Move(thisEntity);
         //foreach (var child in thisEntity.Hierarchy.Children) child.Container.Entity.UpdateGamePruningStructure();
     }
 }
示例#9
0
        public static void RemoveFromGamePruningStructure(this MyEntity thisEntity)
        {
            MyGamePruningStructure.Remove(thisEntity);

            //if (thisEntity.Hierarchy != null)
            //{
            //    foreach (var child in thisEntity.Hierarchy.Children)
            //        child.Container.Entity.RemoveFromGamePruningStructure();
            //}
        }
示例#10
0
        public void RemoveFromGamePruningStructure()
        {
            MyGamePruningStructure.Remove(this);

            if (Hierarchy != null)
            {
                foreach (var child in Hierarchy.Children)
                {
                    child.Container.Entity.RemoveFromGamePruningStructure();
                }
            }
        }
示例#11
0
        private void UpdateFloraAndPhysics()
        {
            BoundingBoxD box = this.PositionComp.WorldAABB;

            box.Min -= PHYSICS_SECTOR_SIZE_METERS;
            box.Max += PHYSICS_SECTOR_SIZE_METERS;
            m_entities.Clear();
            m_sectorsToKeep.Clear();

            MyGamePruningStructure.GetAllTopMostEntitiesInBox <MyEntity>(ref box, m_entities);
            Vector3I increment = m_storage.Size / (m_numCells + 1);

            ProfilerShort.Begin("Myplanet::update physics");
            foreach (var entity in m_entities)
            {
                if (entity.MarkedForClose || entity is MyPlanet || entity is MyVoxelMap)
                {
                    continue;
                }

                Vector3D position = entity.PositionComp.GetPosition();
                double   distance = (WorldMatrix.Translation - position).Length();
                if (IsInRange(position) == false)
                {
                    continue;
                }

                var predictionOffset = ComputePredictionOffset(entity);

                if (CanSpawnFlora)
                {
                    ProfilerShort.Begin("Myplanet:: spawn flora");
                    if ((predictionOffset.LengthSquared() > 0.03 || entity == MySession.LocalCharacter) && distance > m_planetInitValues.MinimumSurfaceRadius)
                    {
                        SpawnFlora(position);
                    }
                    ProfilerShort.End();
                }

                var shapeBox = entity.PositionComp.WorldAABB;
                shapeBox.Inflate(MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES);
                shapeBox.Translate(predictionOffset);
                GeneratePhysicalShapeForBox(ref increment, ref shapeBox);
            }

            if (m_entities.Count < 1 && m_hasGeneratedTexture == true)
            {
                m_storage.DataProvider.ReleaseNoiseHelpTexture();
                m_hasGeneratedTexture = false;
            }

            ProfilerShort.End();
        }
示例#12
0
 public static void AddToGamePruningStructure(this MyEntity thisEntity)
 {
     if (thisEntity.Parent != null)
     {
         return;
     }
     //Debug.Assert(thisEntity.Parent == null,"Only top most entity should be in prunning structure");
     MyGamePruningStructure.Add(thisEntity);
     //disabled for performance
     //to re enable this feature implement way to query hierarchy children
     //foreach (var child in thisEntity.Hierarchy.Children)
     //    child.Container.Entity.AddToGamePruningStructure();
 }
示例#13
0
        private void UpdatePlanetPhysics(ref BoundingBoxD box)
        {
            ProfilerShort.Begin("PlanetPhysics");
            Vector3I increment = m_storage.Size / (m_numCells + 1);

            MyGamePruningStructure.GetAproximateDynamicClustersForSize(ref box, INTRASECTOR_OBJECT_CLUSTER_SIZE, m_clustersIntersection);
            foreach (var res in m_clustersIntersection)
            {
                var shapeBox = res;
                res.Inflate(MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES);
                GeneratePhysicalShapeForBox(ref increment, ref shapeBox);
            }
            m_clustersIntersection.Clear();
            ProfilerShort.End();
        }
示例#14
0
        public MyVoxelBase GetOverlappingWithSphere(ref BoundingSphereD sphere)
        {
            MyVoxelBase ret = null;

            MyGamePruningStructure.GetAllVoxelMapsInSphere(ref sphere, m_tmpVoxelMapsList);
            foreach (var voxelMap in m_tmpVoxelMapsList)
            {
                if (voxelMap.DoOverlapSphereTest((float)sphere.Radius, sphere.Center))
                {
                    ret = voxelMap;
                    break;
                }
            }
            m_tmpVoxelMapsList.Clear();
            return(ret);
        }
        void CheckObjectInVoxel()
        {
            if (m_checkObjectInsideVoxel >= m_synchronizedFloatingObjects.Count)
            {
                m_checkObjectInsideVoxel = 0;
            }

            if (m_synchronizedFloatingObjects.Count > 0)
            {
                var floatingObjectToCheck = m_synchronizedFloatingObjects[m_checkObjectInsideVoxel];

                var localAabb   = (BoundingBoxD)floatingObjectToCheck.PositionComp.LocalAABB;
                var worldMatrix = floatingObjectToCheck.PositionComp.WorldMatrix;
                var worldAabb   = floatingObjectToCheck.PositionComp.WorldAABB;

                using (m_tmpResultList.GetClearToken())
                {
                    MyGamePruningStructure.GetAllVoxelMapsInBox(ref worldAabb, m_tmpResultList);
                    //Debug.Assert(m_tmpResultList.Count == 1, "Voxel map AABBs shouldn't overlap!");
                    foreach (var voxelMap in m_tmpResultList)
                    {
                        if (voxelMap != null && !voxelMap.MarkedForClose && !(voxelMap is MyVoxelPhysics))
                        {
                            if (voxelMap.AreAllAabbCornersInside(ref worldMatrix, localAabb))
                            {
                                floatingObjectToCheck.NumberOfFramesInsideVoxel++;

                                if (floatingObjectToCheck.NumberOfFramesInsideVoxel > MyFloatingObject.NUMBER_OF_FRAMES_INSIDE_VOXEL_TO_REMOVE)
                                {
                                    //MyLog.Default.WriteLine("Floating object " + (floatingObjectToCheck.DisplayName != null ? floatingObjectToCheck.DisplayName : floatingObjectToCheck.ToString()) + " was removed because it was inside voxel.");
                                    if (Sync.IsServer)
                                    {
                                        RemoveFloatingObject(floatingObjectToCheck);
                                    }
                                }
                            }
                            else
                            {
                                floatingObjectToCheck.NumberOfFramesInsideVoxel = 0;
                            }
                        }
                    }
                }
            }

            m_checkObjectInsideVoxel++;
        }
示例#16
0
        void CheckObjectInVoxel()
        {
            if (m_checkObjectInsideVoxel >= m_synchronizedFloatingObjects.Count)
            {
                m_checkObjectInsideVoxel = 0;
            }

            if (m_synchronizedFloatingObjects.Count > 0)
            {
                var floatingObjectToCheck = m_synchronizedFloatingObjects[m_checkObjectInsideVoxel];

                BoundingBoxD aabb = floatingObjectToCheck.PositionComp.WorldAABB;

                using (m_tmpResultList.GetClearToken())
                {
                    MyGamePruningStructure.GetAllEntitiesInBox(ref aabb, m_tmpResultList);
                    MyVoxelMap voxelMap = m_tmpResultList.Find(m_isVoxelMapPredicate) as MyVoxelMap;
                    if (voxelMap != null && !voxelMap.MarkedForClose)
                    {
                        float unused;
                        var   penetrationAmountNormalized = voxelMap.GetVoxelContentInBoundingBox(aabb, out unused);
                        var   penetrationVolume           = penetrationAmountNormalized * MyVoxelConstants.VOXEL_VOLUME_IN_METERS;
                        var   penetrationRatio            = penetrationVolume / aabb.Volume;
                        if (penetrationRatio >= 1.0f)
                        {
                            floatingObjectToCheck.NumberOfFramesInsideVoxel++;

                            if (floatingObjectToCheck.NumberOfFramesInsideVoxel > MyFloatingObject.NUMBER_OF_FRAMES_INSIDE_VOXEL_TO_REMOVE)
                            {
                                //MyLog.Default.WriteLine("Floating object " + (floatingObjectToCheck.DisplayName != null ? floatingObjectToCheck.DisplayName : floatingObjectToCheck.ToString()) + " was removed because it was inside voxel.");
                                if (Sync.IsServer)
                                {
                                    RemoveFloatingObject(floatingObjectToCheck);
                                }
                            }
                        }
                        else
                        {
                            floatingObjectToCheck.NumberOfFramesInsideVoxel = 0;
                        }
                    }
                }
            }

            m_checkObjectInsideVoxel++;
        }
示例#17
0
        private void UpdateFloraAndPhysics()
        {
            BoundingBoxD box = this.PositionComp.WorldAABB;

            box.Min -= PHYSICS_SECTOR_SIZE_METERS;
            box.Max += PHYSICS_SECTOR_SIZE_METERS;
            m_entities.Clear();
            m_sectorsToKeep.Clear();

            MyGamePruningStructure.GetAllTopMostEntitiesInBox <MyEntity>(ref box, m_entities);
            Vector3I increment = m_storage.Size / (m_numCells + 1);

            ProfilerShort.Begin("Myplanet::update physics");
            foreach (var entity in m_entities)
            {
                if (entity.MarkedForClose || entity is MyPlanet || entity is MyVoxelMap)
                {
                    continue;
                }

                Vector3D position = entity.PositionComp.GetPosition();
                double   distance = (WorldMatrix.Translation - position).Length();
                if (IsInRange(position) == false)
                {
                    continue;
                }

                var predictionOffset = ComputePredictionOffset(entity);

                if (CanSpawnFlora)
                {
                    ProfilerShort.Begin("Myplanet:: spawn flora");
                    SpawnFlora(position);
                    ProfilerShort.End();
                }

                var shapeBox = entity.PositionComp.WorldAABB;
                shapeBox.Inflate(MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES);
                shapeBox.Translate(predictionOffset);
                GeneratePhysicalShapeForBox(ref increment, ref shapeBox);
            }

            ProfilerShort.End();
        }
示例#18
0
        public override void UpdateAfterSimulation100()
        {
            base.UpdateAfterSimulation100();

            if (CanSpawnFlora && MySession.LocalHumanPlayer != null)
            {
                Vector3D playerPosition = MySession.LocalHumanPlayer.GetPosition();
                if (IsInRange(playerPosition) && !MySandboxGame.IsDedicated)
                {
                    GenerateFloraGraphics(playerPosition);
                }
            }

            m_sectorsToRemove.Clear();
            if (m_physicsShapes != null)
            {
                foreach (var physicsShape in m_physicsShapes)
                {
                    m_entities.Clear();
                    BoundingBoxD box = physicsShape.Value.PositionComp.WorldAABB;
                    box.Min -= 2.0 * box.HalfExtents;
                    box.Max += 2.0 * box.HalfExtents;

                    MyGamePruningStructure.GetAllTopMostEntitiesInBox <MyEntity>(ref box, m_entities);

                    if (m_entities.Count < 2)
                    {
                        m_sectorsToRemove.Add(physicsShape.Key);
                    }
                }
            }

            foreach (var shapeToRemove in m_sectorsToRemove)
            {
                MyVoxelPhysics physics;
                if (m_physicsShapes.TryGetValue(shapeToRemove, out physics))
                {
                    physics.Close();
                }
                m_physicsShapes.Remove(shapeToRemove);
            }
            m_sectorsToRemove.Clear();
        }
示例#19
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);
        }
示例#20
0
        private static void StartSurprise(object senderEvent)
        {
            BoundingSphereD sphere = new BoundingSphereD(new Vector3D(-18.75f, -2.5f, -1.25f), 2);

            m_getEntities.Clear();
            MyGamePruningStructure.GetAllEntitiesInSphere(ref sphere, m_getEntities);

            m_spawnMedical = null;
            foreach (var entity in m_getEntities)
            {
                m_spawnMedical = entity as MyMedicalRoom;
                if (m_spawnMedical != null)
                {
                    m_spawnMedical.OnClose += delegate { m_spawnMedical = null; };
                    break;
                }
            }

            m_started = true;
        }
        bool IMyShipController.TryGetPlanetPosition(out Vector3D position)
        {
            var blockPosition = this.PositionComp.GetPosition();

            if (!MyGravityProviderSystem.IsPositionInNaturalGravity(blockPosition))
            {
                position = Vector3D.Zero;
                return(false);
            }
            var boundingBox   = PositionComp.WorldAABB;
            var nearestPlanet = MyGamePruningStructure.GetClosestPlanet(ref boundingBox);

            if (nearestPlanet == null)
            {
                position = Vector3D.Zero;
                return(false);
            }
            position = nearestPlanet.PositionComp.GetPosition();
            return(true);
        }
示例#22
0
 private void CheckObjectInVoxel()
 {
     if (m_checkObjectInsideVoxel >= m_synchronizedFloatingObjects.Count)
     {
         m_checkObjectInsideVoxel = 0;
     }
     if (m_synchronizedFloatingObjects.Count > 0)
     {
         MyFloatingObject obj2        = m_synchronizedFloatingObjects[m_checkObjectInsideVoxel];
         BoundingBoxD     localAABB   = obj2.PositionComp.LocalAABB;
         MatrixD          worldMatrix = obj2.PositionComp.WorldMatrix;
         BoundingBoxD     worldAABB   = obj2.PositionComp.WorldAABB;
         using (m_tmpResultList.GetClearToken <MyVoxelBase>())
         {
             MyGamePruningStructure.GetAllVoxelMapsInBox(ref worldAABB, m_tmpResultList);
             foreach (MyVoxelBase base2 in m_tmpResultList)
             {
                 if (base2 == null)
                 {
                     continue;
                 }
                 if (!base2.MarkedForClose && !(base2 is MyVoxelPhysics))
                 {
                     if (!base2.AreAllAabbCornersInside(ref worldMatrix, localAABB))
                     {
                         obj2.NumberOfFramesInsideVoxel = 0;
                         continue;
                     }
                     obj2.NumberOfFramesInsideVoxel++;
                     if ((obj2.NumberOfFramesInsideVoxel > 5) && Sync.IsServer)
                     {
                         RemoveFloatingObject(obj2);
                     }
                 }
             }
         }
     }
     m_checkObjectInsideVoxel++;
 }
示例#23
0
 public static void AddToGamePruningStructure(this MyEntity thisEntity)
 {
     MyGamePruningStructure.Add(thisEntity);
 }
示例#24
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();
        }
示例#25
0
 public static void RemoveFromGamePruningStructure(this MyEntity thisEntity)
 {
     MyGamePruningStructure.Remove(thisEntity);
 }
示例#26
0
 public static void UpdateGamePruningStructure(this MyEntity thisEntity)
 {
     MyGamePruningStructure.Move(thisEntity);
 }
示例#27
0
        public MyDetectedEntityInfo Raycast(double distance, Vector3D direction)
        {
            if (Vector3D.IsZero(direction))
            {
                throw new ArgumentOutOfRangeException("direction", "Direction cannot be 0,0,0");
            }

            //mods can disable raycast on a block by setting the distance limit to 0 (-1 means infinite)
            if (distance <= 0 || (BlockDefinition.RaycastDistanceLimit > -1 && distance > BlockDefinition.RaycastDistanceLimit))
            {
                return(new MyDetectedEntityInfo());
            }

            if (AvailableScanRange < distance || !this.CheckIsWorking())
            {
                return(new MyDetectedEntityInfo());
            }

            AvailableScanRange -= distance;

            var startPos  = this.WorldMatrix.Translation;
            var targetPos = startPos + direction * distance;

            //try a physics raycast first
            //very accurate, but very slow
            List <MyPhysics.HitInfo> hits = new List <MyPhysics.HitInfo>();

            MyPhysics.CastRay(startPos, targetPos, hits);

            foreach (var hit in hits)
            {
                var entity = (MyEntity)hit.HkHitInfo.GetHitEntity();
                if (entity == this)
                {
                    continue;
                }

                m_lastRay = new RaycastInfo()
                {
                    Distance = distance, Start = startPos, End = targetPos, Hit = hit.Position
                };
                return(MyDetectedEntityInfoHelper.Create(entity, this.OwnerId, hit.Position));
            }

            //long-distance planet scanning
            //fastest way is to intersect planet bounding boxes then treat the planet as a sphere
            LineD line   = new LineD(startPos, targetPos);
            var   voxels = new List <MyLineSegmentOverlapResult <MyVoxelBase> >();

            MyGamePruningStructure.GetVoxelMapsOverlappingRay(ref line, voxels);

            foreach (var result in voxels)
            {
                var planet = result.Element as MyPlanet;
                if (planet == null)
                {
                    continue;
                }

                double distCenter = Vector3D.DistanceSquared(this.PositionComp.GetPosition(), planet.PositionComp.GetPosition());
                var    gravComp   = planet.Components.Get <MyGravityProviderComponent>();
                if (gravComp == null)
                {
                    continue;
                }

                if (!gravComp.IsPositionInRange(startPos) && distCenter > planet.MaximumRadius * planet.MaximumRadius)
                {
                    var boundingSphere = new BoundingSphereD(planet.PositionComp.GetPosition(), planet.MaximumRadius);
                    var rayd           = new RayD(startPos, direction);
                    var intersection   = boundingSphere.Intersects(rayd);

                    if (!intersection.HasValue)
                    {
                        continue;
                    }

                    if (distance < intersection.Value)
                    {
                        continue;
                    }

                    var hitPos = startPos + direction * intersection.Value;
                    m_lastRay = new RaycastInfo()
                    {
                        Distance = distance, Start = startPos, End = targetPos, Hit = hitPos
                    };
                    return(MyDetectedEntityInfoHelper.Create(result.Element, this.OwnerId, hitPos));
                }

                //if the camera is inside gravity, query voxel storage
                if (planet.RootVoxel.Storage == null)
                {
                    continue;
                }
                var start = Vector3D.Transform(line.From, planet.PositionComp.WorldMatrixInvScaled);
                start += planet.SizeInMetresHalf;
                var end = Vector3D.Transform(line.To, planet.PositionComp.WorldMatrixInvScaled);
                end += planet.SizeInMetresHalf;

                var voxRay = new LineD(start, end);

                double startOffset;
                double endOffset;
                if (!planet.RootVoxel.Storage.DataProvider.Intersect(ref voxRay, out startOffset, out endOffset))
                {
                    continue;
                }

                var from = voxRay.From;
                voxRay.From = from + voxRay.Direction * voxRay.Length * startOffset;
                voxRay.To   = from + voxRay.Direction * voxRay.Length * endOffset;

                start = voxRay.From - planet.SizeInMetresHalf;
                start = Vector3D.Transform(start, planet.PositionComp.WorldMatrix);

                m_lastRay = new RaycastInfo()
                {
                    Distance = distance, Start = startPos, End = targetPos, Hit = start
                };
                return(MyDetectedEntityInfoHelper.Create(result.Element, this.OwnerId, start));
            }

            m_lastRay = new RaycastInfo()
            {
                Distance = distance, Start = startPos, End = targetPos, Hit = null
            };
            return(new MyDetectedEntityInfo());
        }
示例#28
0
 public void GetAllOverlappingWithSphere(ref BoundingSphereD sphere, List <MyVoxelBase> voxels)
 {
     MyGamePruningStructure.GetAllVoxelMapsInSphere(ref sphere, voxels);
 }
示例#29
0
        private bool TestPlacement()
        {
            if (MySession.ControlledEntity != null &&
                (MySession.GetCameraControllerEnum() == MyCameraControllerEnum.Entity || MySession.GetCameraControllerEnum() == MyCameraControllerEnum.ThirdPersonSpectator))
            {
                for (int i = 0; i < m_previewVoxelMaps.Count; ++i)
                {
                    var aabb = m_previewVoxelMaps[i].PositionComp.WorldAABB;

                    using (m_tmpResultList.GetClearToken())
                    {
                        MyGamePruningStructure.GetAllEntitiesInBox(ref aabb, m_tmpResultList);

                        foreach (var entity in m_tmpResultList)
                        {
                            m_tmpResultHashset.Add(entity.GetTopMostParent());
                        }

                        foreach (var entity in m_tmpResultHashset)
                        {
                            //ignore asteroids
                            if (entity is MyVoxelBase)
                            {
                                continue;
                            }

                            //ignore stations
                            if (entity is MyCubeGrid)
                            {
                                var grid = entity as MyCubeGrid;
                                if (grid.IsStatic)
                                {
                                    continue;
                                }
                            }

                            switch (m_previewVoxelMaps[i].GetVoxelRangeTypeInBoundingBox(entity.PositionComp.WorldAABB))
                            {
                            case MyVoxelRangeType.EMPTY:
                                break;

                            case MyVoxelRangeType.MIXED:
                            {
                                m_tmpResultList.Clear();
                                m_tmpResultHashset.Clear();
                                return(false);
                            }
                            break;

                            case MyVoxelRangeType.FULL:
                            {
                                m_tmpResultList.Clear();
                                m_tmpResultHashset.Clear();
                                return(false);
                            }
                            break;

                            default:
                                throw new InvalidBranchException();
                                break;
                            }
                        }
                        m_tmpResultHashset.Clear();
                    }
                }
            }
            return(true);
        }