public static void AddPlanetPrefab(string prefabName, string name)
        {
            DictionaryValuesReader<MyDefinitionId, MyPlanetPrefabDefinition> planetDefinitions = MyDefinitionManager.Static.GetPlanetsPrefabsDefinitions();
            foreach (var planetPrebabDefinition in planetDefinitions)
            {
                if(planetPrebabDefinition.Id.SubtypeName == prefabName)
                {
                    var voxelMap = new MyPlanet();
                    var ob = planetPrebabDefinition.PlanetBuilder;
             
                    string storageName = MyFileSystem.ContentPath + "\\VoxelMaps\\" + ob.StorageName + MyVoxelConstants.FILE_EXTENSION;
                    voxelMap.EntityId = ob.EntityId;

                    MyPlanetInitArguments planetInitArguments;
                    planetInitArguments.StorageName = ob.StorageName;
                    planetInitArguments.Storage = MyStorageBase.LoadFromFile(storageName);
                    planetInitArguments.PositionMinCorner = ob.PositionAndOrientation.Value.Position;
                    planetInitArguments.AveragePlanetRadius = ob.Radius;
                    planetInitArguments.AtmosphereRadius = ob.AtmosphereRadius;
                    planetInitArguments.MaximumHillRadius = ob.MaximumHillRadius;
                    planetInitArguments.MinimumSurfaceRadius = ob.MinimumSurfaceRadius;
                    planetInitArguments.HasAtmosphere = ob.HasAtmosphere;
                    planetInitArguments.AtmosphereWavelengths = ob.AtmosphereWavelengths;
                    planetInitArguments.MaxOxygen = ob.MaximumOxygen;
                    planetInitArguments.GravityFalloff = ob.GravityFalloff;
                    planetInitArguments.MarkAreaEmpty = true;

                    voxelMap.Init(planetInitArguments);
                    MyEntities.Add(voxelMap);
                }
            }

        }
        public static void AddPlanetPrefab(string planetName,string definitionName,Vector3D position, bool addGPS)
        {
            DictionaryValuesReader<MyDefinitionId, MyPlanetPrefabDefinition> planetPrefabDefinitions = MyDefinitionManager.Static.GetPlanetsPrefabsDefinitions();
            foreach (var planetPrefabDefinition in planetPrefabDefinitions)
            {
                if (planetPrefabDefinition.Id.SubtypeName == planetName)
                {
                    MyPlanetGeneratorDefinition planetDefinition = MyDefinitionManager.Static.GetDefinition<MyPlanetGeneratorDefinition>(MyStringHash.GetOrCompute(definitionName));

                    var planet = new MyPlanet();
                    var ob = planetPrefabDefinition.PlanetBuilder;
             
                    string storageName = MyFileSystem.ContentPath + "\\VoxelMaps\\" + ob.StorageName + MyVoxelConstants.FILE_EXTENSION;
                    planet.EntityId = ob.EntityId;

                    MyPlanetInitArguments planetInitArguments;
                    planetInitArguments.StorageName = ob.StorageName;
                    planetInitArguments.Storage = MyStorageBase.LoadFromFile(storageName);
                    planetInitArguments.PositionMinCorner = position;
                    planetInitArguments.Radius = ob.Radius;
                    planetInitArguments.AtmosphereRadius = ob.AtmosphereRadius;
                    planetInitArguments.MaxRadius = ob.MaximumHillRadius;
                    planetInitArguments.MinRadius = ob.MinimumSurfaceRadius;
                    planetInitArguments.HasAtmosphere = planetDefinition.HasAtmosphere;
                    planetInitArguments.AtmosphereWavelengths = ob.AtmosphereWavelengths;
                    planetInitArguments.GravityFalloff = planetDefinition.GravityFalloffPower;
                    planetInitArguments.MarkAreaEmpty = true;
                    planetInitArguments.AtmosphereSettings = ob.AtmosphereSettings.HasValue ? ob.AtmosphereSettings.Value : MyAtmosphereSettings.Defaults();
                    planetInitArguments.SurfaceGravity = planetDefinition.SurfaceGravity;
                    planetInitArguments.AddGps = addGPS;
                    planetInitArguments.SpherizeWithDistance = true;
                    planetInitArguments.Generator = planetDefinition;
                    planetInitArguments.UserCreated = false;
                    planetInitArguments.InitializeComponents = true;

                    planet.Init(planetInitArguments);
                    MyEntities.Add(planet);
                    MyEntities.RaiseEntityCreated(planet);
                }
            }

        }
        private void CreatePlanet(int seed, float size)
        {
            Vector3D pos = MySector.MainCamera.Position + MySector.MainCamera.ForwardVector * size * 3 - new Vector3D(size);

            MyPlanetGeneratorDefinition planetDefinition = MyDefinitionManager.Static.GetDefinition<MyPlanetGeneratorDefinition>(MyStringHash.GetOrCompute(m_selectedPlanetName));
            MyPlanetStorageProvider provider = new MyPlanetStorageProvider();

            provider.Init(seed, planetDefinition, size / 2f);

            IMyStorage storage = new MyOctreeStorage(provider, provider.StorageSize);

            float minHillSize = provider.Radius * planetDefinition.HillParams.Min;
            float maxHillSize = provider.Radius * planetDefinition.HillParams.Max;

            float averagePlanetRadius = provider.Radius;

            float outerRadius = averagePlanetRadius + maxHillSize;
            float innerRadius = averagePlanetRadius + minHillSize;

            float atmosphereRadius = planetDefinition.AtmosphereSettings.HasValue && planetDefinition.AtmosphereSettings.Value.Scale > 1f ? 1 + planetDefinition.AtmosphereSettings.Value.Scale : 1.75f;
            atmosphereRadius *= provider.Radius;

            var planet = new MyPlanet();
            planet.EntityId = MyRandom.Instance.NextLong();

            MyPlanetInitArguments planetInitArguments;
            planetInitArguments.StorageName = "test";
            planetInitArguments.Storage = storage;
            planetInitArguments.PositionMinCorner = pos;
            planetInitArguments.Radius = provider.Radius;
            planetInitArguments.AtmosphereRadius = atmosphereRadius;
            planetInitArguments.MaxRadius = outerRadius;
            planetInitArguments.MinRadius = innerRadius;
            planetInitArguments.HasAtmosphere = planetDefinition.HasAtmosphere;
            planetInitArguments.AtmosphereWavelengths = Vector3.Zero;
            planetInitArguments.GravityFalloff = planetDefinition.GravityFalloffPower;
            planetInitArguments.MarkAreaEmpty = true;
            planetInitArguments.AtmosphereSettings = planetDefinition.AtmosphereSettings.HasValue ? planetDefinition.AtmosphereSettings.Value : MyAtmosphereSettings.Defaults();
            planetInitArguments.SurfaceGravity = planetDefinition.SurfaceGravity;
            planetInitArguments.AddGps = false;
            planetInitArguments.SpherizeWithDistance = true;
            planetInitArguments.Generator = planetDefinition;
            planetInitArguments.UserCreated = true;

            planet.Init(planetInitArguments);

            m_lastAsteroidInfo = new SpawnAsteroidInfo()
            {
                Asteroid = null,
                RandomSeed = seed,
                Position = Vector3D.Zero,
                IsProcedural = true,
                ProceduralRadius = size,
            };

            MyClipboardComponent.Static.ActivateVoxelClipboard(planet.GetObjectBuilder(), storage, MySector.MainCamera.ForwardVector, (storage.Size * 0.5f).Length());
        }
        public static MyPlanet AddPlanet(string storageName, Vector3D positionMinCorner, int seed, float size, long entityId = 0)
        {
            m_materialsByOreType.Clear();
            m_oreProbalities.Clear();
            m_spawningMaterials.Clear();
            m_organicMaterials.Clear();

            DictionaryValuesReader<MyDefinitionId, MyPlanetDefinition> planetDefinitions = MyDefinitionManager.Static.GetPlanetsDefinitions();

            foreach (var planetDefinition in planetDefinitions)
            {
                if (planetDefinition.Diameter.Min <= size && size <= planetDefinition.Diameter.Max)
                {

                    var random = MyRandom.Instance;
                    using (var stateToken = random.PushSeed(seed))
                    {
                        BuildOreProbabilities(planetDefinition);
                        FillMaterialCollections();

                        MyCsgShapePlanetShapeAttributes shapeAttributes = new MyCsgShapePlanetShapeAttributes();

                        shapeAttributes.Seed = seed;
                        shapeAttributes.Diameter = size;
                        shapeAttributes.Radius = size / 2.0f;
                        shapeAttributes.LayerDeviationSeed = random.Next();
                        shapeAttributes.LayerDeviationNoiseFrequency = random.NextFloat(100.0f, 500.0f);
                        shapeAttributes.NoiseFrequency = random.NextFloat(planetDefinition.StructureRatio.Min, planetDefinition.StructureRatio.Max);
                        shapeAttributes.NormalNoiseFrequency = random.NextFloat(planetDefinition.NormalNoiseValue.Min, planetDefinition.NormalNoiseValue.Max);
                        shapeAttributes.DeviationScale = random.NextFloat(planetDefinition.Deviation.Min, planetDefinition.Deviation.Max);

                        MyCsgShapePlanetHillAttributes hillAttributes = FillValues(planetDefinition.HillParams, random);
                        MyCsgShapePlanetHillAttributes canyonAttributes = FillValues(planetDefinition.CanyonParams, random);

                        float planetHalfDeviation = (shapeAttributes.Diameter * shapeAttributes.DeviationScale) / 2.0f;
                        float averagePlanetRadius = shapeAttributes.Diameter * (1 - shapeAttributes.DeviationScale * hillAttributes.SizeRatio) / 2.0f;

                        float hillHalfDeviation = planetHalfDeviation * hillAttributes.SizeRatio;
                        float canyonHalfDeviation = planetHalfDeviation * canyonAttributes.SizeRatio;

                        float outerRadius = averagePlanetRadius + hillHalfDeviation * 1.5f;
                        float innerRadius = averagePlanetRadius - canyonHalfDeviation * 2.5f;

                        float atmosphereRadius = MathHelper.Max(outerRadius, averagePlanetRadius * 1.06f);
                        float minPlanetRadius = MathHelper.Min(innerRadius, averagePlanetRadius - planetHalfDeviation * 2 * 2.5f);

                        bool isHostile = random.NextFloat(0, 1) < planetDefinition.HostilityProbability;
                        MyMaterialLayer[] materialLayers = CreateMaterialLayers(planetDefinition, isHostile, random, averagePlanetRadius, hillHalfDeviation, canyonHalfDeviation, ref outerRadius, ref innerRadius);

                        IMyStorage storage = new MyOctreeStorage(MyCompositeShapeProvider.CreatePlanetShape(0, ref shapeAttributes, ref hillAttributes, ref canyonAttributes, materialLayers), FindBestOctreeSize(size));

                        float redAtmosphereShift = isHostile ? random.NextFloat(planetDefinition.HostileAtmosphereColorShift.R.Min, planetDefinition.HostileAtmosphereColorShift.R.Max) : 0;
                        float greenAtmosphereShift = isHostile ? random.NextFloat(planetDefinition.HostileAtmosphereColorShift.G.Min, planetDefinition.HostileAtmosphereColorShift.G.Max) : 0;
                        float blueAtmosphereShift = isHostile ? random.NextFloat(planetDefinition.HostileAtmosphereColorShift.B.Min, planetDefinition.HostileAtmosphereColorShift.B.Max) : 0;

                        Vector3 atmosphereWavelengths = new Vector3(0.650f + redAtmosphereShift, 0.570f + greenAtmosphereShift, 0.475f + blueAtmosphereShift);

                        atmosphereWavelengths.X = MathHelper.Clamp(atmosphereWavelengths.X, 0.1f, 1.0f);
                        atmosphereWavelengths.Y = MathHelper.Clamp(atmosphereWavelengths.Y, 0.1f, 1.0f);
                        atmosphereWavelengths.Z = MathHelper.Clamp(atmosphereWavelengths.Z, 0.1f, 1.0f);

                        float gravityFalloff = random.NextFloat(planetDefinition.GravityFalloffPower.Min, planetDefinition.GravityFalloffPower.Max);

                        var voxelMap = new MyPlanet();
                        voxelMap.EntityId = entityId;

                        voxelMap.Init(storageName, storage, positionMinCorner, averagePlanetRadius, atmosphereRadius,
                            averagePlanetRadius + hillHalfDeviation, minPlanetRadius, planetDefinition.HasAtmosphere, atmosphereWavelengths, isHostile ? 0.0f : 1.0f, gravityFalloff);
                        MyEntities.Add(voxelMap);
                        return voxelMap;
                    }


                }
            }
            return null;
        }
        public static MyPlanet AddPlanet(string storageName, Vector3D positionMinCorner, int seed, float size, long entityId = 0)
        {
            if(MyFakes.ENABLE_PLANETS == false)
            {
                return null;
            }

            m_materialsByOreType.Clear();
            m_oreProbalities.Clear();
            m_spawningMaterials.Clear();
            m_organicMaterials.Clear();

            DictionaryValuesReader<MyDefinitionId, MyPlanetGeneratorDefinition> planetDefinitions = MyDefinitionManager.Static.GetPlanetsGeneratorsDefinitions();

            foreach (var planetGeneratorDefinition in planetDefinitions)
            {
                if (planetGeneratorDefinition.Diameter.Min <= size && size <= planetGeneratorDefinition.Diameter.Max)
                {
                    var random = MyRandom.Instance;
                    using (var stateToken = random.PushSeed(seed))
                    {
                        BuildOreProbabilities(planetGeneratorDefinition);
                        FillMaterialCollections();

                        MyCsgShapePlanetShapeAttributes shapeAttributes = new MyCsgShapePlanetShapeAttributes();

                        shapeAttributes.Seed = seed;
                        shapeAttributes.Diameter = size;
                        shapeAttributes.Radius = size / 2.0f;
                        shapeAttributes.LayerDeviationSeed = random.Next();
                        shapeAttributes.LayerDeviationNoiseFrequency = random.NextFloat(10.0f, 500.0f);
                        shapeAttributes.NoiseFrequency = random.NextFloat(planetGeneratorDefinition.StructureRatio.Min, planetGeneratorDefinition.StructureRatio.Max);
                        shapeAttributes.NormalNoiseFrequency = random.NextFloat(planetGeneratorDefinition.NormalNoiseValue.Min, planetGeneratorDefinition.NormalNoiseValue.Max);
                        shapeAttributes.DeviationScale = random.NextFloat(planetGeneratorDefinition.Deviation.Min, planetGeneratorDefinition.Deviation.Max);

                        MyCsgShapePlanetHillAttributes hillAttributes = FillValues(planetGeneratorDefinition.HillParams, random);
                        MyCsgShapePlanetHillAttributes canyonAttributes = FillValues(planetGeneratorDefinition.CanyonParams, random);

                        float planetHalfDeviation = (shapeAttributes.Diameter * shapeAttributes.DeviationScale) / 2.0f;
                        float averagePlanetRadius = shapeAttributes.Diameter * (1 - shapeAttributes.DeviationScale * hillAttributes.SizeRatio) / 2.0f;

                        float hillHalfDeviation = planetHalfDeviation * hillAttributes.SizeRatio;
                        float canyonHalfDeviation = planetHalfDeviation * canyonAttributes.SizeRatio;

                        float outerRadius = averagePlanetRadius + hillHalfDeviation * 1.5f;
                        float innerRadius = averagePlanetRadius - canyonHalfDeviation * 2.5f;

                        float atmosphereRadius = MathHelper.Max(outerRadius, averagePlanetRadius * 1.06f);
                        float minPlanetRadius = MathHelper.Min(innerRadius, averagePlanetRadius - planetHalfDeviation * 2 * 2.5f);

                        MyCsgShapePlanetMaterialAttributes materialAttributes = new MyCsgShapePlanetMaterialAttributes();
                        materialAttributes.OreStartDepth = innerRadius - random.NextFloat(planetGeneratorDefinition.MaterialsMinDeph.Min, planetGeneratorDefinition.MaterialsMinDeph.Max);
                        materialAttributes.OreEndDepth = innerRadius - random.NextFloat(planetGeneratorDefinition.MaterialsMaxDeph.Min, planetGeneratorDefinition.MaterialsMaxDeph.Max);
                        materialAttributes.OreEndDepth = MathHelper.Max(materialAttributes.OreEndDepth, 0);
                        materialAttributes.OreStartDepth = MathHelper.Max(materialAttributes.OreStartDepth, 0);

                        bool isHostile = random.NextFloat(0, 1) < planetGeneratorDefinition.HostilityProbability;
                        MyMaterialLayer[] materialLayers = CreateMaterialLayers(planetGeneratorDefinition, isHostile, random, averagePlanetRadius, hillHalfDeviation, canyonHalfDeviation, ref outerRadius, ref innerRadius);

                        
                        materialAttributes.Layers = materialLayers;
                        materialAttributes.OreProbabilities = new MyOreProbability[m_oreProbalities.Count];

                        for(int i =0; i <m_oreProbalities.Count;++i)
                        {
                            materialAttributes.OreProbabilities[i] = m_oreProbalities[i];
                            materialAttributes.OreProbabilities[i].CummulativeProbability /= m_oreCummulativeProbability;
                        }

                        IMyStorage storage = new MyOctreeStorage(MyCompositeShapeProvider.CreatePlanetShape(0, ref shapeAttributes, ref hillAttributes, ref canyonAttributes, ref materialAttributes), FindBestOctreeSize(size));

                        float redAtmosphereShift = isHostile ? random.NextFloat(planetGeneratorDefinition.HostileAtmosphereColorShift.R.Min, planetGeneratorDefinition.HostileAtmosphereColorShift.R.Max) : 0;
                        float greenAtmosphereShift = isHostile ? random.NextFloat(planetGeneratorDefinition.HostileAtmosphereColorShift.G.Min, planetGeneratorDefinition.HostileAtmosphereColorShift.G.Max) : 0;
                        float blueAtmosphereShift = isHostile ? random.NextFloat(planetGeneratorDefinition.HostileAtmosphereColorShift.B.Min, planetGeneratorDefinition.HostileAtmosphereColorShift.B.Max) : 0;

                        Vector3 atmosphereWavelengths = new Vector3(0.650f + redAtmosphereShift, 0.570f + greenAtmosphereShift, 0.475f + blueAtmosphereShift);

                        atmosphereWavelengths.X = MathHelper.Clamp(atmosphereWavelengths.X, 0.1f, 1.0f);
                        atmosphereWavelengths.Y = MathHelper.Clamp(atmosphereWavelengths.Y, 0.1f, 1.0f);
                        atmosphereWavelengths.Z = MathHelper.Clamp(atmosphereWavelengths.Z, 0.1f, 1.0f);

                        float gravityFalloff = random.NextFloat(planetGeneratorDefinition.GravityFalloffPower.Min, planetGeneratorDefinition.GravityFalloffPower.Max);

                        var voxelMap = new MyPlanet();
                        voxelMap.EntityId = entityId;

                        MyPlanetInitArguments planetInitArguments;
                        planetInitArguments.StorageName = storageName;
                        planetInitArguments.Storage = storage;
                        planetInitArguments.PositionMinCorner = positionMinCorner;
                        planetInitArguments.AveragePlanetRadius = averagePlanetRadius;
                        planetInitArguments.AtmosphereRadius = atmosphereRadius;
                        planetInitArguments.MaximumHillRadius = averagePlanetRadius + hillHalfDeviation;
                        planetInitArguments.MinimumSurfaceRadius = minPlanetRadius;
                        planetInitArguments.HasAtmosphere = planetGeneratorDefinition.HasAtmosphere;
                        planetInitArguments.AtmosphereWavelengths = atmosphereWavelengths;
                        planetInitArguments.MaxOxygen = isHostile ? 0.0f : 1.0f;
                        planetInitArguments.GravityFalloff = gravityFalloff;
                        planetInitArguments.MarkAreaEmpty = false;

                        voxelMap.Init(planetInitArguments);

                        MyEntities.Add(voxelMap);

                        m_materialsByOreType.Clear();
                        m_oreProbalities.Clear();
                        m_spawningMaterials.Clear();
                        m_organicMaterials.Clear();

                        return voxelMap;
                    }
                }
            }
            return null;
        }
        private static MyPlanet CreatePlanet(string storageName, string planetName, ref Vector3D positionMinCorner, int seed, float size, long entityId, ref MyPlanetGeneratorDefinition generatorDef, bool addGPS,bool userCreated = false)
        {
            if (MyFakes.ENABLE_PLANETS == false)
            {
                return null;
            }

            var random = MyRandom.Instance;
            using (MyRandom.Instance.PushSeed(seed))
            {

                MyPlanetStorageProvider provider = new MyPlanetStorageProvider();
                provider.Init(seed, generatorDef, size/2f);

                IMyStorage storage = new MyOctreeStorage(provider, provider.StorageSize);

                float minHillSize = provider.Radius * generatorDef.HillParams.Min;
                float maxHillSize = provider.Radius * generatorDef.HillParams.Max;

                float averagePlanetRadius = provider.Radius;

                float outerRadius = averagePlanetRadius + maxHillSize;
                float innerRadius = averagePlanetRadius + minHillSize;

                float atmosphereRadius = generatorDef.AtmosphereSettings.HasValue && generatorDef.AtmosphereSettings.Value.Scale > 1f ? 1 + generatorDef.AtmosphereSettings.Value.Scale : 1.75f;
                atmosphereRadius *= provider.Radius;

                float redAtmosphereShift = random.NextFloat(generatorDef.HostileAtmosphereColorShift.R.Min, generatorDef.HostileAtmosphereColorShift.R.Max);
                float greenAtmosphereShift = random.NextFloat(generatorDef.HostileAtmosphereColorShift.G.Min, generatorDef.HostileAtmosphereColorShift.G.Max);
                float blueAtmosphereShift = random.NextFloat(generatorDef.HostileAtmosphereColorShift.B.Min, generatorDef.HostileAtmosphereColorShift.B.Max);

                Vector3 atmosphereWavelengths = new Vector3(0.650f + redAtmosphereShift, 0.570f + greenAtmosphereShift, 0.475f + blueAtmosphereShift);

                atmosphereWavelengths.X = MathHelper.Clamp(atmosphereWavelengths.X, 0.1f, 1.0f);
                atmosphereWavelengths.Y = MathHelper.Clamp(atmosphereWavelengths.Y, 0.1f, 1.0f);
                atmosphereWavelengths.Z = MathHelper.Clamp(atmosphereWavelengths.Z, 0.1f, 1.0f);

                var planet = new MyPlanet();
                planet.EntityId = entityId;

                MyPlanetInitArguments planetInitArguments;
                planetInitArguments.StorageName = storageName;
                planetInitArguments.Storage = storage;
                planetInitArguments.PositionMinCorner = positionMinCorner;
                planetInitArguments.Radius = provider.Radius;
                planetInitArguments.AtmosphereRadius = atmosphereRadius;
                planetInitArguments.MaxRadius = outerRadius;
                planetInitArguments.MinRadius = innerRadius;
                planetInitArguments.HasAtmosphere = generatorDef.HasAtmosphere;
                planetInitArguments.AtmosphereWavelengths = atmosphereWavelengths;
                planetInitArguments.GravityFalloff = generatorDef.GravityFalloffPower;
                planetInitArguments.MarkAreaEmpty = true;
                planetInitArguments.AtmosphereSettings = generatorDef.AtmosphereSettings.HasValue ? generatorDef.AtmosphereSettings.Value : MyAtmosphereSettings.Defaults();
                planetInitArguments.SurfaceGravity = generatorDef.SurfaceGravity;
                planetInitArguments.AddGps = addGPS;
                planetInitArguments.SpherizeWithDistance = true;
                planetInitArguments.Generator = generatorDef;
                planetInitArguments.UserCreated = userCreated;
                planetInitArguments.InitializeComponents = true;

                planet.Init(planetInitArguments);

                MyEntities.Add(planet);
                MyEntities.RaiseEntityCreated(planet);

                return planet;
            }
            return null;
        }