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; } } }
public MyPlanetEnvironmentSector GetSector(ref MyPlanetSectorId id) { MyPlanetEnvironmentSector sect; m_planetEnvironmentSectors.TryGetValue(id, out sect); return(sect); }
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); } }
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); } } }
public MyProceduralLogicalSector TryGetLogicalSector(int lod, int logicalx, int logicaly) { MyProceduralLogicalSector sector; m_sectors.TryGetValue(MyPlanetSectorId.MakeSectorId(logicalx, logicaly, ProviderId, lod), out sector); return(sector); }
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); }
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); }
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); }
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); }
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); } } } }
// 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); } } } }
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; }
public void OnEnviromentSectorItemRemoved(ref MyPlanetSectorId id) { }
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; } } }
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); }
// 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); } }
public MyPlanetEnvironmentSector GetSector(ref MyPlanetSectorId id) { MyPlanetEnvironmentSector sect; m_planetEnvironmentSectors.TryGetValue(id, out sect); return sect; }
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); }