/// <summary> /// Update the mesh of the balls and set the visibility /// </summary> internal static void ReloadCharacterBalls(ChaControl chaControl, BallsData ballsData, bool showBalls) { #if KK if (chaControl.hiPoly == false) { return; } #endif if (ballsData != null) { GameObject balls = CommonLib.LoadAsset <GameObject>(ballsData.File, ballsData.Asset, true); foreach (var mesh in balls.gameObject.GetComponentsInChildren <SkinnedMeshRenderer>(true)) { if (BallsParts.Contains(mesh.name)) { UpdateMeshRenderer(chaControl, mesh, chaControl.objBody.GetComponentsInChildren <SkinnedMeshRenderer>(true).FirstOrDefault(x => x.name == mesh.name), true); } } Destroy(balls); } SkinnedMeshRenderer ballsSMR = chaControl?.objBody?.GetComponentsInChildren <SkinnedMeshRenderer>(true).FirstOrDefault(x => x?.name == "o_dan_f"); if (ballsSMR != null) { ballsSMR.gameObject.GetComponent <Renderer>().enabled = showBalls; } }
/// <summary> /// Update the mesh of the balls and set the visibility /// </summary> private void ReloadCharacterBalls() { #if KK if (ChaControl.hiPoly == false) { return; } #endif if (BallsData != null) { GameObject balls = CommonLib.LoadAsset <GameObject>(BallsData.File, BallsData.Asset, true); foreach (var mesh in balls.gameObject.GetComponentsInChildren <SkinnedMeshRenderer>(true)) { if (BallsParts.Contains(mesh.name)) { UpdateMeshRenderer(mesh, ChaControl.objBody.GetComponentsInChildren <SkinnedMeshRenderer>(true).FirstOrDefault(x => x.name == mesh.name), true); } } Destroy(balls); } SkinnedMeshRenderer ballsSMR = ChaControl?.objBody?.GetComponentsInChildren <SkinnedMeshRenderer>(true).FirstOrDefault(x => BallsParts.Any(y => y == x.name)); if (ballsSMR != null) { ballsSMR.gameObject.GetComponent <Renderer>().enabled = DisplayBalls; } }
/// <summary> /// Disable dick and balls for the monochrome body since the main body already has the parts /// </summary> private void UpdateMonochromeBody() { #if AI || HS2 foreach (var renderer in ChaControl.objSimpleBody.GetComponentsInChildren <SkinnedMeshRenderer>()) { if (PenisParts.Contains(renderer.name) || BallsParts.Contains(renderer.name)) { renderer.enabled = false; } } #endif }
/// <summary> /// Copy the mesh from one SkinnedMeshRenderer to another. If there is a significant mismatch in the number of bones /// this will fail horribly and create abominations. Verify the uncensor body has the proper number of bones in such a case. /// </summary> private void UpdateMeshRenderer(SkinnedMeshRenderer src, SkinnedMeshRenderer dst, bool copyMaterials = false) { if (src == null || dst == null) { return; } // Check if UVs got corrupted when we loaded the asset, uncommon var uvCopy = src.sharedMesh.uv.ToArray(); if (AreUVsCorrupted(uvCopy) && !DidErrorMessage) { Logger.LogError($"UVs got corrupted when creating uncensor mesh {src.sharedMesh.name}, body textures might be corrupted. Consider updating your GPU drivers."); DidErrorMessage = true; } //Copy the mesh dst.sharedMesh = src.sharedMesh; //Sort the bones List <Transform> newBones = new List <Transform>(); foreach (Transform t in src.bones) { newBones.Add(Array.Find(dst.bones, c => c?.name == t?.name)); } dst.bones = newBones.ToArray(); if (copyMaterials) { dst.materials = src.materials; } if (!PenisParts.Contains(src.sharedMesh.name) && !BallsParts.Contains(src.sharedMesh.name) && DoHandleUVCorrupions) { DoHandleUVCorrupions = false; ChaControl.StartCoroutine(HandleUVCorrupionsCo(dst, uvCopy)); } //Regardless of the receive shadow settings configured for the mesh it's always set to false for dick and balls, change it so shadows work correctly if (PenisParts.Contains(dst.sharedMesh.name) || BallsParts.Contains(dst.sharedMesh.name)) { dst.receiveShadows = true; } }
/// <summary> /// Update the mesh of the balls and set the visibility /// </summary> private void ReloadCharacterBalls() { if (BallsData != null) { GameObject balls = CommonLib.LoadAsset <GameObject>(BallsData.File, BallsData.Asset, true); var renderers = balls.gameObject.GetComponentsInChildren <SkinnedMeshRenderer>(true); for (var i = 0; i < renderers.Length; i++) { var renderer = renderers[i]; if (BallsParts.Contains(renderer.name)) { var renderers2 = ChaControl.objBody.GetComponentsInChildren <SkinnedMeshRenderer>(true); for (var j = 0; j < renderers2.Length; j++) { var renderer2 = renderers2[j]; if (renderer2.name == renderer.name) { UpdateMeshRenderer(renderer, renderer2, true); break; } } } } Destroy(balls); } if (ChaControl != null && ChaControl.objBody != null) { var ballsSMR = ChaControl.objBody.GetComponentsInChildren <SkinnedMeshRenderer>(true).FirstOrDefault(x => BallsParts.Any(y => y == x.name)); if (ballsSMR != null) { ballsSMR.gameObject.GetComponent <Renderer>().enabled = DisplayBalls; } } }