// 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.BodyPoseMatchSetupUtil using System.Collections.Generic; using System.Linq; using UnityEngine; public class BodyPoseMatchSetupUtil { public void AdjustAvatarScaleByNeck(Transform avatarRoot, Dictionary> humanBoneMap, float targetHeight) { if (avatarRoot == null) { Debug.LogWarning("[AvatarBodyMatchUtil] NormalizeAvatarScaleByNeck: avatar == null"); return; } Transform boneFromBoneMap = new BodyPoseMatch_CommonUtil().GetBoneFromBoneMap(humanBoneMap, HumanBodyBones.Neck); if (boneFromBoneMap == null) { Debug.LogWarning("[AvatarBodyMatchUtil] " + avatarRoot.name + " 에서 Neck 본을 찾지 못했습니다. 스케일 정규화를 건너뜁니다."); return; } Transform transform = avatarRoot.transform; float num = boneFromBoneMap.position.y - transform.position.y; if (Mathf.Approximately(num, 0f)) { Debug.LogWarning($"[AvatarBodyMatchUtil] {avatarRoot.name} Neck Y가 0에 가까워 스케일 계산을 건너뜁니다. (neckY = {num})"); return; } float num2 = targetHeight / num; Vector3 localScale = transform.localScale; localScale *= num2; transform.localScale = localScale; } public GameObject CreateBodyProxy(Animator sourceAvatar, IReadOnlyList sourceBodyMeshes, out List proxyBodyMeshes, out Dictionary sourceToProxy) { proxyBodyMeshes = null; if (sourceAvatar == null) { Debug.LogError("[AvatarBodyMatchUtil] CreateSourceBodyProxy: sourceAvatar == null"); sourceToProxy = new Dictionary(); return null; } GameObject clone = Object.Instantiate(sourceAvatar.gameObject); clone.name = sourceAvatar.name + "_BodyProxy"; HashSet remainTransforms = new HashSet(); remainTransforms.Add(clone.transform); Animator component = clone.GetComponent(); if (component != null) { component.enabled = false; remainTransforms.Add(component.transform); } if (component != null && component.avatar != null && component.avatar.isHuman) { for (int i = 0; i < 55; i++) { HumanBodyBones humanBoneId = (HumanBodyBones)i; Transform boneTransform = component.GetBoneTransform(humanBoneId); if (boneTransform != null) { remainTransforms.Add(boneTransform); } } } HashSet hashSet = new HashSet(); if (sourceBodyMeshes != null) { foreach (SkinnedMeshRenderer sourceBodyMesh in sourceBodyMeshes) { if (!(sourceBodyMesh == null) && !(sourceBodyMesh.sharedMesh == null)) { hashSet.Add(sourceBodyMesh.sharedMesh); } } } SkinnedMeshRenderer[] componentsInChildren = clone.GetComponentsInChildren(includeInactive: true); List list = new List(); SkinnedMeshRenderer[] array = componentsInChildren; foreach (SkinnedMeshRenderer skinnedMeshRenderer in array) { if (!(skinnedMeshRenderer == null)) { Mesh sharedMesh = skinnedMeshRenderer.sharedMesh; if (!(sharedMesh == null) && hashSet.Contains(sharedMesh)) { list.Add(skinnedMeshRenderer); } } } if (list.Count == 0) { Debug.LogWarning("[AvatarBodyMatchUtil] CreateSourceBodyProxy: clone에서 동일 sharedMesh를 가진 BodyMesh를 찾지 못했습니다."); } if (list.Count > 0) { MeshClassifier meshClassifier = new MeshClassifier(); foreach (SkinnedMeshRenderer item in list) { if (item == null) { continue; } remainTransforms.Add(item.transform); HashSet activeBones = meshClassifier.GetActiveBones(item); if (activeBones == null) { Debug.LogWarning("[AvatarBodyMatchUtil] CreateSourceBodyProxy: clone smr '" + item.name + "' has null bones array (mesh='" + item.sharedMesh?.name + "')"); continue; } foreach (Transform item2 in activeBones) { if (!(item2 == null)) { remainTransforms.Add(item2); } } } } foreach (Transform item3 in remainTransforms.ToList()) { AddWithParents(item3); } Transform[] componentsInChildren2 = clone.GetComponentsInChildren(includeInactive: true); for (int num = componentsInChildren2.Length - 1; num >= 0; num--) { Transform transform = componentsInChildren2[num]; if (!(transform == null) && !(transform == clone.transform) && !remainTransforms.Contains(transform)) { Object.DestroyImmediate(transform.gameObject); } } proxyBodyMeshes = list; new BoneMatchUtil().BuildSourceToProxyBoneMap(sourceAvatar, component, out sourceToProxy); return clone; void AddWithParents(Transform t) { while (t != null && t != clone.transform) { remainTransforms.Add(t); t = t.parent; } } } public Vector3 GetComprehensiveScale(Transform rootT, Dictionary> clothHumanoidBoneMap, ProfileData profileData) { if (rootT == null) { throw new AutoMorpherException("Root Transform is Missing", "[BodyPoseMatch_CommonUtil] GetComprehensiveScale\n - rootT is null"); } if (profileData.bones == null || profileData.bones.Count == 0) { throw new AutoMorpherException("Profile Bones are Missing", "[BodyPoseMatch_CommonUtil] GetComprehensiveScale\n - profileData.bones is null or empty"); } Transform transform = null; if (clothHumanoidBoneMap.TryGetValue(HumanBodyBones.Hips, out var value) && value != null && value.Count > 0) { foreach (Transform item in value) { if (item != null) { transform = item; break; } } } if (transform == null) { throw new AutoMorpherException("Hip Transform is Missing", "[BodyPoseMatch_CommonUtil] GetComprehensiveScale\n - failed to get [hip] transform from clothHumanoidBoneMap"); } BoneData boneData = null; for (int i = 0; i < profileData.bones.Count; i++) { BoneData boneData2 = profileData.bones[i]; if (boneData2 != null && boneData2.hBone == HumanBodyBones.Hips) { boneData = boneData2; break; } } if (boneData == null) { throw new AutoMorpherException("Hip Bone Data is Missing in Profile", "[BodyPoseMatch_CommonUtil] GetComprehensiveScale\n - profileData bones does not contain Hips"); } Vector3 rootLocalScale = boneData.rootLocalScale; Vector3 lossyScale = rootT.lossyScale; Vector3 lossyScale2 = transform.lossyScale; Vector3 vector = new Vector3(lossyScale2.x / lossyScale.x, lossyScale2.y / lossyScale.y, lossyScale2.z / lossyScale.z); return new Vector3(vector.x / rootLocalScale.x, vector.y / rootLocalScale.y, vector.z / rootLocalScale.z); } }