public override void AfterPostprocess(MyDefinitionSet set, Dictionary <MyStringHash, MyDefinitionBase> definitions) { List <int> indices = new List <int>(); foreach (MyDefinitionBase base2 in definitions.Values) { MyPlanetGeneratorDefinition definition = (MyPlanetGeneratorDefinition)base2; if (definition.EnvironmentId != null) { definition.EnvironmentDefinition = MyDefinitionManager.Static.GetDefinition <MyWorldEnvironmentDefinition>(definition.EnvironmentId.Value); } else { definition.EnvironmentDefinition = MyProceduralEnvironmentDefinition.FromLegacyPlanet(definition.m_pgob, base2.Context); set.AddOrRelaceDefinition(definition.EnvironmentDefinition); definition.m_pgob = null; } if (definition.EnvironmentDefinition != null) { definition.EnvironmentSectorType = definition.EnvironmentDefinition.SectorType; using (Dictionary <int, Dictionary <string, List <MyPlanetEnvironmentMapping> > > .ValueCollection.Enumerator enumerator2 = definition.MaterialEnvironmentMappings.Values.GetEnumerator()) { while (enumerator2.MoveNext()) { using (Dictionary <string, List <MyPlanetEnvironmentMapping> > .ValueCollection.Enumerator enumerator3 = enumerator2.Current.Values.GetEnumerator()) { while (enumerator3.MoveNext()) { foreach (MyPlanetEnvironmentMapping mapping in enumerator3.Current) { int index = 0; while (true) { MyEnvironmentItemsDefinition definition2; if (index >= mapping.Items.Length) { if (indices.Count > 0) { mapping.Items = mapping.Items.RemoveIndices <MyMaterialEnvironmentItem>(indices); mapping.ComputeDistribution(); indices.Clear(); } break; } if (mapping.Items[index].IsEnvironemntItem && !MyDefinitionManager.Static.TryGetDefinition <MyEnvironmentItemsDefinition>(mapping.Items[index].Definition, out definition2)) { MyLog.Default.WriteLine($"Could not find environment item definition for {mapping.Items[index].Definition}."); indices.Add(index); } index++; } } } } } } } } }
private void InheritFrom(string generator) { MyPlanetGeneratorDefinition definition = MyDefinitionManager.Static.GetDefinition <MyPlanetGeneratorDefinition>(MyStringHash.GetOrCompute(generator)); if (definition == null) { MyDefinitionManager.Static.LoadingSet.m_planetGeneratorDefinitions.TryGetValue(new MyDefinitionId(typeof(MyObjectBuilder_PlanetGeneratorDefinition), generator), out definition); } if (definition == null) { MyLog.Default.WriteLine($"Could not find planet generator definition for '{generator}'."); } else { this.PlanetMaps = definition.PlanetMaps; this.HasAtmosphere = definition.HasAtmosphere; this.Atmosphere = definition.Atmosphere; this.CloudLayers = definition.CloudLayers; this.SoundRules = definition.SoundRules; this.MusicCategories = definition.MusicCategories; this.HillParams = definition.HillParams; this.MaterialsMaxDepth = definition.MaterialsMaxDepth; this.MaterialsMinDepth = definition.MaterialsMinDepth; this.GravityFalloffPower = definition.GravityFalloffPower; this.HostileAtmosphereColorShift = definition.HostileAtmosphereColorShift; this.SurfaceMaterialTable = definition.SurfaceMaterialTable; this.DistortionTable = definition.DistortionTable; this.DefaultSurfaceMaterial = definition.DefaultSurfaceMaterial; this.DefaultSubSurfaceMaterial = definition.DefaultSubSurfaceMaterial; this.MaterialGroups = definition.MaterialGroups; this.MaterialEnvironmentMappings = definition.MaterialEnvironmentMappings; this.SurfaceGravity = definition.SurfaceGravity; this.AtmosphereSettings = definition.AtmosphereSettings; this.FolderName = definition.FolderName; this.MaterialBlending = definition.MaterialBlending; this.OreMappings = definition.OreMappings; this.AnimalSpawnInfo = definition.AnimalSpawnInfo; this.NightAnimalSpawnInfo = definition.NightAnimalSpawnInfo; this.Detail = definition.Detail; this.SectorDensity = definition.SectorDensity; this.EnvironmentSectorType = definition.EnvironmentSectorType; this.MesherPostprocessing = definition.MesherPostprocessing; this.MinimumSurfaceLayerDepth = definition.MinimumSurfaceLayerDepth; } }
private void InheritFrom(string generator) { MyPlanetGeneratorDefinition parent = MyDefinitionManager.Static.GetDefinition <MyPlanetGeneratorDefinition>(MyStringHash.GetOrCompute(generator)); if (parent == null) { MyDefinitionManager.Static.LoadingSet.m_planetGeneratorDefinitions.TryGetValue(new MyDefinitionId(typeof(MyObjectBuilder_PlanetGeneratorDefinition), generator), out parent); } if (parent == null) { MyLog.Default.WriteLine(String.Format("Could not find planet generator definition for '{0}'.", generator)); return; } PlanetMaps = parent.PlanetMaps; HasAtmosphere = parent.HasAtmosphere; Atmosphere = parent.Atmosphere; CloudLayers = parent.CloudLayers; SoundRules = parent.SoundRules; MusicCategories = parent.MusicCategories; HillParams = parent.HillParams; MaterialsMaxDepth = parent.MaterialsMaxDepth; MaterialsMinDepth = parent.MaterialsMinDepth; GravityFalloffPower = parent.GravityFalloffPower; HostileAtmosphereColorShift = parent.HostileAtmosphereColorShift; SurfaceMaterialTable = parent.SurfaceMaterialTable; DistortionTable = parent.DistortionTable; DefaultSurfaceMaterial = parent.DefaultSurfaceMaterial; DefaultSubSurfaceMaterial = parent.DefaultSubSurfaceMaterial; MaterialGroups = parent.MaterialGroups; MaterialEnvironmentMappings = parent.MaterialEnvironmentMappings; SurfaceGravity = parent.SurfaceGravity; AtmosphereSettings = parent.AtmosphereSettings; FolderName = parent.FolderName; MaterialBlending = parent.MaterialBlending; OreMappings = parent.OreMappings; AnimalSpawnInfo = parent.AnimalSpawnInfo; NightAnimalSpawnInfo = parent.NightAnimalSpawnInfo; Detail = parent.Detail; SectorDensity = parent.SectorDensity; EnvironmentSectorType = parent.EnvironmentSectorType; }
public MyPlanetShapeProvider(Vector3 translation, float radius, MyPlanetGeneratorDefinition definition) { m_radius = radius; m_translation = translation; m_maxHillHeight = definition.HillParams.Max * m_radius; m_minHillHeight = definition.HillParams.Min * m_radius; InnerRadius = radius + m_minHillHeight; OuterRadius = radius + m_maxHillHeight; m_heightmap = new MyHeightCubemap(definition.FolderName, definition.Context); m_mapResolutionMinusOne = m_heightmap.Resolution - 1; m_heightRatio = m_maxHillHeight - m_minHillHeight; m_heightRatioRecip = 1f / m_heightRatio; float faceSize = (float)(radius * Math.PI * .5); m_pixelSize = faceSize / m_heightmap.Resolution; m_pixelSizeRecip = 1f / m_pixelSize; m_pixelSizeRecip2 = .5f / m_pixelSize; // Calculate maximum toelerable curvature deviation when approximating the surface by a line // We use this for LOD1 raycasts so the maximum deviation is 8m(half a LOD1 cell) // Find the angle theta that produces an arc whose secant aproximation deviates from the circle at most 8 meters var theta = Math.Acos((radius - 1)/radius); // this produces theta/2 but we use that later and I refuce to multiply and divide // Find the length of this secant segment. var threshold = Math.Sin(theta)*2*radius; // Store it's reciprocal because that's all we use m_curvatureThresholdRecip = 1d/threshold; m_pixelSize4 = m_pixelSize * 4; // Used for inflating query boxes m_voxelSize = (float)(2.0 / (radius * Math.PI)); m_mapStepScale = m_pixelSize / m_heightRatio; m_mapStepScaleSquare = m_mapStepScale * m_mapStepScale; if (definition.Detail != null) m_detail.Init(definition.Detail, faceSize); Closed = false; }
public MyPlanetMaterialProvider(MyPlanetGeneratorDefinition generatorDef, MyPlanetShapeProvider planetShape) { m_materials = new Dictionary<byte, PlanetMaterial>(generatorDef.SurfaceMaterialTable.Length); for (int i = 0; i < generatorDef.SurfaceMaterialTable.Length; ++i) { byte materialValue = (byte)generatorDef.SurfaceMaterialTable[i].Value; m_materials[materialValue] = new PlanetMaterial(generatorDef.SurfaceMaterialTable[i]); } m_defaultMaterial = new PlanetMaterial(generatorDef.DefaultSurfaceMaterial); if (generatorDef.DefaultSubSurfaceMaterial != null) { m_subsurfaceMaterial = new PlanetMaterial(generatorDef.DefaultSubSurfaceMaterial); } else { m_subsurfaceMaterial = m_defaultMaterial; } m_planetShape = planetShape; MyCubemap[] maps; MyHeightMapLoadingSystem.Static.GetPlanetMaps(generatorDef.FolderName, generatorDef.Context, generatorDef.PlanetMaps, out maps); m_materialMap = maps[0]; m_biomeMap = maps[1]; m_oreMap = maps[2]; m_occlusionMap = maps[3]; if (m_biomeMap != null) m_mapResolutionMinusOne = m_biomeMap.Resolution - 1; m_generator = generatorDef; m_invHeightRange = 1 / (m_planetShape.MaxHillHeight - m_planetShape.MinHillHeight); m_biomePixelSize = (float)((planetShape.MaxHillHeight + planetShape.Radius) * Math.PI) / ((float)(m_mapResolutionMinusOne + 1) * 2); m_hashCode = generatorDef.FolderName.GetHashCode(); // Material groups if (m_generator.MaterialGroups != null && m_generator.MaterialGroups.Length > 0) { m_biomes = new Dictionary<byte, PlanetBiome>(); foreach (var group in m_generator.MaterialGroups) { m_biomes.Add(group.Value, new PlanetBiome(group)); } } m_blendingTileset = MyHeightMapLoadingSystem.Static.GetTerrainBlendTexture(m_generator.MaterialBlending); m_ores = new Dictionary<byte, PlanetOre>(); foreach (var mapping in m_generator.OreMappings) { var mat = GetMaterial(mapping.Type); if (mat != null) { if (m_ores.ContainsKey(mapping.Value)) { string message = String.Format("Value {0} is already mapped to another ore.", mapping.Value); Debug.Fail(message); MyLog.Default.WriteLine(message); } else { m_ores[mapping.Value] = new PlanetOre() { Depth = mapping.Depth, Start = mapping.Start, Value = mapping.Value, Material = mat }; } } } Closed = false; }
public void Close() { if (m_providerForRules == this) m_providerForRules = null; // Clear to speed up collection m_blendingTileset = null; m_subsurfaceMaterial = null; m_generator = null; m_biomeMap = null; m_biomes = null; m_materials = null; m_planetShape = null; m_ores = null; m_materialMap = null; m_oreMap = null; m_biomeMap = null; m_occlusionMap = null; Closed = true; }
public MyPlanetDetailModulator(MyPlanetGeneratorDefinition planetDefinition, MyPlanetMaterialProvider oreDeposit, int seed, float radius) { m_planetDefinition = planetDefinition; m_oreDeposit = oreDeposit; m_radius = radius; foreach (var distortionDefinition in m_planetDefinition.DistortionTable) { MyModuleFast modulator = null; float frequency = distortionDefinition.Frequency; frequency *= radius / 6.0f; switch (distortionDefinition.Type) { case "Billow": { modulator = new MyBillowFast( seed: seed, quality: MyNoiseQuality.High, frequency: frequency, layerCount: distortionDefinition.LayerCount); } break; case "RidgedMultifractal": { modulator = new MyRidgedMultifractalFast( seed: seed, quality: MyNoiseQuality.High, frequency: frequency, layerCount: distortionDefinition.LayerCount); } break; case "Perlin": { modulator = new MyPerlinFast( seed: seed, quality: MyNoiseQuality.High, frequency: frequency, octaveCount: distortionDefinition.LayerCount); } break; case "Simplex": { modulator = new MySimplexFast() { Seed = seed, Frequency = frequency, }; } break; default: System.Diagnostics.Debug.Fail("Unknown modulator type!"); break; } if (modulator != null) { m_modulators.Add(distortionDefinition.Value, new MyModulatorData() { Height = distortionDefinition.Height, Modulator = modulator } ); } } }
private static void BuildOreProbabilities(MyPlanetGeneratorDefinition planetDefinition) { m_oreCummulativeProbability = 0.0f; if (planetDefinition.MetalsOreProbability != null) { foreach (var oreProbability in planetDefinition.MetalsOreProbability) { MyOreProbability probability = new MyOreProbability(); m_oreCummulativeProbability += MyRandom.Instance.NextFloat(oreProbability.Min, oreProbability.Max); probability.CummulativeProbability = m_oreCummulativeProbability; probability.OreName = oreProbability.OreName; m_oreProbalities.Add(probability); } } }
private static MyMaterialLayer[] CreateMaterialLayers(MyPlanetGeneratorDefinition planetDefinition, bool isHostile, MyRandom random, float averagePlanetRadius, float hillHalfDeviation, float canyonHalfDeviation, ref float outerRadius, ref float innerRadius) { int numLayers = random.Next((int)planetDefinition.NumLayers.Min, (int)planetDefinition.NumLayers.Max); float startHeight = averagePlanetRadius - canyonHalfDeviation; outerRadius = averagePlanetRadius + hillHalfDeviation; innerRadius = averagePlanetRadius - canyonHalfDeviation; int layerOffset = 0; MyMaterialLayer southPoleLayer = CreatePoleLayer(random, planetDefinition.SouthPole, startHeight, outerRadius, ref layerOffset); MyMaterialLayer northPoleLayer = CreatePoleLayer(random, planetDefinition.NorthPole, startHeight, outerRadius, ref layerOffset); MyMaterialLayer[] materialLayers = new MyMaterialLayer[numLayers + layerOffset]; float endAngle = 1; float startAngle = -1; int currentLayer = 0; if (southPoleLayer != null) { materialLayers[currentLayer] = southPoleLayer; endAngle = southPoleLayer.StartAngle; currentLayer++; } if (northPoleLayer != null) { materialLayers[currentLayer] = northPoleLayer; northPoleLayer.EndAngle = northPoleLayer.StartAngle; northPoleLayer.StartAngle = -1.0f; northPoleLayer.AngleEndDeviation = northPoleLayer.AngleStartDeviation; northPoleLayer.AngleStartDeviation = 0.0f; startAngle = northPoleLayer.EndAngle; } float step = (outerRadius - innerRadius) / materialLayers.Length; float organicHeightEnd = random.NextFloat(planetDefinition.OrganicHeightEnd.Min, planetDefinition.OrganicHeightEnd.Max); float floraMaterialSpawnProbability = random.NextFloat(planetDefinition.FloraMaterialSpawnProbability.Min, planetDefinition.FloraMaterialSpawnProbability.Max); float metalsSpawnValue = random.NextFloat(0, 1); for (int i = layerOffset; i < materialLayers.Length; ++i) { float layerHeight = random.NextFloat(0, step); materialLayers[i] = new MyMaterialLayer(); materialLayers[i].StartHeight = startHeight; materialLayers[i].EndHeight = startHeight + layerHeight; materialLayers[i].StartAngle = startAngle; materialLayers[i].EndAngle = endAngle; materialLayers[i].HeightStartDeviation = random.NextFloat(0, 100.0f / (float)(i + 1)); materialLayers[i].AngleStartDeviation = 0; materialLayers[i].HeightEndDeviation = random.NextFloat(0, 100.0f / (float)(i + 1)); materialLayers[i].AngleEndDeviation = 0; MyVoxelMaterialDefinition materialDefinition = null; if (m_materialsByOreType.ContainsKey("Stone") == true) { materialDefinition = m_materialsByOreType["Stone"][random.Next() % m_materialsByOreType["Stone"].Count]; } if (planetDefinition.HasAtmosphere && isHostile == false) { if ((outerRadius - startHeight) > ((outerRadius - innerRadius) * (1 - organicHeightEnd))) { float value = random.NextFloat(0, 1); if (value > floraMaterialSpawnProbability) { materialDefinition = m_organicMaterials[random.Next() % m_organicMaterials.Count]; } else { materialDefinition = m_spawningMaterials[random.Next() % m_spawningMaterials.Count]; } } } materialLayers[i].MaterialDefinition = materialDefinition; startHeight += layerHeight; } return materialLayers; }
public void Init(long seed, MyPlanetGeneratorDefinition generator, double radius) { Debug.Assert(radius > 0, "The planet radius must be a strictly positive number!"); radius = Math.Max(radius, 1.0); Generator = generator; m_data = new PlanetData() { Radius = radius, Seed = seed, Version = STORAGE_VERSION }; Init(); Closed = false; }
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; }