private static void Load(Stream stream, out MyStorageBase storage, out bool isOldFormat) { ProfilerShort.Begin("MyStorageBase.Load"); try { isOldFormat = false; string storageType = stream.ReadString(); int version = stream.Read7BitEncodedInt(); if (storageType == STORAGE_TYPE_NAME_CELL) { storage = Compatibility_LoadCellStorage(version, stream); isOldFormat = true; } else if (storageType == STORAGE_TYPE_NAME_OCTREE) { storage = new MyOctreeStorage(); storage.LoadInternal(version, stream, ref isOldFormat); storage.m_geometry.Init(storage); } else { throw new InvalidBranchException(); } } finally { ProfilerShort.End(); } }
internal void ReadFrom(MyOctreeStorage.ChunkHeader header, Stream stream) { if (m_octree == null) { Debug.Assert(header.ChunkType == MyOctreeStorage.ChunkTypeEnum.ContentLeafOctree || header.ChunkType == MyOctreeStorage.ChunkTypeEnum.MaterialLeafOctree); m_octree = new MySparseOctree(0, header.ChunkType == MyOctreeStorage.ChunkTypeEnum.ContentLeafOctree ? MyOctreeNode.ContentFilter : MyOctreeNode.MaterialFilter); } m_octree.ReadFrom(header, stream); }
private void RemoveAllAsteroids(MyGuiControlButton sender) { MyCsgShapePlanetShapeAttributes shapeAttributes = new MyCsgShapePlanetShapeAttributes(); shapeAttributes.Seed = 12345; shapeAttributes.Diameter = 60; shapeAttributes.Radius = 60 / 2.0f; shapeAttributes.DeviationScale = 0.003f; float maxHillSize = 10; float planetHalfDeviation = (shapeAttributes.Diameter * shapeAttributes.DeviationScale) / 2.0f; float hillHalfDeviation = planetHalfDeviation * maxHillSize; float canyonHalfDeviation = 1; float averagePlanetRadius = shapeAttributes.Radius - hillHalfDeviation; float outerRadius = averagePlanetRadius + hillHalfDeviation; float innerRadius = averagePlanetRadius - canyonHalfDeviation; float atmosphereRadius = MathHelper.Max(outerRadius, averagePlanetRadius * 1.08f); float minPlanetRadius = MathHelper.Min(innerRadius, averagePlanetRadius - planetHalfDeviation * 2 * 2.5f); MyCsgShapePlanetMaterialAttributes materialAttributes = new MyCsgShapePlanetMaterialAttributes(); materialAttributes.OreStartDepth = innerRadius; materialAttributes.OreEndDepth = innerRadius; materialAttributes.OreEndDepth = MathHelper.Max(materialAttributes.OreEndDepth, 0); materialAttributes.OreStartDepth = MathHelper.Max(materialAttributes.OreStartDepth, 0); materialAttributes.OreProbabilities = new MyOreProbability[10]; for (int i = 0; i < 10; ++i) { materialAttributes.OreProbabilities[i] = new MyOreProbability(); materialAttributes.OreProbabilities[i].OreName = "Ice_01"; materialAttributes.OreProbabilities[i].CummulativeProbability = 0.0f; } shapeAttributes.AveragePlanetRadius = averagePlanetRadius; IMyStorageDataProvider dataProvider = MyCompositeShapeProvider.CreatePlanetShape(0, ref shapeAttributes, maxHillSize, ref materialAttributes); IMyStorage storage = new MyOctreeStorage(dataProvider, MyVoxelCoordSystems.FindBestOctreeSize(shapeAttributes.Diameter)); MyStorageDataCache cache = new MyStorageDataCache(); cache.Resize(storage.Size); Vector3I start = Vector3I.Zero; Vector3I end = storage.Size; storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 1, ref start, ref end); dataProvider.ReleaseHeightMaps(); }
public void ReadFrom(ref MyOctreeStorage.ChunkHeader header, System.IO.Stream stream, ref bool isOldFormat) { m_data.Version = stream.ReadInt64(); m_data.Seed = stream.ReadInt64(); m_data.Radius = stream.ReadDouble(); string generator = stream.ReadString(); if (m_data.Version != STORAGE_VERSION) { isOldFormat = true; } var def = MyDefinitionManager.Static.GetDefinition<MyPlanetGeneratorDefinition>(MyStringHash.GetOrCompute(generator)); if (def == null) throw new Exception(String.Format("Cannot load planet generator definition for subtype '{0}'.", generator)); Generator = def; Init(); }
/// <summary> /// Returns count of changed voxels amount according to the given base storage. This storage is simply modified data of the base storage /// (note that premodified base storage is not supported - base storage must be default unganged one). /// </summary> public ulong CountChangedVoxelsAmount(MyOctreeStorage baseStorage) { ulong count = CountChangedVoxelsAmount(baseStorage, m_treeHeight, m_contentNodes, m_contentLeaves, Vector3I.Zero); return count; }
private static ulong CountChangedVoxelsAmount( MyOctreeStorage baseStorage, int lodIdx, Dictionary <UInt64, MyOctreeNode> nodes, Dictionary <UInt64, IMyOctreeLeafNode> leaves, Vector3I lodCoord) { var currentCell = new MyCellCoord(lodIdx, lodCoord); var leafKey = currentCell.PackId64(); IMyOctreeLeafNode leaf; if (leaves.TryGetValue(leafKey, out leaf)) { if (!leaf.ReadOnly && currentCell.Lod == 0) { // Read data from leaf var rangeEnd = new Vector3I(LeafSizeInVoxels - 1); m_temporaryCache.Resize(Vector3I.Zero, rangeEnd); leaf.ReadRange(m_temporaryCache, ref Vector3I.Zero, 0, ref Vector3I.Zero, ref rangeEnd); // Read data from base storage var minLeafVoxel = currentCell.CoordInLod * LeafSizeInVoxels; var maxLeafVoxel = minLeafVoxel + (LeafSizeInVoxels - 1); m_temporaryCache2.Resize(minLeafVoxel, maxLeafVoxel); baseStorage.ReadRange(m_temporaryCache2, MyStorageDataTypeFlags.Content, currentCell.Lod, ref minLeafVoxel, ref maxLeafVoxel); byte[] origData = m_temporaryCache2.Data; byte[] currData = m_temporaryCache.Data; Debug.Assert(currData.Length == origData.Length); if (currData.Length != origData.Length) { return(0); } ulong countChangedVoxels = 0; for (int i = (int)MyStorageDataTypeEnum.Content; i < m_temporaryCache.SizeLinear; i += m_temporaryCache.StepLinear) { countChangedVoxels += (ulong)Math.Abs(currData[i] - origData[i]); } return(countChangedVoxels); } } else { currentCell.Lod -= 1; var nodeKey = currentCell.PackId64(); var node = nodes[nodeKey]; var childBase = lodCoord << 1; Vector3I childOffset; if (node.HasChildren) { ulong count = 0; for (int i = 0; i < MyOctreeNode.CHILD_COUNT; i++) { if (node.HasChild(i)) { ComputeChildCoord(i, out childOffset); currentCell.CoordInLod = childBase + childOffset; count += CountChangedVoxelsAmount(baseStorage, currentCell.Lod, nodes, leaves, currentCell.CoordInLod); } } return(count); } else { return((ulong)((MyOctreeNode.CHILD_COUNT << (currentCell.Lod * 3)) * LeafSizeInVoxels * LeafSizeInVoxels * LeafSizeInVoxels * MyVoxelConstants.VOXEL_CONTENT_FULL)); } } return(0); }
private void CreatePlanet(int seed, float size) { Vector3D pos = MySector.MainCamera.Position + MySector.MainCamera.ForwardVector * size * 3 - new Vector3D(size); MyPlanetGeneratorDefinition planetDefinition = MyDefinitionManager.Static.GetDefinition<MyPlanetGeneratorDefinition>(MyStringHash.GetOrCompute(m_selectedPlanetName)); MyPlanetStorageProvider provider = new MyPlanetStorageProvider(); provider.Init(seed, planetDefinition, size / 2f); IMyStorage storage = new MyOctreeStorage(provider, provider.StorageSize); float minHillSize = provider.Radius * planetDefinition.HillParams.Min; float maxHillSize = provider.Radius * planetDefinition.HillParams.Max; float averagePlanetRadius = provider.Radius; float outerRadius = averagePlanetRadius + maxHillSize; float innerRadius = averagePlanetRadius + minHillSize; float atmosphereRadius = planetDefinition.AtmosphereSettings.HasValue && planetDefinition.AtmosphereSettings.Value.Scale > 1f ? 1 + planetDefinition.AtmosphereSettings.Value.Scale : 1.75f; atmosphereRadius *= provider.Radius; var planet = new MyPlanet(); planet.EntityId = MyRandom.Instance.NextLong(); MyPlanetInitArguments planetInitArguments; planetInitArguments.StorageName = "test"; planetInitArguments.Storage = storage; planetInitArguments.PositionMinCorner = pos; planetInitArguments.Radius = provider.Radius; planetInitArguments.AtmosphereRadius = atmosphereRadius; planetInitArguments.MaxRadius = outerRadius; planetInitArguments.MinRadius = innerRadius; planetInitArguments.HasAtmosphere = planetDefinition.HasAtmosphere; planetInitArguments.AtmosphereWavelengths = Vector3.Zero; planetInitArguments.GravityFalloff = planetDefinition.GravityFalloffPower; planetInitArguments.MarkAreaEmpty = true; planetInitArguments.AtmosphereSettings = planetDefinition.AtmosphereSettings.HasValue ? planetDefinition.AtmosphereSettings.Value : MyAtmosphereSettings.Defaults(); planetInitArguments.SurfaceGravity = planetDefinition.SurfaceGravity; planetInitArguments.AddGps = false; planetInitArguments.SpherizeWithDistance = true; planetInitArguments.Generator = planetDefinition; planetInitArguments.UserCreated = true; planet.Init(planetInitArguments); m_lastAsteroidInfo = new SpawnAsteroidInfo() { Asteroid = null, RandomSeed = seed, Position = Vector3D.Zero, IsProcedural = true, ProceduralRadius = size, }; MyClipboardComponent.Static.ActivateVoxelClipboard(planet.GetObjectBuilder(), storage, MySector.MainCamera.ForwardVector, (storage.Size * 0.5f).Length()); }
private static MyStorageBase Compatibility_LoadCellStorage(int fileVersion, Stream stream) { // Size of this voxel map (in voxels) Vector3I tmpSize; tmpSize.X = stream.ReadInt32(); tmpSize.Y = stream.ReadInt32(); tmpSize.Z = stream.ReadInt32(); var storage = new MyOctreeStorage(null, tmpSize); // Size of data cell in voxels. Has to be the same as current size specified by our constants. Vector3I cellSize; cellSize.X = stream.ReadInt32(); cellSize.Y = stream.ReadInt32(); cellSize.Z = stream.ReadInt32(); Trace.Assert(cellSize.X == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Y == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Z == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS); Vector3I cellsCount = tmpSize / cellSize; Dictionary<byte, MyVoxelMaterialDefinition> mappingTable = null; if (fileVersion == STORAGE_TYPE_VERSION_CELL) { // loading material names->index mappings mappingTable = Compatibility_LoadMaterialIndexMapping(stream); } else if (fileVersion == 1) { // material name->index mappings were not saved in this version } var startCoord = Vector3I.Zero; var endCoord = new Vector3I(MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); var cache = new MyStorageData(); cache.Resize(Vector3I.Zero, endCoord); Vector3I cellCoord; for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++) { MyVoxelRangeType cellType = (MyVoxelRangeType)stream.ReadByteNoAlloc(); // Cell's are FULL by default, therefore we don't need to change them switch (cellType) { case MyVoxelRangeType.EMPTY: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_EMPTY); break; case MyVoxelRangeType.FULL: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_FULL); break; case MyVoxelRangeType.MIXED: Vector3I v; for (v.X = 0; v.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.X++) { for (v.Y = 0; v.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Y++) { for (v.Z = 0; v.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Z++) { cache.Content(ref v, stream.ReadByteNoAlloc()); } } } break; } startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref startCoord, ref endCoord); } } } try { // In case materials are not saved, catch any exceptions caused by this. // Read materials and indestructible for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++) { bool isSingleMaterial = stream.ReadByteNoAlloc() == 1; MyVoxelMaterialDefinition material = null; if (isSingleMaterial) { material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable); cache.ClearMaterials(material.Index); } else { byte indestructibleContent; Vector3I voxelCoordInCell; for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++) { for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++) { for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++) { material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable); indestructibleContent = stream.ReadByteNoAlloc(); cache.Material(ref voxelCoordInCell, material.Index); } } } } startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); storage.WriteRange(cache, MyStorageDataTypeFlags.Material, ref startCoord, ref endCoord); } } } } catch (EndOfStreamException ex) { MySandboxGame.Log.WriteLine(ex); } return storage; }
void IMyStorageDataProvider.ReadFrom(ref MyOctreeStorage.ChunkHeader header, Stream stream, ref bool isOldFormat) { m_state.Version = stream.ReadUInt32(); if (m_state.Version != CURRENT_VERSION) { // Making sure this gets saved in new format and serialized cache holding old format is discarded. isOldFormat = true; } m_state.Generator = stream.ReadInt32(); m_state.Seed = stream.ReadInt32(); m_state.Size = stream.ReadFloat(); if (m_state.Version == VERSION_WITHOUT_PLANETS) { m_state.IsPlanet = 0; } else { m_state.IsPlanet = stream.ReadUInt32(); } if (m_state.IsPlanet != 0) { int numMaterials = stream.ReadInt32(); m_materialLayers = new MyMaterialLayer[numMaterials]; for (int i = 0; i < numMaterials; ++i) { m_materialLayers[i] = new MyMaterialLayer(); m_materialLayers[i].StartHeight = stream.ReadFloat(); m_materialLayers[i].EndHeight = stream.ReadFloat(); m_materialLayers[i].MaterialName = stream.ReadString(); m_materialLayers[i].StartAngle = stream.ReadFloat(); m_materialLayers[i].EndAngle = stream.ReadFloat(); m_materialLayers[i].HeightStartDeviation = stream.ReadFloat(); m_materialLayers[i].AngleStartDeviation = stream.ReadFloat(); m_materialLayers[i].HeightEndDeviation = stream.ReadFloat(); m_materialLayers[i].AngleEndDeviation = stream.ReadFloat(); } m_shapeAttributes.Seed = stream.ReadInt32(); m_shapeAttributes.Radius = stream.ReadFloat(); m_shapeAttributes.NoiseFrequency = stream.ReadFloat(); m_shapeAttributes.DeviationScale = stream.ReadFloat(); m_shapeAttributes.NormalNoiseFrequency = stream.ReadFloat(); m_shapeAttributes.LayerDeviationNoiseFreqeuncy = stream.ReadFloat(); m_shapeAttributes.LayerDeviationSeed = stream.ReadInt32(); m_hillAttributes.BlendTreshold = stream.ReadFloat(); m_hillAttributes.Treshold = stream.ReadFloat(); m_hillAttributes.SizeRatio = stream.ReadFloat(); m_hillAttributes.NumNoises = stream.ReadInt32(); m_hillAttributes.Frequency = stream.ReadFloat(); m_canyonAttributes.BlendTreshold = stream.ReadFloat(); m_canyonAttributes.Treshold = stream.ReadFloat(); m_canyonAttributes.SizeRatio = stream.ReadFloat(); m_canyonAttributes.NumNoises = stream.ReadInt32(); m_canyonAttributes.Frequency = stream.ReadFloat(); MyCompositeShapes.PlanetGenerators[m_state.Generator](ref m_shapeAttributes,ref m_hillAttributes, ref m_canyonAttributes, m_materialLayers, out m_data); } else { MyCompositeShapes.AsteroidGenerators[m_state.Generator](m_state.Seed, m_state.Size, out m_data); } m_state.Version = CURRENT_VERSION; }
void IMyStorageDataProvider.ReadFrom(ref MyOctreeStorage.ChunkHeader header, Stream stream, ref bool isOldFormat) { m_state.Version = stream.ReadUInt32(); if (m_state.Version != CURRENT_VERSION) { // Making sure this gets saved in new format and serialized cache holding old format is discarded. isOldFormat = true; m_state.Version = CURRENT_VERSION; } m_state.Generator = stream.ReadInt32(); m_state.Seed = stream.ReadInt32(); m_state.Size = stream.ReadFloat(); MyCompositeShapes.AsteroidGenerators[m_state.Generator](m_state.Seed, m_state.Size, out m_data); }
void ShrinkVMap() { Vector3I min, max; m_selectedVoxel.GetFilledStorageBounds(out min, out max); MyVoxelMapStorageDefinition def = null; if (m_selectedVoxel.AsteroidName != null) MyDefinitionManager.Static.TryGetVoxelMapStorageDefinition(m_selectedVoxel.AsteroidName, out def); var origSize = m_selectedVoxel.Size; var tightSize = max - min + 1; var storage = new MyOctreeStorage(null, tightSize); var offset = (storage.Size - tightSize)/2 + 1; MyStorageData data = new MyStorageData(); data.Resize(tightSize); m_selectedVoxel.Storage.ReadRange(data, MyStorageDataTypeFlags.ContentAndMaterial, 0, min, max); min = offset; max = offset + tightSize - 1; storage.WriteRange(data, MyStorageDataTypeFlags.ContentAndMaterial, ref min, ref max); var newMap = MyWorldGenerator.AddVoxelMap(m_selectedVoxel.StorageName, storage, m_selectedVoxel.WorldMatrix); m_selectedVoxel.Close(); newMap.Save = true; if (def == null) { ShowAlert("Voxel map {0} does not have a definition, the shrunk voxel map will be saved with the world instead.", m_selectedVoxel.StorageName); } else { byte[] cVmapData; newMap.Storage.Save(out cVmapData); using (var ostream = MyFileSystem.OpenWrite(Path.Combine(MyFileSystem.ContentPath, def.StorageFile), FileMode.Open)) { ostream.Write(cVmapData, 0, cVmapData.Length); } var notification = new MyHudNotification(MyStringId.GetOrCompute("Voxel prefab {0} updated succesfuly (size changed from {1} to {2})."), 4000); notification.SetTextFormatArguments(def.Id.SubtypeName, origSize, storage.Size); MyHud.Notifications.Add(notification); } }
public static MyPlanet AddPlanet(string storageName, Vector3D positionMinCorner, int seed, float size, long entityId = 0) { if(MyFakes.ENABLE_PLANETS == false) { return null; } m_materialsByOreType.Clear(); m_oreProbalities.Clear(); m_spawningMaterials.Clear(); m_organicMaterials.Clear(); DictionaryValuesReader<MyDefinitionId, MyPlanetGeneratorDefinition> planetDefinitions = MyDefinitionManager.Static.GetPlanetsGeneratorsDefinitions(); foreach (var planetGeneratorDefinition in planetDefinitions) { if (planetGeneratorDefinition.Diameter.Min <= size && size <= planetGeneratorDefinition.Diameter.Max) { var random = MyRandom.Instance; using (var stateToken = random.PushSeed(seed)) { BuildOreProbabilities(planetGeneratorDefinition); FillMaterialCollections(); MyCsgShapePlanetShapeAttributes shapeAttributes = new MyCsgShapePlanetShapeAttributes(); shapeAttributes.Seed = seed; shapeAttributes.Diameter = size; shapeAttributes.Radius = size / 2.0f; shapeAttributes.LayerDeviationSeed = random.Next(); shapeAttributes.LayerDeviationNoiseFrequency = random.NextFloat(10.0f, 500.0f); shapeAttributes.NoiseFrequency = random.NextFloat(planetGeneratorDefinition.StructureRatio.Min, planetGeneratorDefinition.StructureRatio.Max); shapeAttributes.NormalNoiseFrequency = random.NextFloat(planetGeneratorDefinition.NormalNoiseValue.Min, planetGeneratorDefinition.NormalNoiseValue.Max); shapeAttributes.DeviationScale = random.NextFloat(planetGeneratorDefinition.Deviation.Min, planetGeneratorDefinition.Deviation.Max); MyCsgShapePlanetHillAttributes hillAttributes = FillValues(planetGeneratorDefinition.HillParams, random); MyCsgShapePlanetHillAttributes canyonAttributes = FillValues(planetGeneratorDefinition.CanyonParams, random); float planetHalfDeviation = (shapeAttributes.Diameter * shapeAttributes.DeviationScale) / 2.0f; float averagePlanetRadius = shapeAttributes.Diameter * (1 - shapeAttributes.DeviationScale * hillAttributes.SizeRatio) / 2.0f; float hillHalfDeviation = planetHalfDeviation * hillAttributes.SizeRatio; float canyonHalfDeviation = planetHalfDeviation * canyonAttributes.SizeRatio; float outerRadius = averagePlanetRadius + hillHalfDeviation * 1.5f; float innerRadius = averagePlanetRadius - canyonHalfDeviation * 2.5f; float atmosphereRadius = MathHelper.Max(outerRadius, averagePlanetRadius * 1.06f); float minPlanetRadius = MathHelper.Min(innerRadius, averagePlanetRadius - planetHalfDeviation * 2 * 2.5f); MyCsgShapePlanetMaterialAttributes materialAttributes = new MyCsgShapePlanetMaterialAttributes(); materialAttributes.OreStartDepth = innerRadius - random.NextFloat(planetGeneratorDefinition.MaterialsMinDeph.Min, planetGeneratorDefinition.MaterialsMinDeph.Max); materialAttributes.OreEndDepth = innerRadius - random.NextFloat(planetGeneratorDefinition.MaterialsMaxDeph.Min, planetGeneratorDefinition.MaterialsMaxDeph.Max); materialAttributes.OreEndDepth = MathHelper.Max(materialAttributes.OreEndDepth, 0); materialAttributes.OreStartDepth = MathHelper.Max(materialAttributes.OreStartDepth, 0); bool isHostile = random.NextFloat(0, 1) < planetGeneratorDefinition.HostilityProbability; MyMaterialLayer[] materialLayers = CreateMaterialLayers(planetGeneratorDefinition, isHostile, random, averagePlanetRadius, hillHalfDeviation, canyonHalfDeviation, ref outerRadius, ref innerRadius); materialAttributes.Layers = materialLayers; materialAttributes.OreProbabilities = new MyOreProbability[m_oreProbalities.Count]; for(int i =0; i <m_oreProbalities.Count;++i) { materialAttributes.OreProbabilities[i] = m_oreProbalities[i]; materialAttributes.OreProbabilities[i].CummulativeProbability /= m_oreCummulativeProbability; } IMyStorage storage = new MyOctreeStorage(MyCompositeShapeProvider.CreatePlanetShape(0, ref shapeAttributes, ref hillAttributes, ref canyonAttributes, ref materialAttributes), FindBestOctreeSize(size)); float redAtmosphereShift = isHostile ? random.NextFloat(planetGeneratorDefinition.HostileAtmosphereColorShift.R.Min, planetGeneratorDefinition.HostileAtmosphereColorShift.R.Max) : 0; float greenAtmosphereShift = isHostile ? random.NextFloat(planetGeneratorDefinition.HostileAtmosphereColorShift.G.Min, planetGeneratorDefinition.HostileAtmosphereColorShift.G.Max) : 0; float blueAtmosphereShift = isHostile ? random.NextFloat(planetGeneratorDefinition.HostileAtmosphereColorShift.B.Min, planetGeneratorDefinition.HostileAtmosphereColorShift.B.Max) : 0; Vector3 atmosphereWavelengths = new Vector3(0.650f + redAtmosphereShift, 0.570f + greenAtmosphereShift, 0.475f + blueAtmosphereShift); atmosphereWavelengths.X = MathHelper.Clamp(atmosphereWavelengths.X, 0.1f, 1.0f); atmosphereWavelengths.Y = MathHelper.Clamp(atmosphereWavelengths.Y, 0.1f, 1.0f); atmosphereWavelengths.Z = MathHelper.Clamp(atmosphereWavelengths.Z, 0.1f, 1.0f); float gravityFalloff = random.NextFloat(planetGeneratorDefinition.GravityFalloffPower.Min, planetGeneratorDefinition.GravityFalloffPower.Max); var voxelMap = new MyPlanet(); voxelMap.EntityId = entityId; MyPlanetInitArguments planetInitArguments; planetInitArguments.StorageName = storageName; planetInitArguments.Storage = storage; planetInitArguments.PositionMinCorner = positionMinCorner; planetInitArguments.AveragePlanetRadius = averagePlanetRadius; planetInitArguments.AtmosphereRadius = atmosphereRadius; planetInitArguments.MaximumHillRadius = averagePlanetRadius + hillHalfDeviation; planetInitArguments.MinimumSurfaceRadius = minPlanetRadius; planetInitArguments.HasAtmosphere = planetGeneratorDefinition.HasAtmosphere; planetInitArguments.AtmosphereWavelengths = atmosphereWavelengths; planetInitArguments.MaxOxygen = isHostile ? 0.0f : 1.0f; planetInitArguments.GravityFalloff = gravityFalloff; planetInitArguments.MarkAreaEmpty = false; voxelMap.Init(planetInitArguments); MyEntities.Add(voxelMap); m_materialsByOreType.Clear(); m_oreProbalities.Clear(); m_spawningMaterials.Clear(); m_organicMaterials.Clear(); return voxelMap; } } } return null; }
void IMyStorageDataProvider.ReadFrom(ref MyOctreeStorage.ChunkHeader header, Stream stream, ref bool isOldFormat) { m_state.Version = stream.ReadUInt32(); if (m_state.Version != CURRENT_VERSION) { // Making sure this gets saved in new format and serialized cache holding old format is discarded. isOldFormat = true; } m_state.Generator = stream.ReadInt32(); m_state.Seed = stream.ReadInt32(); m_state.Size = stream.ReadFloat(); if (m_state.Version == VERSION_WITHOUT_PLANETS) { m_state.IsPlanet = 0; } else { m_state.IsPlanet = stream.ReadUInt32(); } if (m_state.IsPlanet != 0) { m_materialAttributes.ReadFrom(stream); m_shapeAttributes.ReadFrom(stream); m_hillAttributes.ReadFrom(stream); m_canyonAttributes.ReadFrom(stream); MyCompositeShapes.PlanetGenerators[m_state.Generator](ref m_shapeAttributes, ref m_hillAttributes, ref m_canyonAttributes, ref m_materialAttributes, out m_data); } else { MyCompositeShapes.AsteroidGenerators[m_state.Generator](m_state.Seed, m_state.Size, out m_data); } m_state.Version = CURRENT_VERSION; }
private static MyPlanet CreatePlanet(string storageName, string planetName, ref Vector3D positionMinCorner, int seed, float size, long entityId, ref MyPlanetGeneratorDefinition generatorDef, bool addGPS,bool userCreated = false) { if (MyFakes.ENABLE_PLANETS == false) { return null; } var random = MyRandom.Instance; using (MyRandom.Instance.PushSeed(seed)) { MyPlanetStorageProvider provider = new MyPlanetStorageProvider(); provider.Init(seed, generatorDef, size/2f); IMyStorage storage = new MyOctreeStorage(provider, provider.StorageSize); float minHillSize = provider.Radius * generatorDef.HillParams.Min; float maxHillSize = provider.Radius * generatorDef.HillParams.Max; float averagePlanetRadius = provider.Radius; float outerRadius = averagePlanetRadius + maxHillSize; float innerRadius = averagePlanetRadius + minHillSize; float atmosphereRadius = generatorDef.AtmosphereSettings.HasValue && generatorDef.AtmosphereSettings.Value.Scale > 1f ? 1 + generatorDef.AtmosphereSettings.Value.Scale : 1.75f; atmosphereRadius *= provider.Radius; float redAtmosphereShift = random.NextFloat(generatorDef.HostileAtmosphereColorShift.R.Min, generatorDef.HostileAtmosphereColorShift.R.Max); float greenAtmosphereShift = random.NextFloat(generatorDef.HostileAtmosphereColorShift.G.Min, generatorDef.HostileAtmosphereColorShift.G.Max); float blueAtmosphereShift = random.NextFloat(generatorDef.HostileAtmosphereColorShift.B.Min, generatorDef.HostileAtmosphereColorShift.B.Max); Vector3 atmosphereWavelengths = new Vector3(0.650f + redAtmosphereShift, 0.570f + greenAtmosphereShift, 0.475f + blueAtmosphereShift); atmosphereWavelengths.X = MathHelper.Clamp(atmosphereWavelengths.X, 0.1f, 1.0f); atmosphereWavelengths.Y = MathHelper.Clamp(atmosphereWavelengths.Y, 0.1f, 1.0f); atmosphereWavelengths.Z = MathHelper.Clamp(atmosphereWavelengths.Z, 0.1f, 1.0f); var planet = new MyPlanet(); planet.EntityId = entityId; MyPlanetInitArguments planetInitArguments; planetInitArguments.StorageName = storageName; planetInitArguments.Storage = storage; planetInitArguments.PositionMinCorner = positionMinCorner; planetInitArguments.Radius = provider.Radius; planetInitArguments.AtmosphereRadius = atmosphereRadius; planetInitArguments.MaxRadius = outerRadius; planetInitArguments.MinRadius = innerRadius; planetInitArguments.HasAtmosphere = generatorDef.HasAtmosphere; planetInitArguments.AtmosphereWavelengths = atmosphereWavelengths; planetInitArguments.GravityFalloff = generatorDef.GravityFalloffPower; planetInitArguments.MarkAreaEmpty = true; planetInitArguments.AtmosphereSettings = generatorDef.AtmosphereSettings.HasValue ? generatorDef.AtmosphereSettings.Value : MyAtmosphereSettings.Defaults(); planetInitArguments.SurfaceGravity = generatorDef.SurfaceGravity; planetInitArguments.AddGps = addGPS; planetInitArguments.SpherizeWithDistance = true; planetInitArguments.Generator = generatorDef; planetInitArguments.UserCreated = userCreated; planetInitArguments.InitializeComponents = true; planet.Init(planetInitArguments); MyEntities.Add(planet); MyEntities.RaiseEntityCreated(planet); return planet; } return null; }
private static ulong CountChangedVoxelsAmount( MyOctreeStorage baseStorage, int lodIdx, Dictionary<UInt64, MyOctreeNode> nodes, Dictionary<UInt64, IMyOctreeLeafNode> leaves, Vector3I lodCoord) { var currentCell = new MyCellCoord(lodIdx, lodCoord); var leafKey = currentCell.PackId64(); IMyOctreeLeafNode leaf; if (leaves.TryGetValue(leafKey, out leaf)) { if (!leaf.ReadOnly && currentCell.Lod == 0) { // Read data from leaf var rangeEnd = new Vector3I(LeafSizeInVoxels - 1); m_temporaryCache.Resize(Vector3I.Zero, rangeEnd); leaf.ReadRange(m_temporaryCache, ref Vector3I.Zero, 0, ref Vector3I.Zero, ref rangeEnd); // Read data from base storage var minLeafVoxel = currentCell.CoordInLod * LeafSizeInVoxels; var maxLeafVoxel = minLeafVoxel + (LeafSizeInVoxels - 1); m_temporaryCache2.Resize(minLeafVoxel, maxLeafVoxel); baseStorage.ReadRange(m_temporaryCache2, MyStorageDataTypeFlags.Content, currentCell.Lod, ref minLeafVoxel, ref maxLeafVoxel); byte[] origData = m_temporaryCache2.Data; byte[] currData = m_temporaryCache.Data; Debug.Assert(currData.Length == origData.Length); if (currData.Length != origData.Length) return 0; ulong countChangedVoxels = 0; for (int i = (int)MyStorageDataTypeEnum.Content; i < m_temporaryCache.SizeLinear; i += m_temporaryCache.StepLinear) { countChangedVoxels += (ulong)Math.Abs(currData[i] - origData[i]); } return countChangedVoxels; } } else { currentCell.Lod -= 1; var nodeKey = currentCell.PackId64(); var node = nodes[nodeKey]; var childBase = lodCoord << 1; Vector3I childOffset; if (node.HasChildren) { ulong count = 0; for (int i = 0; i < MyOctreeNode.CHILD_COUNT; i++) { if (node.HasChild(i)) { ComputeChildCoord(i, out childOffset); currentCell.CoordInLod = childBase + childOffset; count += CountChangedVoxelsAmount(baseStorage, currentCell.Lod, nodes, leaves, currentCell.CoordInLod); } } return count; } else { return (ulong)((MyOctreeNode.CHILD_COUNT << (currentCell.Lod * 3)) * LeafSizeInVoxels * LeafSizeInVoxels * LeafSizeInVoxels * MyVoxelConstants.VOXEL_CONTENT_FULL); } } return 0; }
public override void GenerateObjects(List<MyObjectSeed> objectsList, HashSet<MyObjectSeedParams> existingObjectsSeeds) { ProfilerShort.Begin("GenerateObjects"); foreach (var objectSeed in objectsList) { if (objectSeed.Params.Generated || existingObjectsSeeds.Contains(objectSeed.Params)) continue; objectSeed.Params.Generated = true; using (MyRandom.Instance.PushSeed(GetObjectIdSeed(objectSeed))) { switch (objectSeed.Params.Type) { case MyObjectSeedType.Asteroid: ProfilerShort.Begin("Asteroid"); var bbox = objectSeed.BoundingVolume; MyGamePruningStructure.GetAllVoxelMapsInBox(ref bbox, m_tmpVoxelMapsList); String storageName = string.Format("Asteroid_{0}_{1}_{2}_{3}_{4}", objectSeed.CellId.X, objectSeed.CellId.Y, objectSeed.CellId.Z, objectSeed.Params.Index, objectSeed.Params.Seed); bool exists = false; foreach (var voxelMap in m_tmpVoxelMapsList) { if (voxelMap.StorageName == storageName) { existingObjectsSeeds.Add(objectSeed.Params); exists = true; break; } } if (!exists) { var provider = MyCompositeShapeProvider.CreateAsteroidShape(objectSeed.Params.Seed, objectSeed.Size, MySession.Static.Settings.VoxelGeneratorVersion); MyStorageBase storage = new MyOctreeStorage(provider, GetAsteroidVoxelSize(objectSeed.Size)); var voxelMap = MyWorldGenerator.AddVoxelMap(storageName, storage, objectSeed.BoundingVolume.Center - VRageMath.MathHelper.GetNearestBiggerPowerOfTwo(objectSeed.Size) / 2, GetAsteroidEntityId(storageName)); if (voxelMap != null) { voxelMap.Save = false; MyVoxelBase.StorageChanged OnStorageRangeChanged = null; OnStorageRangeChanged = delegate(MyVoxelBase voxel,Vector3I minVoxelChanged, Vector3I maxVoxelChanged, MyStorageDataTypeFlags changedData) { voxelMap.Save = true; voxelMap.RangeChanged -= OnStorageRangeChanged; }; voxelMap.RangeChanged += OnStorageRangeChanged; } } m_tmpVoxelMapsList.Clear(); ProfilerShort.End(); break; case MyObjectSeedType.EncounterAlone: case MyObjectSeedType.EncounterSingle: ProfilerShort.Begin("Encounter"); bool doSpawn = true; foreach (var start in MySession.Static.Scenario.PossiblePlayerStarts) { Vector3D? startPos = start.GetStartingLocation(); if (!startPos.HasValue) startPos = Vector3D.Zero; if ((startPos.Value - objectSeed.BoundingVolume.Center).LengthSquared() < (15000 * 15000)) doSpawn = false; } if (doSpawn) MyEncounterGenerator.PlaceEncounterToWorld(objectSeed.BoundingVolume, objectSeed.Params.Seed, objectSeed.Params.Type); ProfilerShort.End(); break; default: throw new InvalidBranchException(); break; } } } ProfilerShort.End(); }
void IMyStorageDataProvider.ReadFrom(ref MyOctreeStorage.ChunkHeader header, Stream stream, ref bool isOldFormat) { m_state.Version = stream.ReadUInt32(); if (m_state.Version != CURRENT_VERSION) { // Making sure this gets saved in new format and serialized cache holding old format is discarded. isOldFormat = true; } m_state.Generator = stream.ReadInt32(); m_state.Seed = stream.ReadInt32(); m_state.Size = stream.ReadFloat(); if (m_state.Version == VERSION_WITHOUT_PLANETS) { m_state.UnusedCompat = 0; } else { m_state.UnusedCompat = stream.ReadUInt32(); if (m_state.UnusedCompat == 1) { Debug.Fail("This storage is from a prototype version of planets and is no longer supported."); throw new InvalidBranchException(); } } var gen = MyCompositeShapes.AsteroidGenerators[m_state.Generator]; gen(m_state.Seed, m_state.Size, out m_data); m_state.Version = CURRENT_VERSION; }
private static MyStorageBase Compatibility_LoadCellStorage(int fileVersion, Stream stream) { // Size of this voxel map (in voxels) Vector3I tmpSize; tmpSize.X = stream.ReadInt32(); tmpSize.Y = stream.ReadInt32(); tmpSize.Z = stream.ReadInt32(); var storage = new MyOctreeStorage(null, tmpSize); // Size of data cell in voxels. Has to be the same as current size specified by our constants. Vector3I cellSize; cellSize.X = stream.ReadInt32(); cellSize.Y = stream.ReadInt32(); cellSize.Z = stream.ReadInt32(); #if !XB1 Trace.Assert(cellSize.X == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Y == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Z == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS); #else // XB1 System.Diagnostics.Debug.Assert(cellSize.X == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Y == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Z == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS); #endif // XB1 Vector3I cellsCount = tmpSize / cellSize; Dictionary <byte, MyVoxelMaterialDefinition> mappingTable = null; if (fileVersion == STORAGE_TYPE_VERSION_CELL) { // loading material names->index mappings mappingTable = Compatibility_LoadMaterialIndexMapping(stream); } else if (fileVersion == 1) { // material name->index mappings were not saved in this version } var startCoord = Vector3I.Zero; var endCoord = new Vector3I(MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); var cache = new MyStorageData(); cache.Resize(Vector3I.Zero, endCoord); Vector3I cellCoord; for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++) { MyVoxelRangeType cellType = (MyVoxelRangeType)stream.ReadByteNoAlloc(); // Cell's are FULL by default, therefore we don't need to change them switch (cellType) { case MyVoxelRangeType.EMPTY: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_EMPTY); break; case MyVoxelRangeType.FULL: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_FULL); break; case MyVoxelRangeType.MIXED: Vector3I v; for (v.X = 0; v.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.X++) { for (v.Y = 0; v.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Y++) { for (v.Z = 0; v.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Z++) { cache.Content(ref v, stream.ReadByteNoAlloc()); } } } break; } startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref startCoord, ref endCoord); } } } try { // In case materials are not saved, catch any exceptions caused by this. // Read materials and indestructible for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++) { bool isSingleMaterial = stream.ReadByteNoAlloc() == 1; MyVoxelMaterialDefinition material = null; if (isSingleMaterial) { material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable); cache.ClearMaterials(material.Index); } else { byte indestructibleContent; Vector3I voxelCoordInCell; for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++) { for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++) { for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++) { material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable); indestructibleContent = stream.ReadByteNoAlloc(); cache.Material(ref voxelCoordInCell, material.Index); } } } } startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); storage.WriteRange(cache, MyStorageDataTypeFlags.Material, ref startCoord, ref endCoord); } } } } catch (EndOfStreamException ex) { MySandboxGame.Log.WriteLine(ex); } return(storage); }
public unsafe MyStorageBase Compatibility_LoadCellStorage(int fileVersion, Stream stream) { Vector3I vectori; Vector3I vectori2; Vector3I vectori6; vectori.X = stream.ReadInt32(); vectori.Y = stream.ReadInt32(); vectori.Z = stream.ReadInt32(); MyOctreeStorage storage = new MyOctreeStorage(null, vectori); vectori2.X = stream.ReadInt32(); vectori2.Y = stream.ReadInt32(); vectori2.Z = stream.ReadInt32(); Vector3I vectori3 = (Vector3I)(vectori / vectori2); Dictionary <byte, MyVoxelMaterialDefinition> mapping = null; if (fileVersion == 2) { mapping = this.Compatibility_LoadMaterialIndexMapping(stream); } else { int num2 = fileVersion; } Vector3I zero = Vector3I.Zero; Vector3I end = new Vector3I(7); MyStorageData source = new MyStorageData(MyStorageDataTypeFlags.All); source.Resize(Vector3I.Zero, end); vectori6.X = 0; while (vectori6.X < vectori3.X) { vectori6.Y = 0; while (true) { if (vectori6.Y >= vectori3.Y) { int *numPtr6 = (int *)ref vectori6.X; numPtr6[0]++; break; } vectori6.Z = 0; while (true) { if (vectori6.Z >= vectori3.Z) { int *numPtr5 = (int *)ref vectori6.Y; numPtr5[0]++; break; } MyVoxelContentConstitution constitution = (MyVoxelContentConstitution)stream.ReadByteNoAlloc(); switch (constitution) { case MyVoxelContentConstitution.Empty: source.ClearContent(0); break; case MyVoxelContentConstitution.Full: source.ClearContent(0xff); break; case MyVoxelContentConstitution.Mixed: Vector3I vectori7; vectori7.X = 0; while (vectori7.X < 8) { vectori7.Y = 0; while (true) { if (vectori7.Y >= 8) { int *numPtr3 = (int *)ref vectori7.X; numPtr3[0]++; break; } vectori7.Z = 0; while (true) { if (vectori7.Z >= 8) { int *numPtr2 = (int *)ref vectori7.Y; numPtr2[0]++; break; } source.Content(ref vectori7, stream.ReadByteNoAlloc()); int *numPtr1 = (int *)ref vectori7.Z; numPtr1[0]++; } } } break; default: break; } zero = vectori6 * 8; storage.WriteRange(source, MyStorageDataTypeFlags.Content, zero, (Vector3I)(zero + 7), true, false); int *numPtr4 = (int *)ref vectori6.Z; numPtr4[0]++; } } } try { vectori6.X = 0; while (vectori6.X < vectori3.X) { vectori6.Y = 0; while (true) { if (vectori6.Y >= vectori3.Y) { int *numPtr12 = (int *)ref vectori6.X; numPtr12[0]++; break; } vectori6.Z = 0; while (true) { if (vectori6.Z >= vectori3.Z) { int *numPtr11 = (int *)ref vectori6.Y; numPtr11[0]++; break; } MyVoxelMaterialDefinition definition = null; if (stream.ReadByteNoAlloc() == 1) { source.ClearMaterials(this.Compatibility_LoadCellVoxelMaterial(stream, mapping).Index); } else { Vector3I vectori8; vectori8.X = 0; while (vectori8.X < 8) { vectori8.Y = 0; while (true) { if (vectori8.Y >= 8) { int *numPtr9 = (int *)ref vectori8.X; numPtr9[0]++; break; } vectori8.Z = 0; while (true) { if (vectori8.Z >= 8) { int *numPtr8 = (int *)ref vectori8.Y; numPtr8[0]++; break; } definition = this.Compatibility_LoadCellVoxelMaterial(stream, mapping); stream.ReadByteNoAlloc(); source.Material(ref vectori8, definition.Index); int *numPtr7 = (int *)ref vectori8.Z; numPtr7[0]++; } } } } zero = vectori6 * 8; storage.WriteRange(source, MyStorageDataTypeFlags.Material, zero, (Vector3I)(zero + 7), true, false); int *numPtr10 = (int *)ref vectori6.Z; numPtr10[0]++; } } } } catch (EndOfStreamException exception) { MySandboxGame.Log.WriteLine(exception); } return(storage); }
public void GenerateObjects(List<MyObjectSeed> objectsList) { ProfilerShort.Begin("GenerateObjects"); foreach (var objectSeed in objectsList) { if (objectSeed.Generated) continue; objectSeed.Generated = true; using (MyRandom.Instance.PushSeed(GetObjectIdSeed(objectSeed))) { switch (objectSeed.Type) { case MyObjectSeedType.Asteroid: ProfilerShort.Begin("Asteroid"); var bbox = objectSeed.BoundingVolume; MyGamePruningStructure.GetAllVoxelMapsInBox(ref bbox, m_tmpVoxelMapsList); String storageName = string.Format("Asteroid_{0}_{1}_{2}_{3}_{4}", objectSeed.CellId.X, objectSeed.CellId.Y, objectSeed.CellId.Z, objectSeed.Index, objectSeed.Seed); bool exists = false; foreach (var voxelMap in m_tmpVoxelMapsList) { if (voxelMap.StorageName == storageName) { exists = true; break; } } if (!exists) { var provider = MyCompositeShapeProvider.CreateAsteroidShape(objectSeed.Seed, objectSeed.Size, MySession.Static.Settings.VoxelGeneratorVersion); MyStorageBase storage = new MyOctreeStorage(provider, GetAsteroidVoxelSize(objectSeed.Size)); var voxelMap = MyWorldGenerator.AddVoxelMap(storageName, storage, objectSeed.BoundingVolume.Center - VRageMath.MathHelper.GetNearestBiggerPowerOfTwo(objectSeed.Size) / 2, GetAsteroidEntityId(objectSeed)); voxelMap.Save = false; RangeChangedDelegate OnStorageRangeChanged = null; OnStorageRangeChanged = delegate(Vector3I minVoxelChanged, Vector3I maxVoxelChanged, MyStorageDataTypeFlags changedData) { voxelMap.Save = true; storage.RangeChanged -= OnStorageRangeChanged; }; storage.RangeChanged += OnStorageRangeChanged; m_asteroidCount++; } m_tmpVoxelMapsList.Clear(); ProfilerShort.End(); break; case MyObjectSeedType.EncounterAlone: case MyObjectSeedType.EncounterSingle: case MyObjectSeedType.EncounterMulti: ProfilerShort.Begin("Encounter"); MyEncounterGenerator.PlaceEncounterToWorld(objectSeed.BoundingVolume, objectSeed.Seed, objectSeed.Type); m_encounterCount++; ProfilerShort.End(); break; default: throw new InvalidBranchException(); break; } } } ProfilerShort.End(); }
public static MyPlanet AddPlanet(string storageName, Vector3D positionMinCorner, int seed, float size, long entityId = 0) { m_materialsByOreType.Clear(); m_oreProbalities.Clear(); m_spawningMaterials.Clear(); m_organicMaterials.Clear(); DictionaryValuesReader<MyDefinitionId, MyPlanetDefinition> planetDefinitions = MyDefinitionManager.Static.GetPlanetsDefinitions(); foreach (var planetDefinition in planetDefinitions) { if (planetDefinition.Diameter.Min <= size && size <= planetDefinition.Diameter.Max) { var random = MyRandom.Instance; using (var stateToken = random.PushSeed(seed)) { BuildOreProbabilities(planetDefinition); FillMaterialCollections(); MyCsgShapePlanetShapeAttributes shapeAttributes = new MyCsgShapePlanetShapeAttributes(); shapeAttributes.Seed = seed; shapeAttributes.Diameter = size; shapeAttributes.Radius = size / 2.0f; shapeAttributes.LayerDeviationSeed = random.Next(); shapeAttributes.LayerDeviationNoiseFrequency = random.NextFloat(100.0f, 500.0f); shapeAttributes.NoiseFrequency = random.NextFloat(planetDefinition.StructureRatio.Min, planetDefinition.StructureRatio.Max); shapeAttributes.NormalNoiseFrequency = random.NextFloat(planetDefinition.NormalNoiseValue.Min, planetDefinition.NormalNoiseValue.Max); shapeAttributes.DeviationScale = random.NextFloat(planetDefinition.Deviation.Min, planetDefinition.Deviation.Max); MyCsgShapePlanetHillAttributes hillAttributes = FillValues(planetDefinition.HillParams, random); MyCsgShapePlanetHillAttributes canyonAttributes = FillValues(planetDefinition.CanyonParams, random); float planetHalfDeviation = (shapeAttributes.Diameter * shapeAttributes.DeviationScale) / 2.0f; float averagePlanetRadius = shapeAttributes.Diameter * (1 - shapeAttributes.DeviationScale * hillAttributes.SizeRatio) / 2.0f; float hillHalfDeviation = planetHalfDeviation * hillAttributes.SizeRatio; float canyonHalfDeviation = planetHalfDeviation * canyonAttributes.SizeRatio; float outerRadius = averagePlanetRadius + hillHalfDeviation * 1.5f; float innerRadius = averagePlanetRadius - canyonHalfDeviation * 2.5f; float atmosphereRadius = MathHelper.Max(outerRadius, averagePlanetRadius * 1.06f); float minPlanetRadius = MathHelper.Min(innerRadius, averagePlanetRadius - planetHalfDeviation * 2 * 2.5f); bool isHostile = random.NextFloat(0, 1) < planetDefinition.HostilityProbability; MyMaterialLayer[] materialLayers = CreateMaterialLayers(planetDefinition, isHostile, random, averagePlanetRadius, hillHalfDeviation, canyonHalfDeviation, ref outerRadius, ref innerRadius); IMyStorage storage = new MyOctreeStorage(MyCompositeShapeProvider.CreatePlanetShape(0, ref shapeAttributes, ref hillAttributes, ref canyonAttributes, materialLayers), FindBestOctreeSize(size)); float redAtmosphereShift = isHostile ? random.NextFloat(planetDefinition.HostileAtmosphereColorShift.R.Min, planetDefinition.HostileAtmosphereColorShift.R.Max) : 0; float greenAtmosphereShift = isHostile ? random.NextFloat(planetDefinition.HostileAtmosphereColorShift.G.Min, planetDefinition.HostileAtmosphereColorShift.G.Max) : 0; float blueAtmosphereShift = isHostile ? random.NextFloat(planetDefinition.HostileAtmosphereColorShift.B.Min, planetDefinition.HostileAtmosphereColorShift.B.Max) : 0; Vector3 atmosphereWavelengths = new Vector3(0.650f + redAtmosphereShift, 0.570f + greenAtmosphereShift, 0.475f + blueAtmosphereShift); atmosphereWavelengths.X = MathHelper.Clamp(atmosphereWavelengths.X, 0.1f, 1.0f); atmosphereWavelengths.Y = MathHelper.Clamp(atmosphereWavelengths.Y, 0.1f, 1.0f); atmosphereWavelengths.Z = MathHelper.Clamp(atmosphereWavelengths.Z, 0.1f, 1.0f); float gravityFalloff = random.NextFloat(planetDefinition.GravityFalloffPower.Min, planetDefinition.GravityFalloffPower.Max); var voxelMap = new MyPlanet(); voxelMap.EntityId = entityId; voxelMap.Init(storageName, storage, positionMinCorner, averagePlanetRadius, atmosphereRadius, averagePlanetRadius + hillHalfDeviation, minPlanetRadius, planetDefinition.HasAtmosphere, atmosphereWavelengths, isHostile ? 0.0f : 1.0f, gravityFalloff); MyEntities.Add(voxelMap); return voxelMap; } } } return null; }
private void CreateEmptyVoxelMapSpawnMenu(float separatorSize, float usableWidth) { int min = 2; int max = 10; var label = AddLabel("Voxel Size: ", Vector4.One, m_scale); MyGuiControlSlider slider = null; slider = new MyGuiControlSlider( position: m_currentPosition, width: 400f / MyGuiConstants.GUI_OPTIMAL_SIZE.X, minValue: min, maxValue: max, labelText: String.Empty, originAlign: MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, labelFont: MyFontEnum.Debug, intValue: true); slider.DebugScale = m_sliderDebugScale; slider.ColorMask = Color.White.ToVector4(); Controls.Add(slider); label = new MyGuiControlLabel( position: m_currentPosition + new Vector2(slider.Size.X + 0.005f, slider.Size.Y / 2), text: String.Empty, colorMask: Color.White.ToVector4(), textScale: MyGuiConstants.DEFAULT_TEXT_SCALE * 0.8f * m_scale, font: MyFontEnum.Debug); label.OriginAlign = MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER; Controls.Add(label); m_currentPosition.Y += slider.Size.Y; m_currentPosition.Y += separatorSize; slider.ValueChanged += (MyGuiControlSlider s) => { int size = 1 << ((int)s.Value); label.Text = size + "m"; m_procAsteroidSizeValue = size; }; slider.Value = 5; CreateDebugButton(usableWidth, MySpaceTexts.ScreenDebugSpawnMenu_SpawnAsteroid, x => { int size = (int)m_procAsteroidSizeValue; Debug.Assert(MathHelper.IsPowerOfTwo(size)); MyStorageBase storage = new MyOctreeStorage(null, new Vector3I(size)); string name = MakeStorageName("MyEmptyVoxelMap"); var builder = CreateAsteroidObjectBuilder(name); MyClipboardComponent.Static.ActivateVoxelClipboard(builder, storage, MySector.MainCamera.ForwardVector, (storage.Size * 0.5f).Length()); CloseScreenNow(); }); }
/// <summary> /// Returns count of changed voxels amount according to the given base storage. This storage is simply modified data of the base storage /// (note that premodified base storage is not supported - base storage must be default unganged one). /// </summary> public ulong CountChangedVoxelsAmount(MyOctreeStorage baseStorage) { ulong count = CountChangedVoxelsAmount(baseStorage, m_treeHeight, m_contentNodes, m_contentLeaves, Vector3I.Zero); return(count); }