517 lines
32 KiB
C#
517 lines
32 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: Eden.AutoMorpher.BoneMatchUtil
|
|
// Assembly: EdenAutoMorpherScript, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
// MVID: D39968B3-E151-4276-BDB4-E82752BBAFF0
|
|
// Assembly location: D:\git\Spy\Assets\@Eden_Tools\Eden_AutoMorpher\Script\EdenAutoMorpherScript.dll
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
namespace Eden.AutoMorpher
|
|
{
|
|
public class BoneMatchUtil
|
|
{
|
|
private const float PosTolNear = 0.0001f;
|
|
private const float PosTolMid = 0.0005f;
|
|
private const float PosTolFar = 0.002f;
|
|
private const float RotTolDeg = 30f;
|
|
private const float eps = 1E-06f;
|
|
|
|
public List<BoneMatchUtil.BoneRootLocalData> ConvertProfileBoneDataToRootLocalData(
|
|
List<BoneData> boneDataList)
|
|
{
|
|
List<BoneMatchUtil.BoneRootLocalData> rootLocalData = boneDataList != null && boneDataList.Count != 0 ? new List<BoneMatchUtil.BoneRootLocalData>(boneDataList.Count) : throw new AutoMorpherException("Profile Bone Data is Missing", "[BoneMatchUtil] ConvertProfileBoneDataToRootLocalData\n - boneDataList is null or empty");
|
|
foreach (BoneData boneData in boneDataList)
|
|
{
|
|
if (boneData != null)
|
|
{
|
|
BoneMatchUtil.BoneRootLocalData boneRootLocalData = new BoneMatchUtil.BoneRootLocalData()
|
|
{
|
|
t = (Transform)null,
|
|
name = boneData.boneName ?? string.Empty,
|
|
path = boneData.hierarchyPath ?? string.Empty,
|
|
rootLocalPos = boneData.rootLocalPosition,
|
|
rootLocalRot = boneData.rootLocalRotation,
|
|
hBone = boneData.hBone
|
|
};
|
|
rootLocalData.Add(boneRootLocalData);
|
|
}
|
|
}
|
|
return rootLocalData;
|
|
}
|
|
|
|
public HashSet<Transform> GetMeshBones(List<SkinnedMeshRenderer> meshRenderers)
|
|
{
|
|
HashSet<Transform> meshBones = new HashSet<Transform>();
|
|
if (meshRenderers != null)
|
|
{
|
|
foreach (SkinnedMeshRenderer meshRenderer in meshRenderers)
|
|
{
|
|
if (!Object.op_Equality((Object)meshRenderer, (Object)null) && meshRenderer.bones != null)
|
|
{
|
|
foreach (Transform bone in meshRenderer.bones)
|
|
{
|
|
if (Object.op_Inequality((Object)bone, (Object)null))
|
|
meshBones.Add(bone);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return meshBones;
|
|
}
|
|
|
|
public List<BoneMatchUtil.BoneRootLocalData> GetRootLocalBones(
|
|
Transform rootT,
|
|
HashSet<Transform> boneList)
|
|
{
|
|
BoneCorrespondenceUtil correspondenceUtil = new BoneCorrespondenceUtil();
|
|
return boneList.Where<Transform>((Func<Transform, bool>)(t => Object.op_Inequality((Object)t, (Object)null))).Distinct<Transform>().Select<Transform, BoneMatchUtil.BoneRootLocalData>((Func<Transform, BoneMatchUtil.BoneRootLocalData>)(t => new BoneMatchUtil.BoneRootLocalData()
|
|
{
|
|
t = t,
|
|
name = ((Object)t).name,
|
|
path = correspondenceUtil.GetHierarchyPath(rootT, t),
|
|
rootLocalPos = rootT.InverseTransformPoint(t.position),
|
|
rootLocalRot = Quaternion.op_Multiply(Quaternion.Inverse(rootT.rotation), t.rotation)
|
|
})).ToList<BoneMatchUtil.BoneRootLocalData>();
|
|
}
|
|
|
|
public List<BoneMatchUtil.BoneRootLocalData> GetBodyRootLocalBones(
|
|
Transform bodyTransform,
|
|
Animator bodyAnimator,
|
|
List<SkinnedMeshRenderer> bodyMeshes)
|
|
{
|
|
if (Object.op_Equality((Object)bodyTransform, (Object)null))
|
|
throw new AutoMorpherException("Body Transform is Missing", "[BoneMatchUtil] GetBodyRootLocalBones\n - bodyTransform is null");
|
|
Dictionary<Transform, HumanBodyBones> dictionary1 = !Object.op_Equality((Object)bodyAnimator, (Object)null) ? this.GetHumanoidBoneList(bodyAnimator) : throw new AutoMorpherException("Body Animator is Missing", "[BoneMatchUtil] GetBodyRootLocalBones\n - animator is null");
|
|
if (dictionary1 == null || dictionary1.Count == 0)
|
|
throw new AutoMorpherException("Humanoid Bone Map is Missing", "[BoneMatchUtil] GetBodyRootLocalBones\n - Can't find Humanoid Bone List");
|
|
HashSet<Transform> transformSet1 = bodyMeshes != null && bodyMeshes.Count != 0 ? this.GetMeshBones(bodyMeshes) : throw new AutoMorpherException("Body Meshes are Missing", "[BoneMatchUtil] GetBodyRootLocalBones\n - bodyMeshes is null or empty");
|
|
Dictionary<HumanBodyBones, HashSet<Transform>> dictionary2 = new MeshClassifier().MeshHumanoidBoneMatcher(bodyAnimator, (IReadOnlyList<SkinnedMeshRenderer>)bodyMeshes);
|
|
HashSet<Transform> boneList = new HashSet<Transform>();
|
|
HashSet<Transform> transformSet2 = new HashSet<Transform>();
|
|
foreach (KeyValuePair<Transform, HumanBodyBones> keyValuePair in dictionary1)
|
|
{
|
|
if (keyValuePair.Value != 55 && !Object.op_Equality((Object)keyValuePair.Key, (Object)null))
|
|
{
|
|
HashSet<Transform> transformSet3;
|
|
if (!dictionary2.TryGetValue(keyValuePair.Value, out transformSet3) || transformSet3 == null)
|
|
{
|
|
transformSet3 = new HashSet<Transform>();
|
|
dictionary2[keyValuePair.Value] = transformSet3;
|
|
}
|
|
transformSet3.Add(keyValuePair.Key);
|
|
}
|
|
}
|
|
foreach (KeyValuePair<HumanBodyBones, HashSet<Transform>> keyValuePair in dictionary2)
|
|
{
|
|
HumanBodyBones key = keyValuePair.Key;
|
|
if (key != 55)
|
|
{
|
|
HashSet<Transform> source = keyValuePair.Value;
|
|
if (source != null && source.Count != 0)
|
|
{
|
|
Transform transform1 = bodyAnimator.GetBoneTransform(key);
|
|
if (Object.op_Equality((Object)transform1, (Object)null))
|
|
transform1 = source.First<Transform>();
|
|
if (!Object.op_Equality((Object)transform1, (Object)null))
|
|
{
|
|
boneList.Add(transform1);
|
|
foreach (Transform transform2 in source)
|
|
{
|
|
if (!Object.op_Equality((Object)transform2, (Object)transform1) && !Object.op_Equality((Object)transform2, (Object)null))
|
|
transformSet2.Add(transform2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach (Transform transform in transformSet1)
|
|
{
|
|
if (!Object.op_Equality((Object)transform, (Object)null) && !transformSet2.Contains(transform))
|
|
boneList.Add(transform);
|
|
}
|
|
List<BoneMatchUtil.BoneRootLocalData> rootLocalBones = this.GetRootLocalBones(bodyTransform, boneList);
|
|
foreach (BoneMatchUtil.BoneRootLocalData boneRootLocalData in rootLocalBones)
|
|
{
|
|
if (boneRootLocalData != null && !Object.op_Equality((Object)boneRootLocalData.t, (Object)null))
|
|
{
|
|
HumanBodyBones humanBodyBones;
|
|
boneRootLocalData.hBone = !dictionary1.TryGetValue(boneRootLocalData.t, out humanBodyBones) ? (HumanBodyBones)55 : humanBodyBones;
|
|
}
|
|
}
|
|
return rootLocalBones;
|
|
}
|
|
|
|
private Dictionary<Transform, HumanBodyBones> GetHumanoidBoneList(Animator bodyAnimator)
|
|
{
|
|
Dictionary<Transform, HumanBodyBones> humanoidBoneList = new Dictionary<Transform, HumanBodyBones>();
|
|
if (Object.op_Equality((Object)bodyAnimator, (Object)null) || Object.op_Equality((Object)bodyAnimator.avatar, (Object)null) || !bodyAnimator.avatar.isHuman)
|
|
return humanoidBoneList;
|
|
foreach (HumanBodyBones humanBodyBones in Enum.GetValues(typeof(HumanBodyBones)))
|
|
{
|
|
if (humanBodyBones != 55)
|
|
{
|
|
Transform boneTransform = bodyAnimator.GetBoneTransform(humanBodyBones);
|
|
if (!Object.op_Equality((Object)boneTransform, (Object)null))
|
|
humanoidBoneList.TryAdd(boneTransform, humanBodyBones);
|
|
}
|
|
}
|
|
return humanoidBoneList;
|
|
}
|
|
|
|
public void MatchClothesToBodyBones(
|
|
List<BoneMatchUtil.BoneRootLocalData> bodyBones,
|
|
List<BoneMatchUtil.BoneRootLocalData> clothesBones,
|
|
out Dictionary<HumanBodyBones, HashSet<Transform>> clothHumanBones,
|
|
out Dictionary<Transform, ClothBoneType> clothBoneTypeMap,
|
|
out Dictionary<Transform, BoneMatchUtil.BoneRootLocalData> clothToBodyMatched)
|
|
{
|
|
clothHumanBones = new Dictionary<HumanBodyBones, HashSet<Transform>>();
|
|
clothBoneTypeMap = new Dictionary<Transform, ClothBoneType>();
|
|
clothToBodyMatched = new Dictionary<Transform, BoneMatchUtil.BoneRootLocalData>();
|
|
if (bodyBones == null || bodyBones.Count == 0)
|
|
throw new AutoMorpherException("Body Bones are Missing", "[BoneMatchUtil] MatchClothesToBodyBones\n - bodyBones is null or empty");
|
|
if (clothesBones == null || clothesBones.Count == 0)
|
|
throw new AutoMorpherException("Clothes Bones are Missing", "[BoneMatchUtil] MatchClothesToBodyBones\n - clothesBones is null or empty");
|
|
List<(BoneMatchUtil.BoneRootLocalData, BoneMatchUtil.BoneRootLocalData, float, float, float, float, float)> source1 = new List<(BoneMatchUtil.BoneRootLocalData, BoneMatchUtil.BoneRootLocalData, float, float, float, float, float)>();
|
|
BoneCorrespondenceUtil correspondenceUtil = new BoneCorrespondenceUtil();
|
|
foreach (BoneMatchUtil.BoneRootLocalData clothesBone in clothesBones)
|
|
{
|
|
BoneMatchUtil.BoneRootLocalData boneRootLocalData = (BoneMatchUtil.BoneRootLocalData)null;
|
|
float bestDistScore = float.NegativeInfinity;
|
|
float bestRotScore = float.NegativeInfinity;
|
|
float bestNameScore = float.NegativeInfinity;
|
|
float bestD = float.PositiveInfinity;
|
|
float bestAng = float.PositiveInfinity;
|
|
foreach (BoneMatchUtil.BoneRootLocalData bodyBone in bodyBones)
|
|
{
|
|
float num1 = Vector3.Distance(clothesBone.rootLocalPos, bodyBone.rootLocalPos);
|
|
float distanceScore = correspondenceUtil.ComputeDistanceScore(num1, 0.0001f, 0.0005f, 1f / 500f);
|
|
if ((double)distanceScore != 0.0)
|
|
{
|
|
float nameScore = correspondenceUtil.ComputeNameScore(bodyBone.name, bodyBone.path, clothesBone.name, clothesBone.path);
|
|
if ((double)nameScore != 0.0)
|
|
{
|
|
float num2 = Quaternion.Angle(bodyBone.rootLocalRot, clothesBone.rootLocalRot);
|
|
float candRotScore = correspondenceUtil.ComputeRotationScore(num2, 30f) * 1f;
|
|
if (this.IsBetterCandidate(distanceScore, bestDistScore, candRotScore, bestRotScore, nameScore, bestNameScore, num1, bestD, num2, bestAng))
|
|
{
|
|
boneRootLocalData = bodyBone;
|
|
bestDistScore = distanceScore;
|
|
bestRotScore = candRotScore;
|
|
bestNameScore = nameScore;
|
|
bestD = num1;
|
|
bestAng = num2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (boneRootLocalData != null)
|
|
source1.Add((clothesBone, boneRootLocalData, bestDistScore, bestRotScore, bestNameScore, bestD, bestAng));
|
|
}
|
|
Dictionary<Transform, BoneMatchUtil.BoneRootLocalData> dictionary = new Dictionary<Transform, BoneMatchUtil.BoneRootLocalData>();
|
|
foreach (IGrouping<BoneMatchUtil.BoneRootLocalData, (BoneMatchUtil.BoneRootLocalData, BoneMatchUtil.BoneRootLocalData, float, float, float, float, float)> source2 in source1.GroupBy<(BoneMatchUtil.BoneRootLocalData, BoneMatchUtil.BoneRootLocalData, float, float, float, float, float), BoneMatchUtil.BoneRootLocalData>((Func<(BoneMatchUtil.BoneRootLocalData, BoneMatchUtil.BoneRootLocalData, float, float, float, float, float), BoneMatchUtil.BoneRootLocalData>)(x => x.body)))
|
|
{
|
|
if (source2.Key != null)
|
|
{
|
|
List<(BoneMatchUtil.BoneRootLocalData, BoneMatchUtil.BoneRootLocalData, float, float, float, float, float)> list = source2.ToList<(BoneMatchUtil.BoneRootLocalData, BoneMatchUtil.BoneRootLocalData, float, float, float, float, float)>();
|
|
if (list.Count != 0)
|
|
{
|
|
(BoneMatchUtil.BoneRootLocalData, BoneMatchUtil.BoneRootLocalData, float, float, float, float, float) valueTuple = list[0];
|
|
for (int index = 1; index < list.Count; ++index)
|
|
{
|
|
(BoneMatchUtil.BoneRootLocalData, BoneMatchUtil.BoneRootLocalData, float, float, float, float, float) tuple = list[index];
|
|
if (this.IsBetterCandidate(tuple.Item3, valueTuple.Item3, tuple.Item4, valueTuple.Item4, tuple.Item5, valueTuple.Item5, tuple.Item6, valueTuple.Item6, tuple.Item7, valueTuple.Item7))
|
|
valueTuple = tuple;
|
|
}
|
|
if (valueTuple.Item1 != null && Object.op_Inequality((Object)valueTuple.Item1.t, (Object)null) && valueTuple.Item2 != null)
|
|
dictionary[valueTuple.Item1.t] = valueTuple.Item2;
|
|
}
|
|
}
|
|
}
|
|
foreach (BoneMatchUtil.BoneRootLocalData clothesBone in clothesBones)
|
|
{
|
|
if (!Object.op_Equality((Object)clothesBone?.t, (Object)null))
|
|
{
|
|
BoneMatchUtil.BoneRootLocalData boneRootLocalData;
|
|
if (dictionary.TryGetValue(clothesBone.t, out boneRootLocalData))
|
|
{
|
|
clothBoneTypeMap[clothesBone.t] = ClothBoneType.Body;
|
|
clothToBodyMatched[clothesBone.t] = boneRootLocalData;
|
|
HumanBodyBones hBone = boneRootLocalData.hBone;
|
|
if (hBone != 55)
|
|
{
|
|
HashSet<Transform> transformSet;
|
|
if (!clothHumanBones.TryGetValue(hBone, out transformSet))
|
|
{
|
|
transformSet = new HashSet<Transform>();
|
|
clothHumanBones[hBone] = transformSet;
|
|
}
|
|
transformSet.Add(clothesBone.t);
|
|
}
|
|
}
|
|
else
|
|
clothBoneTypeMap[clothesBone.t] = ClothBoneType.Accessory;
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool IsBetterCandidate(
|
|
float candDistScore,
|
|
float bestDistScore,
|
|
float candRotScore,
|
|
float bestRotScore,
|
|
float candNameScore,
|
|
float bestNameScore,
|
|
float candD,
|
|
float bestD,
|
|
float candAng,
|
|
float bestAng)
|
|
{
|
|
if ((double)candDistScore > (double)bestDistScore)
|
|
return true;
|
|
if ((double)candDistScore < (double)bestDistScore)
|
|
return false;
|
|
if ((double)candNameScore > (double)bestNameScore)
|
|
return true;
|
|
if ((double)candNameScore < (double)bestNameScore)
|
|
return false;
|
|
if ((double)Mathf.Abs(candRotScore - bestRotScore) > 9.9999999747524271E-07)
|
|
{
|
|
if ((double)candRotScore > (double)bestRotScore)
|
|
return true;
|
|
if ((double)candRotScore < (double)bestRotScore)
|
|
return false;
|
|
}
|
|
if ((double)Mathf.Abs(candD - bestD) > 9.9999999747524271E-07)
|
|
{
|
|
if ((double)candD < (double)bestD)
|
|
return true;
|
|
if ((double)candD > (double)bestD)
|
|
return false;
|
|
}
|
|
if ((double)Mathf.Abs(candAng - bestAng) <= 9.9999999747524271E-07)
|
|
return false;
|
|
if ((double)candAng < (double)bestAng)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
public Dictionary<Transform, Transform> BuildTransformMatchMap(
|
|
List<BoneMatchUtil.BoneRootLocalData> sourceBones,
|
|
List<BoneMatchUtil.BoneRootLocalData> destBones,
|
|
bool resultReverse = false)
|
|
{
|
|
if (sourceBones == null || sourceBones.Count == 0)
|
|
throw new AutoMorpherException("Source Bones are Missing", "[BoneMatchUtil] BuildTransformMatchMap\n - sourceBones is null or empty");
|
|
if (destBones == null || destBones.Count == 0)
|
|
throw new AutoMorpherException("Destination Bones are Missing", "[BoneMatchUtil] BuildTransformMatchMap\n - destBones is null or empty");
|
|
BoneCorrespondenceUtil correspondenceUtil = new BoneCorrespondenceUtil();
|
|
Dictionary<Transform, Transform> dictionary1 = new Dictionary<Transform, Transform>();
|
|
Dictionary<string, BoneMatchUtil.BoneRootLocalData> dictionary2 = new Dictionary<string, BoneMatchUtil.BoneRootLocalData>();
|
|
Dictionary<string, BoneMatchUtil.BoneRootLocalData> dictionary3 = new Dictionary<string, BoneMatchUtil.BoneRootLocalData>();
|
|
Dictionary<string, List<BoneMatchUtil.BoneRootLocalData>> dictionary4 = new Dictionary<string, List<BoneMatchUtil.BoneRootLocalData>>();
|
|
foreach (BoneMatchUtil.BoneRootLocalData destBone in destBones)
|
|
{
|
|
if (destBone != null && !Object.op_Equality((Object)destBone.t, (Object)null))
|
|
{
|
|
string str = destBone.path ?? "";
|
|
if (str.Length > 0 && !dictionary2.ContainsKey(str))
|
|
dictionary2.Add(str, destBone);
|
|
if (str.Length > 0)
|
|
{
|
|
string key = correspondenceUtil.NormalizePath(str);
|
|
if (key.Length > 0 && !dictionary3.ContainsKey(key))
|
|
dictionary3.Add(key, destBone);
|
|
}
|
|
string key1 = destBone.name ?? ((Object)destBone.t).name;
|
|
if (!string.IsNullOrEmpty(key1))
|
|
{
|
|
List<BoneMatchUtil.BoneRootLocalData> boneRootLocalDataList;
|
|
if (!dictionary4.TryGetValue(key1, out boneRootLocalDataList))
|
|
{
|
|
boneRootLocalDataList = new List<BoneMatchUtil.BoneRootLocalData>();
|
|
dictionary4[key1] = boneRootLocalDataList;
|
|
}
|
|
boneRootLocalDataList.Add(destBone);
|
|
}
|
|
}
|
|
}
|
|
HashSet<Transform> transformSet = new HashSet<Transform>();
|
|
foreach (BoneMatchUtil.BoneRootLocalData sourceBone in sourceBones)
|
|
{
|
|
if (sourceBone != null && !Object.op_Equality((Object)sourceBone.t, (Object)null))
|
|
{
|
|
Transform key2 = (Transform)null;
|
|
string str = sourceBone.path ?? "";
|
|
BoneMatchUtil.BoneRootLocalData boneRootLocalData1;
|
|
if (str.Length > 0 && dictionary2.TryGetValue(str, out boneRootLocalData1) && boneRootLocalData1 != null && Object.op_Inequality((Object)boneRootLocalData1.t, (Object)null) && !transformSet.Contains(boneRootLocalData1.t))
|
|
key2 = boneRootLocalData1.t;
|
|
if (Object.op_Equality((Object)key2, (Object)null) && str.Length > 0)
|
|
{
|
|
string key3 = correspondenceUtil.NormalizePath(str);
|
|
BoneMatchUtil.BoneRootLocalData boneRootLocalData2;
|
|
if (key3.Length > 0 && dictionary3.TryGetValue(key3, out boneRootLocalData2) && boneRootLocalData2 != null && Object.op_Inequality((Object)boneRootLocalData2.t, (Object)null) && !transformSet.Contains(boneRootLocalData2.t))
|
|
key2 = boneRootLocalData2.t;
|
|
}
|
|
if (Object.op_Equality((Object)key2, (Object)null))
|
|
{
|
|
string key4 = sourceBone.name ?? ((Object)sourceBone.t).name;
|
|
List<BoneMatchUtil.BoneRootLocalData> boneRootLocalDataList;
|
|
if (!string.IsNullOrEmpty(key4) && dictionary4.TryGetValue(key4, out boneRootLocalDataList))
|
|
{
|
|
float num1 = float.PositiveInfinity;
|
|
Transform transform = (Transform)null;
|
|
for (int index = 0; index < boneRootLocalDataList.Count; ++index)
|
|
{
|
|
BoneMatchUtil.BoneRootLocalData boneRootLocalData3 = boneRootLocalDataList[index];
|
|
if (boneRootLocalData3 != null && !Object.op_Equality((Object)boneRootLocalData3.t, (Object)null) && !transformSet.Contains(boneRootLocalData3.t))
|
|
{
|
|
float num2 = Vector3.SqrMagnitude(Vector3.op_Subtraction(boneRootLocalData3.rootLocalPos, sourceBone.rootLocalPos));
|
|
if ((double)num2 < (double)num1)
|
|
{
|
|
num1 = num2;
|
|
transform = boneRootLocalData3.t;
|
|
}
|
|
}
|
|
}
|
|
key2 = transform;
|
|
}
|
|
}
|
|
if (Object.op_Inequality((Object)key2, (Object)null))
|
|
{
|
|
if (resultReverse)
|
|
dictionary1[key2] = sourceBone.t;
|
|
else
|
|
dictionary1[sourceBone.t] = key2;
|
|
transformSet.Add(key2);
|
|
}
|
|
}
|
|
}
|
|
return dictionary1;
|
|
}
|
|
|
|
public void RemapSourceClothMatchToTargetCloth(
|
|
Transform sourceClothRoot,
|
|
Transform targetClothRoot,
|
|
Dictionary<HumanBodyBones, HashSet<Transform>> sourceClothHumanBones,
|
|
Dictionary<Transform, ClothBoneType> sourceClothBoneTypeMap,
|
|
out Dictionary<HumanBodyBones, HashSet<Transform>> targetClothHumanBones,
|
|
out Dictionary<Transform, ClothBoneType> targetClothBoneTypeMap)
|
|
{
|
|
targetClothHumanBones = new Dictionary<HumanBodyBones, HashSet<Transform>>();
|
|
targetClothBoneTypeMap = new Dictionary<Transform, ClothBoneType>();
|
|
if (Object.op_Equality((Object)sourceClothRoot, (Object)null) || Object.op_Equality((Object)targetClothRoot, (Object)null))
|
|
throw new AutoMorpherException("Cloth Root is Missing", "[BoneMatchUtil] RemapClothMatchResultToTargetCloth\n - sourceClothRoot or targetClothRoot is null");
|
|
if (sourceClothHumanBones == null || sourceClothBoneTypeMap == null)
|
|
throw new AutoMorpherException("Source Cloth Match Data is Missing", "[BoneMatchUtil] RemapClothMatchResultToTargetCloth\n - sourceClothHumanBones or sourceClothBoneTypeMap is null");
|
|
HashSet<Transform> boneList = new HashSet<Transform>();
|
|
foreach (KeyValuePair<Transform, ClothBoneType> sourceClothBoneType in sourceClothBoneTypeMap)
|
|
{
|
|
if (Object.op_Inequality((Object)sourceClothBoneType.Key, (Object)null))
|
|
boneList.Add(sourceClothBoneType.Key);
|
|
}
|
|
foreach (KeyValuePair<HumanBodyBones, HashSet<Transform>> sourceClothHumanBone in sourceClothHumanBones)
|
|
{
|
|
HashSet<Transform> transformSet = sourceClothHumanBone.Value;
|
|
if (transformSet != null && transformSet.Count != 0)
|
|
{
|
|
foreach (Transform transform in transformSet)
|
|
{
|
|
if (Object.op_Inequality((Object)transform, (Object)null))
|
|
boneList.Add(transform);
|
|
}
|
|
}
|
|
}
|
|
if (boneList.Count == 0)
|
|
throw new AutoMorpherException("Source Cloth Bone Candidates are Missing", "[BoneMatchUtil] RemapClothMatchResultToTargetCloth\n - sourceBoneSet is empty (no bones found in sourceClothBoneTypeMap/sourceClothHumanBones)");
|
|
HashSet<Transform> meshBones = this.GetMeshBones(((IEnumerable<SkinnedMeshRenderer>)((Component)targetClothRoot).GetComponentsInChildren<SkinnedMeshRenderer>(true)).ToList<SkinnedMeshRenderer>());
|
|
if (meshBones == null || meshBones.Count == 0)
|
|
throw new AutoMorpherException("Target Cloth Bone Candidates are Missing", "[BoneMatchUtil] RemapClothMatchResultToTargetCloth\n - targetBoneSet is null or empty (GetMeshBones returned no bones)");
|
|
List<BoneMatchUtil.BoneRootLocalData> rootLocalBones1 = this.GetRootLocalBones(sourceClothRoot, boneList);
|
|
List<BoneMatchUtil.BoneRootLocalData> rootLocalBones2 = this.GetRootLocalBones(targetClothRoot, meshBones);
|
|
if (rootLocalBones1 == null || rootLocalBones1.Count == 0)
|
|
throw new AutoMorpherException("Source RootLocal Bones are Missing", "[BoneMatchUtil] RemapClothMatchResultToTargetCloth\n - sourceRootLocalBones is null or empty");
|
|
Dictionary<Transform, Transform> dictionary = rootLocalBones2 != null && rootLocalBones2.Count != 0 ? this.BuildTransformMatchMap(rootLocalBones1, rootLocalBones2) : throw new AutoMorpherException("Target RootLocal Bones are Missing", "[BoneMatchUtil] RemapClothMatchResultToTargetCloth\n - targetRootLocalBones is null or empty");
|
|
foreach (KeyValuePair<Transform, ClothBoneType> sourceClothBoneType in sourceClothBoneTypeMap)
|
|
{
|
|
Transform key1 = sourceClothBoneType.Key;
|
|
ClothBoneType clothBoneType1 = sourceClothBoneType.Value;
|
|
Transform key2;
|
|
if (!Object.op_Equality((Object)key1, (Object)null) && dictionary.TryGetValue(key1, out key2) && !Object.op_Equality((Object)key2, (Object)null))
|
|
{
|
|
ClothBoneType clothBoneType2;
|
|
if (targetClothBoneTypeMap.TryGetValue(key2, out clothBoneType2))
|
|
{
|
|
if (clothBoneType2 == ClothBoneType.Accessory && clothBoneType1 == ClothBoneType.Body)
|
|
targetClothBoneTypeMap[key2] = ClothBoneType.Body;
|
|
}
|
|
else
|
|
targetClothBoneTypeMap.Add(key2, clothBoneType1);
|
|
}
|
|
}
|
|
foreach (KeyValuePair<HumanBodyBones, HashSet<Transform>> sourceClothHumanBone in sourceClothHumanBones)
|
|
{
|
|
HumanBodyBones key3 = sourceClothHumanBone.Key;
|
|
HashSet<Transform> transformSet1 = sourceClothHumanBone.Value;
|
|
if (transformSet1 != null && transformSet1.Count != 0)
|
|
{
|
|
foreach (Transform key4 in transformSet1)
|
|
{
|
|
Transform transform;
|
|
if (!Object.op_Equality((Object)key4, (Object)null) && dictionary.TryGetValue(key4, out transform) && !Object.op_Equality((Object)transform, (Object)null))
|
|
{
|
|
HashSet<Transform> transformSet2;
|
|
if (!targetClothHumanBones.TryGetValue(key3, out transformSet2))
|
|
{
|
|
transformSet2 = new HashSet<Transform>();
|
|
targetClothHumanBones[key3] = transformSet2;
|
|
}
|
|
transformSet2.Add(transform);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void BuildSourceToProxyBoneMap(
|
|
Animator sourceAvatar,
|
|
Animator proxyAvatar,
|
|
out Dictionary<Transform, Transform> sourceToProxy)
|
|
{
|
|
sourceToProxy = new Dictionary<Transform, Transform>();
|
|
if (Object.op_Equality((Object)sourceAvatar, (Object)null))
|
|
throw new AutoMorpherException("Source Avatar is Missing", "[AvatarBodyMatchUtil] BuildSourceToProxyBoneMap\n - sourceAvatar is null");
|
|
if (Object.op_Equality((Object)proxyAvatar, (Object)null))
|
|
throw new AutoMorpherException("Proxy Avatar is Missing", "[AvatarBodyMatchUtil] BuildSourceToProxyBoneMap\n - proxyAvatar is null");
|
|
Transform transform1 = ((Component)sourceAvatar).transform;
|
|
Transform transform2 = ((Component)proxyAvatar).transform;
|
|
HashSet<Transform> meshBones1 = this.GetMeshBones(((IEnumerable<SkinnedMeshRenderer>)((Component)transform2).GetComponentsInChildren<SkinnedMeshRenderer>(true)).ToList<SkinnedMeshRenderer>());
|
|
if (meshBones1 == null || meshBones1.Count == 0)
|
|
throw new AutoMorpherException("Proxy Body Bone Candidates are Missing", "[AvatarBodyMatchUtil] BuildSourceToProxyBoneMap\n - proxyBoneSet is null or empty (GetMeshBones returned no bones)");
|
|
HashSet<Transform> meshBones2 = this.GetMeshBones(((IEnumerable<SkinnedMeshRenderer>)((Component)transform1).GetComponentsInChildren<SkinnedMeshRenderer>(true)).ToList<SkinnedMeshRenderer>());
|
|
if (meshBones2 == null || meshBones2.Count == 0)
|
|
throw new AutoMorpherException("Source Body Bone Candidates are Missing", "[AvatarBodyMatchUtil] BuildSourceToProxyBoneMap\n - sourceBoneSet is null or empty (GetMeshBones returned no bones)");
|
|
List<BoneMatchUtil.BoneRootLocalData> rootLocalBones1 = this.GetRootLocalBones(transform2, meshBones1);
|
|
List<BoneMatchUtil.BoneRootLocalData> rootLocalBones2 = this.GetRootLocalBones(transform1, meshBones2);
|
|
if (rootLocalBones1 == null || rootLocalBones1.Count == 0)
|
|
throw new AutoMorpherException("Proxy RootLocal Bones are Missing", "[AvatarBodyMatchUtil] BuildSourceToProxyBoneMap\n - proxyRootLocalBones is null or empty");
|
|
sourceToProxy = rootLocalBones2 != null && rootLocalBones2.Count != 0 ? this.BuildTransformMatchMap(rootLocalBones1, rootLocalBones2, true) : throw new AutoMorpherException("Source RootLocal Bones are Missing", "[AvatarBodyMatchUtil] BuildSourceToProxyBoneMap\n - sourceRootLocalBones is null or empty");
|
|
if (sourceToProxy == null)
|
|
throw new AutoMorpherException("Source To Proxy Map Build Failed", "[AvatarBodyMatchUtil] BuildSourceToProxyBoneMap\n - BuildTransformMatchMap returned null");
|
|
}
|
|
|
|
public class BoneRootLocalData
|
|
{
|
|
public Transform t;
|
|
public string name;
|
|
public string path;
|
|
public Vector3 rootLocalPos;
|
|
public Quaternion rootLocalRot;
|
|
public HumanBodyBones hBone = (HumanBodyBones)55;
|
|
}
|
|
}
|
|
}
|