コード例 #1
0
        private static void SectorPhysicsCallback(MyPlanet me, ref MyPlanetSectorId id, ref Vector3D position)
        {
            double   distance;
            Vector3D pos;
            MyPlanetEnvironmentSector sector;

            if (!GetOrCreateSector(me, ref id, ref position, me.Ranges.SECTOR_LOD0_SQUARED, out pos, out distance, out sector))
            {
                return;
            }

            me.SectorsScanned.Hit();
            if (distance <= me.Ranges.SECTOR_LOD0_KEEP_SQUARED)
            {
                using (sector.AcquireStatusLock())
                {
                    MyPlanetSectorOperation ops = sector.PendingOperations;

                    if (sector.HasPhysics || ops.HasFlags(MyPlanetSectorOperation.SpawnPhysics))
                    {
                        ops &= ~(MyPlanetSectorOperation.Close | MyPlanetSectorOperation.ClosePhysics | MyPlanetSectorOperation.CloseDetails);
                    }
                    else if (distance <= me.Ranges.SECTOR_LOD0_SQUARED)
                    {
                        ops |= MyPlanetSectorOperation.SpawnPhysics | MyPlanetSectorOperation.SpawnDetails;
                        if (!sector.Loaded)
                        {
                            ops |= MyPlanetSectorOperation.Spawn;
                        }
                        ops &= ~(MyPlanetSectorOperation.Close | MyPlanetSectorOperation.ClosePhysics | MyPlanetSectorOperation.CloseDetails);
                    }
                    sector.PendingOperations = ops;
                }
            }
        }
コード例 #2
0
        public MyPlanetEnvironmentSector GetSector(ref MyPlanetSectorId id)
        {
            MyPlanetEnvironmentSector sect;

            m_planetEnvironmentSectors.TryGetValue(id, out sect);
            return(sect);
        }
コード例 #3
0
        public void GetSectorIdAt(Vector3 localPosition, out MyPlanetSectorId id)
        {
            id = new MyPlanetSectorId();

            Vector3D local = localPosition;

            MyCubemapHelpers.ProjectToNearestFace(ref local, out localPosition);
            MyCubemapHelpers.GetCubeFaceDirection(ref localPosition, out id.Direction);
            id.Direction = -id.Direction;

            localPosition = (localPosition + 1f) * .5f;

            id.Position = new Vector3S(localPosition.X * m_numSectors, localPosition.Y * m_numSectors, localPosition.Z * m_numSectors);
            if (id.Position.X == m_numSectors)
            {
                id.Position.X = (short)(m_numSectors - 1);
            }
            if (id.Position.Y == m_numSectors)
            {
                id.Position.Y = (short)(m_numSectors - 1);
            }
            if (id.Position.Z == m_numSectors)
            {
                id.Position.Z = (short)(m_numSectors - 1);
            }
        }
コード例 #4
0
        private void ReadPlanetSectors(BitStream stream)
        {
            if (stream.ReadInt32() != 0x42424242)
            {
                throw new BitStreamException("Wrong magic when reading planet sectors from client state.");
            }

            int count = stream.ReadInt32();

            for (int i = 0; i < count; i++)
            {
                long p = stream.ReadInt64();

                long sectorid;

                HashSet <MyPlanetSectorId> sectids = new HashSet <MyPlanetSectorId>();

                KnownSectors.Add(p, sectids);

                while (true)
                {
                    sectorid = stream.ReadInt64();
                    if (sectorid == -1)
                    {
                        break;
                    }

                    MyPlanetSectorId id;
                    MyPlanetSectorId.Unpack64(sectorid, out id);
                    sectids.Add(id);
                }
            }
        }
コード例 #5
0
        public MyProceduralLogicalSector TryGetLogicalSector(int lod, int logicalx, int logicaly)
        {
            MyProceduralLogicalSector sector;

            m_sectors.TryGetValue(MyPlanetSectorId.MakeSectorId(logicalx, logicaly, ProviderId, lod), out sector);

            return(sector);
        }
コード例 #6
0
        public void SectorIdToBoundingBox(ref MyPlanetSectorId id, out BoundingBoxD sectorBox)
        {
            Vector3I modifiedPosition = id.Position - id.Direction;
            Vector3D min = (modifiedPosition * m_sectorSize);

            min += -m_sectorFaceSize * .5;
            Vector3D max = min + m_sectorSize;

            sectorBox = new BoundingBoxD(min, max);
        }
コード例 #7
0
        public void SectorIdToWorldBoundingBox(ref MyPlanetSectorId id, out BoundingBoxD sectorBox)
        {
            Vector3I modifiedPosition = id.Position - id.Direction;
            Vector3D min = modifiedPosition * m_sectorSize;

            min += WorldMatrix.Translation - m_sectorFaceSize * .5;
            Vector3D max = min + (float)m_sectorSize;

            sectorBox = new BoundingBoxD(min, max);
        }
コード例 #8
0
        private MyProceduralLogicalSector GetLogicalSector(int x, int y, int localLod)
        {
            var key = MyPlanetSectorId.MakeSectorId(x, y, ProviderId, localLod);
            MyProceduralLogicalSector sector;

            if (!m_sectors.TryGetValue(key, out sector))
            {
                MyObjectBuilder_ProceduralEnvironmentSector sectorBuilder;
                m_savedSectors.TryGetValue(key, out sectorBuilder);
                sector    = new MyProceduralLogicalSector(this, x, y, localLod, sectorBuilder);
                sector.Id = key;

                m_sectors[key] = sector;
            }
            return(sector);
        }
コード例 #9
0
        private static readonly int PLANET_SECTOR_IDLE_WORK_CYCLE = 50; // maximum number of cancelled sector requests to process


        /**
         * Find or create sector for scanning
         */
        private static bool GetOrCreateSector(MyPlanet me, ref MyPlanetSectorId id, ref Vector3D position, double minDistance, out Vector3D pos, out double distance, out MyPlanetEnvironmentSector sector)
        {
            if (!me.m_planetEnvironmentSectors.TryGetValue(id, out sector))
            {
                BoundingBoxD box;
                me.SectorIdToBoundingBox(ref id, out box);
                pos = box.Center;
                var posf = (Vector3)pos;

                pos = me.GetClosestSurfacePointLocal(ref posf);
                Vector3D.DistanceSquared(ref position, ref pos, out distance);

                if (distance > minDistance)
                {
                    return(false);
                }

                // Build allocator if necessary
                if (me.m_planetSectorsPool == null)
                {
                    me.m_planetSectorsPool = new MyDynamicObjectPool <MyPlanetEnvironmentSector>(SECTOR_POOL_SIZE);
                }

                // Try to get from cache if possible
                sector = me.m_planetSectorsPool.Allocate();
                sector.Init(ref id, me);

                me.m_planetEnvironmentSectors.Add(id, sector);
                me.SectorsCreated.Hit();
            }
            else
            {
                if (sector.IsClosed)
                {
                    sector.Init(ref id, me);
                }

                pos = sector.LocalSurfaceCenter;
                Vector3D.DistanceSquared(ref position, ref pos, out distance);
            }
            return(true);
        }
コード例 #10
0
        public void CloseView(MyProceduralDataView view)
        {
            var lod = view.Lod / LodFactor;

            for (int y = view.Start.Y; y <= view.End.Y; y++)
            {
                for (int x = view.Start.X; x <= view.End.X; x++)
                {
                    var key = MyPlanetSectorId.MakeSectorId(x, y, ProviderId, lod);

                    var sector = m_sectors[key];
                    sector.Viewers.Remove(view);
                    sector.UpdateMinLod();

                    if (sector.Viewers.Count == 0 && !sector.ServerOwned)
                    {
                        CloseSector(sector);
                    }
                }
            }
        }
コード例 #11
0
        public void SectorIdToBoundingBox(ref MyPlanetSectorId id, out BoundingBoxD sectorBox)
        {
            Vector3I modifiedPosition = id.Position - id.Direction;
            Vector3D min = (modifiedPosition * m_sectorSize);
            min += -m_sectorFaceSize * .5;
            Vector3D max = min + m_sectorSize;

            sectorBox = new BoundingBoxD(min, max);
        }
コード例 #12
0
        // Iterate over sector boxes in a range.
        private void ForEachSector(Vector3 localPosition, float range, SectorIteration iterator)
        {
            Vector3 sectorPosition;

            LocalPositionToSectorCube(localPosition, out sectorPosition);

            Vector3D referencePoint = localPosition;

            SectorScans.Hit();

            Vector3 rangev = new Vector3(range);

            BoundingBox  probe = new BoundingBox(sectorPosition - rangev, sectorPosition + rangev);
            BoundingBoxI inter = m_sectorBox.Intersect(probe);

            Vector3S min = new Vector3S(inter.Min);
            Vector3S max = new Vector3S(inter.Max);


            // Iterate over each face of the cube that is in the intersection.

            MyPlanetSectorId id = new MyPlanetSectorId();

            // Front
            if (inter.Min.Z == m_sectorBox.Min.Z)
            {
                id.Direction  = Vector3B.Backward;
                id.Position.Z = min.Z;
                for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++)
                {
                    for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++)
                    {
                        iterator(this, ref id, ref referencePoint);
                    }
                }
            }

            // Back
            if (inter.Max.Z == m_sectorBox.Max.Z)
            {
                id.Direction  = Vector3B.Forward;
                id.Position.Z = max.Z;
                for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++)
                {
                    for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++)
                    {
                        iterator(this, ref id, ref referencePoint);
                    }
                }
            }

            // Right
            if (inter.Min.X == m_sectorBox.Min.X)
            {
                id.Direction  = Vector3B.Right;
                id.Position.X = min.X;
                for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++)
                {
                    for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++)
                    {
                        iterator(this, ref id, ref referencePoint);
                    }
                }
            }

            // Left
            if (inter.Max.X == m_sectorBox.Max.X)
            {
                id.Direction  = Vector3B.Left;
                id.Position.X = max.X;
                for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++)
                {
                    for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++)
                    {
                        iterator(this, ref id, ref referencePoint);
                    }
                }
            }

            // Up
            if (inter.Min.Y == m_sectorBox.Min.Y)
            {
                id.Direction  = Vector3B.Up;
                id.Position.Y = min.Y;
                for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++)
                {
                    for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++)
                    {
                        iterator(this, ref id, ref referencePoint);
                    }
                }
            }

            // Down
            if (inter.Max.Y == m_sectorBox.Max.Y)
            {
                id.Direction  = Vector3B.Down;
                id.Position.Y = max.Y;
                for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++)
                {
                    for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++)
                    {
                        iterator(this, ref id, ref referencePoint);
                    }
                }
            }
        }
コード例 #13
0
        private static readonly int PLANET_SECTOR_IDLE_WORK_CYCLE = 50; // maximum number of cancelled sector requests to process


        /**
         * Find or create sector for scanning
         */
        private static bool GetOrCreateSector(MyPlanet me, ref MyPlanetSectorId id, ref Vector3D position, double minDistance, out Vector3D pos, out double distance, out MyPlanetEnvironmentSector sector)
        {
            if (!me.m_planetEnvironmentSectors.TryGetValue(id, out sector))
            {
                BoundingBoxD box;
                me.SectorIdToBoundingBox(ref id, out box);
                pos = box.Center;
                var posf = (Vector3)pos;

                pos = me.GetClosestSurfacePointLocal(ref posf);
                Vector3D.DistanceSquared(ref position, ref pos, out distance);

                if (distance > minDistance) return false;

                // Build allocator if necessary
                if (me.m_planetSectorsPool == null)
                    me.m_planetSectorsPool = new MyDynamicObjectPool<MyPlanetEnvironmentSector>(SECTOR_POOL_SIZE);

                // Try to get from cache if possible
                sector = me.m_planetSectorsPool.Allocate();
                sector.Init(ref id, me);

                me.m_planetEnvironmentSectors.Add(id, sector);
                me.SectorsCreated.Hit();
            }
            else
            {
                if (sector.IsClosed)
                    sector.Init(ref id, me);

                pos = sector.LocalSurfaceCenter;
                Vector3D.DistanceSquared(ref position, ref pos, out distance);
            }
            return true;
        }
コード例 #14
0
 public void OnEnviromentSectorItemRemoved(ref MyPlanetSectorId id)
 {
 }
コード例 #15
0
        private static void SectorPhysicsCallback(MyPlanet me, ref MyPlanetSectorId id, ref Vector3D position)
        {
            double distance;
            Vector3D pos;
            MyPlanetEnvironmentSector sector;

            if (!GetOrCreateSector(me, ref id, ref position, me.Ranges.SECTOR_LOD0_SQUARED, out pos, out distance, out sector)) return;

            me.SectorsScanned.Hit();
            if (distance <= me.Ranges.SECTOR_LOD0_KEEP_SQUARED)
            {
                using (sector.AcquireStatusLock())
                {
                    MyPlanetSectorOperation ops = sector.PendingOperations;

                    if (sector.HasPhysics || ops.HasFlags(MyPlanetSectorOperation.SpawnPhysics))
                    {
                        ops &= ~(MyPlanetSectorOperation.Close | MyPlanetSectorOperation.ClosePhysics | MyPlanetSectorOperation.CloseDetails);
                    }
                    else if (distance <= me.Ranges.SECTOR_LOD0_SQUARED)
                    {
                        ops |= MyPlanetSectorOperation.SpawnPhysics | MyPlanetSectorOperation.SpawnDetails;
                        if (!sector.Loaded)
                            ops |= MyPlanetSectorOperation.Spawn;
                        ops &= ~(MyPlanetSectorOperation.Close | MyPlanetSectorOperation.ClosePhysics | MyPlanetSectorOperation.CloseDetails);
                    }
                    sector.PendingOperations = ops;
                }
            }

        }
コード例 #16
0
        public void SectorIdToWorldBoundingBox(ref MyPlanetSectorId id, out BoundingBoxD sectorBox)
        {
            Vector3I modifiedPosition = id.Position - id.Direction;
            Vector3D min = modifiedPosition * m_sectorSize;
            min += WorldMatrix.Translation - m_sectorFaceSize * .5;
            Vector3D max = min + (float)m_sectorSize;

            sectorBox = new BoundingBoxD(min, max);
        }
コード例 #17
0
        public void GetSectorIdAt(Vector3 localPosition, out MyPlanetSectorId id)
        {
            id = new MyPlanetSectorId();

            Vector3D local = localPosition;
            MyCubemapHelpers.ProjectToNearestFace(ref local, out localPosition);
            MyCubemapHelpers.GetCubeFaceDirection(ref localPosition, out id.Direction);
            id.Direction = -id.Direction;

            localPosition = (localPosition + 1f) * .5f;

            id.Position = new Vector3S(localPosition.X * m_numSectors, localPosition.Y * m_numSectors, localPosition.Z * m_numSectors);
            if (id.Position.X == m_numSectors) id.Position.X = (short)(m_numSectors - 1);
            if (id.Position.Y == m_numSectors) id.Position.Y = (short)(m_numSectors - 1);
            if (id.Position.Z == m_numSectors) id.Position.Z = (short)(m_numSectors - 1);
        }
コード例 #18
0
        // Iterate over sector boxes in a range.
        private void ForEachSector(Vector3 localPosition, float range, SectorIteration iterator)
        {
            Vector3 sectorPosition;
            LocalPositionToSectorCube(localPosition, out sectorPosition);

            Vector3D referencePoint = localPosition;

            SectorScans.Hit();

            Vector3 rangev = new Vector3(range);

            BoundingBox probe = new BoundingBox(sectorPosition - rangev, sectorPosition + rangev);
            BoundingBoxI inter = m_sectorBox.Intersect(probe);

            Vector3S min = new Vector3S(inter.Min);
            Vector3S max = new Vector3S(inter.Max);


            // Iterate over each face of the cube that is in the intersection.

            MyPlanetSectorId id = new MyPlanetSectorId();

            // Front
            if (inter.Min.Z == m_sectorBox.Min.Z)
            {
                id.Direction = Vector3B.Backward;
                id.Position.Z = min.Z;
                for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++)
                    for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++)
                        iterator(this, ref id, ref referencePoint);
            }

            // Back
            if (inter.Max.Z == m_sectorBox.Max.Z)
            {
                id.Direction = Vector3B.Forward;
                id.Position.Z = max.Z;
                for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++)
                    for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++)
                        iterator(this, ref id, ref referencePoint);
            }

            // Right
            if (inter.Min.X == m_sectorBox.Min.X)
            {
                id.Direction = Vector3B.Right;
                id.Position.X = min.X;
                for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++)
                    for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++)
                        iterator(this, ref id, ref referencePoint);
            }

            // Left
            if (inter.Max.X == m_sectorBox.Max.X)
            {
                id.Direction = Vector3B.Left;
                id.Position.X = max.X;
                for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++)
                    for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++)
                        iterator(this, ref id, ref referencePoint);
            }

            // Up
            if (inter.Min.Y == m_sectorBox.Min.Y)
            {
                id.Direction = Vector3B.Up;
                id.Position.Y = min.Y;
                for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++)
                    for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++)
                        iterator(this, ref id, ref referencePoint);
            }

            // Down
            if (inter.Max.Y == m_sectorBox.Max.Y)
            {
                id.Direction = Vector3B.Down;
                id.Position.Y = max.Y;
                for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++)
                    for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++)
                        iterator(this, ref id, ref referencePoint);
            }
        }
コード例 #19
0
 public MyPlanetEnvironmentSector GetSector(ref MyPlanetSectorId id)
 {
     MyPlanetEnvironmentSector sect;
     m_planetEnvironmentSectors.TryGetValue(id, out sect);
     return sect;
 }
コード例 #20
0
        public unsafe MyEnvironmentDataView GetItemView(int lod, ref Vector2I start, ref Vector2I end, ref Vector3D localOrigin)
        {
            var localLod   = lod / LodFactor;
            var logicalLod = lod % LodFactor;

            start >>= (localLod * LodFactor);
            end   >>= (localLod * LodFactor);

            MyProceduralDataView view = new MyProceduralDataView(this, lod, ref start, ref end);

            var lcount = (end - start + 1).Size();

            view.SectorOffsets      = new List <int>(lcount);
            view.LogicalSectors     = new List <MyLogicalEnvironmentSectorBase>(lcount);
            view.IntraSectorOffsets = new List <int>(lcount);

            // First round, calculate offsets and find any missing sectors.
            int offset = 0;

            for (int y = start.Y; y <= end.Y; y++)
            {
                for (int x = start.X; x <= end.X; x++)
                {
                    var sector = GetLogicalSector(x, y, localLod);

                    if (sector.MinimumScannedLod != logicalLod)
                    {
                        sector.ScanItems(logicalLod);
                    }

                    sector.Viewers.Add(view);
                    sector.UpdateMinLod();

                    view.SectorOffsets.Add(offset);
                    view.LogicalSectors.Add(sector);
                    offset += sector.ItemCountForLod[logicalLod];
                    view.IntraSectorOffsets.Add(0);
                }
            }

            // Allocate item list.
            view.Items = new List <ItemInfo>(offset);

            int offsetIndex = 0;

            for (int y = start.Y; y <= end.Y; y++)
            {
                for (int x = start.X; x <= end.X; x++)
                {
                    MyProceduralLogicalSector sector = m_sectors[MyPlanetSectorId.MakeSectorId(x, y, ProviderId, localLod)];

                    int itemCnt = sector.ItemCountForLod[logicalLod];

                    offset = view.SectorOffsets[offsetIndex++];

                    Vector3 centerOffset = sector.WorldPos - localOrigin;

                    fixed(ItemInfo *viewItems = view.Items.GetInternalArray())
                    fixed(ItemInfo * sectorItems = sector.Items.GetInternalArray())
                    for (int i = 0; i < itemCnt; ++i)
                    {
                        int vi = i + offset;     // view index

                        viewItems[vi].Position = sectorItems[i].Position + centerOffset;

                        // TODO: Memcpy?
                        viewItems[vi].DefinitionIndex = sectorItems[i].DefinitionIndex;
                        viewItems[vi].ModelIndex      = sectorItems[i].ModelIndex;
                        viewItems[vi].Rotation        = sectorItems[i].Rotation;
                    }
                }
            }

            view.Items.SetSize(view.Items.Capacity);

            if ((m_sectorsToRaise.Count > 0 || m_sectorsToRaise.Count > 0) && !m_sectorsQueued)
            {
                m_sectorsQueued = true;

                Parallel.ScheduleForThread(m_raiseCallback, null, MySandboxGame.Static.UpdateThread);
            }
            return(view);
        }