303 lines
8.2 KiB
C#
303 lines
8.2 KiB
C#
// 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.ClothHumanoidMaskUtil
|
|
using System.Collections.Generic;
|
|
using Eden.AutoMorpher;
|
|
using UnityEngine;
|
|
|
|
public class ClothHumanoidMaskUtil
|
|
{
|
|
public void BuildExcludedVertexMaskForHandsAndHead(ClothInstance clothInstance, bool excludeHandRoot = false, bool excludeThumbRoot = false)
|
|
{
|
|
if (clothInstance == null || clothInstance.smr == null)
|
|
{
|
|
Debug.LogWarning("[ClothHumanoidMaskUtil] clothInstance / smr 가 null");
|
|
return;
|
|
}
|
|
SkinnedMeshRenderer smr = clothInstance.smr;
|
|
Mesh mesh = clothInstance.editableMesh ?? smr.sharedMesh;
|
|
if (mesh == null)
|
|
{
|
|
Debug.LogWarning("[ClothHumanoidMaskUtil] mesh 가 null");
|
|
return;
|
|
}
|
|
BoneWeight[] boneWeights = mesh.boneWeights;
|
|
Transform[] bones = smr.bones;
|
|
if (boneWeights == null || boneWeights.Length == 0 || bones == null || bones.Length == 0)
|
|
{
|
|
Debug.LogWarning("[ClothHumanoidMaskUtil] boneWeights 또는 bones 비어있음");
|
|
return;
|
|
}
|
|
if (clothInstance.humanoidMatchedBones == null || clothInstance.humanoidMatchedBones.Count == 0)
|
|
{
|
|
Debug.LogWarning("[ClothHumanoidMaskUtil] humanoidMatchedBones 가 비어있음 (BodyToClothPoseApplier에서 매칭 안 되었을 가능성)");
|
|
return;
|
|
}
|
|
int num = mesh.vertexCount;
|
|
if (boneWeights.Length != num)
|
|
{
|
|
num = Mathf.Min(num, boneWeights.Length);
|
|
}
|
|
HashSet<Transform> excludedBones = new HashSet<Transform>();
|
|
Dictionary<HumanBodyBones, HashSet<Transform>> humanoidMatchedBones = clothInstance.humanoidMatchedBones;
|
|
if (humanoidMatchedBones.TryGetValue(HumanBodyBones.Head, out var value) && value != null)
|
|
{
|
|
foreach (Transform item in value)
|
|
{
|
|
if (!(item == null))
|
|
{
|
|
AddHierarchy(item, includeRoot: true);
|
|
}
|
|
}
|
|
}
|
|
if (humanoidMatchedBones.TryGetValue(HumanBodyBones.LeftHand, out var value2) && value2 != null)
|
|
{
|
|
foreach (Transform item2 in value2)
|
|
{
|
|
if (!(item2 == null))
|
|
{
|
|
AddHierarchy(item2, excludeHandRoot);
|
|
}
|
|
}
|
|
}
|
|
if (humanoidMatchedBones.TryGetValue(HumanBodyBones.RightHand, out var value3) && value3 != null)
|
|
{
|
|
foreach (Transform item3 in value3)
|
|
{
|
|
if (!(item3 == null))
|
|
{
|
|
AddHierarchy(item3, excludeHandRoot);
|
|
}
|
|
}
|
|
}
|
|
if (humanoidMatchedBones.TryGetValue(HumanBodyBones.LeftThumbProximal, out var value4) && value4 != null)
|
|
{
|
|
foreach (Transform item4 in value4)
|
|
{
|
|
if (!(item4 == null))
|
|
{
|
|
if (excludeThumbRoot)
|
|
{
|
|
excludedBones.Add(item4);
|
|
}
|
|
else
|
|
{
|
|
excludedBones.Remove(item4);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (humanoidMatchedBones.TryGetValue(HumanBodyBones.RightThumbProximal, out var value5) && value5 != null)
|
|
{
|
|
foreach (Transform item5 in value5)
|
|
{
|
|
if (!(item5 == null))
|
|
{
|
|
if (excludeThumbRoot)
|
|
{
|
|
excludedBones.Add(item5);
|
|
}
|
|
else
|
|
{
|
|
excludedBones.Remove(item5);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
bool[] boneIndexExcluded = new bool[bones.Length];
|
|
for (int i = 0; i < bones.Length; i++)
|
|
{
|
|
Transform transform = bones[i];
|
|
if (transform != null && excludedBones.Contains(transform))
|
|
{
|
|
boneIndexExcluded[i] = true;
|
|
}
|
|
}
|
|
bool[] array = new bool[num];
|
|
for (int j = 0; j < num; j++)
|
|
{
|
|
BoneWeight boneWeight = boneWeights[j];
|
|
float excludedWeightSum = 0f;
|
|
AddExcludedWeight(boneWeight.weight0, boneWeight.boneIndex0);
|
|
AddExcludedWeight(boneWeight.weight1, boneWeight.boneIndex1);
|
|
AddExcludedWeight(boneWeight.weight2, boneWeight.boneIndex2);
|
|
AddExcludedWeight(boneWeight.weight3, boneWeight.boneIndex3);
|
|
array[j] = excludedWeightSum >= 0.8f;
|
|
void AddExcludedWeight(float w, int bi)
|
|
{
|
|
if (!(w <= 0f) && bi >= 0 && bi < boneIndexExcluded.Length && boneIndexExcluded[bi])
|
|
{
|
|
excludedWeightSum += w;
|
|
}
|
|
}
|
|
}
|
|
clothInstance.excludedVertices = array;
|
|
BuildLegVertexMasks(clothInstance);
|
|
void AddHierarchy(Transform root, bool includeRoot)
|
|
{
|
|
if (!(root == null))
|
|
{
|
|
Stack<Transform> stack = new Stack<Transform>();
|
|
if (includeRoot)
|
|
{
|
|
stack.Push(root);
|
|
}
|
|
else
|
|
{
|
|
for (int k = 0; k < root.childCount; k++)
|
|
{
|
|
stack.Push(root.GetChild(k));
|
|
}
|
|
}
|
|
while (stack.Count > 0)
|
|
{
|
|
Transform transform2 = stack.Pop();
|
|
if (!(transform2 == null) && excludedBones.Add(transform2))
|
|
{
|
|
for (int l = 0; l < transform2.childCount; l++)
|
|
{
|
|
stack.Push(transform2.GetChild(l));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void BuildLegVertexMasks(ClothInstance clothInstance)
|
|
{
|
|
if (clothInstance == null || clothInstance.smr == null)
|
|
{
|
|
Debug.LogWarning("[ClothHumanoidMaskUtil] clothInstance / smr 가 null");
|
|
return;
|
|
}
|
|
SkinnedMeshRenderer smr = clothInstance.smr;
|
|
Mesh mesh = clothInstance.editableMesh ?? smr.sharedMesh;
|
|
if (mesh == null)
|
|
{
|
|
Debug.LogWarning("[ClothHumanoidMaskUtil] mesh 가 null");
|
|
return;
|
|
}
|
|
BoneWeight[] boneWeights = mesh.boneWeights;
|
|
Transform[] bones = smr.bones;
|
|
if (boneWeights == null || boneWeights.Length == 0 || bones == null || bones.Length == 0)
|
|
{
|
|
Debug.LogWarning("[ClothHumanoidMaskUtil] boneWeights 또는 bones 비어있음");
|
|
return;
|
|
}
|
|
if (clothInstance.humanoidMatchedBones == null || clothInstance.humanoidMatchedBones.Count == 0)
|
|
{
|
|
Debug.LogWarning("[ClothHumanoidMaskUtil] humanoidMatchedBones 가 비어있음 (BodyToClothPoseApplier에서 매칭 필요)");
|
|
return;
|
|
}
|
|
int num = mesh.vertexCount;
|
|
if (boneWeights.Length != num)
|
|
{
|
|
num = Mathf.Min(num, boneWeights.Length);
|
|
}
|
|
Dictionary<HumanBodyBones, HashSet<Transform>> humanoidMatchedBones = clothInstance.humanoidMatchedBones;
|
|
HashSet<Transform> hashSet = new HashSet<Transform>();
|
|
HashSet<Transform> hashSet2 = new HashSet<Transform>();
|
|
if (humanoidMatchedBones.TryGetValue(HumanBodyBones.LeftUpperLeg, out var value) && value != null)
|
|
{
|
|
foreach (Transform item in value)
|
|
{
|
|
if (!(item == null))
|
|
{
|
|
CollectHierarchy(item, hashSet);
|
|
}
|
|
}
|
|
}
|
|
if (humanoidMatchedBones.TryGetValue(HumanBodyBones.RightUpperLeg, out var value2) && value2 != null)
|
|
{
|
|
foreach (Transform item2 in value2)
|
|
{
|
|
if (!(item2 == null))
|
|
{
|
|
CollectHierarchy(item2, hashSet2);
|
|
}
|
|
}
|
|
}
|
|
bool[] boneIsLeftLeg = new bool[bones.Length];
|
|
bool[] boneIsRightLeg = new bool[bones.Length];
|
|
for (int i = 0; i < bones.Length; i++)
|
|
{
|
|
Transform transform = bones[i];
|
|
if (!(transform == null))
|
|
{
|
|
if (hashSet.Contains(transform))
|
|
{
|
|
boneIsLeftLeg[i] = true;
|
|
}
|
|
if (hashSet2.Contains(transform))
|
|
{
|
|
boneIsRightLeg[i] = true;
|
|
}
|
|
}
|
|
}
|
|
bool[] array = new bool[num];
|
|
bool[] array2 = new bool[num];
|
|
for (int j = 0; j < num; j++)
|
|
{
|
|
BoneWeight boneWeight = boneWeights[j];
|
|
float leftWeight = 0f;
|
|
float rightWeight = 0f;
|
|
Check(boneWeight.boneIndex0, boneWeight.weight0);
|
|
Check(boneWeight.boneIndex1, boneWeight.weight1);
|
|
Check(boneWeight.boneIndex2, boneWeight.weight2);
|
|
Check(boneWeight.boneIndex3, boneWeight.weight3);
|
|
if (leftWeight > 0.8f)
|
|
{
|
|
array[j] = true;
|
|
array2[j] = false;
|
|
}
|
|
else if (rightWeight > 0.8f)
|
|
{
|
|
array[j] = false;
|
|
array2[j] = true;
|
|
}
|
|
else
|
|
{
|
|
array[j] = false;
|
|
array2[j] = false;
|
|
}
|
|
void Check(int bi, float w)
|
|
{
|
|
if (bi >= 0 && bi < bones.Length && !(w <= 0f))
|
|
{
|
|
if (boneIsLeftLeg[bi])
|
|
{
|
|
leftWeight += w;
|
|
}
|
|
if (boneIsRightLeg[bi])
|
|
{
|
|
rightWeight += w;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
clothInstance.isLeftLegVertex = array;
|
|
clothInstance.isRightLegVertex = array2;
|
|
static void CollectHierarchy(Transform root, HashSet<Transform> set)
|
|
{
|
|
if (!(root == null))
|
|
{
|
|
Stack<Transform> stack = new Stack<Transform>();
|
|
stack.Push(root);
|
|
while (stack.Count > 0)
|
|
{
|
|
Transform transform2 = stack.Pop();
|
|
if (!(transform2 == null) && set.Add(transform2))
|
|
{
|
|
for (int k = 0; k < transform2.childCount; k++)
|
|
{
|
|
stack.Push(transform2.GetChild(k));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|