//utility methods private void SetHelmet(bool value) { foreach (var rend in Kerbal.GetComponentsInChildren <Renderer>()) { if (rend.name == "helmet" || rend.name == "visor" || rend.name == "flare1" || rend.name == "flare2") { rend.enabled = value; } } _hasHelmet = value; }
//utility methods private void SetHelmet(bool value) { #if false foreach (var rend in Kerbal.GetComponentsInChildren <Renderer>()) { if (rend.name == "helmet" || rend.name == "visor" || rend.name == "flare1" || rend.name == "flare2") { rend.enabled = value; } } #endif foreach (Renderer renderer in Kerbal.GetComponentsInChildren <Renderer>()) { var smr = renderer as SkinnedMeshRenderer; if (smr != null) { switch (smr.name) { case "helmet": { if (helmetMesh == null) { helmetMesh = smr.sharedMesh; } smr.sharedMesh = value ? helmetMesh : null; } break; case "visor": { if (visorMesh == null) { visorMesh = smr.sharedMesh; } smr.sharedMesh = value ? visorMesh : null; } break; case "flare1": { if (flare1Mesh == null) { visorMesh = smr.sharedMesh; } smr.sharedMesh = value ? flare1Mesh : null; } break; case "flare2": { if (flare2Mesh == null) { flare2Mesh = smr.sharedMesh; } smr.sharedMesh = value ? flare2Mesh : null; } break; } } } _hasHelmet = value; }
/** * Post-load initialisation. */ public void load() { foreach (SkinnedMeshRenderer smr in Resources.FindObjectsOfTypeAll <SkinnedMeshRenderer>()) { if (skinningQuality != SkinQuality.Auto) { smr.quality = skinningQuality; } } foreach (Texture texture in Resources.FindObjectsOfTypeAll <Texture>()) { if (texture.filterMode == FilterMode.Bilinear) { texture.filterMode = FilterMode.Trilinear; } } foreach (GameDatabase.TextureInfo texInfo in GameDatabase.Instance.databaseTexture) { Texture2D texture = texInfo.texture; if (texture == null) { continue; } foreach (string path in paths) { if (!texture.name.StartsWith(path, StringComparison.Ordinal)) { continue; } string originalName = texture.name.Substring(path.Length); // Since we are merging multiple directories, we must expect conflicts. if (!mappedTextures.ContainsKey(originalName)) { if (originalName.StartsWith("GalaxyTex_", StringComparison.Ordinal)) { texture.wrapMode = TextureWrapMode.Clamp; } mappedTextures.Add(originalName, texture); } break; } } Shader headShader = Shader.Find("Bumped Diffuse"); Shader suitShader = Shader.Find("Bumped Diffuse"); Texture2D[] headNormalMaps = { null, null }; Texture2D ivaVisorTexture = null; if (mappedTextures.TryGetValue("kerbalHeadNRM", out headNormalMaps[0])) { mappedTextures.Remove("kerbalHeadNRM"); } if (mappedTextures.TryGetValue("kerbalGirl_06_BaseColorNRM", out headNormalMaps[1])) { mappedTextures.Remove("kerbalGirl_06_BaseColorNRM"); } if (mappedTextures.TryGetValue("kerbalVisor", out ivaVisorTexture)) { mappedTextures.Remove("kerbalVisor"); } // Fix female shaders, set normal-mapped shader for head and visor texture on proto-IVA and -EVA Kerbals. Kerbal[] kerbals = Resources.FindObjectsOfTypeAll <Kerbal>(); Kerbal maleIva = kerbals.First(k => k.transform.name == "kerbalMale"); Kerbal femaleIva = kerbals.First(k => k.transform.name == "kerbalFemale"); Part maleEva = PartLoader.getPartInfoByName("kerbalEVA").partPrefab; Part femaleEva = PartLoader.getPartInfoByName("kerbalEVAfemale").partPrefab; SkinnedMeshRenderer[][] maleMeshes = { maleIva.GetComponentsInChildren <SkinnedMeshRenderer>(true), maleEva.GetComponentsInChildren <SkinnedMeshRenderer>(true) }; SkinnedMeshRenderer[][] femaleMeshes = { femaleIva.GetComponentsInChildren <SkinnedMeshRenderer>(true), femaleEva.GetComponentsInChildren <SkinnedMeshRenderer>(true) }; // Male materials to be copied to females to fix tons of female issues (missing normal maps, non-bumpmapped // shaders, missing teeth texture ...) Material headMaterial = null; Material[] suitMaterials = { null, null }; Material[] helmetMaterials = { null, null }; Material[] visorMaterials = { null, null }; Material jetpackMaterial = null; for (int i = 0; i < 2; ++i) { foreach (SkinnedMeshRenderer smr in maleMeshes[i]) { // Many meshes share material, so it suffices to enumerate only one mesh for each material. switch (smr.name) { case "headMesh01": // Replace with bump-mapped shader so normal maps for heads will work. smr.sharedMaterial.shader = headShader; if (headNormalMaps[0] != null) { smr.sharedMaterial.SetTexture(Util.BUMPMAP_PROPERTY, headNormalMaps[0]); } headMaterial = smr.sharedMaterial; break; case "body01": // Also replace shader on EVA suits to match the one on IVA suits and to enable heat effects. smr.sharedMaterial.shader = suitShader; suitMaterials[i] = smr.sharedMaterial; break; case "helmet": // Also replace shader on EVA suits to match the one on IVA suits and to enable heat effects. smr.sharedMaterial.shader = suitShader; helmetMaterials[i] = smr.sharedMaterial; break; case "jetpack_base01": // Also replace shader on EVA suits to match the one on IVA suits and to enable heat effects. smr.sharedMaterial.shader = suitShader; jetpackMaterial = smr.sharedMaterial; break; case "visor": if (smr.transform.root == maleIva.transform && ivaVisorTexture != null) { smr.sharedMaterial.mainTexture = ivaVisorTexture; smr.sharedMaterial.color = Color.white; } visorMaterials[i] = smr.sharedMaterial; break; } } } for (int i = 0; i < 2; ++i) { foreach (SkinnedMeshRenderer smr in femaleMeshes[i]) { // Here we must enumarate all meshes wherever we are replacing the material. switch (smr.name) { case "headMesh": smr.sharedMaterial.shader = headShader; if (headNormalMaps[1] != null) { smr.sharedMaterial.SetTexture(Util.BUMPMAP_PROPERTY, headNormalMaps[1]); } break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_upTeeth01": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_downTeeth01": case "upTeeth01": case "downTeeth01": // Females don't have textured teeth, they use the same material as for the eyeballs. Extending female // head material/texture to their teeth is not possible since teeth overlap with some ponytail subtexture. // However, female teeth map to the same texture coordinates as male teeth, so we fix this by applying // male head & teeth material for female teeth. smr.sharedMaterial = headMaterial; break; case "mesh_female_kerbalAstronaut01_body01": case "body01": smr.sharedMaterial = suitMaterials[i]; break; case "mesh_female_kerbalAstronaut01_helmet": case "helmet": smr.sharedMaterial = helmetMaterials[i]; break; case "jetpack_base01": smr.sharedMaterial = jetpackMaterial; break; case "mesh_female_kerbalAstronaut01_visor": case "visor": smr.sharedMaterial = visorMaterials[i]; break; } } } // Find NavBall replacement textures if available. if (mappedTextures.TryGetValue(HUD_NAVBALL, out hudNavBallTexture)) { mappedTextures.Remove(HUD_NAVBALL); if (hudNavBallTexture.mipmapCount != 1) { Util.log("HUDNavBall texture should not have mipmaps!"); } } if (mappedTextures.TryGetValue(IVA_NAVBALL, out ivaNavBallTexture)) { mappedTextures.Remove(IVA_NAVBALL); if (ivaNavBallTexture.mipmapCount != 1) { Util.log("IVANavBall texture should not have mipmaps!"); } } }
void FixKerbalModels() { mappedTextures.TryGetValue("eyeballLeft", out Texture2D eyeballLeft); mappedTextures.TryGetValue("eyeballRight", out Texture2D eyeballRight); mappedTextures.TryGetValue("pupilLeft", out Texture2D pupilLeft); mappedTextures.TryGetValue("pupilRight", out Texture2D pupilRight); mappedTextures.TryGetValue("kerbalVisor", out Texture2D ivaVisorTexture); mappedTextures.TryGetValue("EVAvisor", out Texture2D evaVisorTexture); // Shaders between male and female models are inconsistent, female models are missing normal maps and specular // lighting. So, we copy shaders from male materials to respective female materials. Kerbal[] kerbals = Resources.FindObjectsOfTypeAll <Kerbal>(); Kerbal maleIva = kerbals.First(k => k.transform.name == "kerbalMale"); Kerbal femaleIva = kerbals.First(k => k.transform.name == "kerbalFemale"); Part maleEva = PartLoader.getPartInfoByName("kerbalEVA").partPrefab; Part femaleEva = PartLoader.getPartInfoByName("kerbalEVAfemale").partPrefab; Part maleEvaVintage = PartLoader.getPartInfoByName("kerbalEVAVintage").partPrefab; Part femaleEvaVintage = PartLoader.getPartInfoByName("kerbalEVAfemaleVintage").partPrefab; if (logKerbalHierarchy) { LogHierarchies(maleIva, maleEva, maleEvaVintage, femaleIva, femaleEva, femaleEvaVintage); } SkinnedMeshRenderer[][] maleMeshes = { maleIva.GetComponentsInChildren <SkinnedMeshRenderer>(true), maleEva.GetComponentsInChildren <SkinnedMeshRenderer>(true), maleEvaVintage?.GetComponentsInChildren <SkinnedMeshRenderer>(true) }; SkinnedMeshRenderer[][] femaleMeshes = { femaleIva.GetComponentsInChildren <SkinnedMeshRenderer>(true), femaleEva.GetComponentsInChildren <SkinnedMeshRenderer>(true), femaleEvaVintage?.GetComponentsInChildren <SkinnedMeshRenderer>(true) }; // Male materials to be copied to females to fix tons of female issues (missing normal maps, non-bumpmapped // shaders, missing teeth texture ...) Material headMaterial = null; Material[] visorMaterials = { null, null, null }; for (int i = 0; i < 3; ++i) { if (maleMeshes[i] == null) { continue; } foreach (SkinnedMeshRenderer smr in maleMeshes[i]) { // Many meshes share the same material, so it suffices to enumerate only one mesh for each material. switch (smr.name) { case "eyeballLeft": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = eyeballLeft; break; case "eyeballRight": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = eyeballRight; break; case "pupilLeft": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = pupilLeft; if (pupilLeft != null) { smr.sharedMaterial.color = Color.white; } break; case "pupilRight": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = pupilRight; if (pupilRight != null) { smr.sharedMaterial.color = Color.white; } break; case "headMesh01": case "headMesh02": // Replace with bump-mapped shader so normal maps for heads will work. smr.sharedMaterial.shader = HeadShader; headMaterial = smr.sharedMaterial; break; case "visor": // It will be raplaced with reflective shader later, if reflections are enabled. switch (i) { case 0: // maleIva if (ivaVisorTexture != null) { smr.sharedMaterial.shader = TexturedVisorShader; smr.sharedMaterial.mainTexture = ivaVisorTexture; smr.sharedMaterial.color = Color.white; } break; case 1: // maleEva if (evaVisorTexture != null) { smr.sharedMaterial.shader = TexturedVisorShader; smr.sharedMaterial.mainTexture = evaVisorTexture; smr.sharedMaterial.color = Color.white; } break; case 2: // maleEvaVintage smr.sharedMaterial = visorMaterials[1]; break; } visorMaterials[i] = smr.sharedMaterial; break; } } } for (int i = 0; i < 3; ++i) { if (femaleMeshes[i] == null) { continue; } foreach (SkinnedMeshRenderer smr in femaleMeshes[i]) { // Here we must enumerate all meshes wherever we are replacing the material. switch (smr.name) { case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballLeft": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = eyeballLeft; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_eyeballRight": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = eyeballRight; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilLeft": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = pupilLeft; if (pupilLeft != null) { smr.sharedMaterial.color = Color.white; } break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pupilRight": smr.sharedMaterial.shader = EyeShader; smr.sharedMaterial.mainTexture = pupilRight; if (pupilRight != null) { smr.sharedMaterial.color = Color.white; } break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_pCube1": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_polySurface51": // Replace with bump-mapped shader so normal maps for heads will work. smr.sharedMaterial.shader = HeadShader; break; case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_upTeeth01": case "mesh_female_kerbalAstronaut01_kerbalGirl_mesh_downTeeth01": // Females don't have textured teeth, they use the same material as for the eyeballs. Extending female // head material/texture to their teeth is not possible since teeth overlap with some ponytail subtexture. // However, female teeth map to the same texture coordinates as male teeth, so we fix this by applying // male head & teeth material for female teeth. smr.sharedMaterial = headMaterial; break; case "visor": case "mesh_female_kerbalAstronaut01_visor": smr.sharedMaterial = visorMaterials[i]; break; } } } }