public PlanetMaterialRule(MyPlanetMaterialPlacementRule def)
     : base(def)
 {
     Height    = def.Height;
     Latitude  = def.Latitude;
     Longitude = def.Longitude;
     Slope     = def.Slope;
 }
        private void InheritFrom(string generator)
        {
            MyPlanetGeneratorDefinition parent = MyDefinitionManager.Static.GetDefinition <MyPlanetGeneratorDefinition>(MyStringHash.GetOrCompute(generator));

            if (parent == null)
            {
                MyDefinitionManager.Static.LoadingSet.m_planetGeneratorDefinitions.TryGetValue(new MyDefinitionId(typeof(MyObjectBuilder_PlanetGeneratorDefinition), generator), out parent);
            }

            if (parent == null)
            {
                MyLog.Default.WriteLine(String.Format("Could not find planet generator definition for '{0}'.", generator));
                return;
            }

            PlanetMaps                  = parent.PlanetMaps;
            HasAtmosphere               = parent.HasAtmosphere;
            Atmosphere                  = parent.Atmosphere;
            CloudLayers                 = parent.CloudLayers;
            SoundRules                  = parent.SoundRules;
            MusicCategories             = parent.MusicCategories;
            HillParams                  = parent.HillParams;
            MaterialsMaxDepth           = parent.MaterialsMaxDepth;
            MaterialsMinDepth           = parent.MaterialsMinDepth;
            GravityFalloffPower         = parent.GravityFalloffPower;
            HostileAtmosphereColorShift = parent.HostileAtmosphereColorShift;
            SurfaceMaterialTable        = parent.SurfaceMaterialTable;
            DistortionTable             = parent.DistortionTable;
            DefaultSurfaceMaterial      = parent.DefaultSurfaceMaterial;
            DefaultSubSurfaceMaterial   = parent.DefaultSubSurfaceMaterial;
            MaterialGroups              = parent.MaterialGroups;
            MaterialEnvironmentMappings = parent.MaterialEnvironmentMappings;
            SurfaceGravity              = parent.SurfaceGravity;
            AtmosphereSettings          = parent.AtmosphereSettings;
            FolderName                  = parent.FolderName;
            MaterialBlending            = parent.MaterialBlending;
            OreMappings                 = parent.OreMappings;
            AnimalSpawnInfo             = parent.AnimalSpawnInfo;
            NightAnimalSpawnInfo        = parent.NightAnimalSpawnInfo;
            Detail        = parent.Detail;
            SectorDensity = parent.SectorDensity;
        }
        protected override void Init(MyObjectBuilder_DefinitionBase builder)
        {
            base.Init(builder);
            var ob = builder as MyObjectBuilder_PlanetGeneratorDefinition;

            if (ob.InheritFrom != null && ob.InheritFrom.Length > 0)
            {
                InheritFrom(ob.InheritFrom);
            }

            if (ob.PlanetMaps.HasValue)
            {
                PlanetMaps = ob.PlanetMaps.Value;
            }

            if (ob.HasAtmosphere.HasValue)
            {
                HasAtmosphere = ob.HasAtmosphere.Value;
            }

            if (ob.CloudLayers != null)
            {
                CloudLayers = ob.CloudLayers;
            }

            if (ob.SoundRules != null)
            {
                SoundRules = new MyPlanetEnvironmentalSoundRule[ob.SoundRules.Length];

                for (int ruleIndex = 0; ruleIndex < ob.SoundRules.Length; ++ruleIndex)
                {
                    MyPlanetEnvironmentalSoundRule sr;

                    sr = new MyPlanetEnvironmentalSoundRule()
                    {
                        Latitude           = ob.SoundRules[ruleIndex].Latitude,
                        Height             = ob.SoundRules[ruleIndex].Height,
                        SunAngleFromZenith = ob.SoundRules[ruleIndex].SunAngleFromZenith,
                        EnvironmentSound   = MyStringHash.GetOrCompute(ob.SoundRules[ruleIndex].EnvironmentSound)
                    };

                    sr.Latitude.ConvertToSine();
                    sr.SunAngleFromZenith.ConvertToCosine();
                    SoundRules[ruleIndex] = sr;
                }
            }

            if (ob.HillParams.HasValue)
            {
                HillParams = ob.HillParams.Value;
            }

            if (ob.Atmosphere != null)
            {
                Atmosphere = ob.Atmosphere;
            }

            if (ob.GravityFalloffPower.HasValue)
            {
                GravityFalloffPower = ob.GravityFalloffPower.Value;
            }

            if (ob.HostileAtmosphereColorShift != null)
            {
                HostileAtmosphereColorShift = ob.HostileAtmosphereColorShift;
            }

            if (ob.MaterialsMaxDepth.HasValue)
            {
                MaterialsMaxDepth = ob.MaterialsMaxDepth.Value;
            }
            if (ob.MaterialsMinDepth.HasValue)
            {
                MaterialsMinDepth = ob.MaterialsMinDepth.Value;
            }

            if (ob.CustomMaterialTable != null && ob.CustomMaterialTable.Length > 0)
            {
                SurfaceMaterialTable = ob.CustomMaterialTable;
                for (int i = 0; i < SurfaceMaterialTable.Length; i++)
                {
                    if (SurfaceMaterialTable[i].Material == null && !SurfaceMaterialTable[i].HasLayers)
                    {
                        MyLog.Default.WriteLine("Custom material does not contain any material ids.");
                    }
                    else if (SurfaceMaterialTable[i].HasLayers)
                    {
                        // Make the depth cumulative so we don't have to calculate it later.
                        // If we want we can even binary search it.
                        float depth = SurfaceMaterialTable[i].Layers[0].Depth;
                        for (int j = 1; j < SurfaceMaterialTable[i].Layers.Length; j++)
                        {
                            SurfaceMaterialTable[i].Layers[j].Depth += depth;
                            depth = SurfaceMaterialTable[i].Layers[j].Depth;
                        }
                    }
                }
            }

            if (ob.DistortionTable != null && ob.DistortionTable.Length > 0)
            {
                DistortionTable = ob.DistortionTable;
            }

            if (ob.DefaultSurfaceMaterial != null)
            {
                DefaultSurfaceMaterial = ob.DefaultSurfaceMaterial;
            }

            if (ob.DefaultSubSurfaceMaterial != null)
            {
                DefaultSubSurfaceMaterial = ob.DefaultSubSurfaceMaterial;
            }

            if (ob.SurfaceGravity.HasValue)
            {
                SurfaceGravity = ob.SurfaceGravity.Value;
            }

            if (ob.AtmosphereSettings != null)
            {
                AtmosphereSettings = ob.AtmosphereSettings;
            }

            // Folder name is not inherited to avoid weirdness.
            FolderName = ob.FolderName != null ? ob.FolderName : ob.Id.SubtypeName;

            if (ob.ComplexMaterials != null && ob.ComplexMaterials.Length > 0)
            {
                MaterialGroups = ob.ComplexMaterials;

                for (int k = 0; k < ob.ComplexMaterials.Length; k++)
                {
                    var        group        = ob.ComplexMaterials[k];
                    var        matRules     = group.MaterialRules;
                    List <int> badMaterials = new List <int>();

                    for (int i = 0; i < matRules.Length; i++)
                    {
                        if (matRules[i].Material == null && (matRules[i].Layers == null || matRules[i].Layers.Length == 0))
                        {
                            MyLog.Default.WriteLine("Material rule does not contain any material ids.");
                            badMaterials.Add(i);
                            continue;
                        }
                        else if (matRules[i].Layers != null && matRules[i].Layers.Length != 0)
                        {
                            // Make the depth cumulative so we don't have to calculate it later.
                            // If we want we can even binary search it.
                            float depth = matRules[i].Layers[0].Depth;
                            for (int j = 1; j < matRules[i].Layers.Length; j++)
                            {
                                matRules[i].Layers[j].Depth += depth;
                                depth = matRules[i].Layers[j].Depth;
                            }
                        }

                        // We use the cosine later so we precompute it here.
                        matRules[i].Slope.ConvertToCosine();
                        matRules[i].Latitude.ConvertToSine();
                        matRules[i].Longitude.ConvertToCosineLongitude();
                    }

                    if (badMaterials.Count > 0)
                    {
                        matRules = matRules.RemoveIndices(badMaterials);
                    }

                    group.MaterialRules = matRules;
                }
            }

            if (ob.EnvironmentItems != null && ob.EnvironmentItems.Length > 0)
            {
                MaterialEnvironmentMappings = new Dictionary <int, Dictionary <string, List <MyPlanetEnvironmentMapping> > >();

                for (int i = 0; i < ob.EnvironmentItems.Length; i++)
                {
                    var map = ob.EnvironmentItems[i];
                    if (map.Rule == null)
                    {
                        map.Rule = new MyPlanetSurfaceRule();
                    }
                    map.Rule.Slope.ConvertToCosine();
                    map.Rule.Latitude.ConvertToSine();
                    map.Rule.Longitude.ConvertToCosineLongitude();

                    // If the mapping does not assign a material it is ignored
                    if (map.Materials == null)
                    {
                        break;
                    }

                    if (map.Biomes == null)
                    {
                        map.Biomes = m_arrayOfZero;
                    }

                    foreach (var biome in map.Biomes)
                    {
                        Dictionary <string, List <MyPlanetEnvironmentMapping> > matmap;

                        if (MaterialEnvironmentMappings.ContainsKey(biome))
                        {
                            matmap = MaterialEnvironmentMappings[biome];
                        }
                        else
                        {
                            matmap = new Dictionary <string, List <MyPlanetEnvironmentMapping> >();
                            MaterialEnvironmentMappings.Add(biome, matmap);
                        }

                        foreach (var material in map.Materials)
                        {
                            if (!matmap.ContainsKey(material))
                            {
                                matmap.Add(material, new List <MyPlanetEnvironmentMapping>());
                            }

                            matmap[material].Add(new MyPlanetEnvironmentMapping(map));
                        }
                    }
                }
            }

            if (ob.OreMappings != null)
            {
                OreMappings = ob.OreMappings;
            }

            if (ob.MaterialBlending.HasValue)
            {
                MaterialBlending = ob.MaterialBlending.Value;
            }

            if (ob.SurfaceDetail != null)
            {
                Detail = ob.SurfaceDetail;
            }

            if (ob.AnimalSpawnInfo != null)
            {
                AnimalSpawnInfo = ob.AnimalSpawnInfo;
            }

            if (ob.NightAnimalSpawnInfo != null)
            {
                NightAnimalSpawnInfo = ob.NightAnimalSpawnInfo;
            }

            if (ob.SectorDensity.HasValue)
            {
                SectorDensity = ob.SectorDensity.Value;
            }
        }