// 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.MeshClassifier using System; using System.Collections.Generic; using UnityEngine; public class MeshClassifier { private HumanBodyBones[] bodyBones; private HumanBodyBones[] headBones; public SkinnedMeshRenderer GetBodyMesh(Transform root, Animator animator) { List list = this.HumanBodyBonesTrsnforms(this.bodyBones, animator); if (list.Count != this.bodyBones.Length) { if (AutoMorpherDev.isDeveloperMode) { Debug.LogWarning("[Body Mesh] Animator Bone is not enough"); } return null; } return this.GetBoneMatchedMesh(root, list); } public SkinnedMeshRenderer GetHeadMesh(Transform root, Animator animator) { List list = this.HumanBodyBonesTrsnforms(this.headBones, animator); if (list.Count != this.headBones.Length) { return null; } return this.GetBoneMatchedMesh(root, list); } private List HumanBodyBonesTrsnforms(HumanBodyBones[] humanBonesList, Animator animator) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) List list = new List(); List list2 = new List(); foreach (HumanBodyBones val in humanBonesList) { Transform boneTransform = animator.GetBoneTransform(val); if (boneTransform == null) { list2.Add(val); } else { list.Add(boneTransform); } } if (list2.Count > 0) { string text = string.Join(", ", list2); throw new AutoMorpherException("[Body Mesh Finding] Required Humanoid Bones are Missing", "[BodyMeshUtil] HumanBodyBonesTrsnforms\n - Missing Humanoid Bones: [" + text + "]\n - Animator Humanoid mapping may be broken\n - Please check whether the missing humanoid bones are correctly assigned in [Animator → Avatar → Configure]."); } return list; } private SkinnedMeshRenderer GetBoneMatchedMesh(Transform root, List humanBoneTransforms) { SkinnedMeshRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(false); foreach (SkinnedMeshRenderer val in componentsInChildren) { bool flag = true; HashSet activeBones = this.GetActiveBones(val); if (AutoMorpherDev.isDeveloperMode) { Debug.Log($"[Body Mesh] {val.gameObject.name} have bone Set {activeBones.Count}"); } foreach (Transform humanBoneTransform in humanBoneTransforms) { if (!activeBones.Contains(humanBoneTransform) && !this.BoneExistsByPosition(humanBoneTransform, activeBones)) { flag = false; if (AutoMorpherDev.isDeveloperMode) { Debug.Log(("[Body Mesh] " + val.gameObject.name + " Doesn't hav bone " + humanBoneTransform.name)); } break; } } if (flag) { return val; } } return null; } private bool BoneExistsByPosition(Transform boneToCheck, HashSet smrBoneSet, float posTolerance = 0.0001f) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) foreach (Transform item in smrBoneSet) { Vector3 val = item.position - boneToCheck.position; if (val.sqrMagnitude <= posTolerance * posTolerance) { return true; } } return false; } public HashSet GetActiveBones(SkinnedMeshRenderer smr, float weightThreshold = 0.0001f) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) Mesh sharedMesh = smr.sharedMesh; if (sharedMesh == null) { Debug.LogWarning("SkinnedMeshRenderer에 연결된 Mesh가 없습니다."); return new HashSet(); } Transform[] bones = smr.bones; BoneWeight[] boneWeights = sharedMesh.boneWeights; HashSet hashSet = new HashSet(); BoneWeight[] array = boneWeights; for (int i = 0; i < array.Length; i++) { BoneWeight val = array[i]; if (val.weight0 > weightThreshold) { hashSet.Add(val.boneIndex0); } if (val.weight1 > weightThreshold) { hashSet.Add(val.boneIndex1); } if (val.weight2 > weightThreshold) { hashSet.Add(val.boneIndex2); } if (val.weight3 > weightThreshold) { hashSet.Add(val.boneIndex3); } } HashSet hashSet2 = new HashSet(); foreach (int item in hashSet) { if (item >= 0 && item < bones.Length) { hashSet2.Add(bones[item]); } } return hashSet2; } public Dictionary> MeshHumanoidBoneMatcher(Animator animator, IReadOnlyList bodyMeshes, float posTolerance = 0.0001f, float weightThreshold = 0.0001f) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) Dictionary> dictionary = new Dictionary>(); if (animator == null) { throw new AutoMorpherException("Animator is Missing", "[MeshHumanoidBoneMatcher] MeshHumanoidBoneMatcher\n - animator is null"); } HashSet hashSet = new HashSet(); if (bodyMeshes != null) { foreach (SkinnedMeshRenderer bodyMesh in bodyMeshes) { if (bodyMesh == null) { continue; } foreach (Transform activeBone in this.GetActiveBones(bodyMesh, weightThreshold)) { if (activeBone != null) { hashSet.Add(activeBone); } } } } for (int i = 0; i < 55; i++) { HumanBodyBones val = (HumanBodyBones)i; Transform boneTransform = animator.GetBoneTransform(val); if (boneTransform == null) { continue; } HashSet hashSet2 = new HashSet(); hashSet2.Add(boneTransform); foreach (Transform item in this.FindBonesByPosition(boneTransform, hashSet, posTolerance)) { hashSet2.Add(item); } dictionary[val] = hashSet2; } return dictionary; } private List FindBonesByPosition(Transform boneToCheck, HashSet smrBoneSet, float posTolerance = 0.0001f) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) List list = new List(); if (boneToCheck == null) { return list; } float num = posTolerance * posTolerance; Vector3 position = boneToCheck.position; foreach (Transform item in smrBoneSet) { if (!(item == null) && !(item == boneToCheck) && this.NameMatches((((Component)item).gameObject).name, (((Component)boneToCheck).gameObject).name)) { Vector3 val = item.position - position; if (val.sqrMagnitude <= num) { list.Add(item); } } } return list; } private string[] TokenizeBoneName(string name) { if (string.IsNullOrWhiteSpace(name)) { return Array.Empty(); } char[] separator = new char[5] { '-', '_', ':', '.', '|' }; name = name.Trim(); return name.Split(separator, StringSplitOptions.RemoveEmptyEntries); } private bool NameMatches(string boneToCheckName, string candidateName) { string[] array = this.TokenizeBoneName(boneToCheckName); string[] array2 = this.TokenizeBoneName(candidateName); if (array.Length == 0 || array2.Length == 0) { return false; } if (!array[0].Equals(array2[0], StringComparison.OrdinalIgnoreCase)) { return false; } if (array.Length > 1 && array2.Length > 1 && !array[1].Equals(array2[1], StringComparison.OrdinalIgnoreCase)) { return false; } return true; } public MeshClassifier() { this.bodyBones = new HumanBodyBones[28] { HumanBodyBones.Hips, HumanBodyBones.Spine, HumanBodyBones.Chest, HumanBodyBones.Neck, HumanBodyBones.LeftShoulder, HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand, HumanBodyBones.LeftThumbProximal, HumanBodyBones.LeftIndexProximal, HumanBodyBones.LeftMiddleProximal, HumanBodyBones.LeftRingProximal, HumanBodyBones.LeftLittleProximal, HumanBodyBones.RightShoulder, HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand, HumanBodyBones.RightThumbProximal, HumanBodyBones.RightIndexProximal, HumanBodyBones.RightMiddleProximal, HumanBodyBones.RightRingProximal, HumanBodyBones.RightLittleProximal, HumanBodyBones.LeftUpperLeg, HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot, HumanBodyBones.RightUpperLeg, HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot }; this.headBones = new HumanBodyBones[3] { HumanBodyBones.Head, HumanBodyBones.LeftEye, HumanBodyBones.RightEye }; } }