/// <summary>
        /// Generates all Cells data that are within sphere, if they have not been generated.
        /// </summary>
        /// <param name="sphere">Bounding Sphere of the cells to generate</param>
        protected void GenerateObjectsData(ref BoundingSphereD sphere)
        {
            BoundingBoxD box = BoundingBoxD.CreateFromSphere(sphere);

            Vector3I cellId = Vector3I.Floor(box.Min / CELL_SIZE);

            for (var it = GetCellsIterator(sphere); it.IsValid(); it.GetNext(out cellId))
            {
                if (m_cells.ContainsKey(cellId))
                {
                    continue;
                }

                BoundingBoxD cellBounds = new BoundingBoxD(cellId * CELL_SIZE, (cellId + 1) * CELL_SIZE);
                if (!(sphere.Contains(cellBounds) != ContainmentType.Disjoint))
                {
                    continue;
                }

                MyProceduralCell cell = GenerateCell(ref cellId);
                if (cell != null)
                {
                    m_cells.Add(cellId, cell);

                    BoundingBoxD aabb = cell.BoundingVolume;
                    cell.proxyId = m_cellsTree.AddProxy(ref aabb, cell, 0u);
                }
            }
        }
        public override MyProceduralCell GenerateCell(ref Vector3I id)
        {
            MyProceduralCell cell = new MyProceduralCell(id, CELL_SIZE_);
            int cellSeed          = GetCellSeed(ref id);

            using (MyRandom.Instance.PushSeed(cellSeed))
            {
                int index = 0;

                int subCellSize = (int)(OBJECT_SIZE_MAX * 2 / m_density);
                int subcells    = CELL_SIZE_ / subCellSize;

                Vector3I subcellId = Vector3I.Zero;
                Vector3I max       = new Vector3I(subcells - 1);

                for (var it = new Vector3I_RangeIterator(ref Vector3I.Zero, ref max); it.IsValid(); it.GetNext(out subcellId))
                {
                    Vector3D position = new Vector3D(MyRandom.Instance.NextDouble(), MyRandom.Instance.NextDouble(), MyRandom.Instance.NextDouble());
                    position += (Vector3D)subcellId;
                    position *= subCellSize;
                    position += id * CELL_SIZE_;

                    if (!MyEntities.IsInsideWorld(position))
                    {
                        continue;
                    }

                    MySystemItem obj = IsInsideRing(position);

                    if (obj == null)
                    {
                        continue;
                    }
                    int minSize = OBJECT_SIZE_MIN;
                    int maxSize = OBJECT_SIZE_MAX;

                    if (obj.Type == SystemObjectType.BELT)
                    {
                        minSize = ((MySystemBeltItem)obj).RoidSize;
                    }

                    if (obj.Type == SystemObjectType.RING)
                    {
                        minSize = ((MyPlanetRingItem)obj).RoidSize;
                        maxSize = ((MyPlanetRingItem)obj).RoidSizeMax;
                    }

                    var cellObject = new MyObjectSeed(cell, position, MyRandom.Instance.Next(Math.Min(maxSize, minSize), Math.Max(maxSize, minSize)));
                    cellObject.Params.Type  = MyObjectSeedType.Asteroid;
                    cellObject.Params.Seed  = MyRandom.Instance.Next();
                    cellObject.Params.Index = index++;

                    cell.AddObject(cellObject);
                }
            }

            return(cell);
        }
        protected override MyProceduralCell GenerateCellSeeds(Vector3I cellId)
        {
            if (m_loadedCells.ContainsKey(cellId))
            {
                return(null);
            }

            var settings = MySettingsSession.Static.Settings.GeneratorSettings;

            if (settings.AsteroidGenerator == AsteroidGenerationMethod.VANILLA)
            {
                return(null);
            }

            MyProceduralCell cell = new MyProceduralCell(cellId, CELL_SIZE);
            int    cellSeed       = CalculateCellSeed(cellId);
            int    index          = 0;
            double subCellSize    = OBJECT_SIZE_MAX * 1f / settings.AsteroidDensity;
            int    subcells       = (int)(CELL_SIZE / subCellSize);

            using (MyRandom.Instance.PushSeed(cellSeed))
            {
                Vector3I subcellId = Vector3I.Zero;
                Vector3I max       = new Vector3I(subcells - 1);

                for (var it = new Vector3I_RangeIterator(ref Vector3I.Zero, ref max); it.IsValid(); it.GetNext(out subcellId))
                {
                    Vector3D position = new Vector3D(MyRandom.Instance.NextDouble(), MyRandom.Instance.NextDouble(), MyRandom.Instance.NextDouble());
                    position += (Vector3D)subcellId;
                    position *= subCellSize;
                    position += ((Vector3D)cellId) * CELL_SIZE;

                    if (!MyEntities.IsInsideWorld(position) || (settings.WorldSize >= 0 && position.Length() > settings.WorldSize))
                    {
                        continue;
                    }

                    var ring = GetAsteroidObjectAt(position);

                    if (ring == null)
                    {
                        continue;
                    }

                    var cellObjectSeed = new MyObjectSeed(cell, position, MyRandom.Instance.Next(ring.AsteroidSize.Min, ring.AsteroidSize.Max));
                    cellObjectSeed.Params.Type          = VRage.Game.MyObjectSeedType.Asteroid;
                    cellObjectSeed.Params.Seed          = MyRandom.Instance.Next();
                    cellObjectSeed.Params.Index         = index++;
                    cellObjectSeed.Params.GeneratorSeed = m_definition.UseGeneratorSeed ? MyRandom.Instance.Next() : 0;

                    cell.AddObject(cellObjectSeed);

                    MyPluginLog.Debug("Adding seed");
                }
            }

            return(cell);
        }
        /// <summary>
        /// Gets all seeds within said bounds.
        /// If a cell inside the bounds is not loaded, it will generate the seed but wont load the cell.
        /// </summary>
        /// <param name="bounds">Bounds to get seeds from</param>
        /// <param name="list">List to put seeds into.</param>
        public void GetSeedsInBounds(BoundingSphereD bounds, List <MyObjectSeed> list)
        {
            BoundingBoxD box    = BoundingBoxD.CreateFromSphere(bounds);
            Vector3I     cellId = Vector3I.Floor(box.Min / m_cellSize);

            for (var it = GetCellsIterator(box); it.IsValid(); it.GetNext(out cellId))
            {
                if (m_loadedCells.ContainsKey(cellId))
                {
                    m_loadedCells[cellId].GetAll(list, false);
                }
                else
                {
                    MyProceduralCell cell = GenerateCellSeeds(cellId);
                    cell.GetAll(list);
                }
            }
        }
        /// <summary>
        /// Generates all marked to be loaded cells seeds
        /// </summary>
        public void LoadCells()
        {
            m_toLoadCells.ApplyAdditions();

            foreach (var cellId in m_toLoadCells)
            {
                if (m_loadedCells.ContainsKey(cellId))
                {
                    continue;
                }

                MyProceduralCell cell = GenerateCellSeeds(cellId);
                if (cell != null)
                {
                    m_loadedCells.Add(cellId, cell);

                    BoundingBoxD aabb = cell.BoundingVolume;
                    cell.proxyId = m_cellsTree.AddProxy(ref aabb, cell, 0u);
                }
            }

            m_toLoadCells.Clear();
        }