// Decompiled with JetBrains decompiler // Type: Eden.AutoMorpher.MeshClassifier // Assembly: EdenAutoMorpherScript, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null // MVID: D39968B3-E151-4276-BDB4-E82752BBAFF0 // Assembly location: D:\dev\AutoMorpher\Assets\@Eden_Tools\Eden_AutoMorpher\Script\EdenAutoMorpherScript.dll using System; using System.Collections.Generic; using UnityEngine; namespace Eden.AutoMorpher { public class MeshClassifier { private HumanBodyBones[] bodyBones; private HumanBodyBones[] headBones; public SkinnedMeshRenderer GetBodyMesh(Transform root, Animator animator) { List humanBoneTransforms = this.HumanBodyBonesTrsnforms(this.bodyBones, animator); if (humanBoneTransforms.Count == this.bodyBones.Length) return this.GetBoneMatchedMesh(root, humanBoneTransforms); if (AutoMorpherDev.isDeveloperMode) Debug.LogWarning((object)"[Body Mesh] Animator Bone is not enough"); return (SkinnedMeshRenderer)null; } public SkinnedMeshRenderer GetHeadMesh(Transform root, Animator animator) { List humanBoneTransforms = this.HumanBodyBonesTrsnforms(this.headBones, animator); return humanBoneTransforms.Count != this.headBones.Length ? (SkinnedMeshRenderer)null : this.GetBoneMatchedMesh(root, humanBoneTransforms); } private List HumanBodyBonesTrsnforms( HumanBodyBones[] humanBonesList, Animator animator) { List transformList = new List(); List values = new List(); foreach (int humanBones in humanBonesList) { HumanBodyBones humanBodyBones = (HumanBodyBones)humanBones; Transform boneTransform = animator.GetBoneTransform(humanBodyBones); if (Object.op_Equality((Object)boneTransform, (Object)null)) values.Add(humanBodyBones); else transformList.Add(boneTransform); } if (values.Count > 0) throw new AutoMorpherException("[Body Mesh Finding] Required Humanoid Bones are Missing", $"[BodyMeshUtil] HumanBodyBonesTrsnforms\n - Missing Humanoid Bones: [{string.Join(", ", (IEnumerable)values)}]\n - Animator Humanoid mapping may be broken\n - Please check whether the missing humanoid bones are correctly assigned in [Animator → Avatar → Configure]."); return transformList; } private SkinnedMeshRenderer GetBoneMatchedMesh( Transform root, List humanBoneTransforms) { foreach (SkinnedMeshRenderer componentsInChild in ((Component)root).GetComponentsInChildren(false)) { bool flag = true; HashSet activeBones = this.GetActiveBones(componentsInChild); if (AutoMorpherDev.isDeveloperMode) Debug.Log((object)$"[Body Mesh] {((Object)((Component)componentsInChild).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((object)$"[Body Mesh] {((Object)((Component)componentsInChild).gameObject).name} Doesn't hav bone {((Object)humanBoneTransform).name}"); break; } break; } } if (flag) return componentsInChild; } return (SkinnedMeshRenderer)null; } private bool BoneExistsByPosition( Transform boneToCheck, HashSet smrBoneSet, float posTolerance = 0.0001f) { foreach (Transform smrBone in smrBoneSet) { Vector3 vector3 = Vector3.op_Subtraction(smrBone.position, boneToCheck.position); if ((double)((Vector3)ref vector3).sqrMagnitude <= (double)posTolerance * (double)posTolerance) return true; } return false; } public HashSet GetActiveBones(SkinnedMeshRenderer smr, float weightThreshold = 0.0001f) { Mesh sharedMesh = smr.sharedMesh; if (Object.op_Equality((Object)sharedMesh, (Object)null)) { Debug.LogWarning((object)"SkinnedMeshRenderer에 연결된 Mesh가 없습니다."); return new HashSet(); } Transform[] bones = smr.bones; BoneWeight[] boneWeights = sharedMesh.boneWeights; HashSet intSet = new HashSet(); foreach (BoneWeight boneWeight in boneWeights) { if ((double)((BoneWeight)ref boneWeight).weight0 > (double)weightThreshold) intSet.Add(((BoneWeight)ref boneWeight).boneIndex0); if ((double)((BoneWeight)ref boneWeight).weight1 > (double)weightThreshold) intSet.Add(((BoneWeight)ref boneWeight).boneIndex1); if ((double)((BoneWeight)ref boneWeight).weight2 > (double)weightThreshold) intSet.Add(((BoneWeight)ref boneWeight).boneIndex2); if ((double)((BoneWeight)ref boneWeight).weight3 > (double)weightThreshold) intSet.Add(((BoneWeight)ref boneWeight).boneIndex3); } HashSet activeBones = new HashSet(); foreach (int index in intSet) { if (index >= 0 && index < bones.Length) activeBones.Add(bones[index]); } return activeBones; } public Dictionary> MeshHumanoidBoneMatcher( Animator animator, IReadOnlyList bodyMeshes, float posTolerance = 0.0001f, float weightThreshold = 0.0001f) { Dictionary> dictionary = new Dictionary>(); if (Object.op_Equality((Object)animator, (Object)null)) throw new AutoMorpherException("Animator is Missing", "[MeshHumanoidBoneMatcher] MeshHumanoidBoneMatcher\n - animator is null"); HashSet smrBoneSet = new HashSet(); if (bodyMeshes != null) { foreach (SkinnedMeshRenderer bodyMesh in (IEnumerable)bodyMeshes) { if (!Object.op_Equality((Object)bodyMesh, (Object)null)) { foreach (Transform activeBone in this.GetActiveBones(bodyMesh, weightThreshold)) { if (Object.op_Inequality((Object)activeBone, (Object)null)) smrBoneSet.Add(activeBone); } } } } for (int index = 0; index < 55; ++index) { HumanBodyBones key = (HumanBodyBones)index; Transform boneTransform = animator.GetBoneTransform(key); if (!Object.op_Equality((Object)boneTransform, (Object)null)) { HashSet transformSet = new HashSet(); transformSet.Add(boneTransform); foreach (Transform transform in this.FindBonesByPosition(boneTransform, smrBoneSet, posTolerance)) transformSet.Add(transform); dictionary[key] = transformSet; } } return dictionary; } private List FindBonesByPosition( Transform boneToCheck, HashSet smrBoneSet, float posTolerance = 0.0001f) { List bonesByPosition = new List(); if (Object.op_Equality((Object)boneToCheck, (Object)null)) return bonesByPosition; float num = posTolerance * posTolerance; Vector3 position = boneToCheck.position; foreach (Transform smrBone in smrBoneSet) { if (!Object.op_Equality((Object)smrBone, (Object)null) && !Object.op_Equality((Object)smrBone, (Object)boneToCheck) && this.NameMatches(((Object)((Component)smrBone).gameObject).name, ((Object)((Component)boneToCheck).gameObject).name)) { Vector3 vector3 = Vector3.op_Subtraction(smrBone.position, position); if ((double)((Vector3)ref vector3).sqrMagnitude <= (double)num) bonesByPosition.Add(smrBone); } } return bonesByPosition; } 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[] strArray1 = this.TokenizeBoneName(boneToCheckName); string[] strArray2 = this.TokenizeBoneName(candidateName); return strArray1.Length != 0 && strArray2.Length != 0 && strArray1[0].Equals(strArray2[0], StringComparison.OrdinalIgnoreCase) && (strArray1.Length <= 1 || strArray2.Length <= 1 || strArray1[1].Equals(strArray2[1], StringComparison.OrdinalIgnoreCase)); } public MeshClassifier() { // ISSUE: unable to decompile the method. } } }