public override void LoadData() { //if (true) return; Static = this; if (!MyFakes.ENABLE_ASTEROID_FIELDS) { return; } var settings = MySession.Static.Settings; if (settings.ProceduralDensity == 0f) { Enabled = false; MySandboxGame.Log.WriteLine("Skip Procedural World Generator"); return; } m_seed = settings.ProceduralSeed; m_objectDensity = MathHelper.Clamp(settings.ProceduralDensity * 2 - 1, -1, 1); // must be -1..1 MySandboxGame.Log.WriteLine(string.Format("Loading Procedural World Generator: Seed = '{0}' = {1}, Density = {2}", settings.ProceduralSeed, m_seed, settings.ProceduralDensity)); using (MyRandom.Instance.PushSeed(m_seed)) { m_asteroidsModule = new MyProceduralAsteroidCellGenerator(m_seed, m_objectDensity); m_modules.Add(m_asteroidsModule); } Enabled = true; }
protected override void UnloadData() { Enabled = false; if (!MyFakes.ENABLE_ASTEROID_FIELDS) { return; } MySandboxGame.Log.WriteLine("Unloading Procedural World Generator"); m_modules.Clear(); m_trackedEntities.Clear(); Debug.Assert(m_tempObjectSeedList.Count == 0, "temp list is not empty!"); m_tempObjectSeedList.Clear(); Static = null; }
public MyCompositeOrePlanetDeposit(MyCsgShapeBase baseShape, int seed, float minDepth, float maxDepth, MyOreProbability[] oreProbabilties, MyVoxelMaterialDefinition material) : base(baseShape, material) { m_minDepth = minDepth; double outherSphereVolume = (4.0 * MathHelper.Pi * Math.Pow(minDepth, 3.0f)) / 3.0; double innerSphereVolume = (4.0 * MathHelper.Pi * Math.Pow(maxDepth, 3.0f)) / 3.0; double depositVolume = (4.0 * MathHelper.Pi * Math.Pow(DEPOSIT_MAX_SIZE, 3.0f)) / 3.0; double volume = outherSphereVolume - innerSphereVolume; m_numDeposits = oreProbabilties.Length > 0 ? (int)Math.Floor((volume * 0.4f) / depositVolume) : 0; int numSectors = (int)(minDepth / DEPOSIT_MAX_SIZE); MyRandom random = MyRandom.Instance; FillMaterialCollections(); Vector3D offset = -new Vector3D(DEPOSIT_MAX_SIZE / 2.0); using (var stateToken = random.PushSeed(seed)) { for (int i = 0; i < m_numDeposits; ++i) { Vector3D direction = MyProceduralWorldGenerator.GetRandomDirection(random); float distanceFromCenter = random.NextFloat(maxDepth, minDepth); Vector3D position = direction * distanceFromCenter; Vector3I cellPos = Vector3I.Ceiling((Shape.Center() + position) / DEPOSIT_MAX_SIZE); MyCompositeShapeOreDeposit deposit; if (m_deposits.TryGetValue(cellPos, out deposit) == false) { var oreDefinition = GetOre(random.NextFloat(0, 1), oreProbabilties); var materialDefinition = m_materialsByOreType[oreDefinition.OreName][random.Next() % m_materialsByOreType[oreDefinition.OreName].Count]; deposit = new MyCompositeShapeOreDeposit(new MyCsgSimpleSphere(cellPos * DEPOSIT_MAX_SIZE + offset, random.NextFloat(64, DEPOSIT_MAX_SIZE / 2.0f)), materialDefinition); m_deposits[cellPos] = deposit; } } } m_materialsByOreType.Clear(); }
protected override void UnloadData() { Enabled = false; if (!MyFakes.ENABLE_ASTEROID_FIELDS) return; MySandboxGame.Log.WriteLine("Unloading Procedural World Generator"); m_modules.Clear(); m_trackedEntities.Clear(); Debug.Assert(m_tempObjectSeedList.Count == 0, "temp list is not empty!"); m_tempObjectSeedList.Clear(); Static = null; }
public override void LoadData() { //if (true) return; Static = this; if (!MyFakes.ENABLE_ASTEROID_FIELDS) return; var settings = MySession.Static.Settings; if (settings.ProceduralDensity == 0f) { Enabled = false; MySandboxGame.Log.WriteLine("Skip Procedural World Generator"); return; } m_seed = settings.ProceduralSeed; m_objectDensity = MathHelper.Clamp(settings.ProceduralDensity * 2 - 1, -1, 1); // must be -1..1 MySandboxGame.Log.WriteLine(string.Format("Loading Procedural World Generator: Seed = '{0}' = {1}, Density = {2}", settings.ProceduralSeed, m_seed, settings.ProceduralDensity)); using (MyRandom.Instance.PushSeed(m_seed)) { if (MySession.Static.Settings.EnablePlanets) { var planets = new MyProceduralPlanetCellGenerator(m_seed, m_objectDensity); m_modules.Add(planets); var asteroids = new MyProceduralAsteroidCellGenerator(m_seed, m_objectDensity, planets); m_modules.Add(asteroids); } else { m_modules.Add(new MyProceduralAsteroidCellGenerator(m_seed, m_objectDensity)); } } Enabled = true; }
private void GenerateObject(MyProceduralCell cell, MyObjectSeed objectSeed, ref int index, MyRandom random, IMyModule densityFunctionFilled, IMyModule densityFunctionRemoved) { cell.AddObject(objectSeed); switch (objectSeed.Type) { case MyObjectSeedType.Asteroid: break; case MyObjectSeedType.AsteroidCluster: objectSeed.Type = MyObjectSeedType.Asteroid; m_tmpClusterBoxes.Add(objectSeed.BoundingVolume); for (int i = 0; i < OBJECT_MAX_IN_CLUSTER; ++i) { var direction = MyProceduralWorldGenerator.GetRandomDirection(random); var size = GetClusterObjectSize(random.NextDouble()); var distance = MathHelper.Lerp(OBJECT_MIN_DISTANCE_CLUSTER, OBJECT_MAX_DISTANCE_CLUSTER, random.NextDouble()); var clusterObjectPosition = objectSeed.BoundingVolume.Center + direction * (size + objectSeed.BoundingVolume.HalfExtents.Length() * 2 + distance); ProfilerShort.Begin("Density functions"); double valueRemoved = -1; if (densityFunctionRemoved != null) { valueRemoved = densityFunctionRemoved.GetValue(clusterObjectPosition.X, clusterObjectPosition.Y, clusterObjectPosition.Z); if (valueRemoved <= -1) { ProfilerShort.End(); continue; } } var valueFilled = densityFunctionFilled.GetValue(clusterObjectPosition.X, clusterObjectPosition.Y, clusterObjectPosition.Z); if (densityFunctionRemoved != null) { if (valueRemoved < valueFilled) { ProfilerShort.End(); continue; } } ProfilerShort.End(); if (valueFilled < OBJECT_DENSITY_CLUSTER) // -1..+1 { var clusterObjectSeed = new MyObjectSeed(cell, clusterObjectPosition, size); clusterObjectSeed.Seed = random.Next(); clusterObjectSeed.Index = index++; clusterObjectSeed.Type = GetClusterSeedType(random.NextDouble()); bool overlaps = false; foreach (var box in m_tmpClusterBoxes) { if (overlaps |= clusterObjectSeed.BoundingVolume.Intersects(box)) { break; } } if (!overlaps) { m_tmpClusterBoxes.Add(clusterObjectSeed.BoundingVolume); GenerateObject(cell, clusterObjectSeed, ref index, random, densityFunctionFilled, densityFunctionRemoved); } } } m_tmpClusterBoxes.Clear(); break; case MyObjectSeedType.EncounterAlone: case MyObjectSeedType.EncounterSingle: case MyObjectSeedType.EncounterMulti: break; default: throw new InvalidBranchException(); break; } }
private void GenerateObject(MyProceduralCell cell, MyObjectSeed objectSeed, ref int index, MyRandom random, IMyModule densityFunctionFilled, IMyModule densityFunctionRemoved) { cell.AddObject(objectSeed); IMyAsteroidFieldDensityFunction func = objectSeed.UserData as IMyAsteroidFieldDensityFunction; if (func != null) { ChildrenAddDensityFunctionRemoved(func); } switch (objectSeed.Params.Type) { case MyObjectSeedType.Moon: break; case MyObjectSeedType.Planet: m_tmpClusterBoxes.Add(objectSeed.BoundingVolume); for (int i = 0; i < MOONS_MAX; ++i) { var direction = MyProceduralWorldGenerator.GetRandomDirection(random); var size = MathHelper.Lerp(MOON_SIZE_MIN, MOON_SIZE_MAX, random.NextDouble()); var distance = MathHelper.Lerp(MOON_DISTANCE_MIN, MOON_DISTANCE_MAX, random.NextDouble()); var position = objectSeed.BoundingVolume.Center + direction * (size + objectSeed.BoundingVolume.HalfExtents.Length() * 2 + distance); ProfilerShort.Begin("GetValue"); var value = densityFunctionFilled.GetValue(position.X, position.Y, position.Z); ProfilerShort.End(); if (value < MOON_DENSITY) // -1..+1 { var clusterObjectSeed = new MyObjectSeed(cell, position, size); clusterObjectSeed.Params.Seed = random.Next(); clusterObjectSeed.Params.Type = MyObjectSeedType.Moon; clusterObjectSeed.Params.Index = index++; clusterObjectSeed.UserData = new MySphereDensityFunction(position, MOON_SIZE_MAX / 2.0 * GRAVITY_SIZE_MULTIPLIER + FALLOFF, FALLOFF); bool overlaps = false; foreach (var box in m_tmpClusterBoxes) { if (overlaps |= clusterObjectSeed.BoundingVolume.Intersects(box)) { break; } } if (!overlaps) { m_tmpClusterBoxes.Add(clusterObjectSeed.BoundingVolume); GenerateObject(cell, clusterObjectSeed, ref index, random, densityFunctionFilled, densityFunctionRemoved); } } } m_tmpClusterBoxes.Clear(); break; case MyObjectSeedType.Empty: break; default: throw new InvalidBranchException(); break; } }