Files
AutoMorpherDecompiled/Assets/@Eden_Tools/Eden_AutoMorpher/Script/MeshClassifier.cs

219 lines
10 KiB
C#

// 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.
}
}
}