// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts, // for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies. // EdenAutoMorpherScript, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null // Eden.AutoMorpher.ClothHumanoidMaskUtil using System.Collections.Generic; using Eden.AutoMorpher; using UnityEngine; public class ClothHumanoidMaskUtil { public void BuildExcludedVertexMaskForHandsAndHead(ClothInstance clothInstance, bool excludeHandRoot = false, bool excludeThumbRoot = false) { if (clothInstance == null || clothInstance.smr == null) { Debug.LogWarning("[ClothHumanoidMaskUtil] clothInstance / smr 가 null"); return; } SkinnedMeshRenderer smr = clothInstance.smr; Mesh mesh = clothInstance.editableMesh ?? smr.sharedMesh; if (mesh == null) { Debug.LogWarning("[ClothHumanoidMaskUtil] mesh 가 null"); return; } BoneWeight[] boneWeights = mesh.boneWeights; Transform[] bones = smr.bones; if (boneWeights == null || boneWeights.Length == 0 || bones == null || bones.Length == 0) { Debug.LogWarning("[ClothHumanoidMaskUtil] boneWeights 또는 bones 비어있음"); return; } if (clothInstance.humanoidMatchedBones == null || clothInstance.humanoidMatchedBones.Count == 0) { Debug.LogWarning("[ClothHumanoidMaskUtil] humanoidMatchedBones 가 비어있음 (BodyToClothPoseApplier에서 매칭 안 되었을 가능성)"); return; } int num = mesh.vertexCount; if (boneWeights.Length != num) { num = Mathf.Min(num, boneWeights.Length); } HashSet excludedBones = new HashSet(); Dictionary> humanoidMatchedBones = clothInstance.humanoidMatchedBones; if (humanoidMatchedBones.TryGetValue(HumanBodyBones.Head, out var value) && value != null) { foreach (Transform item in value) { if (!(item == null)) { AddHierarchy(item, includeRoot: true); } } } if (humanoidMatchedBones.TryGetValue(HumanBodyBones.LeftHand, out var value2) && value2 != null) { foreach (Transform item2 in value2) { if (!(item2 == null)) { AddHierarchy(item2, excludeHandRoot); } } } if (humanoidMatchedBones.TryGetValue(HumanBodyBones.RightHand, out var value3) && value3 != null) { foreach (Transform item3 in value3) { if (!(item3 == null)) { AddHierarchy(item3, excludeHandRoot); } } } if (humanoidMatchedBones.TryGetValue(HumanBodyBones.LeftThumbProximal, out var value4) && value4 != null) { foreach (Transform item4 in value4) { if (!(item4 == null)) { if (excludeThumbRoot) { excludedBones.Add(item4); } else { excludedBones.Remove(item4); } } } } if (humanoidMatchedBones.TryGetValue(HumanBodyBones.RightThumbProximal, out var value5) && value5 != null) { foreach (Transform item5 in value5) { if (!(item5 == null)) { if (excludeThumbRoot) { excludedBones.Add(item5); } else { excludedBones.Remove(item5); } } } } bool[] boneIndexExcluded = new bool[bones.Length]; for (int i = 0; i < bones.Length; i++) { Transform transform = bones[i]; if (transform != null && excludedBones.Contains(transform)) { boneIndexExcluded[i] = true; } } bool[] array = new bool[num]; for (int j = 0; j < num; j++) { BoneWeight boneWeight = boneWeights[j]; float excludedWeightSum = 0f; AddExcludedWeight(boneWeight.weight0, boneWeight.boneIndex0); AddExcludedWeight(boneWeight.weight1, boneWeight.boneIndex1); AddExcludedWeight(boneWeight.weight2, boneWeight.boneIndex2); AddExcludedWeight(boneWeight.weight3, boneWeight.boneIndex3); array[j] = excludedWeightSum >= 0.8f; void AddExcludedWeight(float w, int bi) { if (!(w <= 0f) && bi >= 0 && bi < boneIndexExcluded.Length && boneIndexExcluded[bi]) { excludedWeightSum += w; } } } clothInstance.excludedVertices = array; BuildLegVertexMasks(clothInstance); void AddHierarchy(Transform root, bool includeRoot) { if (!(root == null)) { Stack stack = new Stack(); if (includeRoot) { stack.Push(root); } else { for (int k = 0; k < root.childCount; k++) { stack.Push(root.GetChild(k)); } } while (stack.Count > 0) { Transform transform2 = stack.Pop(); if (!(transform2 == null) && excludedBones.Add(transform2)) { for (int l = 0; l < transform2.childCount; l++) { stack.Push(transform2.GetChild(l)); } } } } } } public void BuildLegVertexMasks(ClothInstance clothInstance) { if (clothInstance == null || clothInstance.smr == null) { Debug.LogWarning("[ClothHumanoidMaskUtil] clothInstance / smr 가 null"); return; } SkinnedMeshRenderer smr = clothInstance.smr; Mesh mesh = clothInstance.editableMesh ?? smr.sharedMesh; if (mesh == null) { Debug.LogWarning("[ClothHumanoidMaskUtil] mesh 가 null"); return; } BoneWeight[] boneWeights = mesh.boneWeights; Transform[] bones = smr.bones; if (boneWeights == null || boneWeights.Length == 0 || bones == null || bones.Length == 0) { Debug.LogWarning("[ClothHumanoidMaskUtil] boneWeights 또는 bones 비어있음"); return; } if (clothInstance.humanoidMatchedBones == null || clothInstance.humanoidMatchedBones.Count == 0) { Debug.LogWarning("[ClothHumanoidMaskUtil] humanoidMatchedBones 가 비어있음 (BodyToClothPoseApplier에서 매칭 필요)"); return; } int num = mesh.vertexCount; if (boneWeights.Length != num) { num = Mathf.Min(num, boneWeights.Length); } Dictionary> humanoidMatchedBones = clothInstance.humanoidMatchedBones; HashSet hashSet = new HashSet(); HashSet hashSet2 = new HashSet(); if (humanoidMatchedBones.TryGetValue(HumanBodyBones.LeftUpperLeg, out var value) && value != null) { foreach (Transform item in value) { if (!(item == null)) { CollectHierarchy(item, hashSet); } } } if (humanoidMatchedBones.TryGetValue(HumanBodyBones.RightUpperLeg, out var value2) && value2 != null) { foreach (Transform item2 in value2) { if (!(item2 == null)) { CollectHierarchy(item2, hashSet2); } } } bool[] boneIsLeftLeg = new bool[bones.Length]; bool[] boneIsRightLeg = new bool[bones.Length]; for (int i = 0; i < bones.Length; i++) { Transform transform = bones[i]; if (!(transform == null)) { if (hashSet.Contains(transform)) { boneIsLeftLeg[i] = true; } if (hashSet2.Contains(transform)) { boneIsRightLeg[i] = true; } } } bool[] array = new bool[num]; bool[] array2 = new bool[num]; for (int j = 0; j < num; j++) { BoneWeight boneWeight = boneWeights[j]; float leftWeight = 0f; float rightWeight = 0f; Check(boneWeight.boneIndex0, boneWeight.weight0); Check(boneWeight.boneIndex1, boneWeight.weight1); Check(boneWeight.boneIndex2, boneWeight.weight2); Check(boneWeight.boneIndex3, boneWeight.weight3); if (leftWeight > 0.8f) { array[j] = true; array2[j] = false; } else if (rightWeight > 0.8f) { array[j] = false; array2[j] = true; } else { array[j] = false; array2[j] = false; } void Check(int bi, float w) { if (bi >= 0 && bi < bones.Length && !(w <= 0f)) { if (boneIsLeftLeg[bi]) { leftWeight += w; } if (boneIsRightLeg[bi]) { rightWeight += w; } } } } clothInstance.isLeftLegVertex = array; clothInstance.isRightLegVertex = array2; static void CollectHierarchy(Transform root, HashSet set) { if (!(root == null)) { Stack stack = new Stack(); stack.Push(root); while (stack.Count > 0) { Transform transform2 = stack.Pop(); if (!(transform2 == null) && set.Add(transform2)) { for (int k = 0; k < transform2.childCount; k++) { stack.Push(transform2.GetChild(k)); } } } } } } }