示例#1
0
            /**
             * Constructor for pre-existing PQS
             *
             * @param pqsVersion Existing PQS to augment
             **/
            public PQSLoader(PQS pqsVersion)
            {
                this.pqsVersion = pqsVersion;

                // Get the required PQS information
                transform      = pqsVersion.GetComponentsInChildren <PQSMod_CelestialBodyTransform> (true).Where(mod => mod.transform.parent == pqsVersion.transform).FirstOrDefault();
                lightDirection = pqsVersion.GetComponentsInChildren <PQSMod_MaterialSetDirection>(true).Where(mod => mod.transform.parent == pqsVersion.transform).FirstOrDefault();
                uvs            = pqsVersion.GetComponentsInChildren <PQSMod_UVPlanetRelativePosition>(true).Where(mod => mod.transform.parent == pqsVersion.transform).FirstOrDefault();
                collider       = pqsVersion.GetComponentsInChildren <PQSMod_QuadMeshColliders>(true).Where(mod => mod.transform.parent == pqsVersion.transform).FirstOrDefault();

                // Create physics material editor
                physicsMaterial = new PhysicsMaterialParser(collider.physicsMaterial);
            }
示例#2
0
            // Constructor for pre-existing PQS
            public PQSLoader(PQS pqsVersion)
            {
                this.pqsVersion = pqsVersion;

                // Get the required PQS information
                transform      = pqsVersion.GetComponentsInChildren <PQSMod_CelestialBodyTransform> (true).Where(mod => mod.transform.parent == pqsVersion.transform).FirstOrDefault();
                lightDirection = pqsVersion.GetComponentsInChildren <PQSMod_MaterialSetDirection>(true).Where(mod => mod.transform.parent == pqsVersion.transform).FirstOrDefault();
                uvs            = pqsVersion.GetComponentsInChildren <PQSMod_UVPlanetRelativePosition>(true).Where(mod => mod.transform.parent == pqsVersion.transform).FirstOrDefault();
                collider       = pqsVersion.GetComponentsInChildren <PQSMod_QuadMeshColliders>(true).Where(mod => mod.transform.parent == pqsVersion.transform).FirstOrDefault();

                // Create physics material editor
                physicsMaterial = new PhysicsMaterialParser(collider.physicsMaterial);

                // Clone the surface material of the PQS
                if (PQSMainOptimised.UsesSameShader(pqsVersion.surfaceMaterial))
                {
                    pqsVersion.surfaceMaterial = new PQSMainOptimisedLoader(pqsVersion.surfaceMaterial);
                    if (((PQSMainOptimisedLoader)pqsVersion.surfaceMaterial).globalDensity < 2)
                    {
                        ((PQSMainOptimisedLoader)pqsVersion.surfaceMaterial).globalDensity = -8E-06f;
                    }
                }
                else if (PQSMainShader.UsesSameShader(pqsVersion.surfaceMaterial))
                {
                    pqsVersion.surfaceMaterial = new PQSMainShaderLoader(pqsVersion.surfaceMaterial);
                    if (((PQSMainShaderLoader)pqsVersion.surfaceMaterial).globalDensity < 2)
                    {
                        ((PQSMainShaderLoader)pqsVersion.surfaceMaterial).globalDensity = -8E-06f;
                    }
                }
                else if (PQSProjectionAerialQuadRelative.UsesSameShader(pqsVersion.surfaceMaterial))
                {
                    pqsVersion.surfaceMaterial = new PQSProjectionAerialQuadRelativeLoader(pqsVersion.surfaceMaterial);
                    if (((PQSProjectionAerialQuadRelativeLoader)pqsVersion.surfaceMaterial).globalDensity < 2)
                    {
                        ((PQSProjectionAerialQuadRelativeLoader)pqsVersion.surfaceMaterial).globalDensity = -8E-06f;
                    }
                }
                else if (PQSProjectionSurfaceQuad.UsesSameShader(pqsVersion.surfaceMaterial))
                {
                    pqsVersion.surfaceMaterial = new PQSProjectionSurfaceQuadLoader(pqsVersion.surfaceMaterial);
                }
                surfaceMaterial      = pqsVersion.surfaceMaterial;
                surfaceMaterial.name = Guid.NewGuid().ToString();

                // Clone the fallback material of the PQS
                fallbackMaterial            = new PQSProjectionFallbackLoader(pqsVersion.fallbackMaterial);
                pqsVersion.fallbackMaterial = fallbackMaterial;
                fallbackMaterial.name       = Guid.NewGuid().ToString();
            }
示例#3
0
        public static T[] GetPQSMods <T>(this PQS pqs) where T : PQSMod
        {
            List <T> mods = new List <T> ();

            foreach (var mod in pqs.GetComponentsInChildren <T>())
            {
                mods.Add(mod);
            }
            return(mods.ToArray());
        }
示例#4
0
        internal static void Update()
        {
            Debug.Log("EditorBuildings.Update");

            // Destroy old clones
            DestroyAll();

            // Find the homeworld
            CelestialBody homeBody = FlightGlobals.GetHomeBody();

            Debug.Log("EditorBuildings.Update", "homeBody = " + homeBody);

            // Get the pqsController
            PQS pqs = homeBody?.pqsController;

            Debug.Log("EditorBuildings.Update", "pqsController = " + pqs);

            // Filter and Duplicate PQSMods
            Duplicate(pqs?.GetComponentsInChildren <PQSMod>());
        }
示例#5
0
        public static Mesh ComputeScaledSpaceMesh(CelestialBody body, PQS pqs)
        {
            // We need to get the body for Jool (to steal it's mesh)
            const Double R_SCALED_JOOL        = 1000.0f;
            Double       rMetersToScaledUnits = (Single)(R_SCALED_JOOL / body.Radius);

            // Generate a duplicate of the Jool mesh
            Mesh mesh = DuplicateMesh(Templates.ReferenceGeosphere);

            Logger.Active.Log(body);
            Logger.Active.Log(pqs);
            Logger.Active.Log(body.pqsController);

            // If this body has a PQS, we can create a more detailed object, otherwise just return the generic mesh
            if (pqs == null)
            {
                return(mesh);
            }

            // first we enable all maps
            OnDemandStorage.EnableBody(body.bodyName);

            // In order to generate the scaled space we have to enable the mods.  Since this is
            // a prefab they don't get disabled as kill game performance.  To resolve this we
            // clone the PQS, use it, and then delete it when done. At runtime we can simply use
            // the PQS that is active
            GameObject pqsVersionGameObject =
                Injector.IsInPrefab ? Instantiate(pqs.gameObject) : pqs.gameObject;
            PQS pqsVersion = pqsVersionGameObject.GetComponent <PQS>();

            // Deactivate blacklisted Mods
            PQSMod[] mods = pqsVersion.GetComponentsInChildren <PQSMod>(true).OrderBy(m => m.order).ToArray();
            for (Int32 i = 0; i < mods.Length; i++)
            {
                // Disable mods that don't belong to us
                if (mods[i].transform.parent != pqsVersion.transform)
                {
                    mods[i].modEnabled = false;
                    continue;
                }

                switch (mods[i])
                {
                // Disable the OnDemand notifier
                case PQSMod_OnDemandHandler _:
                    mods[i].modEnabled = false;
                    continue;

                case PQSMod_FlattenArea _:
                    typeof(PQSMod_FlattenArea).GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                    .First(f => f.FieldType == typeof(Boolean)).SetValue(mods[i], true);
                    break;
                }
            }

            pqsVersion.StartUpSphere();
            pqsVersion.isBuildingMaps = true;

            // If we were able to find PQS mods
            if (mods.Length > 0)
            {
                // Generate the PQS modifications
                Vector3[] vertices = mesh.vertices;
                for (Int32 i = 0; i < mesh.vertexCount; i++)
                {
                    // Get the UV coordinate of this vertex
                    Vector2 uv = mesh.uv[i];

                    // Since this is a geosphere, normalizing the vertex gives the direction from center center
                    Vector3 direction = vertices[i];
                    direction.Normalize();

                    // Build the vertex data object for the PQS mods
                    PQS.VertexBuildData vertex = new PQS.VertexBuildData
                    {
                        directionFromCenter = direction,
                        vertHeight          = body.Radius,
                        u = uv.x,
                        v = uv.y
                    };

                    // Build from the PQS
                    for (Int32 m = 0; m < mods.Length; m++)
                    {
                        // Don't build disabled mods
                        if (!mods[m].modEnabled)
                        {
                            continue;
                        }

                        // Don't build mods that don't belong to us
                        if (mods[m].transform.parent != pqsVersion.transform)
                        {
                            continue;
                        }

                        mods[m].OnVertexBuildHeight(vertex);
                    }

                    // Check for sea level
                    if (pqsVersion.mapOcean)
                    {
                        vertex.vertHeight = Math.Max(vertex.vertHeight, body.Radius);
                    }

                    // Adjust the displacement
                    vertices[i] = direction * (Single)(vertex.vertHeight * rMetersToScaledUnits);
                }
                mesh.vertices = vertices;
                mesh.RecalculateNormals();
                mesh.RecalculateBounds();
                RecalculateTangents(mesh);
            }

            // Cleanup
            pqsVersion.isBuildingMaps = false;
            pqsVersion.DeactivateSphere();

            // If we are working with a copied PQS, clean it up
            if (Injector.IsInPrefab)
            {
                UnityEngine.Object.Destroy(pqsVersionGameObject);
            }
            OnDemandStorage.DisableBody(body.bodyName);

            // Return the generated scaled space mesh
            return(mesh);
        }
示例#6
0
            public static IEnumerator UpdateTextures(CelestialBody celestialBody, TextureOptions options)
            {
                // Get time
                DateTime now = DateTime.Now;

                // If the user wants to export normals, we need height too
                if (options.ExportNormal)
                {
                    options.ExportHeight = true;
                }

                // Prepare the PQS
                PQS pqsVersion = celestialBody.pqsController;

                // If the PQS is null, abort
                if (pqsVersion == null)
                {
                    throw new InvalidOperationException();
                }

                // Tell the PQS that we are going to build maps
                pqsVersion.SetupExternalRender();

                // Get the mod building methods from the PQS
                Action <PQS.VertexBuildData> modOnVertexBuildHeight =
                    (Action <PQS.VertexBuildData>)Delegate.CreateDelegate(
                        typeof(Action <PQS.VertexBuildData>),
                        pqsVersion,
                        typeof(PQS).GetMethod("Mod_OnVertexBuildHeight",
                                              BindingFlags.Instance | BindingFlags.NonPublic));
                Action <PQS.VertexBuildData> modOnVertexBuild = (Action <PQS.VertexBuildData>)Delegate.CreateDelegate(
                    typeof(Action <PQS.VertexBuildData>),
                    pqsVersion,
                    typeof(PQS).GetMethod("Mod_OnVertexBuild", BindingFlags.Instance | BindingFlags.NonPublic));

                // Get all mods the PQS is connected to
                PQSMod[] mods = pqsVersion.GetComponentsInChildren <PQSMod>()
                                .Where(m => m.sphere == pqsVersion && m.modEnabled).OrderBy(m => m.order).ToArray();

                // Prevent the PQS from updating
                pqsVersion.enabled = false;

                // Create the Textures
                Texture2D colorMap = new Texture2D(pqsVersion.mapFilesize, pqsVersion.mapFilesize / 2,
                                                   TextureFormat.ARGB32,
                                                   true);
                Texture2D heightMap = new Texture2D(pqsVersion.mapFilesize, pqsVersion.mapFilesize / 2,
                                                    TextureFormat.RGB24,
                                                    true);

                // Arrays
                Color[] colorMapValues  = new Color[pqsVersion.mapFilesize * (pqsVersion.mapFilesize / 2)];
                Color[] heightMapValues = new Color[pqsVersion.mapFilesize * (pqsVersion.mapFilesize / 2)];

                // Create a VertexBuildData
                PQS.VertexBuildData data = new PQS.VertexBuildData();

                // Display
                ScreenMessage message = ScreenMessages.PostScreenMessage("Generating Planet-Maps", Single.MaxValue, ScreenMessageStyle.UPPER_CENTER);

                yield return(null);

                // Loop through the pixels
                for (Int32 y = 0; y < pqsVersion.mapFilesize / 2; y++)
                {
                    for (Int32 x = 0; x < pqsVersion.mapFilesize; x++)
                    {
                        // Update Message
                        Double percent = (Double)(y * pqsVersion.mapFilesize + x) /
                                         (pqsVersion.mapFilesize / 2 * pqsVersion.mapFilesize) * 100;
                        while (CanvasUpdateRegistry.IsRebuildingLayout())
                        {
                            Thread.Sleep(10);
                        }
                        message.textInstance.text.text = "Generating Planet-Maps: " + percent.ToString("0.00") + "%";

                        // Update the VertexBuildData
                        data.directionFromCenter =
                            QuaternionD.AngleAxis(360d / pqsVersion.mapFilesize * x, Vector3d.up) *
                            QuaternionD.AngleAxis(90d - 180d / (pqsVersion.mapFilesize / 2f) * y, Vector3d.right)
                            * Vector3d.forward;
                        data.vertHeight = pqsVersion.radius;

                        // Build from the Mods
                        Double height = Double.MinValue;
                        if (options.ExportHeight)
                        {
                            modOnVertexBuildHeight(data);

                            // Adjust the height
                            height = (data.vertHeight - pqsVersion.radius) * (1d / pqsVersion.mapMaxHeight);
                            if (height < 0)
                            {
                                height = 0;
                            }
                            else if (height > 1)
                            {
                                height = 1;
                            }

                            // Set the Pixels
                            heightMapValues[y * pqsVersion.mapFilesize + x] =
                                new Color((Single)height, (Single)height, (Single)height);
                        }

                        if (options.ExportColor)
                        {
                            modOnVertexBuild(data);

                            // Adjust the Color
                            Color color = data.vertColor;
                            if (!pqsVersion.mapOcean)
                            {
                                color.a = 1f;
                            }
                            else if (height > pqsVersion.mapOceanHeight)
                            {
                                color.a = options.TransparentMaps ? 0f : 1f;
                            }
                            else
                            {
                                color = pqsVersion.mapOceanColor.A(1f);
                            }

                            // Set the Pixels
                            colorMapValues[y * pqsVersion.mapFilesize + x] = color;
                        }
                    }

                    yield return(null);
                }

                // Serialize the maps to disk
                String name = "KittopiaTech/PluginData/" + celestialBody.transform.name + "/";
                String path = KSPUtil.ApplicationRootPath + "/GameData/" + name;

                Directory.CreateDirectory(path);

                // Colormap
                if (options.ExportColor)
                {
                    // Save it
                    colorMap.SetPixels(colorMapValues);
                    yield return(null);

                    if (options.SaveToDisk)
                    {
                        File.WriteAllBytes(path + celestialBody.transform.name + "_Color.png", colorMap.EncodeToPNG());
                        colorMap.name = name + celestialBody.transform.name + "_Color.png";
                        yield return(null);
                    }

                    // Apply it
                    if (options.ApplyToScaled)
                    {
                        colorMap.Apply();
                        celestialBody.scaledBody.GetComponent <MeshRenderer>().material.SetTexture("_MainTex", colorMap);
                    }
                }

                if (options.ExportHeight)
                {
                    heightMap.SetPixels(heightMapValues);
                    yield return(null);

                    if (options.SaveToDisk)
                    {
                        File.WriteAllBytes(path + celestialBody.transform.name + "_Height.png",
                                           heightMap.EncodeToPNG());
                        yield return(null);
                    }

                    if (options.ExportNormal)
                    {
                        // Bump to Normal Map
                        Texture2D normalMap = Utility.BumpToNormalMap(heightMap, pqsVersion.radius, options.NormalStrength);
                        yield return(null);

                        if (options.SaveToDisk)
                        {
                            File.WriteAllBytes(path + celestialBody.transform.name + "_Normal.png",
                                               normalMap.EncodeToPNG());
                            normalMap.name = name + celestialBody.transform.name + "_Normal.png";
                            yield return(null);
                        }

                        // Apply it
                        if (options.ApplyToScaled)
                        {
                            normalMap.Apply();
                            celestialBody.scaledBody.GetComponent <MeshRenderer>().material
                            .SetTexture("_BumpMap", normalMap);
                        }
                    }
                }

                // Close the Renderer
                pqsVersion.enabled = true;
                pqsVersion.CloseExternalRender();

                // Declare that we're done
                ScreenMessages.RemoveMessage(message);
                ScreenMessages.PostScreenMessage("Operation completed in: " + (DateTime.Now - now).TotalMilliseconds + " ms", 2f, ScreenMessageStyle.UPPER_CENTER);
            }
示例#7
0
            /// <summary>
            /// Renders the Window
            /// </summary>
            protected override void Render(Int32 id)
            {
                // Call base
                base.Render(id);

                // Check for PQS
                if (Current.pqsController == null)
                {
                    Button(Localization.LOC_KITTOPIATECH_PQSEDITOR_ADD, () =>
                    {
                        // Create a new PQS
                        GameObject controllerRoot       = new GameObject(Current.name);
                        controllerRoot.transform.parent = Current.transform;
                        PQS pqsVersion = controllerRoot.AddComponent <PQS>();

                        // I am at this time unable to determine some of the magic parameters which cause the PQS to work... (Or just lazy but who cares :P)
                        PSystemBody Laythe = Utility.FindBody(Injector.StockSystemPrefab.rootBody, "Laythe");
                        Utility.CopyObjectFields(Laythe.pqsVersion, pqsVersion);
                        pqsVersion.surfaceMaterial = Laythe.pqsVersion.surfaceMaterial;

                        // Create the fallback material (always the same shader)
                        pqsVersion.fallbackMaterial      = new PQSProjectionFallbackLoader();
                        pqsVersion.fallbackMaterial.name = Guid.NewGuid().ToString();

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

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

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

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

                        // Assing the new PQS
                        Current.pqsController              = pqsVersion;
                        pqsVersion.transform.position      = Current.transform.position;
                        pqsVersion.transform.localPosition = Vector3.zero;

                        // Set mode
                        _mode = Modes.List;
                    }, new Rect(20, index * distance + 10, 350, 20));
                    return;
                }

                // Mode List
                if (_mode == Modes.List)
                {
                    // Get the PQS-Spheres and their mods
                    IEnumerable <PQS>    pqsList    = Current.GetComponentsInChildren <PQS>(true);
                    IEnumerable <PQSMod> pqsModList = Current.GetComponentsInChildren <PQSMod>(true);

                    // Scroll
                    BeginScrollView(250, (pqsList.Count() + pqsModList.Count()) * distance + distance * 4, 20);

                    // Index
                    index = 0;

                    // Render
                    foreach (PQS pqs in pqsList)
                    {
                        Button(pqs.ToString(), () =>
                        {
                            _mode   = Modes.PQS;
                            _sphere = pqs;
                        }, new Rect(20, index * distance + 10, 350, 20));
                    }
                    foreach (PQSMod mod in pqsModList)
                    {
                        Button(mod.ToString(), () =>
                        {
                            _mode   = Modes.PQSMod;
                            _sphere = mod.sphere;
                            _mod    = mod;
                        }, new Rect(20, index * distance + 10, 350, 20));
                    }
                    index++;
                    Button(Localization.LOC_KITTOPIATECH_PQSEDITOR_ADD_MOD, () => _mode = Modes.AddMod, new Rect(20, index * distance + 10, 350, 20));
                    if (Current.pqsController.ChildSpheres.All(s => s.name != Current.pqsController.name + "Ocean"))
                    {
                        Button(Localization.LOC_KITTOPIATECH_PQSEDITOR_ADD_OCEAN, () =>
                        {
                            // Generate the PQS object
                            GameObject gameObject = new GameObject("Ocean");
                            gameObject.layer      = Constants.GameLayers.LocalSpace;
                            PQS ocean             = gameObject.AddComponent <PQS>();

                            // Setup materials
                            PSystemBody Body = Utility.FindBody(Injector.StockSystemPrefab.rootBody, "Laythe");
                            foreach (PQS oc in Body.pqsVersion.GetComponentsInChildren <PQS>(true))
                            {
                                if (oc.name != "LaytheOcean")
                                {
                                    continue;
                                }

                                // Copying Laythes Ocean-properties
                                Utility.CopyObjectFields <PQS>(oc, ocean);
                            }

                            // Load our new Material into the PQS
                            ocean.surfaceMaterial      = new PQSOceanSurfaceQuadLoader(ocean.surfaceMaterial);
                            ocean.surfaceMaterial.name = Guid.NewGuid().ToString();

                            // Load fallback material into the PQS
                            ocean.fallbackMaterial      = new PQSOceanSurfaceQuadFallbackLoader(ocean.fallbackMaterial);
                            ocean.fallbackMaterial.name = Guid.NewGuid().ToString();

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

                            // Create the AerialPerspective Material
                            AerialPerspectiveMaterial mat = new AerialPerspectiveMaterial();
                            mat.Create(ocean);

                            // Create the OceanFX
                            OceanFX oceanFX = new OceanFX();
                            oceanFX.Create(ocean);

                            // Apply the Ocean
                            ocean.transform.parent = Current.pqsController.transform;

                            // Add the ocean PQS to the secondary renders of the CelestialBody Transform
                            PQSMod_CelestialBodyTransform transform = Current.pqsController.GetComponentsInChildren <PQSMod_CelestialBodyTransform>(true).FirstOrDefault(mod_ => mod_.transform.parent == Current.pqsController.transform);
                            transform.planetFade.secondaryRenderers.Add(ocean.gameObject);
                            typeof(PQS).GetField("_childSpheres", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(Current.pqsController, null);

                            // Names!
                            ocean.name            = Current.pqsController.name + "Ocean";
                            ocean.gameObject.name = Current.pqsController.name + "Ocean";
                            ocean.transform.name  = Current.pqsController.name + "Ocean";

                            // Set up the ocean PQS
                            ocean.parentSphere            = Current.pqsController;
                            ocean.transform.position      = Current.pqsController.transform.position;
                            ocean.transform.localPosition = Vector3.zero;
                            ocean.radius = Current.Radius;
                        }, new Rect(20, index * distance + 10, 350, 20));
                    }
                    else
                    {
                        Button(Localization.LOC_KITTOPIATECH_PQSEDITOR_REMOVE_OCEAN, () =>
                        {
                            // Find atmosphere the ocean PQS
                            PQS ocean = Current.pqsController.GetComponentsInChildren <PQS>(true).First(pqs => pqs != Current.pqsController);
                            PQSMod_CelestialBodyTransform cbt = Current.pqsController.GetComponentsInChildren <PQSMod_CelestialBodyTransform>(true).First();

                            // Destroy the ocean PQS (this could be bad - destroying the secondary fades...)
                            cbt.planetFade.secondaryRenderers.Remove(ocean.gameObject);
                            typeof(PQS).GetField("_childSpheres", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(Current.pqsController, null);
                            cbt.secondaryFades     = new PQSMod_CelestialBodyTransform.AltitudeFade[0];
                            ocean.transform.parent = null;
                            UnityEngine.Object.Destroy(ocean);
                        }, new Rect(20, index * distance + 10, 350, 20));
                    }

                    // End Scroll
                    EndScrollView();
                }

                // Mode PQS
                if (_mode == Modes.PQS)
                {
                    // Scroll
                    BeginScrollView(250, Utils.GetScrollSize <PQS>() + Utils.GetScrollSize <HazardousOcean>() + distance * 1, 20);

                    // Index
                    index = 0;

                    // Render the PQS
                    RenderObject(_sphere);

                    // If it is an ocean, create an Hazardous Ocean button
                    if (PQSOceanSurfaceQuad.UsesSameShader(_sphere.surfaceMaterial))
                    {
                        Label("hazardousOcean"); index--;
                        if (_sphere.GetComponent <HazardousOcean>() != null)
                        {
                            Button(Localization.LOC_KITTOPIATECH_EDIT, () =>
                            {
                                UIController.Instance.SetEditedObject(KittopiaWindows.Curve, _sphere.GetComponent <HazardousOcean>().heatCurve ?? new FloatCurve(), c => _sphere.GetComponent <HazardousOcean>().heatCurve = c);
                                UIController.Instance.EnableWindow(KittopiaWindows.Curve);
                            }, new Rect(200, index * distance + 10, 75, 20)); index--;
                            Button(Localization.LOC_KITTOPIATECH_REMOVE, () => UnityEngine.Object.DestroyImmediate(_sphere.GetComponent <HazardousOcean>()), new Rect(285, index * distance + 10, 75, 20));
                        }
                        else
                        {
                            Button(Localization.LOC_KITTOPIATECH_PQSEDITOR_ADD_HAZOCEAN, () => _sphere.gameObject.AddComponent <HazardousOcean>(), new Rect(200, index * distance + 10, 170, 20));
                        }
                    }
                    index++;

                    // Rebuild
                    Button(Localization.LOC_KITTOPIATECH_PQSEDITOR_REBUILD, () => _sphere.RebuildSphere());

                    // End Scroll
                    EndScrollView();
                }

                // Mode PQSMod
                if (_mode == Modes.PQSMod)
                {
                    // Scroll
                    BeginScrollView(250, Utils.GetScrollSize(_mod.GetType()) + distance * 5, 20);

                    // Index
                    index = 0;

                    // Render the PQS
                    RenderObject(_mod);
                    index++;

                    // Rebuild
                    Button(Localization.LOC_KITTOPIATECH_PQSEDITOR_REBUILD, () => _sphere.RebuildSphere());

                    // Remove
                    Button(Localization.LOC_KITTOPIATECH_PQSEDITOR_REMOVE_MOD, () =>
                    {
                        _mod.sphere = null;
                        UnityEngine.Object.Destroy(_mod);
                        _mod = null;

                        // Hack
                        _sphere.SetupExternalRender();
                        _sphere.CloseExternalRender();

                        _mode = Modes.List;
                    });

                    // End Scroll
                    EndScrollView();
                }

                // Mode AddPQSMod
                if (_mode == Modes.AddMod)
                {
                    // Get all PQSMod types
                    List <Type> types = Parser.ModTypes.Where(t => t.IsSubclassOf(typeof(PQSMod))).ToList();

                    // Begin Scroll
                    BeginScrollView(250, types.Count * distance + 10, 20);

                    // Index
                    index = 0;

                    // Render the possible types
                    foreach (Type t in types)
                    {
                        Button(t.FullName, () =>
                        {
                            // Hack^6
                            GameObject pqsModObject       = new GameObject(t.Name);
                            pqsModObject.transform.parent = Current.pqsController.transform;
                            PQSMod mod = pqsModObject.AddComponent(t) as PQSMod;
                            mod.sphere = Current.pqsController;

                            if (t == typeof(PQSMod_VoronoiCraters))
                            {
                                PQS mun = Utility.FindBody(Injector.StockSystemPrefab.rootBody, "Mun").pqsVersion;
                                PQSMod_VoronoiCraters craters = mun.GetComponentsInChildren <PQSMod_VoronoiCraters>()[0];
                                PQSMod_VoronoiCraters nc      = pqsModObject.GetComponentsInChildren <PQSMod_VoronoiCraters>()[0];
                                nc.craterColourRamp           = craters.craterColourRamp;
                                nc.craterCurve = craters.craterCurve;
                                nc.jitterCurve = craters.jitterCurve;
                            }
                            else if (t == typeof(PQSMod_VertexPlanet))
                            {
                                PQSMod_VertexPlanet vp     = mod as PQSMod_VertexPlanet;
                                vp.landClasses             = new [] { new PQSMod_VertexPlanet.LandClass("Class", 0, 1, Color.black, Color.white, 0) };
                                vp.continental             = new PQSMod_VertexPlanet.SimplexWrapper(0, 0, 0, 0);
                                vp.continentalRuggedness   = new PQSMod_VertexPlanet.SimplexWrapper(0, 0, 0, 0);
                                vp.continentalSharpness    = new PQSMod_VertexPlanet.NoiseModWrapper(0, 0, 0, 0);
                                vp.continentalSharpnessMap = new PQSMod_VertexPlanet.SimplexWrapper(0, 0, 0, 0);
                                vp.terrainType             = new PQSMod_VertexPlanet.SimplexWrapper(0, 0, 0, 0);
                            }
                            else if (t == typeof(PQSMod_HeightColorMap))
                            {
                                (mod as PQSMod_HeightColorMap).landClasses = new [] { new PQSMod_HeightColorMap.LandClass("Class", 0, 1, Color.black, Color.white, 0) };
                            }
                            else if (t == typeof(PQSMod_HeightColorMap2))
                            {
                                (mod as PQSMod_HeightColorMap2).landClasses = new[] { new PQSMod_HeightColorMap2.LandClass("Class", 0, 1, Color.black, Color.white, 0) };
                            }
                            else if (t == typeof(PQSMod_HeightColorMapNoise))
                            {
                                (mod as PQSMod_HeightColorMapNoise).landClasses = new[] { new PQSMod_HeightColorMapNoise.LandClass("Class", 0, 1, Color.black, Color.white, 0) };
                            }
                            else if (t == typeof(PQSLandControl))
                            {
                                PQSLandControl lc  = mod as PQSLandControl;
                                lc.altitudeSimplex = new Simplex();
                                lc.scatters        = new PQSLandControl.LandClassScatter[0];
                                lc.landClasses     = new [] { new PQSLandControl.LandClass()
                                                              {
                                                                  altitudeRange       = new PQSLandControl.LerpRange(),
                                                                  coverageSimplex     = new Simplex(),
                                                                  longitudeRange      = new PQSLandControl.LerpRange(),
                                                                  latitudeDoubleRange = new PQSLandControl.LerpRange(),
                                                                  latitudeRange       = new PQSLandControl.LerpRange(),
                                                                  scatter             = new PQSLandControl.LandClassScatterAmount[0]
                                                              } };
                                lc.latitudeSimplex  = new Simplex();
                                lc.longitudeSimplex = new Simplex();
                            }

                            // Edit the mod
                            _mod    = mod;
                            _sphere = mod.sphere;
                            _mode   = Modes.PQSMod;
                        }, new Rect(20, index * distance + 10, 350, 20));
                    }


                    // End Scroll
                    EndScrollView();
                }
            }
            public static IEnumerator UpdateTextures(CelestialBody celestialBody, TextureOptions options)
            {
                // Get time
                DateTime now = DateTime.Now;

                // If the user wants to export normals, we need height too
                if (options.ExportNormal)
                {
                    options.ExportHeight = true;
                }

                // Prepare the PQS
                PQS pqsVersion = celestialBody.pqsController;

                // If the PQS is null, abort
                if (pqsVersion == null)
                {
                    yield break;
                }

                // Tell the PQS that we are going to build maps
                pqsVersion.SetupExternalRender();

                // Get the mod building methods from the PQS
                #if !KSP131
                Action <PQS.VertexBuildData, Boolean> modOnVertexBuildHeight =
                    (Action <PQS.VertexBuildData, Boolean>)Delegate.CreateDelegate(
                        typeof(Action <PQS.VertexBuildData, Boolean>),
                        pqsVersion,
                        typeof(PQS).GetMethod("Mod_OnVertexBuildHeight",
                                              BindingFlags.Instance | BindingFlags.NonPublic));
                #else
                Action <PQS.VertexBuildData> modOnVertexBuildHeight =
                    (Action <PQS.VertexBuildData>)Delegate.CreateDelegate(
                        typeof(Action <PQS.VertexBuildData>),
                        pqsVersion,
                        typeof(PQS).GetMethod("Mod_OnVertexBuildHeight",
                                              BindingFlags.Instance | BindingFlags.NonPublic));
                #endif
                Action <PQS.VertexBuildData> modOnVertexBuild = (Action <PQS.VertexBuildData>)Delegate.CreateDelegate(
                    typeof(Action <PQS.VertexBuildData>),
                    pqsVersion,
                    typeof(PQS).GetMethod("Mod_OnVertexBuild", BindingFlags.Instance | BindingFlags.NonPublic));

                // Get all mods the PQS is connected to
                PQSMod[] mods = pqsVersion.GetComponentsInChildren <PQSMod>()
                                .Where(m => m.sphere == pqsVersion && m.modEnabled).OrderBy(m => m.order).ToArray();

                // Prevent the PQS from updating
                pqsVersion.enabled = false;

                // Create the Textures
                Texture2D colorMap = new Texture2D(options.Resolution, options.Resolution / 2,
                                                   TextureFormat.ARGB32,
                                                   true);
                Texture2D heightMap = new Texture2D(options.Resolution, options.Resolution / 2,
                                                    TextureFormat.RGB24,
                                                    true);

                // Arrays
                Color[] colorMapValues  = new Color[options.Resolution * (options.Resolution / 2)];
                Color[] heightMapValues = new Color[options.Resolution * (options.Resolution / 2)];

                // Create a VertexBuildData
                PQS.VertexBuildData data = new PQS.VertexBuildData();

                // Display
                ScreenMessage message = ScreenMessages.PostScreenMessage("Generating terrain data", Single.MaxValue, ScreenMessageStyle.UPPER_CENTER);
                yield return(null);

                Double[] heightValues = new Double[options.Resolution * (options.Resolution / 2)];

                // Loop through the pixels
                for (Int32 y = 0; y < options.Resolution / 2; y++)
                {
                    // Update Message
                    Double percent = y / (options.Resolution / 2d) * 100;
                    while (CanvasUpdateRegistry.IsRebuildingLayout())
                    {
                        Thread.Sleep(10);
                    }
                    message.textInstance.text.text = "Generating terrain data: " + percent.ToString("0.00") + "%";

                    for (Int32 x = 0; x < options.Resolution; x++)
                    {
                        // Update the VertexBuildData
                        data.directionFromCenter =
                            QuaternionD.AngleAxis(360d / options.Resolution * x, Vector3d.up) *
                            QuaternionD.AngleAxis(90d - 180d / (options.Resolution / 2f) * y, Vector3d.right)
                            * Vector3d.forward;
                        data.vertHeight = pqsVersion.radius;

                        #if !KSP131
                        modOnVertexBuildHeight(data, true);
                        #else
                        modOnVertexBuildHeight(data);
                        #endif
                        modOnVertexBuild(data);

                        // Cache the results
                        heightValues[y * options.Resolution + x]   = data.vertHeight;
                        colorMapValues[y * options.Resolution + x] = data.vertColor;
                    }
                    yield return(null);
                }

                // Update Message
                while (CanvasUpdateRegistry.IsRebuildingLayout())
                {
                    Thread.Sleep(10);
                }
                message.textInstance.text.text = "Calculating height difference";

                // Figure out the delta radius ourselves
                Double minHeight = Double.MaxValue;
                Double maxHeight = Double.MinValue;
                for (Int32 i = 0; i < heightValues.Length; i++)
                {
                    if (heightValues[i] > maxHeight)
                    {
                        maxHeight = heightValues[i];
                    }
                    else if (heightValues[i] < minHeight)
                    {
                        minHeight = heightValues[i];
                    }
                }
                Double deltaRadius = maxHeight - minHeight;
                yield return(null);

                // Update Message
                while (CanvasUpdateRegistry.IsRebuildingLayout())
                {
                    Thread.Sleep(10);
                }
                message.textInstance.text.text = "Calculating color data";

                // Apply the values
                for (Int32 y = 0; y < options.Resolution / 2; y++)
                {
                    // Update Message
                    Double percent = y / (options.Resolution / 2d) * 100;
                    while (CanvasUpdateRegistry.IsRebuildingLayout())
                    {
                        Thread.Sleep(10);
                    }
                    message.textInstance.text.text = "Calculating color data: " + percent.ToString("0.00") + "%";

                    for (Int32 x = 0; x < options.Resolution; x++)
                    {
                        // Build from the Mods
                        Double height = heightValues[y * options.Resolution + x] - pqsVersion.radius;
                        if (options.ExportColor)
                        {
                            // Adjust the Color
                            Color color = colorMapValues[y * options.Resolution + x];
                            if (!pqsVersion.mapOcean)
                            {
                                color.a = 1f;
                            }
                            else if (height > pqsVersion.mapOceanHeight)
                            {
                                color.a = options.TransparentMaps ? 0f : 1f;
                            }
                            else
                            {
                                color = pqsVersion.mapOceanColor.A(1f);
                            }

                            // Set the Pixels
                            colorMapValues[y * options.Resolution + x] = color;
                        }
                        if (options.ExportHeight)
                        {
                            // Adjust the height
                            height = height / deltaRadius;
                            if (height < 0)
                            {
                                height = 0;
                            }
                            else if (height > 1)
                            {
                                height = 1;
                            }

                            // Set the Pixels
                            heightMapValues[y * options.Resolution + x] =
                                new Color((Single)height, (Single)height, (Single)height);
                        }
                    }

                    yield return(null);
                }

                // Serialize the maps to disk
                String name = "KittopiaTech/PluginData/" + celestialBody.transform.name + "/" + DateTime.Now.ToString("yyyy-MM-dd_hh-mm-ss") + "/";
                String path = KSPUtil.ApplicationRootPath + "/GameData/" + name;
                Directory.CreateDirectory(path);

                // Colormap
                if (options.ExportColor)
                {
                    // Update Message
                    while (CanvasUpdateRegistry.IsRebuildingLayout())
                    {
                        Thread.Sleep(10);
                    }
                    message.textInstance.text.text = "Exporting planet maps: Color";

                    // Save it
                    colorMap.SetPixels(colorMapValues);
                    yield return(null);

                    if (options.SaveToDisk)
                    {
                        File.WriteAllBytes(path + celestialBody.transform.name + "_Color.png", colorMap.EncodeToPNG());
                        colorMap.name = name + celestialBody.transform.name + "_Color.png";
                        yield return(null);
                    }

                    // Apply it
                    if (options.ApplyToScaled)
                    {
                        ScaledSpaceOnDemand od = celestialBody.scaledBody.GetComponent <ScaledSpaceOnDemand>();
                        if (od != null)
                        {
                            od.texture = colorMap.name;
                            UnityEngine.Object.DestroyImmediate(colorMap);

                            if (od.isLoaded)
                            {
                                od.UnloadTextures();
                                od.LoadTextures();
                            }
                        }
                        else
                        {
                            colorMap.Apply();
                            celestialBody.scaledBody.GetComponent <MeshRenderer>().sharedMaterial.SetTexture("_MainTex", colorMap);
                        }
                    }
                    else
                    {
                        UnityEngine.Object.DestroyImmediate(colorMap);
                    }
                }

                if (options.ExportHeight)
                {
                    // Update Message
                    while (CanvasUpdateRegistry.IsRebuildingLayout())
                    {
                        Thread.Sleep(10);
                    }
                    message.textInstance.text.text = "Exporting planet maps: Height";

                    heightMap.SetPixels(heightMapValues);
                    yield return(null);

                    if (options.SaveToDisk)
                    {
                        File.WriteAllBytes(path + celestialBody.transform.name + "_Height.png",
                                           heightMap.EncodeToPNG());
                        yield return(null);
                    }

                    if (options.ExportNormal)
                    {
                        // Update Message
                        while (CanvasUpdateRegistry.IsRebuildingLayout())
                        {
                            Thread.Sleep(10);
                        }
                        message.textInstance.text.text = "Exporting planet maps: Normal";

                        // Bump to Normal Map
                        Texture2D normalMap = Utility.BumpToNormalMap(heightMap, pqsVersion, options.NormalStrength / 10);
                        yield return(null);

                        if (options.SaveToDisk)
                        {
                            File.WriteAllBytes(path + celestialBody.transform.name + "_Normal.png",
                                               normalMap.EncodeToPNG());
                            normalMap.name = name + celestialBody.transform.name + "_Normal.png";
                            yield return(null);
                        }

                        // Apply it
                        if (options.ApplyToScaled)
                        {
                            ScaledSpaceOnDemand od = celestialBody.scaledBody.GetComponent <ScaledSpaceOnDemand>();
                            if (od != null)
                            {
                                od.normals = normalMap.name;
                                UnityEngine.Object.DestroyImmediate(normalMap);

                                if (od.isLoaded)
                                {
                                    od.UnloadTextures();
                                    od.LoadTextures();
                                }
                            }
                            else
                            {
                                normalMap.Apply();
                                celestialBody.scaledBody.GetComponent <MeshRenderer>().sharedMaterial
                                .SetTexture("_BumpMap", normalMap);
                            }
                        }
                        else
                        {
                            UnityEngine.Object.DestroyImmediate(normalMap);
                        }
                    }

                    UnityEngine.Object.DestroyImmediate(heightMap);
                }

                // Close the Renderer
                pqsVersion.enabled = true;
                pqsVersion.CloseExternalRender();

                // Declare that we're done
                ScreenMessages.RemoveMessage(message);
                ScreenMessages.PostScreenMessage("Operation completed in: " + (DateTime.Now - now).TotalMilliseconds + " ms", 2f, ScreenMessageStyle.UPPER_CENTER);
            }
示例#9
0
            /// <summary>
            /// Generate the scaled space Textures using PQS in a Coroutine
            /// </summary>
            public static IEnumerator GeneratePQSMaps(CelestialBody body, Boolean transparentMaps, ExportMode mode)
            {
                // Get time
                DateTime now = DateTime.Now;

                // Get PQS
                PQS pqs = body.pqsController;

                pqs.isBuildingMaps = true;
                pqs.isFakeBuild    = true;

                // Get the mods
                Action <PQS.VertexBuildData> modOnVertexBuildHeight = (Action <PQS.VertexBuildData>)Delegate.CreateDelegate(
                    typeof(Action <PQS.VertexBuildData>),
                    pqs,
                    typeof(PQS).GetMethod("Mod_OnVertexBuildHeight", BindingFlags.Instance | BindingFlags.NonPublic));
                Action <PQS.VertexBuildData> modOnVertexBuild = (Action <PQS.VertexBuildData>)Delegate.CreateDelegate(
                    typeof(Action <PQS.VertexBuildData>),
                    pqs,
                    typeof(PQS).GetMethod("Mod_OnVertexBuild", BindingFlags.Instance | BindingFlags.NonPublic));

                PQSMod[] mods = pqs.GetComponentsInChildren <PQSMod>().Where(m => m.sphere == pqs && m.modEnabled).ToArray();

                // Create the Textures
                Texture2D colorMap  = new Texture2D(pqs.mapFilesize, pqs.mapFilesize / 2, TextureFormat.ARGB32, true);
                Texture2D heightMap = new Texture2D(pqs.mapFilesize, pqs.mapFilesize / 2, TextureFormat.RGB24, true);

                // Arrays
                Color[] colorMapValues  = new Color[pqs.mapFilesize * (pqs.mapFilesize / 2)];
                Color[] heightMapValues = new Color[pqs.mapFilesize * (pqs.mapFilesize / 2)];

                // Stuff
                ScreenMessage message = ScreenMessages.PostScreenMessage("Generating Planet-Maps", Single.MaxValue, ScreenMessageStyle.UPPER_CENTER);

                // Wait a some time
                yield return(null);

                // Loop through the pixels
                for (int y = 0; y < (pqs.mapFilesize / 2); y++)
                {
                    for (int x = 0; x < pqs.mapFilesize; x++)
                    {
                        // Update Message
                        Double percent = ((double)((y * pqs.mapFilesize) + x) / ((pqs.mapFilesize / 2) * pqs.mapFilesize)) * 100;
                        while (CanvasUpdateRegistry.IsRebuildingLayout())
                        {
                            Thread.Sleep(10);
                        }
                        message.textInstance.text.text = "Generating Planet-Maps: " + percent.ToString("0.00") + "%";

                        // Create a VertexBuildData
                        PQS.VertexBuildData data = new PQS.VertexBuildData
                        {
                            directionFromCenter = (QuaternionD.AngleAxis((360d / pqs.mapFilesize) * x, Vector3d.up) * QuaternionD.AngleAxis(90d - (180d / (pqs.mapFilesize / 2)) * y, Vector3d.right)) * Vector3d.forward,
                            vertHeight          = pqs.radius
                        };

                        // Build from the Mods
                        double height = Double.MinValue;
                        if (mode != ExportMode.COLOR)
                        {
                            modOnVertexBuildHeight(data);

                            // Adjust the height
                            height = (data.vertHeight - pqs.radius) * (1d / pqs.mapMaxHeight);
                            if (height < 0)
                            {
                                height = 0;
                            }
                            else if (height > 1)
                            {
                                height = 1;
                            }

                            // Set the Pixels
                            heightMapValues[(y * pqs.mapFilesize) + x] = new Color((Single)height, (Single)height, (Single)height);
                        }
                        if (mode == ExportMode.COLOR || mode == ExportMode.ALL)
                        {
                            modOnVertexBuild(data);

                            // Adjust the Color
                            Color color = data.vertColor;
                            if (!pqs.mapOcean)
                            {
                                color.a = 1f;
                            }
                            else if (height > pqs.mapOceanHeight)
                            {
                                color.a = transparentMaps ? 0f : 1f;
                            }
                            else if (mode == ExportMode.COLOR)
                            {
                                color.a = 1f;
                            }
                            else
                            {
                                color = pqs.mapOceanColor.A(1f);
                            }

                            // Set the Pixels
                            colorMapValues[(y * pqs.mapFilesize) + x] = color;
                        }
                    }
                    yield return(null);
                }

                // Apply the maps
                if (mode == ExportMode.COLOR || mode == ExportMode.ALL)
                {
                    colorMap.SetPixels(colorMapValues);
                    colorMap.Apply();
                }
                if (mode != ExportMode.COLOR)
                {
                    heightMap.SetPixels(heightMapValues);
                }
                yield return(null);

                // Close the Renderer
                pqs.isBuildingMaps = false;
                pqs.isFakeBuild    = false;

                // Serialize them to disk
                string path = KSPUtil.ApplicationRootPath + "/GameData/KittopiaTech/Textures/" + body.name + "/";

                Directory.CreateDirectory(path);
                if (mode == ExportMode.COLOR || mode == ExportMode.ALL)
                {
                    File.WriteAllBytes(path + body.name + "_Color.png", colorMap.EncodeToPNG());

                    // Apply them to the ScaledVersion
                    body.scaledBody.GetComponent <MeshRenderer>().material.SetTexture("_MainTex", colorMap);
                }
                if (mode != ExportMode.COLOR)
                {
                    File.WriteAllBytes(path + body.name + "_Height.png", heightMap.EncodeToPNG());
                }
                if (mode == ExportMode.HEIGHTNORMAL || mode == ExportMode.ALL)
                {
                    // Bump to Normal Map
                    Texture2D normalMap = Utility.BumpToNormalMap(heightMap, UIController.NormalStrength);
                    File.WriteAllBytes(path + body.name + "_Normal.png", normalMap.EncodeToPNG());

                    // Apply them to the ScaledVersion
                    body.scaledBody.GetComponent <MeshRenderer>().material.SetTexture("_BumpMap", normalMap);
                }
                yield return(null);

                // Declare that we're done
                ScreenMessages.RemoveMessage(message);
                ScreenMessages.PostScreenMessage("Operation completed in: " + (DateTime.Now - now).TotalMilliseconds + " ms", 2f, ScreenMessageStyle.UPPER_CENTER);
            }
 /// <summary>
 /// Find quads that are near a transform
 /// </summary>
 public static PQ[] FindNearbyQuads(PQS pqsVersion, Vector3d position, Int32 count)
 {
     IEnumerable<PQ> quads = pqsVersion.GetComponentsInChildren<PQ>(true);
     quads = quads.OrderBy(q => Vector3.Distance(q.quadTransform.position, position)).Take(count);
     return quads.ToArray();
 }
        // Generate the scaled space mesh using PQS (all results use scale of 1)
        public static Mesh ComputeScaledSpaceMesh(CelestialBody body, PQS pqsVersion)
        {
            // We need to get the body for Jool (to steal it's mesh)
            const Double rScaledJool          = 1000.0f;
            Double       rMetersToScaledUnits = (Single)(rScaledJool / body.Radius);

            // Generate a duplicate of the Jool mesh
            Mesh mesh = DuplicateMesh(Templates.ReferenceGeosphere);

            // If this body has a PQS, we can create a more detailed object
            if (pqsVersion != null)
            {
                // Find the PQS mods and enable the PQS-sphere
                IEnumerable <PQSMod> mods = pqsVersion.GetComponentsInChildren <PQSMod>(true).Where(m => m.modEnabled).OrderBy(m => m.order);
                foreach (PQSMod flatten in mods.Where(m => m is PQSMod_FlattenArea))
                {
                    flatten.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).First(f => f.FieldType == typeof(Boolean)).SetValue(flatten, true);
                }

                pqsVersion.isBuildingMaps = true;

                // If we were able to find PQS mods
                if (mods.Any())
                {
                    // Generate the PQS modifications
                    Vector3[] vertices = mesh.vertices;
                    for (Int32 i = 0; i < mesh.vertexCount; i++)
                    {
                        // Get the UV coordinate of this vertex
                        Vector2 uv = mesh.uv[i];

                        // Since this is a geosphere, normalizing the vertex gives the direction from center center
                        Vector3 direction = vertices[i];
                        direction.Normalize();

                        // Build the vertex data object for the PQS mods
                        PQS.VertexBuildData vertex = new PQS.VertexBuildData();
                        vertex.directionFromCenter = direction;
                        vertex.vertHeight          = body.Radius;
                        vertex.u = uv.x;
                        vertex.v = uv.y;

                        // Build from the PQS
                        foreach (PQSMod mod in mods)
                        {
                            mod.OnVertexBuildHeight(vertex);
                        }

                        // Check for sea level
                        if (body.ocean && vertex.vertHeight < body.Radius)
                        {
                            vertex.vertHeight = body.Radius;
                        }

                        // Adjust the displacement
                        vertices[i] = direction * (Single)(vertex.vertHeight * rMetersToScaledUnits);
                    }
                    mesh.vertices = vertices;
                    mesh.RecalculateNormals();
                    mesh.RecalculateBounds();
                }

                // Cleanup
                pqsVersion.isBuildingMaps = false;
            }

            // Return the generated scaled space mesh
            return(mesh);
        }
示例#12
0
        // Generate the scaled space mesh using PQS (all results use scale of 1)
        public static Mesh ComputeScaledSpaceMesh(CelestialBody body, PQS pqs)
        {
            // We need to get the body for Jool (to steal it's mesh)
            const Double rScaledJool          = 1000.0f;
            Double       rMetersToScaledUnits = (Single)(rScaledJool / body.Radius);

            // Generate a duplicate of the Jool mesh
            Mesh mesh = DuplicateMesh(Templates.ReferenceGeosphere);

            Logger.Active.Log(body);
            Logger.Active.Log(pqs);
            Logger.Active.Log(body.pqsController);

            // If this body has a PQS, we can create a more detailed object
            if (pqs != null)
            {
                // first we enable all maps
                OnDemandStorage.EnableBody(body.bodyName);

                // The game object the PQS is attached to
                GameObject pqsVersionGameObject = null;
                if (Injector.IsInPrefab)
                {
                    // In order to generate the scaled space we have to enable the mods.  Since this is
                    // a prefab they don't get disabled as kill game performance.  To resolve this we
                    // clone the PQS, use it, and then delete it when done
                    pqsVersionGameObject = UnityEngine.Object.Instantiate(pqs.gameObject);
                }
                else
                {
                    // At runtime we simply use the PQS that is active
                    pqsVersionGameObject = pqs.gameObject;
                }
                PQS pqsVersion = pqsVersionGameObject.GetComponent <PQS>();

                // Load the PQS of the ocean
                PQS pqsOcean = pqs.ChildSpheres?.FirstOrDefault();

                // Deactivate blacklisted Mods
                Type[] blacklist = { typeof(PQSMod_OnDemandHandler) };
                foreach (PQSMod mod in pqsVersion.GetComponentsInChildren <PQSMod>(true)
                         .Where(m => m.enabled && blacklist.Contains(m.GetType())))
                {
                    mod.modEnabled = false;
                }

                // Find the PQS mods and enable the PQS-sphere
                PQSMod[] mods = pqsVersion.GetComponentsInChildren <PQSMod>(true)
                                .Where(m => m.modEnabled && m.transform.parent == pqsVersion.transform).OrderBy(m => m.order).ToArray();
                foreach (PQSMod flatten in mods.Where(m => m is PQSMod_FlattenArea))
                {
                    flatten.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                    .First(f => f.FieldType == typeof(Boolean)).SetValue(flatten, true);
                }
                Logger.Active.Log(mods.Length);

                // Do the same for the ocean
                PQSMod[] oceanMods = new PQSMod[0];
                if (pqsOcean != null)
                {
                    oceanMods = pqsOcean.GetComponentsInChildren <PQSMod>(true)
                                .Where(m => m.modEnabled && m.transform.parent == pqsOcean.transform).OrderBy(m => m.order).ToArray();
                    foreach (PQSMod flatten in oceanMods.Where(m => m is PQSMod_FlattenArea))
                    {
                        flatten.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                        .First(f => f.FieldType == typeof(Boolean)).SetValue(flatten, true);
                    }

                    pqsOcean.StartUpSphere();
                    pqsOcean.isBuildingMaps = true;
                }

                pqsVersion.StartUpSphere();
                pqsVersion.isBuildingMaps = true;

                // If we were able to find PQS mods
                if (mods.Any())
                {
                    // Generate the PQS modifications
                    Vector3[] vertices = mesh.vertices;
                    for (Int32 i = 0; i < mesh.vertexCount; i++)
                    {
                        // Get the UV coordinate of this vertex
                        Vector2 uv = mesh.uv[i];

                        // Since this is a geosphere, normalizing the vertex gives the direction from center center
                        Vector3 direction = vertices[i];
                        direction.Normalize();

                        // Build the vertex data object for the PQS mods
                        PQS.VertexBuildData vertex = new PQS.VertexBuildData();
                        vertex.directionFromCenter = direction;
                        vertex.vertHeight          = body.Radius;
                        vertex.u = uv.x;
                        vertex.v = uv.y;

                        // Build from the PQS
                        foreach (PQSMod mod in mods)
                        {
                            mod.OnVertexBuildHeight(vertex);
                        }

                        // Check for sea level
                        if (pqsOcean != null)
                        {
                            // Build the vertex data object for the ocean
                            PQS.VertexBuildData vertexOcean = new PQS.VertexBuildData();
                            vertexOcean.directionFromCenter = direction;
                            vertexOcean.vertHeight          = body.Radius;
                            vertexOcean.u = uv.x;
                            vertexOcean.v = uv.y;

                            // Build from the PQS
                            foreach (PQSMod mod in oceanMods)
                            {
                                mod.OnVertexBuildHeight(vertexOcean);
                            }

                            vertex.vertHeight = Math.Max(vertex.vertHeight, vertexOcean.vertHeight);
                        }

                        // Adjust the displacement
                        vertices[i] = direction * (Single)(vertex.vertHeight * rMetersToScaledUnits);
                    }
                    mesh.vertices = vertices;
                    mesh.RecalculateNormals();
                    mesh.RecalculateBounds();
                }

                // Cleanup
                if (pqsOcean != null)
                {
                    pqsOcean.isBuildingMaps = false;
                    pqsOcean.DeactivateSphere();
                }
                pqsVersion.isBuildingMaps = false;
                pqsVersion.DeactivateSphere();

                // If we are working with a copied PQS, clean it up
                if (Injector.IsInPrefab)
                {
                    UnityEngine.Object.Destroy(pqsVersionGameObject);
                }
                OnDemandStorage.DisableBody(body.bodyName);
            }

            // Return the generated scaled space mesh
            return(mesh);
        }
示例#13
0
 public static T[] GetMods <T>(PQS sphere) where T : PQSMod
 {
     return(sphere.GetComponentsInChildren <T>(true).Where(m => m.transform.parent == sphere.transform).ToArray());
 }
            /// <summary>
            /// Writes a PQS to a new config node
            /// </summary>
            public static void WritePQSToConfigNode(PQS pqsVersion, ref ConfigNode body, bool ocean)
            {
                ConfigNode pqs = null;

                if (!ocean)
                {
                    CelestialBody cb        = pqsVersion.GetComponentInParent <CelestialBody>();
                    PQSLoader     pqsLoader = new PQSLoader(cb);
                    pqs = WriteObjectToConfigNode("PQS", ref body, pqsLoader);
                    WriteObjectToConfigNode("Material", ref pqs, pqsLoader.surfaceMaterial);
                    WriteObjectToConfigNode("FallbackMaterial", ref pqs, pqsLoader.fallbackMaterial);
                    if (pqsLoader.physicsMaterial.Value != null)
                    {
                        WriteObjectToConfigNode("PhysicsMaterial", ref pqs, pqsLoader.physicsMaterial);
                    }
                }
                else
                {
                    CelestialBody cb          = pqsVersion.parentSphere.GetComponentInParent <CelestialBody>();
                    OceanLoader   oceanLoader = new OceanLoader(cb);
                    pqs = WriteObjectToConfigNode("Ocean", ref body, oceanLoader);
                    pqs.AddValue("ocean", pqsVersion.parentSphere.mapOcean && cb.ocean);
                    pqs.AddValue("oceanColor", pqsVersion.parentSphere.mapOceanColor);
                    pqs.AddValue("oceanHeight", pqsVersion.parentSphere.mapOceanHeight);
                    pqs.AddValue("density", cb.oceanDensity);
                    WriteObjectToConfigNode("Material", ref pqs, oceanLoader.surfaceMaterial);
                    WriteObjectToConfigNode("FallbackMaterial", ref pqs, oceanLoader.fallbackMaterial);
                    WriteObjectToConfigNode("Fog", ref pqs, new FogLoader(Part.GetComponentUpwards <CelestialBody>(pqsVersion.gameObject)));
                    if (pqsVersion.gameObject.GetComponent <HazardousOcean>() != null)
                    {
                        pqsVersion.gameObject.GetComponent <HazardousOcean>().heatCurve.Save(pqs.AddNode("HazardousOcean"));
                    }
                }

                // Mods
                IEnumerable <PQSMod> mods = pqsVersion.GetComponentsInChildren <PQSMod>(true).Where(m => (ocean || m.sphere == pqsVersion) && !(m is PQSCity) && !(m is PQSCity2));

                // Get all loaded types
                IEnumerable <Type> types = AssemblyLoader.loadedAssemblies.SelectMany(a => a.assembly.GetTypes());

                if (mods.Count() != 0)
                {
                    ConfigNode modsNode = pqs.AddNode("Mods");
                    foreach (PQSMod Mod in mods)
                    {
                        // Fix PQSMods
                        PQSMod mod = Mod;

                        Type loaderType = types.FirstOrDefault(t => t.Name == Mod.GetType().Name.Replace("PQSMod_", "").Replace("PQS", ""));

                        // No loader
                        if (loaderType == null)
                        {
                            continue;
                        }

                        // Create the loader
                        object loader = Activator.CreateInstance(loaderType);

                        // Reflection, because C# being silly... :/
                        PropertyInfo info = loaderType.GetProperty("mod");
                        if (info == null)
                        {
                            continue;
                        }
                        info.SetValue(loader, mod, null);

                        // Load
                        ConfigNode           modNode      = WriteObjectToConfigNode(loaderType.Name, ref modsNode, loader);
                        IEnumerable <PQSMod> existingMods = pqsVersion.GetComponentsInChildren <PQSMod>(true).Where(m => m.GetType() == mod.GetType() && m.sphere == pqsVersion && m.name == mod.name);
                        modNode.AddValue("index", existingMods.ToList().IndexOf(mod));

                        // Submods
                        PQSMod_HeightColorMap hcm = mod as PQSMod_HeightColorMap;
                        if (hcm?.landClasses != null)
                        {
                            ConfigNode landClasses = modNode.AddNode("LandClasses");
                            foreach (PQSMod_HeightColorMap.LandClass landClass in hcm.landClasses)
                            {
                                WriteObjectToConfigNode("Class", ref landClasses, new HeightColorMap.LandClassLoader(landClass));
                            }
                        }
                        PQSMod_HeightColorMap2 hcm2 = mod as PQSMod_HeightColorMap2;
                        if (hcm2?.landClasses != null)
                        {
                            ConfigNode landClasses = modNode.AddNode("LandClasses");
                            foreach (PQSMod_HeightColorMap2.LandClass landClass in hcm2.landClasses)
                            {
                                WriteObjectToConfigNode("Class", ref landClasses, new HeightColorMap2.LandClassLoader(landClass));
                            }
                        }
                        PQSMod_HeightColorMapNoise hcmNoise = mod as PQSMod_HeightColorMapNoise;
                        if (hcmNoise?.landClasses != null)
                        {
                            ConfigNode landClasses = modNode.AddNode("LandClasses");
                            foreach (PQSMod_HeightColorMapNoise.LandClass landClass in hcmNoise.landClasses)
                            {
                                WriteObjectToConfigNode("Class", ref landClasses, new HeightColorMapNoise.LandClassLoader(landClass));
                            }
                        }
                        if (mod is PQSLandControl)
                        {
                            PQSLandControl lc = mod as PQSLandControl;
                            if (lc.altitudeSimplex != null)
                            {
                                KopernicusSimplexWrapper lcaltsimpwrap = new KopernicusSimplexWrapper(lc.altitudeBlend, lc.altitudeOctaves, lc.altitudePersistance, lc.altitudeFrequency);
                                lcaltsimpwrap.seed = lc.altitudeSeed;
                                WriteObjectToConfigNode("altitudeSimplex", ref modNode, new VertexPlanet.SimplexLoader(lcaltsimpwrap));
                            }
                            if (lc.latitudeSimplex != null)
                            {
                                KopernicusSimplexWrapper lclatsimpwrap = new KopernicusSimplexWrapper(lc.latitudeBlend, lc.latitudeOctaves, lc.latitudePersistance, lc.latitudeFrequency);
                                lclatsimpwrap.seed = lc.latitudeSeed;
                                WriteObjectToConfigNode("latitudeSimplex", ref modNode, new VertexPlanet.SimplexLoader(lclatsimpwrap));
                            }
                            if (lc.longitudeSimplex != null)
                            {
                                KopernicusSimplexWrapper lclongsimpwrap = new KopernicusSimplexWrapper(lc.longitudeBlend, lc.longitudeOctaves, lc.longitudePersistance, lc.longitudeFrequency);
                                lclongsimpwrap.seed = lc.longitudeSeed;
                                WriteObjectToConfigNode("longitudeSimplex", ref modNode, new VertexPlanet.SimplexLoader(lclongsimpwrap));
                            }
                            if (lc.landClasses != null)
                            {
                                ConfigNode landClasses = modNode.AddNode("landClasses");
                                foreach (PQSLandControl.LandClass landClass in lc.landClasses)
                                {
                                    ConfigNode lcNode = WriteObjectToConfigNode("Class", ref landClasses, new LandControl.LandClassLoader(landClass));
                                    WriteObjectToConfigNode("altitudeRange", ref lcNode, new LandControl.LerpRangeLoader(landClass.altitudeRange));
                                    KopernicusSimplexWrapper lccovsimpwrap = new KopernicusSimplexWrapper(landClass.coverageBlend, landClass.coverageOctaves, landClass.coveragePersistance, landClass.coverageFrequency);
                                    lccovsimpwrap.seed = landClass.coverageSeed;
                                    WriteObjectToConfigNode("coverageSimplex", ref lcNode, new VertexPlanet.SimplexLoader(lccovsimpwrap));
                                    WriteObjectToConfigNode("latitudeDoubleRange", ref lcNode, new LandControl.LerpRangeLoader(landClass.latitudeDoubleRange));
                                    WriteObjectToConfigNode("latitudeRange", ref lcNode, new LandControl.LerpRangeLoader(landClass.latitudeRange));
                                    WriteObjectToConfigNode("longitudeRange", ref lcNode, new LandControl.LerpRangeLoader(landClass.longitudeRange));
                                    KopernicusSimplexWrapper lcnoisesimpwrap = new KopernicusSimplexWrapper(landClass.noiseBlend, landClass.noiseOctaves, landClass.noisePersistance, landClass.noiseFrequency);
                                    lcnoisesimpwrap.seed = landClass.noiseSeed;
                                    WriteObjectToConfigNode("noiseSimplex", ref lcNode, new VertexPlanet.SimplexLoader(lcnoisesimpwrap));
                                    if (landClass.scatter != null)
                                    {
                                        ConfigNode amount = lcNode.AddNode("scatters");
                                        foreach (PQSLandControl.LandClassScatterAmount scatterAmount in landClass.scatter)
                                        {
                                            WriteObjectToConfigNode("Scatter", ref amount, new LandControl.LandClassScatterAmountLoader(scatterAmount));
                                        }
                                    }
                                }
                            }
                            if (lc.scatters != null)
                            {
                                ConfigNode scatters = modNode.AddNode("scatters");
                                foreach (PQSLandControl.LandClassScatter scatter in lc.scatters)
                                {
                                    LandControl.LandClassScatterLoader classLoader = new LandControl.LandClassScatterLoader(scatter);
                                    if (scatter.material.shader == new NormalDiffuse().shader)
                                    {
                                        classLoader.customMaterial = new NormalDiffuseLoader(scatter.material);
                                    }
                                    else if (scatter.material.shader == new NormalBumped().shader)
                                    {
                                        classLoader.customMaterial = new NormalBumpedLoader(scatter.material);
                                    }
                                    else if (scatter.material.shader == new NormalDiffuseDetail().shader)
                                    {
                                        classLoader.customMaterial = new NormalDiffuseDetailLoader(scatter.material);
                                    }
                                    else if (scatter.material.shader == new DiffuseWrapLoader().shader)
                                    {
                                        classLoader.customMaterial = new DiffuseWrapLoader(scatter.material);
                                    }
                                    else if (scatter.material.shader == new AlphaTestDiffuse().shader)
                                    {
                                        classLoader.customMaterial = new AlphaTestDiffuseLoader(scatter.material);
                                    }
                                    else if (scatter.material.shader == new AerialTransCutout().shader)
                                    {
                                        classLoader.customMaterial = new AerialTransCutoutLoader(scatter.material);
                                    }
                                    ConfigNode scatterNode = WriteObjectToConfigNode("Scatter", ref scatters, classLoader);
                                    WriteObjectToConfigNode("Material", ref scatterNode, classLoader.customMaterial);
                                    scatterNode.AddNode("Experiment");
                                }
                            }
                        }
                        if (mod is PQSMod_VertexPlanet)
                        {
                            PQSMod_VertexPlanet vp = mod as PQSMod_VertexPlanet;
                            WriteObjectToConfigNode("ContinentalSimplex", ref modNode, new PQSMod_VertexPlanet.SimplexWrapper(vp.continental));
                            WriteObjectToConfigNode("RuggednessSimplex", ref modNode, new PQSMod_VertexPlanet.SimplexWrapper(vp.continentalRuggedness));
                            WriteObjectToConfigNode("SharpnessNoise", ref modNode, new PQSMod_VertexPlanet.NoiseModWrapper(vp.continentalSharpness));
                            WriteObjectToConfigNode("SharpnessSimplexMap", ref modNode, new PQSMod_VertexPlanet.SimplexWrapper(vp.continentalSharpnessMap));
                            WriteObjectToConfigNode("TerrainTypeSimplex", ref modNode, new PQSMod_VertexPlanet.SimplexWrapper(vp.terrainType));
                            if (vp.landClasses != null)
                            {
                                ConfigNode landClasses = modNode.AddNode("LandClasses");
                                foreach (PQSMod_VertexPlanet.LandClass landClass in vp.landClasses)
                                {
                                    ConfigNode classNode = WriteObjectToConfigNode("Class", ref landClasses, new VertexPlanet.LandClassLoader(landClass));
                                    WriteObjectToConfigNode("SimplexNoiseMap", ref classNode, new PQSMod_VertexPlanet.SimplexWrapper(landClass.colorNoiseMap));
                                }
                            }
                        }
                        if (!(mod is PQSMod_OceanFX))
                        {
                            continue;
                        }
                        List <Texture2DParser> wm        = (loader as OceanFX).watermain;
                        ConfigNode             watermain = modNode.AddNode("Watermain");
                        foreach (Texture2DParser texture in wm)
                        {
                            watermain.AddValue("waterTex-" + wm.ToList().IndexOf(texture), texture.Value.name);
                        }
                    }
                }
            }
示例#15
0
        /// <summary>
        /// Will remove all mods of given types (or all, if types null)
        /// </summary>
        /// <param name="types">If null, will remove all mods except blacklisted mods</param>
        /// <param name="p">PQS to remove from</param>
        /// <param name="blacklist">list of mod types to not remove (optional)</param>
        public static void RemoveModsOfType(List <Type> types, PQS p, List <Type> blacklist = null)
        {
            Logger.Active.Log("Removing mods from pqs " + p.name);
            List <PQSMod> cpMods   = p.GetComponentsInChildren <PQSMod>(true).ToList();
            Boolean       addTypes = types == null;

            if (addTypes)
            {
                types = new List <Type>();
            }
            if (blacklist == null)
            {
                Logger.Active.Log("Creating blacklist");
                blacklist = new List <Type>();
                if (!types.Contains(typeof(PQSMod_CelestialBodyTransform)))
                {
                    blacklist.Add(typeof(PQSMod_CelestialBodyTransform));
                }
                if (!types.Contains(typeof(PQSMod_MaterialSetDirection)))
                {
                    blacklist.Add(typeof(PQSMod_MaterialSetDirection));
                }
                if (!types.Contains(typeof(PQSMod_UVPlanetRelativePosition)))
                {
                    blacklist.Add(typeof(PQSMod_UVPlanetRelativePosition));
                }
                if (!types.Contains(typeof(PQSMod_QuadMeshColliders)))
                {
                    blacklist.Add(typeof(PQSMod_QuadMeshColliders));
                }
                Logger.Active.Log("Blacklist count = " + blacklist.Count);
            }

            if (addTypes)
            {
                Logger.Active.Log("Adding all found PQSMods in pqs " + p.name);
                foreach (PQSMod m in cpMods)
                {
                    Type mType = m.GetType();
                    if (types.Contains(mType) || blacklist.Contains(mType))
                    {
                        continue;
                    }

                    Logger.Active.Log("Adding to remove list: " + mType);
                    types.Add(mType);
                }
            }
            List <GameObject> toCheck = new List <GameObject>();

            foreach (Type mType in types)
            {
                List <PQSMod> mods = cpMods.Where(m => m.GetType() == mType).ToList();
                foreach (PQSMod delMod in mods)
                {
                    if (delMod == null)
                    {
                        continue;
                    }

                    Logger.Active.Log("Removed mod " + mType);
                    if (!toCheck.Contains(delMod.gameObject))
                    {
                        toCheck.Add(delMod.gameObject);
                    }

                    delMod.sphere = null;
                    switch (delMod)
                    {
                    case PQSCity mod:
                    {
                        PQSCity city = mod;
                        if (city.lod != null)
                        {
                            foreach (PQSCity.LODRange range in city.lod)
                            {
                                if (range.objects != null)
                                {
                                    foreach (GameObject o in range.objects)
                                    {
                                        UnityEngine.Object.DestroyImmediate(o);
                                    }
                                }

                                if (range.renderers == null)
                                {
                                    continue;
                                }
                                foreach (GameObject o in range.renderers)
                                {
                                    UnityEngine.Object.DestroyImmediate(o);
                                }
                            }
                        }
                        break;
                    }

                    case PQSCity2 mod:
                    {
                        PQSCity2 city = mod;
                        if (city.objects != null)
                        {
                            foreach (PQSCity2.LodObject range in city.objects)
                            {
                                if (range.objects == null)
                                {
                                    continue;
                                }
                                foreach (GameObject o in range.objects)
                                {
                                    UnityEngine.Object.DestroyImmediate(o);
                                }
                            }
                        }
                        break;
                    }
                    }

                    cpMods.Remove(delMod);

                    // If no mod is left, delete the game object too
                    GameObject gameObject = delMod.gameObject;
                    UnityEngine.Object.DestroyImmediate(delMod);
                    PQSMod[] allRemainingMods = gameObject.GetComponentsInChildren <PQSMod>(true);
                    if (allRemainingMods.Length == 0)
                    {
                        UnityEngine.Object.DestroyImmediate(gameObject);
                    }
                }
            }
        }
示例#16
0
 private static void AddMapSOs(List<MapSO> list, PQS pqs)
 {
     PQSMod[] mods = pqs.GetComponentsInChildren<PQSMod>(true) as PQSMod[];
     foreach (PQSMod m in mods)
     {
         foreach (FieldInfo fi in m.GetType().GetFields())
         {
             // this _should_ get everything derived from it.
             MapSO val = fi.GetValue(m) as MapSO;
             if(val != null)
                 if(!list.Contains(val))
                     list.Add(val);
         }
     }
 }
示例#17
0
        /// <summary>
        /// A coroutine that updates the scaled space in the background
        /// </summary>
        private IEnumerator UpdateScaledSpace()
        {
            // Path to the cache
            String CacheDirectory = "saves/" + HighLogic.SaveFolder + "/diversity/";

            for (Int32 a = 0; a < scaledSpaceUpdate.Count; a++)
            {
                // Get the body
                CelestialBody body = scaledSpaceUpdate[a];
                current = body.bodyDisplayName;
                index   = a + 1;

                // Mesh
                Directory.CreateDirectory(CacheDirectory + "mesh");
                Utility.UpdateScaledMesh(body.scaledBody, body.pqsController, body, CacheDirectory + "mesh/");

                // Textures
                Directory.CreateDirectory(CacheDirectory + "textures/" + body.bodyName);
                String TextureDirectory = CacheDirectory + "textures/" + body.bodyName + "/";
                if (File.Exists(TextureDirectory + "color.png") && File.Exists(TextureDirectory + "normal.png"))
                {
                    Texture2D colorMap = Utility.LoadTexture(TextureDirectory + "color.png", false, true, true);
                    yield return(null);

                    Texture2D normalMap = Utility.LoadTexture(TextureDirectory + "normal.png", false, true, true);
                    yield return(null);

                    // Apply them to the ScaledVersion
                    body.scaledBody.GetComponent <MeshRenderer>().material.SetTexture("_MainTex", colorMap);
                    body.scaledBody.GetComponent <MeshRenderer>().material.SetTexture("_BumpMap", normalMap);
                    yield return(null);
                }
                else
                {
                    // Get PQS
                    PQS pqs = body.pqsController;
                    pqs.SetupExternalRender();

                    // Get the mods
                    Action <PQS.VertexBuildData> modOnVertexBuildHeight = (Action <PQS.VertexBuildData>)Delegate.CreateDelegate(
                        typeof(Action <PQS.VertexBuildData>),
                        pqs,
                        typeof(PQS).GetMethod("Mod_OnVertexBuildHeight", BindingFlags.Instance | BindingFlags.NonPublic));
                    Action <PQS.VertexBuildData> modOnVertexBuild = (Action <PQS.VertexBuildData>)Delegate.CreateDelegate(
                        typeof(Action <PQS.VertexBuildData>),
                        pqs,
                        typeof(PQS).GetMethod("Mod_OnVertexBuild", BindingFlags.Instance | BindingFlags.NonPublic));
                    PQSMod[] mods = pqs.GetComponentsInChildren <PQSMod>().Where(m => m.sphere == pqs && m.modEnabled).ToArray();

                    // Create the Textures
                    Texture2D colorMap  = new Texture2D(pqs.mapFilesize, pqs.mapFilesize / 2, TextureFormat.ARGB32, true);
                    Texture2D heightMap = new Texture2D(pqs.mapFilesize, pqs.mapFilesize / 2, TextureFormat.RGB24, true);

                    // Arrays
                    Color[] colorMapValues  = new Color[pqs.mapFilesize * (pqs.mapFilesize / 2)];
                    Color[] heightMapValues = new Color[pqs.mapFilesize * (pqs.mapFilesize / 2)];

                    // Wait a some time
                    yield return(null);

                    // Loop through the pixels
                    for (Int32 y = 0; y < (pqs.mapFilesize / 2); y++)
                    {
                        for (Int32 x = 0; x < pqs.mapFilesize; x++)
                        {
                            // Update Message
                            percent = ((Double)((y * pqs.mapFilesize) + x) / ((pqs.mapFilesize / 2) * pqs.mapFilesize)) * 100;

                            // Create a VertexBuildData
                            PQS.VertexBuildData data = new PQS.VertexBuildData
                            {
                                directionFromCenter = (QuaternionD.AngleAxis((360d / pqs.mapFilesize) * x, Vector3d.up) * QuaternionD.AngleAxis(90d - (180d / (pqs.mapFilesize / 2)) * y, Vector3d.right)) * Vector3d.forward,
                                vertHeight          = pqs.radius
                            };

                            // Build from the Mods
                            modOnVertexBuildHeight(data);
                            modOnVertexBuild(data);

                            // Adjust the height
                            Double height = (data.vertHeight - pqs.radius) * (1d / pqs.mapMaxHeight);
                            if (height < 0)
                            {
                                height = 0;
                            }
                            else if (height > 1)
                            {
                                height = 1;
                            }

                            // Adjust the Color
                            Color color = data.vertColor;
                            if (!pqs.mapOcean)
                            {
                                color.a = 1f;
                            }
                            else if (height > pqs.mapOceanHeight)
                            {
                                color.a = 0f;
                            }
                            else
                            {
                                color = pqs.mapOceanColor.A(1f);
                            }

                            // Set the Pixels
                            colorMapValues[(y * pqs.mapFilesize) + x]  = color;
                            heightMapValues[(y * pqs.mapFilesize) + x] = new Color((Single)height, (Single)height, (Single)height);
                        }
                        yield return(null);
                    }

                    // Apply the maps
                    colorMap.SetPixels(colorMapValues);
                    colorMap.Apply();
                    heightMap.SetPixels(heightMapValues);
                    yield return(null);

                    // Close the Renderer
                    pqs.CloseExternalRender();

                    // Bump to Normal Map
                    Texture2D normalMap = Utility.BumpToNormalMap(heightMap, 7);

                    // Serialize them to disk
                    File.WriteAllBytes(TextureDirectory + "color.png", colorMap.EncodeToPNG());
                    File.WriteAllBytes(TextureDirectory + "normal.png", normalMap.EncodeToPNG());
                    yield return(null);

                    // Apply them to the ScaledVersion
                    body.scaledBody.GetComponent <MeshRenderer>().material.SetTexture("_MainTex", colorMap);
                    body.scaledBody.GetComponent <MeshRenderer>().material.SetTexture("_BumpMap", normalMap);
                    yield return(null);
                }

                // OnDemand
                if (Templates.IsKopernicusInstalled)
                {
                    Type      onDemandType = Templates.Types.FirstOrDefault(t => t.Name == "ScaledSpaceOnDemand");
                    Component onDemand     = body.scaledBody.GetComponent(onDemandType);
                    if (onDemand != null)
                    {
                        FieldInfo texture           = onDemandType.GetField("texture");
                        FieldInfo normals           = onDemandType.GetField("normals");
                        String    RelativeDirectory = TextureDirectory.Replace(KSPUtil.ApplicationRootPath, "../");
                        texture.SetValue(onDemand, RelativeDirectory + "color.png");
                        normals.SetValue(onDemand, RelativeDirectory + "normal.png");
                    }
                }
                percent = 0;
                yield return(null);
            }
            guiEnabled = false;
            scaledSpaceUpdate.Clear();

            FlightDriver.SetPause(false, false);
            InputLockManager.RemoveControlLock("planetaryDiversityCache");
        }
示例#18
0
            // Generate the scaled space mesh using PQS (all results use scale of 1)
            public static Mesh ComputeScaledSpaceMesh(PSystemBody body)
            {
                // We need to get the body for Jool (to steal it's mesh)
                PSystemBody  Jool                 = Utility.FindBody(PSystemManager.Instance.systemPrefab.rootBody, "Jool");
                const double rScaledJool          = 1000.0f;
                double       rMetersToScaledUnits = (float)(rScaledJool / body.celestialBody.Radius);

                // Generate a duplicate of the Jool mesh
                Mesh mesh = Utility.DuplicateMesh(Jool.scaledVersion.GetComponent <MeshFilter> ().sharedMesh);

                // If this body has a PQS, we can create a more detailed object
                if (body.pqsVersion != null)
                {
                    // In order to generate the scaled space we have to enable the mods.  Since this is
                    // a prefab they don't get disabled as kill game performance.  To resolve this we
                    // clone the PQS, use it, and then delete it when done
                    GameObject pqsVersionGameObject = UnityEngine.Object.Instantiate(body.pqsVersion.gameObject) as GameObject;
                    PQS        pqsVersion           = pqsVersionGameObject.GetComponent <PQS>();

                    // Find and enable the PQS mods that modify height
                    IEnumerable <PQSMod> mods = pqsVersion.GetComponentsInChildren <PQSMod>(true).Where(mod => (mod.GetType().ToString().Contains("VertexHeight") ||
                                                                                                                mod.GetType().ToString().Contains("VertexSimplexHeight")));
                    foreach (PQSMod mod in mods)
                    {
                        mod.OnSetup();
                    }

                    // If we were able to find PQS mods
                    if (mods.Count() > 0)
                    {
                        // Generate the PQS modifications
                        Vector3[] vertices = mesh.vertices;
                        for (int i = 0; i < mesh.vertexCount; i++)
                        {
                            // Get the UV coordinate of this vertex
                            Vector2 uv = mesh.uv[i];

                            // Since this is a geosphere, normalizing the vertex gives the direction from center center
                            Vector3 direction = vertices[i];
                            direction.Normalize();

                            // Build the vertex data object for the PQS mods
                            PQS.VertexBuildData vertex = new PQS.VertexBuildData();
                            vertex.directionFromCenter = direction;
                            vertex.vertHeight          = body.celestialBody.Radius;
                            vertex.u = uv.x;
                            vertex.v = uv.y;

                            // Build from the PQS
                            foreach (PQSMod mod in mods)
                            {
                                mod.OnVertexBuildHeight(vertex);
                            }

                            // Adjust the displacement
                            vertices [i] = direction * (float)(vertex.vertHeight * rMetersToScaledUnits);
                        }
                        mesh.vertices = vertices;
                        mesh.RecalculateNormals();
                        mesh.RecalculateBounds();
                    }

                    // Otherwise log an error
                    else
                    {
                        Debug.LogError("PQS BODY HAS NO PQS MODS");
                        Debug.LogError("-------- PQS ----------");
                        Utility.GameObjectWalk(body.pqsVersion.gameObject);
                        Debug.LogError("-----------------------");
                    }

                    // Cleanup
                    UnityEngine.Object.Destroy(pqsVersionGameObject);
                }

                // Return the generated scaled space mesh
                return(mesh);
            }
示例#19
0
            // Constructor for pre-existing PQS
            public PQSLoader(PQS pqsVersion)
            {
                this.pqsVersion = pqsVersion;

                // Get the required PQS information
                transform = pqsVersion.GetComponentsInChildren<PQSMod_CelestialBodyTransform> (true).FirstOrDefault (mod => mod.transform.parent == pqsVersion.transform);
                lightDirection = pqsVersion.GetComponentsInChildren<PQSMod_MaterialSetDirection> (true).FirstOrDefault (mod => mod.transform.parent == pqsVersion.transform);
                uvs = pqsVersion.GetComponentsInChildren<PQSMod_UVPlanetRelativePosition> (true).FirstOrDefault (mod => mod.transform.parent == pqsVersion.transform);
                collider = pqsVersion.GetComponentsInChildren<PQSMod_QuadMeshColliders> (true).FirstOrDefault (mod => mod.transform.parent == pqsVersion.transform);

                // Create physics material editor
                physicsMaterial = new PhysicsMaterialParser (collider.physicsMaterial);

                // Clone the surface material of the PQS
                if (PQSMainOptimised.UsesSameShader(pqsVersion.surfaceMaterial))
                {
                    pqsVersion.surfaceMaterial = new PQSMainOptimisedLoader(pqsVersion.surfaceMaterial);
                    if (((PQSMainOptimisedLoader)pqsVersion.surfaceMaterial).globalDensity < 2)
                        ((PQSMainOptimisedLoader)pqsVersion.surfaceMaterial).globalDensity = -8E-06f;
                }
                else if (PQSMainShader.UsesSameShader(pqsVersion.surfaceMaterial))
                {
                    pqsVersion.surfaceMaterial = new PQSMainShaderLoader(pqsVersion.surfaceMaterial);
                    if (((PQSMainShaderLoader)pqsVersion.surfaceMaterial).globalDensity < 2)
                        ((PQSMainShaderLoader)pqsVersion.surfaceMaterial).globalDensity = -8E-06f;
                }
                else if (PQSProjectionAerialQuadRelative.UsesSameShader(pqsVersion.surfaceMaterial))
                {
                    pqsVersion.surfaceMaterial = new PQSProjectionAerialQuadRelativeLoader(pqsVersion.surfaceMaterial);
                    if (((PQSProjectionAerialQuadRelativeLoader)pqsVersion.surfaceMaterial).globalDensity < 2)
                        ((PQSProjectionAerialQuadRelativeLoader)pqsVersion.surfaceMaterial).globalDensity = -8E-06f;
                }
                else if (PQSProjectionSurfaceQuad.UsesSameShader(pqsVersion.surfaceMaterial))
                {
                    pqsVersion.surfaceMaterial = new PQSProjectionSurfaceQuadLoader(pqsVersion.surfaceMaterial);
                }
                surfaceMaterial = pqsVersion.surfaceMaterial;
                surfaceMaterial.name = Guid.NewGuid ().ToString ();

                // Clone the fallback material of the PQS
                fallbackMaterial = new PQSProjectionFallbackLoader (pqsVersion.fallbackMaterial);
                pqsVersion.fallbackMaterial = fallbackMaterial;
                fallbackMaterial.name = Guid.NewGuid ().ToString ();
            }
示例#20
0
		//Initialization
		public void Start ()
		{
			m_radius = m_manager.GetRadius ();
			Rt = (Rt / Rg) * m_radius;
			RL = (RL / Rg) * m_radius;
			Rg = m_radius;
			
			m_mesh = MeshFactory.MakePlane (2, 2, MeshFactory.PLANE.XY, false, false);
			m_mesh.bounds = new Bounds (parentCelestialBody.transform.position, new Vector3 (1e8f, 1e8f, 1e8f));
			
			//Inscatter is responsible for the change in the sky color as the sun moves
			//The raw file is a 4D array of 32 bit floats with a range of 0 to 1.589844
			//As there is not such thing as a 4D texture the data is packed into a 3D texture
			//and the shader manually performs the sample for the 4th dimension
			m_inscatter = new RenderTexture (RES_MU_S * RES_NU, RES_MU * RES_R, 0, RenderTextureFormat.ARGBHalf);

			m_inscatter.wrapMode = TextureWrapMode.Clamp;
			m_inscatter.filterMode = FilterMode.Bilinear;
			
			
			//Transmittance is responsible for the change in the sun color as it moves
			//The raw file is a 2D array of 32 bit floats with a range of 0 to 1
			m_transmit = new RenderTexture (TRANSMITTANCE_W, TRANSMITTANCE_H, 0, RenderTextureFormat.ARGBHalf);
			m_transmit.wrapMode = TextureWrapMode.Clamp;
			m_transmit.filterMode = FilterMode.Bilinear;
			
			//Irradiance is responsible for the change in the sky color as the sun moves
			//The raw file is a 2D array of 32 bit floats with a range of 0 to 1
			m_irradiance = new RenderTexture (SKY_W, SKY_H, 0, RenderTextureFormat.ARGBHalf);
			m_irradiance.wrapMode = TextureWrapMode.Clamp;
			m_irradiance.filterMode = FilterMode.Bilinear;
			
			
			initiateOrRestart ();
			m_skyMaterialScaled = new Material (ShaderTool.GetMatFromShader2 ("CompiledSkyScaled.shader"));
			//m_skyMaterialScaled.renderQueue = 2004;
			
			
			
			m_skyExtinction = new Material (ShaderTool.GetMatFromShader2 ("CompiledSkyExtinction.shader"));
			//m_skyExtinction.renderQueue = 2002;
			
			sunGlare = new Texture2D (512, 512);
			black = new Texture2D (512, 512);
			
			sunGlare.LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", assetDir + m_filePath, "sunglare.png")));
			black.LoadImage (System.IO.File.ReadAllBytes (String.Format ("{0}/{1}", assetDir + m_filePath, "black.png")));
			
			sunGlare.wrapMode = TextureWrapMode.Clamp;
			m_skyMaterialScaled.SetTexture ("_Sun_Glare", sunGlare);
			
			InitUniforms (m_skyMaterialScaled);
			InitUniforms (m_skyExtinction);
			
			if (m_manager.GetCore ().render24bitDepthBuffer && !m_manager.GetCore ().d3d9) {
				m_atmosphereMaterial = ShaderTool.GetMatFromShader2 ("CompiledAtmosphericScatter24bitdepth.shader");
			} else {
				m_atmosphereMaterial = ShaderTool.GetMatFromShader2 ("CompiledAtmosphericScatter.shader");
			}
			
			CurrentPQS = parentCelestialBody.pqsController;

			currentPQSMod_CelestialBodyTransform = CurrentPQS.GetComponentsInChildren<PQSMod_CelestialBodyTransform> ()[0];
			

			if (!currentPQSMod_CelestialBodyTransform)
			{
				Debug.Log ("[Scatterer] PQSMod_CelestialBodyTransform not found for " + parentCelestialBody.name);
			}


			//testPQS = parentCelestialBody.pqsController;
			
			
			//			for (int j = 0; j < 10; j++) {
			//				debugSettings[j] = true;
			//			}
			
			for (int j = 0; j < 10; j++) {
				additionalScales [j] = 1f;
			}
			
			skyObject = new GameObject ();
			skyMF = skyObject.AddComponent < MeshFilter > ();
			Mesh idmesh = skyMF.mesh;
			idmesh.Clear ();
			idmesh = m_mesh;
			//
			skyObject.layer = layer;
			//			celestialTransform = ScaledSpace.Instance.scaledSpaceTransforms.Single(t => t.name == parentCelestialBody.name);
			celestialTransform = ParentPlanetTransform;
			//			skyObject.transform.parent = parentCelestialBody.transform;
			skyObject.transform.parent = celestialTransform;
			
			skyMR = skyObject.AddComponent < MeshRenderer > ();
			skyMR.sharedMaterial = m_skyMaterialScaled;
			skyMR.material = m_skyMaterialScaled;
			skyMR.castShadows = false;
			skyMR.receiveShadows = false;
			
			///same for skyextinct
			skyExtinctObject = new GameObject ();
			skyExtinctMF = skyExtinctObject.AddComponent < MeshFilter > ();
			idmesh = skyExtinctMF.mesh;
			idmesh.Clear ();
			idmesh = m_mesh;
			//
			skyExtinctObject.layer = layer;
			skyExtinctObject.transform.parent = celestialTransform;
			
			skyExtinctMR = skyExtinctObject.AddComponent < MeshRenderer > ();
			skyExtinctMR.sharedMaterial = m_skyExtinction;
			skyExtinctMR.material = m_skyExtinction;
			skyExtinctMR.castShadows = false;
			skyExtinctMR.receiveShadows = false;
			
			hp = new SimplePostProcessCube (10000, m_atmosphereMaterial);
			atmosphereMesh = hp.GameObject;
			atmosphereMesh.layer = 15;
			atmosphereMeshrenderer = hp.GameObject.GetComponent < MeshRenderer > ();
			atmosphereMeshrenderer.material = m_atmosphereMaterial;
			
			//celestialBodies = (CelestialBody[]) CelestialBody.FindObjectsOfType(typeof(CelestialBody));
			
		}