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 Vector3D GetRandomDirection(MyRandom random) { double phi = random.NextDouble() * 2.0 * Math.PI; double z = random.NextDouble() * 2.0 - 1.0; double root = Math.Sqrt(1.0 - z * z); return new Vector3D(root * Math.Cos(phi), root * Math.Sin(phi), z); }
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; } }