private static List<PSystemBody> GetBodiesRecursive(PSystemBody body)
 {
     List<PSystemBody> bodies = new List<PSystemBody> ();
     bodies.Add (body);
     foreach (var child in body.children)
     {
         bodies.AddRange(GetBodiesRecursive (child));
     }
     return bodies;
 }
示例#2
0
        public static void GrabPSystemBodies(PSystemBody PSB)
        {
            StarSystem.PSBDict[PSB.celestialBody.bodyName] = PSB;
            Debug.Log(PSB.celestialBody.bodyName);

            foreach (var ChildPSB in PSB.children)
            {
                GrabPSystemBodies(ChildPSB);
            }
        }
示例#3
0
        public Star(StarSystemDefintion star, PSystemBody InternalStarPSB,PSystemBody InternalSunPSB)
        {
            defintion = star;
            var InternalStarCB = InternalStarPSB.celestialBody;

            //Set Star CB and PSB Parameters
            InternalStarPSB.name = star.Name;
            InternalStarPSB.flightGlobalsIndex = star.FlightGlobalsIndex;
            InternalStarPSB.children.Clear();

            InternalStarPSB.enabled = false;

            InternalStarCB.bodyName = star.Name;

            InternalStarCB.Radius = star.Radius;

            InternalStarCB.CBUpdate();

            //Add Star to Sun children
            InternalSunPSB.children.Add(InternalStarPSB);
        }
示例#4
0
 // Patch the FlightGlobalsIndex of bodies
 private void PatchFGI(ref List<int> numbers, ref int index, PSystemBody rootBody)
 {
     foreach (PSystemBody body in rootBody.children)
     {
         if (numbers.Contains(body.flightGlobalsIndex))
             body.flightGlobalsIndex = index++;
         numbers.Add(body.flightGlobalsIndex);
         PatchFGI(ref numbers, ref index, body);
     }
 }
示例#5
0
 // Sort bodies by distance from parent body
 private void RecursivelySortBodies(PSystemBody body)
 {
     body.children = body.children.OrderBy(b => b.orbitDriver.orbit.semiMajorAxis * (1 + b.orbitDriver.orbit.eccentricity)).ToList();
     foreach (PSystemBody child in body.children)
     {
         RecursivelySortBodies (child);
     }
 }
示例#6
0
            // Apply event
            void IParserEventSubscriber.Apply(ConfigNode node)
            {
                // Instantiate (clone) the template body
                GameObject bodyGameObject = UnityEngine.Object.Instantiate (originalBody.gameObject) as GameObject;
                bodyGameObject.name = originalBody.name;
                bodyGameObject.transform.parent = Utility.Deactivator;
                body = bodyGameObject.GetComponent<PSystemBody> ();
                body.children = new List<PSystemBody> ();

                // Clone the scaled version
                body.scaledVersion = UnityEngine.Object.Instantiate (originalBody.scaledVersion) as GameObject;
                body.scaledVersion.transform.parent = Utility.Deactivator;
                body.scaledVersion.name = originalBody.scaledVersion.name;

                // Clone the PQS version (if it has one) and we want the PQS
                if (body.pqsVersion != null && removePQS.value != true)
                {
                    body.pqsVersion = UnityEngine.Object.Instantiate (originalBody.pqsVersion) as PQS;
                    body.pqsVersion.transform.parent = Utility.Deactivator;
                    body.pqsVersion.name = originalBody.pqsVersion.name;
                }
                else
                {
                    // Make sure we have no ties to the PQS, as we wanted to remove it or it didn't exist
                    body.pqsVersion = null;
                    body.celestialBody.ocean = false;
                }

                // Store the initial radius (so scaled version can be computed)
                radius = body.celestialBody.Radius;
            }
 public void ListPlanetsRecursive(PSystemBody body)
 {
     Templates.Add( body );
     foreach (PSystemBody current in body.children)
     {
         ListPlanetsRecursive(current);
     }
 }
示例#8
0
            // Copy orbit provided
            public OrbitLoader(PSystemBody body)
            {
                this.orbit = body.orbitDriver.orbit;
                this.color.value = body.orbitRenderer.orbitColor;

                float[] bounds = new float[] {body.orbitRenderer.lowerCamVsSmaRatio, body.orbitRenderer.upperCamVsSmaRatio};
                this.cameraSmaRatioBounds.value = new List<float>(bounds);
            }
示例#9
0
 // Populate the PSystemBody with the results of the orbit loader
 public void Apply(PSystemBody body)
 {
     if (!double.IsNaN(Templates.instance.epoch))
     {
         if (hasEpoch)
             orbit.epoch += Templates.instance.epoch;
         else
             orbit.epoch = Templates.instance.epoch;
     }
     body.orbitDriver.orbit = orbit;
     body.orbitRenderer.orbitColor = color.value;
     body.orbitRenderer.lowerCamVsSmaRatio = cameraSmaRatioBounds.value[0];
     body.orbitRenderer.upperCamVsSmaRatio = cameraSmaRatioBounds.value[1];
 }
示例#10
0
        public static void GetUsedLists(List<MapSO> mapList, List<Texture> texList, PSystemBody body)
        {
            // get the biome map
            if (body.celestialBody.BiomeMap != null)
                mapList.Add(body.celestialBody.BiomeMap);

            // get any MapSOs in PQSs
            if (body.pqsVersion != null)
            {
                AddMapSOs(mapList, body.pqsVersion); // main PQS

                // get other PQSs (like ocean)
                PQS[] pqss = body.pqsVersion.GetComponentsInChildren<PQS>(true);
                foreach(PQS p in pqss)
                    if(p != body.pqsVersion)
                        AddMapSOs(mapList, p);

            }
            if (body.scaledVersion != null)
                AddTexes(texList, body.scaledVersion);

            // Recurse
            foreach (PSystemBody child in body.children)
                GetUsedLists(mapList, texList, child);
        }
 public extern PSystemBody AddBody(PSystemBody parent);
        public static PSystemBody GenerateSystemBody(PSystem system, PSystemBody parent, string templateName, string name, Orbit orbit)
        {
            // Look up the template body
            PSystemBody template = Utility.FindBody (system.rootBody, templateName);

            // Create a new celestial body as a clone of this template
            PSystemBody clone = system.AddBody (parent);
            clone.name = name;

            // Set up the celestial body of the clone (back up the orbit driver)
            Utility.CopyObjectFields<CelestialBody> (template.celestialBody, clone.celestialBody);
            clone.celestialBody.bodyName = name;
            clone.celestialBody.orbitingBodies = null;
            clone.celestialBody.orbitDriver = clone.orbitDriver;
            clone.flightGlobalsIndex = 100 + template.flightGlobalsIndex;

            // Setup the orbit driver
            clone.orbitRenderer.orbitColor = template.orbitRenderer.orbitColor;
            clone.orbitDriver.orbit = orbit;
            clone.orbitDriver.celestialBody = clone.celestialBody;
            clone.orbitDriver.updateMode = OrbitDriver.UpdateMode.UPDATE;

            // Setup the deactivator object
            GameObject deactivator = new GameObject ("Deactivator");
            deactivator.SetActive (false);
            UnityEngine.Object.DontDestroyOnLoad (deactivator);

            // Clone the template's PQS
            clone.pqsVersion = UnityEngine.Object.Instantiate (template.pqsVersion) as PQS;
            clone.pqsVersion.transform.parent = deactivator.transform;
            clone.pqsVersion.name = name;

            // Clone the scaled space
            clone.scaledVersion = UnityEngine.Object.Instantiate (template.scaledVersion) as GameObject;
            clone.scaledVersion.transform.parent = deactivator.transform;
            clone.scaledVersion.name = name;

            return clone;
        }
        public static PSystemBody GenerateSystemBody(PSystem system, PSystemBody parent, String name, Orbit orbit = null)
        {
            PSystemBody Jool = Utility.FindBody (system.rootBody, "Jool");  // Need the geosphere for scaled version
            PSystemBody Laythe = Utility.FindBody (system.rootBody, "Laythe"); // Need pqs and ocean definitions

            //Utility.DumpObject (Laythe.celestialBody, " Laythe Celestial Body ");
            //Utility.DumpObject (Laythe.pqsVersion, " Laythe PQS ");
            //Transform laytheOcean = Utility.FindInChildren (Laythe.pqsVersion.transform, "LaytheOcean");
            //Utility.DumpObject (laytheOcean.GetComponent<PQS> (), " Laythe Ocean PQS ");

            // AddBody makes the GameObject and stuff. It also attaches it to the system and parent.
            PSystemBody body = system.AddBody (parent);

            // set up the various parameters
            body.name = name;
            body.flightGlobalsIndex = 100;

            // Some parameters of the celestialBody, which represents the actual planet...
            // PSystemBody is more of a container that associates the planet with its orbit
            // and position in the planetary system, etc.
            body.celestialBody.bodyName               = name;
            body.celestialBody.bodyDescription        = "Merciful Kod, this thing just APPEARED! And unlike last time, it wasn't bird droppings on the telescope.";
            body.celestialBody.Radius                 = 320000;
            //body.celestialBody.Radius                 = 3380100;
            body.celestialBody.GeeASL                 = 0.3;
            //body.celestialBody.Mass                   = 6.4185E+23;
            body.celestialBody.Mass                   = 4.5154812E+21;
            body.celestialBody.timeWarpAltitudeLimits = (float[])Laythe.celestialBody.timeWarpAltitudeLimits.Clone();
            body.celestialBody.rotationPeriod         = 88642.6848;
            body.celestialBody.rotates                = true;
            body.celestialBody.BiomeMap               = GenerateCBAttributeMapSO(name);//Dres.celestialBody.BiomeMap;//
            body.celestialBody.scienceValues          = Laythe.celestialBody.scienceValues;
            body.celestialBody.ocean                  = false;

            // Presumably true of Kerbin. I do not know what the consequences are of messing with this exactly.
            // I think this just affects where the Planetarium/Tracking station starts.
            body.celestialBody.isHomeWorld            = false;

            // Setup the orbit of "Kopernicus."  The "Orbit" class actually is built to support serialization straight
            // from Squad, so storing these to files (and loading them) will be pretty easy.
            body.orbitRenderer.orbitColor             = Color.magenta;
            body.orbitDriver.celestialBody            = body.celestialBody;
            body.orbitDriver.updateMode               = OrbitDriver.UpdateMode.UPDATE;
            if (orbit == null)
                body.orbitDriver.orbit = new Orbit (0.0, 0.0, 47500000000, 0, 0, 0, 0, system.rootBody.celestialBody);
            else
                body.orbitDriver.orbit = orbit;

            #region PSystemBody.pqsVersion generation

            // Create the PQS controller game object for Kopernicus
            GameObject controllerRoot       = new GameObject(name);
            controllerRoot.layer            = Constants.GameLayers.LocalSpace;
            controllerRoot.transform.parent = Utility.Deactivator;

            // Create the PQS object and pull all the values from Dres (has some future proofing i guess? adapts to PQS changes)
            body.pqsVersion = controllerRoot.AddComponent<PQS>();
            Utility.CopyObjectFields(Laythe.pqsVersion, body.pqsVersion);
            //body.pqsVersion.surfaceMaterial = new PQSProjectionSurfaceQuad();
            //body.pqsVersion.fallbackMaterial = new PQSProjectionFallback();
            body.pqsVersion.surfaceMaterial = new PQSProjectionAerialQuadRelative(Laythe.pqsVersion.surfaceMaterial); // use until we determine all the functions of the shader textures
            body.pqsVersion.fallbackMaterial = new PQSProjectionFallback(Laythe.pqsVersion.fallbackMaterial);
            body.pqsVersion.radius = body.celestialBody.Radius;
            body.pqsVersion.mapOcean = false;

            // Debug
            Utility.DumpObjectProperties(body.pqsVersion.surfaceMaterial, " Surface Material ");
            Utility.DumpObjectProperties(body.pqsVersion.fallbackMaterial, " Fallback Material ");

            // Detail defaults
            body.pqsVersion.maxQuadLenghtsPerFrame = 0.03f;
            body.pqsVersion.minLevel = 1;
            body.pqsVersion.maxLevel = 10;
            body.pqsVersion.minDetailDistance = 8;

            // Create the celestial body transform
            GameObject mod = new GameObject("_CelestialBody");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_CelestialBodyTransform celestialBodyTransform = mod.AddComponent<PQSMod_CelestialBodyTransform>();
            celestialBodyTransform.sphere = body.pqsVersion;
            celestialBodyTransform.forceActivate = false;
            celestialBodyTransform.deactivateAltitude = 115000;
            celestialBodyTransform.forceRebuildOnTargetChange = false;
            celestialBodyTransform.planetFade = new PQSMod_CelestialBodyTransform.AltitudeFade();
            celestialBodyTransform.planetFade.fadeFloatName = "_PlanetOpacity";
            celestialBodyTransform.planetFade.fadeStart = 100000.0f;
            celestialBodyTransform.planetFade.fadeEnd = 110000.0f;
            celestialBodyTransform.planetFade.valueStart = 0.0f;
            celestialBodyTransform.planetFade.valueEnd = 1.0f;
            celestialBodyTransform.planetFade.secondaryRenderers = new List<GameObject>();
            celestialBodyTransform.secondaryFades = new PQSMod_CelestialBodyTransform.AltitudeFade[0];
            celestialBodyTransform.requirements = PQS.ModiferRequirements.Default;
            celestialBodyTransform.modEnabled = true;
            celestialBodyTransform.order = 10;

            // Create the color PQS mods
            mod = new GameObject("_Color");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_VertexSimplexNoiseColor vertexSimplexNoiseColor = mod.AddComponent<PQSMod_VertexSimplexNoiseColor>();
            vertexSimplexNoiseColor.sphere = body.pqsVersion;
            vertexSimplexNoiseColor.seed = 45;
            vertexSimplexNoiseColor.blend = 1.0f;
            vertexSimplexNoiseColor.colorStart = new Color(0.768656731f, 0.6996614f, 0.653089464f, 1);
            vertexSimplexNoiseColor.colorEnd = new Color(0.0f, 0.0f, 0.0f, 1.0f);
            vertexSimplexNoiseColor.octaves = 12.0;
            vertexSimplexNoiseColor.persistence = 0.5;
            vertexSimplexNoiseColor.frequency = 2.0;
            vertexSimplexNoiseColor.requirements = PQS.ModiferRequirements.MeshColorChannel;
            vertexSimplexNoiseColor.modEnabled = true;
            vertexSimplexNoiseColor.order = 200;

            PQSMod_HeightColorMap heightColorMap = mod.AddComponent<PQSMod_HeightColorMap>();
            heightColorMap.sphere = body.pqsVersion;
            List<PQSMod_HeightColorMap.LandClass> landClasses = new List<PQSMod_HeightColorMap.LandClass>();

            PQSMod_HeightColorMap.LandClass landClass = new PQSMod_HeightColorMap.LandClass("AbyPl", 0.0, 0.5, new Color(0.0f, 0.0f, 0.0f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = true;
            landClasses.Add(landClass);

            landClass = new PQSMod_HeightColorMap.LandClass("Beach", 0.5, 0.550000011920929, new Color(0.164179087f, 0.164179087f, 0.164179087f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = true;
            landClasses.Add(landClass);

            landClass = new PQSMod_HeightColorMap.LandClass("Beach", 0.550000011920929, 1.0, new Color(0.373134315f, 0.373134315f, 0.373134315f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = false;
            landClasses.Add(landClass);

            // Generate an array from the land classes list
            heightColorMap.landClasses = landClasses.ToArray();
            heightColorMap.blend = 0.7f;
            heightColorMap.lcCount = 3;
            heightColorMap.requirements = PQS.ModiferRequirements.MeshColorChannel;
            heightColorMap.modEnabled = true;
            heightColorMap.order = 201;

            // Create the alititude alpha mods
            mod = new GameObject("_Material_ModProjection");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_AltitudeAlpha altitudeAlpha = mod.AddComponent<PQSMod_AltitudeAlpha>();
            altitudeAlpha.sphere = body.pqsVersion;
            altitudeAlpha.atmosphereDepth = 4000.0;
            altitudeAlpha.invert = false;
            altitudeAlpha.requirements = PQS.ModiferRequirements.Default;
            altitudeAlpha.modEnabled = false;
            altitudeAlpha.order = 999999999;

            // Create the aerial perspective material
            mod = new GameObject("_Material_AerialPerspective");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_AerialPerspectiveMaterial aerialPerspectiveMaterial = mod.AddComponent<PQSMod_AerialPerspectiveMaterial>();
            aerialPerspectiveMaterial.sphere = body.pqsVersion;
            aerialPerspectiveMaterial.globalDensity = -0.00001f;
            aerialPerspectiveMaterial.heightFalloff = 6.75f;
            aerialPerspectiveMaterial.atmosphereDepth = 150000;
            aerialPerspectiveMaterial.DEBUG_SetEveryFrame = true;
            aerialPerspectiveMaterial.cameraAlt = 0;
            aerialPerspectiveMaterial.cameraAtmosAlt = 0;
            aerialPerspectiveMaterial.heightDensAtViewer = 0;
            aerialPerspectiveMaterial.requirements = PQS.ModiferRequirements.Default;
            aerialPerspectiveMaterial.modEnabled = true;
            aerialPerspectiveMaterial.order = 100;

            // Create the UV planet relative position
            mod = new GameObject("_Material_SurfaceQuads");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_UVPlanetRelativePosition planetRelativePosition = mod.AddComponent<PQSMod_UVPlanetRelativePosition>();
            planetRelativePosition.sphere = body.pqsVersion;
            planetRelativePosition.requirements = PQS.ModiferRequirements.Default;
            planetRelativePosition.modEnabled = true;
            planetRelativePosition.order = 999999;

            // Create the height noise module
            mod = new GameObject("_HeightNoise");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_VertexHeightMap vertexHeightMap = mod.gameObject.AddComponent<PQSMod_VertexHeightMap>();
            vertexHeightMap.sphere = body.pqsVersion;
            //vertexHeightMap.heightMapDeformity = 29457.0;
            vertexHeightMap.heightMapDeformity = 10000.0;
            vertexHeightMap.heightMapOffset = -1000.0;
            vertexHeightMap.scaleDeformityByRadius = false;
            vertexHeightMap.requirements = PQS.ModiferRequirements.MeshCustomNormals | PQS.ModiferRequirements.VertexMapCoords;
            vertexHeightMap.modEnabled = true;
            vertexHeightMap.order = 20;

            // Load the heightmap for this planet
            Texture2D map = new Texture2D(4, 4, TextureFormat.Alpha8, false);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Height.png"));
            vertexHeightMap.heightMap = ScriptableObject.CreateInstance<MapSO>();
            vertexHeightMap.heightMap.CreateMap(MapSO.MapDepth.Greyscale, map);
            UnityEngine.Object.DestroyImmediate(map);

            // Create the simplex height module
            PQSMod_VertexSimplexHeight vertexSimplexHeight = mod.AddComponent<PQSMod_VertexSimplexHeight>();
            vertexSimplexHeight.sphere = body.pqsVersion;
            vertexSimplexHeight.seed = 670000;
            vertexSimplexHeight.deformity = 1700.0;
            vertexSimplexHeight.octaves = 12.0;
            vertexSimplexHeight.persistence = 0.5;
            vertexSimplexHeight.frequency = 4.0;
            vertexSimplexHeight.requirements = PQS.ModiferRequirements.MeshCustomNormals;
            vertexSimplexHeight.modEnabled = true;
            vertexSimplexHeight.order = 21;

            // SERIOUSLY RECOMMENDED FOR NO OCEAN WORLDS
            // Create the flatten ocean module
            PQSMod_FlattenOcean flattenOcean = mod.AddComponent<PQSMod_FlattenOcean>();
            flattenOcean.sphere = body.pqsVersion;
            flattenOcean.oceanRadius = 1.0;
            flattenOcean.requirements = PQS.ModiferRequirements.MeshCustomNormals;
            flattenOcean.modEnabled = true;
            flattenOcean.order = 25;

            // Creat the vertex height noise module
            PQSMod_VertexHeightNoise vertexHeightNoise = mod.AddComponent<PQSMod_VertexHeightNoise>();
            vertexHeightNoise.sphere = body.pqsVersion;
            vertexHeightNoise.noiseType = PQSMod_VertexHeightNoise.NoiseType.RiggedMultifractal;
            vertexHeightNoise.deformity = 1000.0f;
            vertexHeightNoise.seed = 5906;
            vertexHeightNoise.frequency = 2.0f;
            vertexHeightNoise.lacunarity = 2.5f;
            vertexHeightNoise.persistance = 0.5f;
            vertexHeightNoise.octaves = 4;
            vertexHeightNoise.mode = LibNoise.Unity.QualityMode.Low;
            vertexHeightNoise.requirements = PQS.ModiferRequirements.MeshColorChannel;
            vertexHeightNoise.modEnabled = true;
            vertexHeightNoise.order = 22;

            // Create the material direction
            mod = new GameObject("_Material_SunLight");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_MaterialSetDirection materialSetDirection = mod.AddComponent<PQSMod_MaterialSetDirection>();
            materialSetDirection.sphere = body.pqsVersion;
            materialSetDirection.valueName = "_sunLightDirection";
            materialSetDirection.requirements = PQS.ModiferRequirements.Default;
            materialSetDirection.modEnabled = true;
            materialSetDirection.order = 100;

            // Crete the quad mesh colliders
            mod = new GameObject("QuadMeshColliders");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_QuadMeshColliders quadMeshColliders = mod.AddComponent<PQSMod_QuadMeshColliders>();
            quadMeshColliders.sphere = body.pqsVersion;
            quadMeshColliders.maxLevelOffset = 0;
            quadMeshColliders.physicsMaterial = new PhysicMaterial();
            quadMeshColliders.physicsMaterial.name = "Ground";
            quadMeshColliders.physicsMaterial.dynamicFriction = 0.6f;
            quadMeshColliders.physicsMaterial.staticFriction = 0.8f;
            quadMeshColliders.physicsMaterial.bounciness = 0.0f;
            quadMeshColliders.physicsMaterial.frictionDirection2 = Vector3.zero;
            quadMeshColliders.physicsMaterial.dynamicFriction2 = 0.0f;
            quadMeshColliders.physicsMaterial.staticFriction2 = 0.0f;
            quadMeshColliders.physicsMaterial.frictionCombine = PhysicMaterialCombine.Maximum;
            quadMeshColliders.physicsMaterial.bounceCombine = PhysicMaterialCombine.Average;
            quadMeshColliders.requirements = PQS.ModiferRequirements.Default;
            quadMeshColliders.modEnabled = true;
            quadMeshColliders.order = 100;

            // Create the simplex height absolute
            mod = new GameObject("_FineDetail");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_VertexSimplexHeightAbsolute vertexSimplexHeightAbsolute = mod.AddComponent<PQSMod_VertexSimplexHeightAbsolute>();
            vertexSimplexHeightAbsolute.sphere = body.pqsVersion;
            vertexSimplexHeightAbsolute.seed = 4234;
            vertexSimplexHeightAbsolute.deformity = 400.0;
            vertexSimplexHeightAbsolute.octaves = 6.0;
            vertexSimplexHeightAbsolute.persistence = 0.5;
            vertexSimplexHeightAbsolute.frequency = 18.0;
            vertexSimplexHeightAbsolute.requirements = PQS.ModiferRequirements.Default;
            vertexSimplexHeightAbsolute.modEnabled = true;
            vertexSimplexHeightAbsolute.order = 30;

            // Surface color map
            mod = new GameObject("_LandClass");
            mod.transform.parent = body.pqsVersion.gameObject.transform;
            PQSMod_VertexColorMap colorMap = mod.AddComponent<PQSMod_VertexColorMap>();
            colorMap.sphere = body.pqsVersion;
            colorMap.order = 500;
            colorMap.modEnabled = true;

            // Decompress and load the color
            map = new Texture2D(4, 4, TextureFormat.RGB24, false);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Color.png"));
            colorMap.vertexColorMap = ScriptableObject.CreateInstance<MapSO>();
            colorMap.vertexColorMap.CreateMap(MapSO.MapDepth.RGB, map);
            UnityEngine.Object.DestroyImmediate(map);

            #endregion

            #region PSystemBody.scaledVersion generation

            // Create the scaled version of the planet for use in map view
            body.scaledVersion = new GameObject(name);
            body.scaledVersion.layer = Constants.GameLayers.ScaledSpace;
            body.scaledVersion.transform.parent = Utility.Deactivator;

            // DEPRECATED - USE PQSMeshWrapper
            // Make sure the scaled version cooresponds to the size of the body
            // Turns out that the localScale is directly related to the planet size.
            // Jool's local scale is {1,1,1}, Kerbin's is {0.1,0.1,0.1}.  Jool's
            // radius is 6000 km, Kerbin's is 600 km.  Notice the relation?
            float scale = (float) body.celestialBody.Radius / 6000000.0f;
            body.scaledVersion.transform.localScale = new Vector3(scale, scale, scale);

            // Generate a mesh to fit the PQS we generated (it would be cool to generate this FROM the PQS)
            Mesh mesh = new Mesh();
            Utility.CopyMesh(Jool.scaledVersion.GetComponent<MeshFilter>().sharedMesh, mesh);

            // Iterate though the UVs
            // Geosphere with a radius of 1000, cooresponds to an object 6000km in radius
            Vector3[] vertices = mesh.vertices;
            for(int i = 0; i < mesh.vertexCount; i++)
            {
                // Get the height offset from the height map
                Vector2 uv = mesh.uv[i];
                float displacement = vertexHeightMap.heightMap.GetPixelFloat(uv.x, uv.y);

                // Since this is a geosphere, normalizing the vertex gives the vector to translate on
                Vector3 v = vertices[i];
                v.Normalize();

                // Calculate the real height displacement (in meters), normalized vector "v" scale (1 unit = 6 km)
                displacement = (float) vertexHeightMap.heightMapOffset + (displacement * (float) vertexHeightMap.heightMapDeformity);
                Vector3 offset = v * ((displacement / 6000.0f) / scale);

                // Adjust the displacement
                vertices[i] += offset;
            }
            mesh.vertices = vertices;
            mesh.RecalculateNormals();

            // Create the mesh filter
            MeshFilter meshFilter = body.scaledVersion.AddComponent<MeshFilter> ();
            meshFilter.mesh = mesh;

            // Load and compress the color texture for the custom planet
            Texture2D colorTexture = new Texture2D(4, 4, TextureFormat.RGBA32, true);
            colorTexture.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Color.png"));
            colorTexture.Compress(true);
            colorTexture.Apply(true, true);

            // Load and compress the color texture for the custom planet
            Texture2D normalTexture = new Texture2D(4, 4, TextureFormat.RGB24, true);
            normalTexture.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Normals.png"));
            //normalTexture = GameDatabase.BitmapToUnityNormalMap(normalTexture);
            normalTexture.Compress(true);
            normalTexture.Apply(true, true);

            // Create the renderer and material for the scaled version
            MeshRenderer renderer = body.scaledVersion.AddComponent<MeshRenderer>();
            //ScaledPlanetSimple material = new ScaledPlanetSimple();   // for atmosphereless planets
            ScaledPlanetRimAerial material = new ScaledPlanetRimAerial();
            material.color       = Color.white;
            material.specColor   = Color.black;
            material.mainTexture = colorTexture;
            material.bumpMap     = normalTexture;
            renderer.material    = material;

            // Create the sphere collider
            SphereCollider collider = body.scaledVersion.AddComponent<SphereCollider> ();
            collider.center         = Vector3.zero;
            collider.radius         = 1000.0f;

            // Create the ScaledSpaceFader to fade the orbit out where we view it (maybe?)
            ScaledSpaceFader fader = body.scaledVersion.AddComponent<ScaledSpaceFader> ();
            fader.celestialBody    = body.celestialBody;
            fader.fadeStart        = 95000.0f;
            fader.fadeEnd          = 100000.0f;
            fader.floatName        = "_Opacity";

            #endregion

            #region Atmosphere
            //--------------------- PROPERTIES EXCLUSIVE TO BODIES WITH ATMOSPHERE

            // Load the atmosphere gradient (compress it, does not need to be high quality)
            Texture2D atmosphereGradient = new Texture2D(4, 4, TextureFormat.RGB24, true);
            atmosphereGradient.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/AtmosphereGradient.png"));
            atmosphereGradient.Compress(true);
            atmosphereGradient.wrapMode = TextureWrapMode.Clamp;
            atmosphereGradient.mipMapBias = 0.0f;
            atmosphereGradient.Apply(true, true);

            // Set the additional settings in the scaledVersion body's shader
            material.rimPower = 2.06f;
            material.rimBlend = 0.3f;
            material.rimColorRamp = atmosphereGradient;

            // Atmosphere specific properties (for scaled version root) (copied from duna)
            MaterialSetDirection materialLightDirection = body.scaledVersion.AddComponent<MaterialSetDirection>();
            materialLightDirection.valueName            = "_localLightDirection";

            // Create the atmosphere shell itself
            GameObject scaledAtmosphere               = new GameObject("atmosphere");
            scaledAtmosphere.transform.parent         = body.scaledVersion.transform;
            scaledAtmosphere.layer                    = Constants.GameLayers.ScaledSpaceAtmosphere;
            meshFilter                                = scaledAtmosphere.AddComponent<MeshFilter>();
            meshFilter.sharedMesh                     = Jool.scaledVersion.GetComponent<MeshFilter>().sharedMesh;
            renderer                                  = scaledAtmosphere.AddComponent<MeshRenderer>();
            renderer.material                         = new Kopernicus.MaterialWrapper.AtmosphereFromGround();
            AtmosphereFromGround atmosphereRenderInfo = scaledAtmosphere.AddComponent<AtmosphereFromGround>();
            atmosphereRenderInfo.waveLength           = new Color(0.509f, 0.588f, 0.643f, 0.000f);

            // Technical info for atmosphere
            body.celestialBody.atmosphere = true;
            body.celestialBody.atmosphereContainsOxygen = true;
            body.celestialBody.staticPressureASL = 1.0; // can't find anything that references this, especially with the equation in mind - where is this used?
            body.celestialBody.altitudeMultiplier = 1.4285f; // ditto
            body.celestialBody.atmosphereScaleHeight = 4.0;   // pressure (in atm) = atmosphereMultipler * e ^ -(altitude / (atmosphereScaleHeight * 1000))
            body.celestialBody.atmosphereMultiplier = 0.8f;
            body.celestialBody.atmoshpereTemperatureMultiplier = 1.0f; // how does this coorespond?
            body.celestialBody.maxAtmosphereAltitude = 55000.0f;  // i guess this is so the math doesn't drag out?
            body.celestialBody.useLegacyAtmosphere = true;
            body.celestialBody.atmosphericAmbientColor = new Color(0.306f, 0.187f, 0.235f, 1.000f);
            #endregion

            #region Ocean
            // ---------------- FOR BODIES WITH OCEANS ----------
            /*body.celestialBody.ocean = true;

            // Setup the laythe ocean info in master pqs
            body.pqsVersion.mapOcean = true;
            body.pqsVersion.mapOceanColor = new Color(0.117f, 0.126f, 0.157f, 1.000f);
            body.pqsVersion.mapOceanHeight = 0.0f;

            // Generate the PQS object
            GameObject oceanRoot       = new GameObject(name + "Ocean");
            oceanRoot.transform.parent = body.pqsVersion.transform;
            oceanRoot.layer            = Constants.GameLayers.LocalSpace;
            PQS oceanPQS               = oceanRoot.AddComponent<PQS>();

            // Add this new PQS to the secondary renderers of the altitude fade controller
            celestialBodyTransform.planetFade.secondaryRenderers.Add(oceanRoot);

            // Setup the PQS object data
            Utility.CopyObjectFields<PQS>(laytheOcean.GetComponent<PQS>(), oceanPQS);
            oceanPQS.radius            = body.pqsVersion.radius;
            oceanPQS.surfaceMaterial   = new PQSOceanSurfaceQuad(laytheOcean.GetComponent<PQS>().surfaceMaterial);
            oceanPQS.fallbackMaterial  = new PQSOceanSurfaceQuadFallback(laytheOcean.GetComponent<PQS>().fallbackMaterial);
            Utility.DumpObjectProperties(oceanPQS.surfaceMaterial, oceanPQS.surfaceMaterial.ToString());
            Utility.DumpObjectProperties(oceanPQS.fallbackMaterial, oceanPQS.fallbackMaterial.ToString());

            // Create the aerial perspective material
            mod = new GameObject("_Material_AerialPerspective");
            mod.transform.parent = oceanRoot.transform;
            aerialPerspectiveMaterial = mod.AddComponent<PQSMod_AerialPerspectiveMaterial>();
            aerialPerspectiveMaterial.sphere = body.pqsVersion;
            aerialPerspectiveMaterial.globalDensity = -0.00001f;
            aerialPerspectiveMaterial.heightFalloff = 6.75f;
            aerialPerspectiveMaterial.atmosphereDepth = 150000;
            aerialPerspectiveMaterial.DEBUG_SetEveryFrame = true;
            aerialPerspectiveMaterial.cameraAlt = 0;
            aerialPerspectiveMaterial.cameraAtmosAlt = 0;
            aerialPerspectiveMaterial.heightDensAtViewer = 0;
            aerialPerspectiveMaterial.requirements = PQS.ModiferRequirements.Default;
            aerialPerspectiveMaterial.modEnabled = true;
            aerialPerspectiveMaterial.order = 100;

            // Create the UV planet relative position
            mod = new GameObject("_Material_SurfaceQuads");
            mod.transform.parent = oceanRoot.transform;
            planetRelativePosition = mod.AddComponent<PQSMod_UVPlanetRelativePosition>();
            planetRelativePosition.sphere = body.pqsVersion;
            planetRelativePosition.requirements = PQS.ModiferRequirements.Default;
            planetRelativePosition.modEnabled = true;
            planetRelativePosition.order = 100;

            // Create the quad map remover (da fuck?)
            mod = new GameObject("QuadRemoveMap");
            mod.transform.parent = oceanRoot.transform;
            PQSMod_RemoveQuadMap removeQuadMap = mod.AddComponent<PQSMod_RemoveQuadMap>();
            removeQuadMap.mapDeformity = 0.0f;
            removeQuadMap.minHeight = 0.0f;
            removeQuadMap.maxHeight = 0.5f;
            removeQuadMap.requirements = PQS.ModiferRequirements.Default;
            removeQuadMap.modEnabled = true;
            removeQuadMap.order = 1000;

            // Load the heightmap into whatever the hell this is
            map = new Texture2D(4, 4, TextureFormat.Alpha8, false);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Height.png"));
            removeQuadMap.map = ScriptableObject.CreateInstance<MapSO>();
            removeQuadMap.map.CreateMap(MapSO.MapDepth.Greyscale, map);
            UnityEngine.Object.DestroyImmediate(map);

            // Setup the ocean effects
            mod = new GameObject("OceanFX");
            mod.transform.parent = oceanRoot.transform;
            PQSMod_OceanFX oceanFX = mod.AddComponent<PQSMod_OceanFX>();
            oceanFX.watermain = Utility.RecursivelyGetComponent<PQSMod_OceanFX>(laytheOcean).watermain.Clone() as Texture2D[];
            oceanFX.requirements = PQS.ModiferRequirements.Default;
            oceanFX.modEnabled = true;
            oceanFX.order = 100;*/

            #endregion

            // Return the new body
            return body;
        }
 public void findPrefabBodies(PSystemBody body)
 {
     prefabBodies[body.celestialBody.name] = body;
     foreach (var c in body.children)
     {
         findPrefabBodies(c);
     }
 }
		public static void AddCometTail(PSystemBody body, CometTail tail)
		{
			Transform scaledVersion = body.scaledVersion.transform;

			GameObject obj = new GameObject ("CometTail");
			obj.layer = GameLayers.ScaledSpace;
			obj.transform.parent = Kopernicus.Utility.Deactivator;

			var mr = obj.AddComponent<MeshRenderer> ();
			var mf = obj.AddComponent<MeshFilter> ();

			var teardrop = new Teardrop (1f, (tail.length / tail.radius), 60, 90);
			mf.mesh = teardrop;

			if (Settings.AllowAdvancedCometShader)
			{
				mr.sharedMaterial = new Material (Shaders.CometTail);

				//set default material values
				mr.sharedMaterial.SetColor ("_TintColor", new Color(tail.color.r, tail.color.g, tail.color.b, 0.5f));

				mr.sharedMaterial.SetFloat ("_RimPower", tail.rimPower);
				mr.sharedMaterial.SetFloat ("_Distortion", tail.distortion);
				mr.sharedMaterial.SetFloat ("_AlphaDistortion", tail.alphaDistortion);
				mr.sharedMaterial.SetFloat ("_ZDistortion", tail.zDistortion);
				mr.sharedMaterial.SetFloat ("_VertexDistortion", 0f);
				mr.sharedMaterial.SetFloat ("_Frequency", tail.frequency);
				mr.sharedMaterial.SetFloat ("_Lacunarity", tail.lacunarity);
				mr.sharedMaterial.SetFloat ("_Gain", tail.gain);
			}
			else
			{
				mr.sharedMaterial = new Material (Shader.Find(FallbackShader));

				//set default material values
				mr.sharedMaterial.SetColor ("_TintColor", new Color(tail.color.r, tail.color.g, tail.color.b, 0.3f));
			}

			mr.castShadows = false;
			mr.receiveShadows = false;

			var cometController = obj.AddComponent<CometTailController> ();
			cometController.targetBodyName = "Sun";
			cometController.usingAdvancedShader = Settings.AllowAdvancedCometShader;
			cometController.type = tail.type;
			cometController.color = tail.color;
			cometController.orbit = body.celestialBody.orbit;
			cometController.opacityCurve = tail.opacityCurve;
			cometController.brightnessCurve = tail.brightnessCurve;

			obj.transform.parent = scaledVersion;
			obj.transform.localPosition = Vector3.zero;
			obj.transform.localScale = (Vector3.one * tail.length);
			obj.SetActive (true);
			obj.layer = GameLayers.ScaledSpace;

			//initialize comet
			cometController.Init ();
		}