private MyProceduralCell GenerateObjectSeedsCell(ref Vector3I cellId) { MyProceduralCell cell = new MyProceduralCell(cellId); ProfilerShort.Begin("GenerateObjectSeedsCell"); IMyModule cellDensityFunction = CalculateCellDensityFunction(ref cellId); if (cellDensityFunction == null) { ProfilerShort.End(); return(null); } int cellSeed = GetCellSeed(ref cellId); using (MyRandom.Instance.PushSeed(cellSeed)) { var random = MyRandom.Instance; int index = 0; Vector3I subCellId = Vector3I.Zero; Vector3I max = new Vector3I(SUBCELLS - 1); for (var iter = new Vector3I.RangeIterator(ref Vector3I.Zero, ref max); iter.IsValid(); iter.GetNext(out subCellId)) { Vector3D position = new Vector3D(random.NextDouble(), random.NextDouble(), random.NextDouble()); position += (Vector3D)subCellId / SUBCELL_SIZE; position += cellId; position *= CELL_SIZE; if (!MyEntities.IsInsideWorld(position)) { continue; } ProfilerShort.Begin("GetValue"); var value = cellDensityFunction.GetValue(position.X, position.Y, position.Z); ProfilerShort.End(); if (value < m_objectDensity) // -1..+1 { var objectSeed = new MyObjectSeed(cell, position, GetObjectSize(random.NextDouble())); objectSeed.Type = GetSeedType(random.NextDouble()); objectSeed.Seed = random.Next(); objectSeed.Index = index++; GenerateObject(cell, objectSeed, ref index, random, cellDensityFunction); } } } ProfilerShort.End(); return(cell); }
protected override MyProceduralCell GenerateProceduralCell(ref VRageMath.Vector3I cellId) { MyProceduralCell cell = new MyProceduralCell(cellId, this.CELL_SIZE); ProfilerShort.Begin("GenerateProceduralCell"); IMyModule densityFunctionFilled = GetCellDensityFunctionFilled(cell.BoundingVolume); if (densityFunctionFilled == null) { ProfilerShort.End(); return(null); } IMyModule densityFunctionRemoved = GetCellDensityFunctionRemoved(cell.BoundingVolume); int cellSeed = GetCellSeed(ref cellId); var random = MyRandom.Instance; using (random.PushSeed(cellSeed)) { Vector3D position = new Vector3D(random.NextDouble(), random.NextDouble(), random.NextDouble()); position *= (CELL_SIZE - 2 * OBJECT_SEED_RADIUS) / CELL_SIZE; position += OBJECT_SEED_RADIUS / CELL_SIZE; position += (Vector3D)cellId; position *= CELL_SIZE; if (MyEntities.IsInsideWorld(position)) { ProfilerShort.Begin("GetValue"); var value = densityFunctionFilled.GetValue(position.X, position.Y, position.Z); ProfilerShort.End(); if (value < m_objectDensity) // -1..+1 { var size = MathHelper.Lerp(PLANET_SIZE_MIN, PLANET_SIZE_MAX, random.NextDouble()); var objectSeed = new MyObjectSeed(cell, position, size); objectSeed.Params.Type = MyObjectSeedType.Planet; objectSeed.Params.Seed = random.Next(); objectSeed.Params.Index = 0; objectSeed.UserData = new MySphereDensityFunction(position, PLANET_SIZE_MAX / 2.0 * GRAVITY_SIZE_MULTIPLIER + FALLOFF, FALLOFF); int index = 1; GenerateObject(cell, objectSeed, ref index, random, densityFunctionFilled, densityFunctionRemoved); } } } ProfilerShort.End(); return(cell); }
protected override MyProceduralCell GenerateProceduralCell(ref VRageMath.Vector3I cellId) { MyProceduralCell cell = new MyProceduralCell(cellId, this); ProfilerShort.Begin("GenerateProceduralCell"); IMyModule densityFunctionFilled = GetCellDensityFunctionFilled(cell.BoundingVolume); if (densityFunctionFilled == null) { ProfilerShort.End(); return null; } IMyModule densityFunctionRemoved = GetCellDensityFunctionRemoved(cell.BoundingVolume); int cellSeed = GetCellSeed(ref cellId); var random = MyRandom.Instance; using (random.PushSeed(cellSeed)) { Vector3D position = new Vector3D(random.NextDouble(), random.NextDouble(), random.NextDouble()); position *= (CELL_SIZE - 2 * OBJECT_SEED_RADIUS) / CELL_SIZE; position += OBJECT_SEED_RADIUS / CELL_SIZE; position += (Vector3D)cellId; position *= CELL_SIZE; if (MyEntities.IsInsideWorld(position)) { ProfilerShort.Begin("GetValue"); var value = densityFunctionFilled.GetValue(position.X, position.Y, position.Z); ProfilerShort.End(); if (value < m_objectDensity) // -1..+1 { var size = MathHelper.Lerp(PLANET_SIZE_MIN, PLANET_SIZE_MAX, random.NextDouble()); var objectSeed = new MyObjectSeed(cell, position, size); objectSeed.Type = MyObjectSeedType.Planet; objectSeed.Seed = random.Next(); objectSeed.Index = 0; objectSeed.UserData = new MySphereDensityFunction(position, OBJECT_SEED_RADIUS, OBJECT_SEED_RADIUS); int index = 1; GenerateObject(cell, objectSeed, ref index, random, densityFunctionFilled, densityFunctionRemoved); } } } ProfilerShort.End(); return cell; }
private void GenerateObject(MyProceduralCell cell, MyObjectSeed objectSeed, ref int index, MyRandom random, IMyModule densityFunction) { cell.AddObject(objectSeed); switch (objectSeed.Type) { case MyObjectSeedType.Asteroid: m_asteroidSeedCount++; break; case MyObjectSeedType.AsteroidCluster: objectSeed.Type = MyObjectSeedType.Asteroid; m_asteroidSeedCount++; m_tmpClusterBoxes.Add(objectSeed.BoundingVolume); for (int j = 0; j < OBJECT_MAX_IN_CLUSTER; ++j) { var direction = 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("GetValue"); var value = densityFunction.GetValue(clusterObjectPosition.X, clusterObjectPosition.Y, clusterObjectPosition.Z); ProfilerShort.End(); if (value < 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, densityFunction); } } } m_tmpClusterBoxes.Clear(); break; case MyObjectSeedType.EncounterAlone: case MyObjectSeedType.EncounterSingle: case MyObjectSeedType.EncounterMulti: m_encounterSeedCount++; break; default: throw new InvalidBranchException(); break; } }
private MyProceduralCell GenerateObjectSeedsCell(ref Vector3I cellId) { MyProceduralCell cell = new MyProceduralCell(cellId); ProfilerShort.Begin("GenerateObjectSeedsCell"); IMyModule cellDensityFunction = CalculateCellDensityFunction(ref cellId); if (cellDensityFunction == null) { ProfilerShort.End(); return null; } int cellSeed = GetCellSeed(ref cellId); using (MyRandom.Instance.PushSeed(cellSeed)) { var random = MyRandom.Instance; int index = 0; Vector3I subCellId = Vector3I.Zero; Vector3I max = new Vector3I(SUBCELLS - 1); for (var iter = new Vector3I.RangeIterator(ref Vector3I.Zero, ref max); iter.IsValid(); iter.GetNext(out subCellId)) { Vector3D position = new Vector3D(random.NextDouble(), random.NextDouble(), random.NextDouble()); position += (Vector3D)subCellId / SUBCELL_SIZE; position += cellId; position *= CELL_SIZE; if (!MyEntities.IsInsideWorld(position)) { continue; } ProfilerShort.Begin("GetValue"); var value = cellDensityFunction.GetValue(position.X, position.Y, position.Z); ProfilerShort.End(); if (value < m_objectDensity) // -1..+1 { var objectSeed = new MyObjectSeed(cell, position, GetObjectSize(random.NextDouble())); objectSeed.Type = GetSeedType(random.NextDouble()); objectSeed.Seed = random.Next(); objectSeed.Index = index++; GenerateObject(cell, objectSeed, ref index, random, cellDensityFunction); } } } ProfilerShort.End(); return cell; }
public MyObjectSeed(MyProceduralCell cell, Vector3D position, double size) { Cell = cell; Size = (float)size; BoundingVolume = new BoundingBoxD(position - size, position + size); }
protected override MyProceduralCell GenerateProceduralCell(ref VRageMath.Vector3I cellId) { MyProceduralCell cell = new MyProceduralCell(cellId, this); ProfilerShort.Begin("GenerateObjectSeedsCell"); IMyModule densityFunctionFilled = GetCellDensityFunctionFilled(cell.BoundingVolume); if (densityFunctionFilled == null) { ProfilerShort.End(); return null; } IMyModule densityFunctionRemoved = GetCellDensityFunctionRemoved(cell.BoundingVolume); int cellSeed = GetCellSeed(ref cellId); var random = MyRandom.Instance; using (random.PushSeed(cellSeed)) { int index = 0; Vector3I subCellId = Vector3I.Zero; Vector3I max = new Vector3I(SUBCELLS - 1); for (var iter = new Vector3I.RangeIterator(ref Vector3I.Zero, ref max); iter.IsValid(); iter.GetNext(out subCellId)) { // there is a bug in the position calculation which can very rarely cause overlaping objects but backwards compatibility so meh Vector3D position = new Vector3D(random.NextDouble(), random.NextDouble(), random.NextDouble()); position += (Vector3D)subCellId / SUBCELL_SIZE; position += cellId; position *= CELL_SIZE; if (!MyEntities.IsInsideWorld(position)) { continue; } ProfilerShort.Begin("Density functions"); double valueRemoved = -1; if (densityFunctionRemoved != null) { valueRemoved = densityFunctionRemoved.GetValue(position.X, position.Y, position.Z); if (valueRemoved <= -1) { ProfilerShort.End(); continue; } } var valueFilled = densityFunctionFilled.GetValue(position.X, position.Y, position.Z); if (densityFunctionRemoved != null) { if (valueRemoved < valueFilled) { ProfilerShort.End(); continue; } } ProfilerShort.End(); if (valueFilled < m_objectDensity) // -1..+1 { var objectSeed = new MyObjectSeed(cell, position, GetObjectSize(random.NextDouble())); objectSeed.Type = GetSeedType(random.NextDouble()); objectSeed.Seed = random.Next(); objectSeed.Index = index++; GenerateObject(cell, objectSeed, ref index, random, densityFunctionFilled, densityFunctionRemoved); } } } ProfilerShort.End(); return cell; }
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.Type) { case MyObjectSeedType.Moon: break; case MyObjectSeedType.Planet: m_tmpClusterBoxes.Add(objectSeed.BoundingVolume); for (int i = 0; i < MOONS_MAX; ++i) { var direction = 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.Seed = random.Next(); clusterObjectSeed.Type = MyObjectSeedType.Moon; clusterObjectSeed.Index = index++; clusterObjectSeed.UserData = new MySphereDensityFunction(position, OBJECT_SEED_RADIUS, OBJECT_SEED_RADIUS); 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; } }
protected override MyProceduralCell GenerateProceduralCell(ref VRageMath.Vector3I cellId) { MyProceduralCell cell = new MyProceduralCell(cellId, this); ProfilerShort.Begin("GenerateObjectSeedsCell"); IMyModule densityFunctionFilled = GetCellDensityFunctionFilled(cell.BoundingVolume); if (densityFunctionFilled == null) { ProfilerShort.End(); return(null); } IMyModule densityFunctionRemoved = GetCellDensityFunctionRemoved(cell.BoundingVolume); int cellSeed = GetCellSeed(ref cellId); var random = MyRandom.Instance; using (random.PushSeed(cellSeed)) { int index = 0; Vector3I subCellId = Vector3I.Zero; Vector3I max = new Vector3I(SUBCELLS - 1); for (var iter = new Vector3I.RangeIterator(ref Vector3I.Zero, ref max); iter.IsValid(); iter.GetNext(out subCellId)) { // there is a bug in the position calculation which can very rarely cause overlaping objects but backwards compatibility so meh Vector3D position = new Vector3D(random.NextDouble(), random.NextDouble(), random.NextDouble()); position += (Vector3D)subCellId / SUBCELL_SIZE; position += cellId; position *= CELL_SIZE; if (!MyEntities.IsInsideWorld(position)) { continue; } ProfilerShort.Begin("Density functions"); double valueRemoved = -1; if (densityFunctionRemoved != null) { valueRemoved = densityFunctionRemoved.GetValue(position.X, position.Y, position.Z); if (valueRemoved <= -1) { ProfilerShort.End(); continue; } } var valueFilled = densityFunctionFilled.GetValue(position.X, position.Y, position.Z); if (densityFunctionRemoved != null) { if (valueRemoved < valueFilled) { ProfilerShort.End(); continue; } } ProfilerShort.End(); if (valueFilled < m_objectDensity) // -1..+1 { var objectSeed = new MyObjectSeed(cell, position, GetObjectSize(random.NextDouble())); objectSeed.Type = GetSeedType(random.NextDouble()); objectSeed.Seed = random.Next(); objectSeed.Index = index++; GenerateObject(cell, objectSeed, ref index, random, densityFunctionFilled, densityFunctionRemoved); } } } ProfilerShort.End(); return(cell); }
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; } }
public MyObjectSeed(MyProceduralCell cell, Vector3D position, double size) { Cell = cell; Size = (float)size; BoundingVolume = new BoundingBoxD(position - Size, position + Size); }
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; } }