Beispiel #1
0
        private void ShowKerbalSuitTextures(Suit suit)
        {
            var mapper = Mapper.Instance;

            Texture2D ivaSuitTex;
            Texture2D evaSuitTex;

            if (selectedKerbal != null)
            {
                Suit defaultSuit = mapper.GetDefault(selectedKerbal.suit);
                ivaSuitTex = suit.GetSuit(false, selectedKerbal) ?? defaultSuit.GetSuit(false, selectedKerbal);
                evaSuitTex = suit.GetSuit(true, selectedKerbal) ?? defaultSuit.GetSuit(true, selectedKerbal);
            }
            else
            {
                Suit defaultSuit = mapper.GetDefault(suit.Kind);
                ivaSuitTex = suit.IvaSuit[0] ?? defaultSuit.IvaSuit[0];
                evaSuitTex = suit.EvaSuit[0] ?? defaultSuit.EvaSuit[0];
            }

            GUILayout.BeginHorizontal();
            GUILayout.Box(ivaSuitTex, GUILayout.Width(100), GUILayout.Height(100));
            GUILayout.Space(10);
            GUILayout.Box(evaSuitTex, GUILayout.Width(100), GUILayout.Height(100));
            GUILayout.EndHorizontal();

            GUILayout.Label(suit.Name);
            GUILayout.Space(10);
        }
Beispiel #2
0
        /// <summary>
        /// Replace textures on a Kerbal model.
        /// </summary>
        void PersonaliseKerbal(Component component, ProtoCrewMember kerbal, bool isEva, bool useEvaSuit)
        {
            Appearance appearance = GetAppearance(kerbal);
            bool       isVintage  = kerbal.suit == KerbalSuit.Vintage;

            Skin skin        = GetKerbalSkin(kerbal, appearance);
            Suit suit        = GetKerbalSuit(kerbal, appearance);
            Suit defaultSuit = isVintage ? VintageSuit : DefaultSuit;

            Transform model = isEva || !isVintage?component.transform.Find("model01")
                                  : component.transform.Find("kbIVA@idle/model01");

            Transform flag      = isEva ? component.transform.Find("model/kbEVA_flagDecals") : null;
            Transform parachute = isEva ? component.transform.Find("model/EVAparachute/base") : null;

            // We determine body and helmet texture here to avoid code duplication between suit and helmet cases in the
            // following switch.
            // Setting the suit explicitly -- even when default -- is necessary for two reasons: to fix IVA suits after KSP
            // resetting them to the stock ones all the time and to fix the switch to default texture on start of EVA walk or
            // EVA suit toggle.
            Texture2D suitTexture   = suit.GetSuit(useEvaSuit, kerbal) ?? defaultSuit.GetSuit(useEvaSuit, kerbal);
            Texture2D suitNormalMap = suit.GetSuitNRM(useEvaSuit) ?? defaultSuit.GetSuitNRM(useEvaSuit);

            if (isEva)
            {
                flag.GetComponent <Renderer>().enabled      = useEvaSuit;
                parachute.GetComponent <Renderer>().enabled = useEvaSuit && !HideParachuteBackpack;
            }

            // We must include hidden meshes, since flares are hidden when light is turned off.
            // All other meshes are always visible, so no performance hit here.
            foreach (Renderer renderer in model.GetComponentsInChildren <Renderer>(true))
            {
                var smr = renderer as SkinnedMeshRenderer;

                // Headlight flares and thruster jets.
                if (smr == null)
                {
                    renderer.enabled = useEvaSuit;
                    continue;
                }

                Texture2D newTexture   = null;
                Texture2D newNormalMap = null;

                switch (smr.name)
                {
                case "eyeballLeft":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballLeft":
                    if (skin.IsEyeless)
                    {
                        smr.sharedMesh = null;
                    }
                    else
                    {
                        newTexture = skin.EyeballLeft;
                        // Vintage IVA is missing a proto-model so it has to be replaced always.
                        if (!isEva && isVintage)
                        {
                            smr.material.shader = Replacer.EyeShader;
                            newTexture          = newTexture ?? DefaultSkin[(int)kerbal.gender].EyeballLeft;
                        }
                    }
                    break;

                case "eyeballRight":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballRight":
                    if (skin.IsEyeless)
                    {
                        smr.sharedMesh = null;
                    }
                    else
                    {
                        newTexture = skin.EyeballRight;
                        // Vintage IVA is missing a proto-model so it has to be replaced always.
                        if (!isEva && isVintage)
                        {
                            smr.material.shader = Replacer.EyeShader;
                            newTexture          = newTexture ?? DefaultSkin[(int)kerbal.gender].EyeballRight;
                        }
                    }
                    break;

                case "pupilLeft":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilLeft":
                    if (skin.IsEyeless)
                    {
                        smr.sharedMesh = null;
                    }
                    else
                    {
                        newTexture = skin.PupilLeft;
                        // Vintage IVA is missing a proto-model so it has to be replaced always.
                        if (!isEva && isVintage)
                        {
                            smr.material.shader = Replacer.EyeShader;
                            newTexture          = newTexture ?? DefaultSkin[(int)kerbal.gender].PupilLeft;
                        }
                        if (newTexture != null)
                        {
                            smr.material.color = Color.white;
                        }
                    }
                    break;

                case "pupilRight":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilRight":
                    if (skin.IsEyeless)
                    {
                        smr.sharedMesh = null;
                    }
                    else
                    {
                        newTexture = skin.PupilRight;
                        // Vintage IVA is missing a proto-model so it has to be replaced always.
                        if (!isEva && isVintage)
                        {
                            smr.material.shader = Replacer.EyeShader;
                            newTexture          = newTexture ?? DefaultSkin[(int)kerbal.gender].PupilRight;
                        }
                        if (newTexture != null)
                        {
                            smr.material.color = Color.white;
                        }
                    }
                    break;

                case "headMesh01":
                case "headMesh02":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pCube1":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_polySurface51":
                    if (!skin.IsDefault)
                    {
                        newTexture = skin.Head;
                    }
                    break;

                case "tongue":
                case "upTeeth01":
                case "upTeeth02":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_upTeeth01":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_downTeeth01":
                    break;

                case "body01":
                case "mesh_female_kerbalAstronaut01_body01":
                    newTexture   = suitTexture;
                    newNormalMap = suitNormalMap;

                    // Update textures in Kerbal IVA object since KSP resets them to these values a few frames later.
                    var kerbalIva = component as Kerbal;
                    if (kerbalIva != null)
                    {
                        kerbalIva.textureStandard = newTexture;
                        kerbalIva.textureVeteran  = newTexture;
                    }
                    break;

                case "neckRing":
                    newTexture   = suitTexture;
                    newNormalMap = suitNormalMap;
                    break;

                case "helmet":
                case "mesh_female_kerbalAstronaut01_helmet":
                    newTexture   = suitTexture;
                    newNormalMap = suitNormalMap;
                    break;

                case "visor":
                case "mesh_female_kerbalAstronaut01_visor":
                    // Visor texture has to be replaced every time.
                    newTexture = suit.GetVisor(useEvaSuit);
                    if (newTexture != null)
                    {
                        smr.material.color = Color.white;
                    }
                    break;

                default: // Jetpack.
                    if (isEva)
                    {
                        smr.enabled = useEvaSuit;

                        if (useEvaSuit)
                        {
                            newTexture   = suit.EvaJetpack;
                            newNormalMap = suit.EvaJetpackNRM;
                        }
                    }
                    break;
                }

                if (newTexture != null)
                {
                    smr.material.mainTexture = newTexture;
                }
                if (newNormalMap != null)
                {
                    smr.material.SetTexture(Util.BumpMapProperty, newNormalMap);
                }
            }
        }
        /// <summary>
        /// Replace textures on a Kerbal model.
        /// </summary>
        private void PersonaliseKerbal(Component component, ProtoCrewMember kerbal, bool isEva, bool useEvaSuit)
        {
            Transform transform = component.transform;

            // Prefabricated Vintage & Future IVA models are missing so they are instantiated anew every time. Hence, we have
            // to apply fixes to them and set fallback default textures.
            bool isPrefabMissing = !isEva && kerbal.suit != KerbalSuit.Default;

            Transform modelTransform = (isEva, kerbal.suit, kerbal.gender) switch {
                (false, KerbalSuit.Default, _) => transform.Find("model01"),
                (false, KerbalSuit.Vintage, _) => transform.Find("kbIVA@idle/model01"),
                (false, KerbalSuit.Future, Gender.Male) => transform.Find("serenityMaleIVA/model01"),
                (false, KerbalSuit.Future, Gender.Female) => transform.Find("serenityFemaleIVA/model01"),
                _ => transform.Find("model01")
            };

            // Sometimes when we switch between suits (e.g. with clothes hanger) suit kind and model get out of sync.
            // Just try all possible nodes in such cases.
            modelTransform ??= transform.Find("model01") ?? transform.Find("kbIVA@idle/model01") ??
            transform.Find("serenityMaleIVA/model01") ?? transform.Find("serenityFemaleIVA/model01");

            Appearance appearance = mapper.GetAppearance(kerbal);

            Skin skin        = mapper.GetKerbalSkin(kerbal, appearance);
            Skin defaultSkin = mapper.GetDefault(kerbal.gender);

            // We determine body and helmet texture here to avoid code duplication between suit and helmet cases in the
            // following switch.
            // Setting the suit explicitly -- even when default -- is necessary to fix the switch to the default IVA texture
            // when on EVA.
            Suit      suit          = null;
            Texture2D suitTexture   = null;
            Texture2D suitNormalMap = null;

            if (mapper.PersonaliseSuit)
            {
                Suit defaultSuit = mapper.GetDefault(kerbal.suit);

                suit          = mapper.GetKerbalSuit(kerbal, appearance);
                suitTexture   = suit.GetSuit(useEvaSuit, kerbal) ?? defaultSuit.GetSuit(useEvaSuit, kerbal);
                suitNormalMap = suit.GetSuitNRM(useEvaSuit) ?? defaultSuit.GetSuitNRM(useEvaSuit);
            }

            foreach (Renderer renderer in modelTransform.GetComponentsInChildren <Renderer>())
            {
                var smr = renderer as SkinnedMeshRenderer;

                // Headlight flares and thruster jets.
                if (smr == null)
                {
                    continue;
                }

                Material material = smr.material;

                Texture2D newTexture   = null;
                Texture2D newNormalMap = null;
                Texture2D newEmissive  = null;

                switch (smr.name)
                {
                case "eyeballLeft":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballLeft": {
                    if (skin.Eyeless)
                    {
                        smr.sharedMesh = null;
                        break;
                    }

                    newTexture = skin.EyeballLeft;

                    if (isPrefabMissing)
                    {
                        newTexture ??= defaultSkin.EyeballLeft;
                        material.shader = Replacer.EyeShader;
                    }
                    break;
                }

                case "eyeballRight":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballRight": {
                    if (skin.Eyeless)
                    {
                        smr.sharedMesh = null;
                        break;
                    }

                    newTexture = skin.EyeballRight;

                    if (isPrefabMissing)
                    {
                        newTexture ??= defaultSkin.EyeballRight;
                        material.shader = Replacer.EyeShader;
                    }
                    break;
                }

                case "pupilLeft":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilLeft": {
                    if (skin.Eyeless)
                    {
                        smr.sharedMesh = null;
                        break;
                    }

                    newTexture = skin.PupilLeft;

                    if (isPrefabMissing)
                    {
                        newTexture ??= defaultSkin.PupilLeft;
                        material.shader = Replacer.EyeShader;
                    }

                    if (newTexture != null)
                    {
                        material.color = Color.white;
                    }
                    break;
                }

                case "pupilRight":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilRight": {
                    if (skin.Eyeless)
                    {
                        smr.sharedMesh = null;
                        break;
                    }

                    newTexture = skin.PupilRight;

                    if (isPrefabMissing)
                    {
                        newTexture ??= defaultSkin.PupilRight;
                        material.shader = Replacer.EyeShader;
                    }

                    if (newTexture != null)
                    {
                        material.color = Color.white;
                    }
                    break;
                }

                case "headMesh01":
                case "headMesh02":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pCube1":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_polySurface51": {
                    newTexture   = skin.Head;
                    newNormalMap = skin.HeadNRM;

                    if (isPrefabMissing)
                    {
                        newTexture ??= defaultSkin.Head;
                        newNormalMap ??= defaultSkin.HeadNRM;
                        material.shader = newNormalMap == null ? Replacer.HeadShader : Replacer.BumpedHeadShader;
                    }
                    else if (newNormalMap != null)
                    {
                        material.shader = Replacer.BumpedHeadShader;
                    }
                    break;
                }

                case "tongue":
                case "upTeeth01":
                case "upTeeth02":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_upTeeth01":
                case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_downTeeth01": {
                    if (isPrefabMissing)
                    {
                        smr.material = Replacer.Instance.TeethMaterial;
                    }
                    break;
                }

                case "body01":
                case "mesh_female_kerbalAstronaut01_body01": {
                    if (suit == null)
                    {
                        break;
                    }

                    newTexture   = suitTexture;
                    newNormalMap = suitNormalMap;
                    if (isEva)
                    {
                        newEmissive = suit.EvaSuitEmissive;
                    }

                    // Update textures in Kerbal IVA object since KSP resets them to these values a few frames later.
                    if (component is Kerbal kerbalIva)
                    {
                        kerbalIva.textureStandard = newTexture;
                        kerbalIva.textureVeteran  = newTexture;
                    }
                    break;
                }

                case "neckRing": {
                    if (suit == null)
                    {
                        break;
                    }

                    newTexture   = suitTexture;
                    newNormalMap = suitNormalMap;
                    if (isEva)
                    {
                        newEmissive = suit.EvaSuitEmissive;
                    }
                    break;
                }

                case "helmet":
                case "mesh_female_kerbalAstronaut01_helmet": {
                    if (suit == null)
                    {
                        break;
                    }

                    newTexture   = suitTexture;
                    newNormalMap = suitNormalMap;
                    if (isEva)
                    {
                        newEmissive = suit.EvaSuitEmissive;
                    }
                    break;
                }

                case "visor":
                case "mesh_female_kerbalAstronaut01_visor": {
                    if (suit == null)
                    {
                        break;
                    }

                    // Visor texture has to be replaced every time.
                    newTexture = suit.GetVisor(useEvaSuit);
                    if (newTexture != null)
                    {
                        material.color = Color.white;
                    }
                    break;
                }

                default: { // Jetpack.
                    if (isEva)
                    {
                        smr.enabled = useEvaSuit;

                        if (suit == null)
                        {
                            break;
                        }

                        if (useEvaSuit)
                        {
                            newTexture   = suit.Jetpack;
                            newNormalMap = suit.JetpackNRM;
                            newEmissive  = suit.JetpackEmissive;
                        }
                    }
                    break;
                }
                }

                if (newTexture != null)
                {
                    material.mainTexture = newTexture;
                }
                if (newNormalMap != null)
                {
                    material.SetTexture(Util.BumpMapProperty, newNormalMap);
                }
                if (newEmissive != null)
                {
                    material.SetTexture(Util.EmissiveProperty, newEmissive);
                }
            }

            // Backpacks and parachute are positioned on another node in model hierarchy.
            if (isEva)
            {
                bool showJetpack  = useEvaSuit;
                bool showBackpack = showJetpack && !mapper.HideBackpack;

                Transform flagTransform      = transform.Find("model/kbEVA_flagDecals");
                Transform cargoPackTransform = transform.Find("model/EVABackpack/kerbalCargoContainerPack/base") ??
                                               transform.Find("model/kerbalCargoContainerPack/base");
                Transform parachutePackTransform   = transform.Find("model/EVAparachute/base");
                Transform parachuteCanopyTransform = transform.Find("model/EVAparachute/canopyrot/canopy");

                var flag            = flagTransform.GetComponent <Renderer>();
                var cargoPack       = cargoPackTransform.GetComponent <Renderer>();
                var parachutePack   = parachutePackTransform.GetComponent <Renderer>();
                var parachuteCanopy = parachuteCanopyTransform.GetComponent <Renderer>();

                flag.enabled          = showJetpack;
                cargoPack.enabled     = showBackpack;
                parachutePack.enabled = showBackpack;

                if (suit == null)
                {
                    return;
                }

                if (showBackpack)
                {
                    Material cargoPackMaterial     = cargoPack.material;
                    Material parachutePackMaterial = parachutePack.material;

                    if (suit.CargoPack != null)
                    {
                        cargoPackMaterial.mainTexture = suit.CargoPack;
                    }
                    if (suit.CargoPackNRM != null)
                    {
                        cargoPackMaterial.SetTexture(Util.BumpMapProperty, suit.CargoPackNRM);
                    }
                    if (suit.CargoPackEmissive != null)
                    {
                        cargoPackMaterial.SetTexture(Util.EmissiveProperty, suit.CargoPackEmissive);
                    }

                    if (suit.ParachutePack != null)
                    {
                        parachutePackMaterial.mainTexture = suit.ParachutePack;
                    }
                    if (suit.ParachutePackNRM != null)
                    {
                        parachutePackMaterial.SetTexture(Util.BumpMapProperty, suit.ParachutePackNRM);
                    }
                }

                Material parachuteCanopyMaterial = parachuteCanopy.material;

                if (suit.ParachuteCanopy != null)
                {
                    parachuteCanopyMaterial.mainTexture = suit.ParachuteCanopy;
                }
                if (suit.ParachuteCanopyNRM != null)
                {
                    parachuteCanopyMaterial.SetTexture(Util.BumpMapProperty, suit.ParachuteCanopyNRM);
                }
            }
        }