EdenAutoMorpherScript dll을 디컴파일한 결과를 그대로 가져옴
This commit is contained in:
218
Assets/@Eden_Tools/Eden_AutoMorpher/Script/MeshClassifier.cs
Normal file
218
Assets/@Eden_Tools/Eden_AutoMorpher/Script/MeshClassifier.cs
Normal file
@@ -0,0 +1,218 @@
|
||||
// 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<Transform> 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<Transform> humanBoneTransforms = this.HumanBodyBonesTrsnforms(this.headBones, animator);
|
||||
return humanBoneTransforms.Count != this.headBones.Length ? (SkinnedMeshRenderer)null : this.GetBoneMatchedMesh(root, humanBoneTransforms);
|
||||
}
|
||||
|
||||
private List<Transform> HumanBodyBonesTrsnforms(
|
||||
HumanBodyBones[] humanBonesList,
|
||||
Animator animator)
|
||||
{
|
||||
List<Transform> transformList = new List<Transform>();
|
||||
List<HumanBodyBones> values = new List<HumanBodyBones>();
|
||||
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<HumanBodyBones>(", ", (IEnumerable<HumanBodyBones>)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<Transform> humanBoneTransforms)
|
||||
{
|
||||
foreach (SkinnedMeshRenderer componentsInChild in ((Component)root).GetComponentsInChildren<SkinnedMeshRenderer>(false))
|
||||
{
|
||||
bool flag = true;
|
||||
HashSet<Transform> 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<Transform> 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<Transform> 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>();
|
||||
}
|
||||
Transform[] bones = smr.bones;
|
||||
BoneWeight[] boneWeights = sharedMesh.boneWeights;
|
||||
HashSet<int> intSet = new HashSet<int>();
|
||||
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<Transform> activeBones = new HashSet<Transform>();
|
||||
foreach (int index in intSet)
|
||||
{
|
||||
if (index >= 0 && index < bones.Length)
|
||||
activeBones.Add(bones[index]);
|
||||
}
|
||||
return activeBones;
|
||||
}
|
||||
|
||||
public Dictionary<HumanBodyBones, HashSet<Transform>> MeshHumanoidBoneMatcher(
|
||||
Animator animator,
|
||||
IReadOnlyList<SkinnedMeshRenderer> bodyMeshes,
|
||||
float posTolerance = 0.0001f,
|
||||
float weightThreshold = 0.0001f)
|
||||
{
|
||||
Dictionary<HumanBodyBones, HashSet<Transform>> dictionary = new Dictionary<HumanBodyBones, HashSet<Transform>>();
|
||||
if (Object.op_Equality((Object)animator, (Object)null))
|
||||
throw new AutoMorpherException("Animator is Missing", "[MeshHumanoidBoneMatcher] MeshHumanoidBoneMatcher\n - animator is null");
|
||||
HashSet<Transform> smrBoneSet = new HashSet<Transform>();
|
||||
if (bodyMeshes != null)
|
||||
{
|
||||
foreach (SkinnedMeshRenderer bodyMesh in (IEnumerable<SkinnedMeshRenderer>)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<Transform> transformSet = new HashSet<Transform>();
|
||||
transformSet.Add(boneTransform);
|
||||
foreach (Transform transform in this.FindBonesByPosition(boneTransform, smrBoneSet, posTolerance))
|
||||
transformSet.Add(transform);
|
||||
dictionary[key] = transformSet;
|
||||
}
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
private List<Transform> FindBonesByPosition(
|
||||
Transform boneToCheck,
|
||||
HashSet<Transform> smrBoneSet,
|
||||
float posTolerance = 0.0001f)
|
||||
{
|
||||
List<Transform> bonesByPosition = new List<Transform>();
|
||||
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<string>();
|
||||
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.
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user