Exemplo n.º 1
0
        // Update the menu body
        private void Start()
        {
            if (!Templates.KopernicusMainMenu)
            {
                return;
            }

            // Select a random body?
            if (Templates.RandomMainMenuBodies.Any())
            {
                Templates.MenuBody =
                    Templates.RandomMainMenuBodies[new Random().Next(0, Templates.RandomMainMenuBodies.Count)];
            }

            // Grab the main body
            CelestialBody planetCb = UBI.GetBody(Templates.MenuBody);

            if (planetCb == null)
            {
                planetCb = PSystemManager.Instance.localBodies.Find(b => b.isHomeWorld);
            }
            if (planetCb == null)
            {
                Debug.LogError("[Kopernicus] Could not find home world!");
                return;
            }

            // Load Textures
            OnDemandStorage.EnableBody(Templates.MenuBody);

            // Get the MainMenu-Logic
            MainMenu main = FindObjectOfType <MainMenu>();

            if (main == null)
            {
                Debug.LogError("[Kopernicus] No main menu object!");
                return;
            }
            MainMenuEnvLogic logic = main.envLogic;

            // Set it to Space, because the Mun-Area won't work with sth else than Mun
            if (logic.areas.Length < 2)
            {
                Debug.LogError("[Kopernicus] Not enough bodies");
                return;
            }

            // Get our active Space
            GameObject space = logic.areas[1];

            // Deactivate Kerbins Transform
            Transform kerbin = space.transform.Find("Kerbin");

            if (kerbin == null)
            {
                Debug.LogError("[Kopernicus] No Kerbin transform!");
                return;
            }
            kerbin.gameObject.SetActive(false);

            // Deactivate Muns Transform
            Transform munPivot = space.transform.Find("MunPivot");

            if (munPivot == null)
            {
                Debug.LogError("[Kopernicus] No MunPivot transform!");
                return;
            }
            munPivot.gameObject.SetActive(false);

            // Activate the textures
            ScaledSpaceOnDemand od = planetCb.scaledBody.GetComponentInChildren <ScaledSpaceOnDemand>();

            if (od != null)
            {
                od.Start();
                od.LoadTextures();
            }

            // Clone the scaledVersion and attach it to the Scene
            GameObject menuPlanet = Utility.Instantiate(Utility
                                                        .FindBody(PSystemManager.Instance.systemPrefab.rootBody, planetCb.transform.name).scaledVersion, space.transform, true);

            menuPlanet.name = planetCb.transform.name;

            // Destroy stuff
            DestroyImmediate(menuPlanet.GetComponent <ScaledSpaceFader>());
            DestroyImmediate(menuPlanet.GetComponent <SphereCollider>());
            DestroyImmediate(menuPlanet.GetComponentInChildren <AtmosphereFromGround>());
            DestroyImmediate(menuPlanet.GetComponent <MaterialSetDirection>());

            // That sounds funny
            Rotato planetRotato    = menuPlanet.AddComponent <Rotato>();
            Rotato planetRefRotato = kerbin.GetComponent <Rotato>();

            planetRotato.speed = planetRefRotato.speed * ((Single)planetCb.rotationPeriod / KERBIN_ROTATION_PERIOD);
            menuPlanet.transform.Rotate(0f, (Single)planetCb.initialRotation, 0f);

            // Scale the body
            menuPlanet.transform.localScale    = kerbin.localScale;
            menuPlanet.transform.localPosition = kerbin.localPosition;
            menuPlanet.transform.position      = kerbin.position;

            // And set it to layer 0
            menuPlanet.layer = 0;

            Events.OnRuntimeUtilityUpdateMenu.Fire();
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
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);
        }