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;
            }
        }
示例#7
0
        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;
            }
        }