209 lines
11 KiB
C#
209 lines
11 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: Eden.AutoMorpher.MeshMatcher
|
|
// 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.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Eden.AutoMorpher
|
|
{
|
|
public class MeshMatcher
|
|
{
|
|
public BvhTriangleMesh bodyBVH;
|
|
private readonly HashSet<HumanBodyBones> LeftLegBones = new HashSet<HumanBodyBones>()
|
|
{
|
|
(HumanBodyBones) 1,
|
|
(HumanBodyBones) 3,
|
|
(HumanBodyBones) 5,
|
|
(HumanBodyBones) 19
|
|
};
|
|
private readonly HashSet<HumanBodyBones> RightLegBones = new HashSet<HumanBodyBones>()
|
|
{
|
|
(HumanBodyBones) 2,
|
|
(HumanBodyBones) 4,
|
|
(HumanBodyBones) 6,
|
|
(HumanBodyBones) 20
|
|
};
|
|
|
|
public BvhTriangleMesh BuildBvhMulti(
|
|
IReadOnlyList<SkinnedMeshRenderer> bodies,
|
|
Animator bodyAnimator)
|
|
{
|
|
BvhTriangleMesh bvhTriangleMesh = bodies != null && bodies.Count != 0 ? new BvhTriangleMesh().BuildFromSkinnedMeshes(bodies, bodyAnimator) : throw new AutoMorpherException("Body Meshes are Missing", "[BuildBvhMulti] BuildBvhMulti\n - bodies is null or empty");
|
|
if (bvhTriangleMesh == null || bvhTriangleMesh.triangles == null)
|
|
{
|
|
Debug.LogError((object)"Failed to build multi-body BVH (no triangles).");
|
|
throw new AutoMorpherException(LanguageManager.Get("UI.Exception.title.BodyBVHFail"), LanguageManager.GetFormat("UI.Exception.message.BodyBVHFail", (object)((Object)((Component)bodyAnimator).gameObject).name, (object)(bvhTriangleMesh == null), (object)(bvhTriangleMesh.triangles == null)));
|
|
}
|
|
return bvhTriangleMesh;
|
|
}
|
|
|
|
public Vector3[] ExpandVertexMatch(
|
|
ClothInstance clothInstance,
|
|
float defaultMinDist = 0.005f,
|
|
bool skipFootFitting = false,
|
|
float maxMatchDistance = 0.1f)
|
|
{
|
|
Vector3[] worldVertices = clothInstance.worldVertices;
|
|
float[] minDistance = clothInstance.minDistance;
|
|
if (this.bodyBVH == null)
|
|
throw new AutoMorpherException("Body BVH is Missing", "[ExpandVertexMatch] ExpandVertexMatch\n - bodyBVH is null");
|
|
if (worldVertices == null)
|
|
throw new AutoMorpherException("Cloth World Vertices are Missing", "[ExpandVertexMatch] ExpandVertexMatch\n - clothInstance.worldVertices is null");
|
|
if (worldVertices.Length == 0)
|
|
{
|
|
Debug.LogWarning((object)"clothes mesh has no vertices");
|
|
return (Vector3[])null;
|
|
}
|
|
if (minDistance == null)
|
|
Debug.LogWarning((object)"minDists is null");
|
|
if (minDistance.Length != worldVertices.Length)
|
|
Debug.LogWarning((object)"minDists.Length != worldVertexs.Length");
|
|
Vector3[] vector3Array = new Vector3[worldVertices.Length];
|
|
float num1 = maxMatchDistance * maxMatchDistance;
|
|
for (int index = 0; index < worldVertices.Length; ++index)
|
|
{
|
|
if (clothInstance.excludedVertices[index])
|
|
vector3Array[index] = Vector3.zero;
|
|
else if (clothInstance.isInsideVertex[index])
|
|
{
|
|
vector3Array[index] = Vector3.zero;
|
|
}
|
|
else
|
|
{
|
|
float num2 = minDistance[index] + defaultMinDist;
|
|
BvhTriangleMesh.ClosestHit closestHit = !clothInstance.isLeftLegVertex[index] ? (!clothInstance.isRightLegVertex[index] ? this.bodyBVH.QueryClosest(worldVertices[index]) : this.bodyBVH.QueryClosest(worldVertices[index], this.RightLegBones)) : this.bodyBVH.QueryClosest(worldVertices[index], this.LeftLegBones);
|
|
if (skipFootFitting && (closestHit.mainHumanBone == 5 || closestHit.mainHumanBone == 6 || closestHit.mainHumanBone == 20 || closestHit.mainHumanBone == 19))
|
|
vector3Array[index] = Vector3.zero;
|
|
else if ((double)closestHit.sqrDistance > (double)num1)
|
|
{
|
|
vector3Array[index] = Vector3.zero;
|
|
}
|
|
else
|
|
{
|
|
Vector3 vector3 = Vector3.op_Subtraction(closestHit.closestPoint, worldVertices[index]);
|
|
Vector3 normalized = ((Vector3)ref vector3).normalized;
|
|
float num3 = Vector3.Dot(normalized, ((Vector3)ref closestHit.normal).normalized);
|
|
if ((double)num3 > 0.699999988079071)
|
|
vector3Array[index] = Vector3.op_Subtraction(Vector3.op_Addition(closestHit.closestPoint, Vector3.op_Multiply(normalized, num2)), worldVertices[index]);
|
|
else if ((double)num3 < -0.699999988079071)
|
|
{
|
|
if ((double)closestHit.sqrDistance < (double)num2 * (double)num2)
|
|
vector3Array[index] = Vector3.op_Subtraction(Vector3.op_Subtraction(closestHit.closestPoint, Vector3.op_Multiply(normalized, num2)), worldVertices[index]);
|
|
}
|
|
else
|
|
vector3Array[index] = Vector3.zero;
|
|
}
|
|
}
|
|
}
|
|
return vector3Array;
|
|
}
|
|
|
|
public Vector3[] ShrinkVertexMatch(
|
|
ClothInstance clothInstance,
|
|
float defaultMinDist = 0.005f,
|
|
float maxMatchDistance = 0.1f)
|
|
{
|
|
Vector3[] worldVertices = clothInstance.worldVertices;
|
|
float[] minDistance = clothInstance.minDistance;
|
|
if (this.bodyBVH == null)
|
|
throw new AutoMorpherException("Body BVH is Missing", "[ShrinkVertexMatch] ShrinkVertexMatch\n - bodyBVH is null");
|
|
if (worldVertices == null)
|
|
throw new AutoMorpherException("Cloth World Vertices are Missing", "[ShrinkVertexMatch] ShrinkVertexMatch\n - clothInstance.worldVertices is null");
|
|
if (worldVertices.Length == 0)
|
|
{
|
|
Debug.LogWarning((object)"clothes mesh has no vertices");
|
|
return (Vector3[])null;
|
|
}
|
|
if (minDistance == null)
|
|
Debug.LogWarning((object)"minDists is null");
|
|
if (minDistance.Length != worldVertices.Length)
|
|
Debug.LogWarning((object)"minDists.Length != worldVertexs.Length");
|
|
Vector3[] vector3Array = new Vector3[worldVertices.Length];
|
|
float num1 = maxMatchDistance * maxMatchDistance;
|
|
bool[] isLeftLegVertex = clothInstance.isLeftLegVertex;
|
|
bool[] isRightLegVertex = clothInstance.isRightLegVertex;
|
|
for (int index = 0; index < worldVertices.Length; ++index)
|
|
{
|
|
if (clothInstance.excludedVertices[index])
|
|
vector3Array[index] = Vector3.zero;
|
|
else if (clothInstance.isInsideVertex[index])
|
|
{
|
|
vector3Array[index] = Vector3.zero;
|
|
}
|
|
else
|
|
{
|
|
float num2 = minDistance[index] + defaultMinDist;
|
|
BvhTriangleMesh.ClosestHit closestHit = !clothInstance.isLeftLegVertex[index] ? (!clothInstance.isRightLegVertex[index] ? this.bodyBVH.QueryClosest(worldVertices[index]) : this.bodyBVH.QueryClosest(worldVertices[index], this.RightLegBones)) : this.bodyBVH.QueryClosest(worldVertices[index], this.LeftLegBones);
|
|
if ((double)closestHit.sqrDistance > (double)num1)
|
|
vector3Array[index] = Vector3.zero;
|
|
else if (closestHit.mainHumanBone == 5 || closestHit.mainHumanBone == 6 || closestHit.mainHumanBone == 20 || closestHit.mainHumanBone == 19)
|
|
{
|
|
vector3Array[index] = Vector3.zero;
|
|
}
|
|
else
|
|
{
|
|
Vector3 vector3 = Vector3.op_Subtraction(closestHit.closestPoint, worldVertices[index]);
|
|
Vector3 normalized = ((Vector3)ref vector3).normalized;
|
|
float num3 = Vector3.Dot(normalized, ((Vector3)ref closestHit.normal).normalized);
|
|
if ((double)num3 < -0.699999988079071)
|
|
vector3Array[index] = Vector3.op_Subtraction(Vector3.op_Subtraction(closestHit.closestPoint, Vector3.op_Multiply(normalized, num2)), worldVertices[index]);
|
|
else if ((double)num3 < -0.699999988079071)
|
|
{
|
|
if ((double)closestHit.sqrDistance < (double)num2 * (double)num2)
|
|
vector3Array[index] = Vector3.op_Subtraction(Vector3.op_Addition(closestHit.closestPoint, Vector3.op_Multiply(normalized, num2)), worldVertices[index]);
|
|
}
|
|
else
|
|
vector3Array[index] = Vector3.zero;
|
|
}
|
|
}
|
|
}
|
|
return vector3Array;
|
|
}
|
|
|
|
public Vector3[] GetMinDistanceToBody(Vector3[] clothesVertices)
|
|
{
|
|
if (this.bodyBVH == null)
|
|
throw new AutoMorpherException("sourceBodyBVH is null", "[MeshMatcher] GetMinDistanceToBodysourceBodyBVH is null");
|
|
Vector3[] minDistanceToBody = clothesVertices != null && clothesVertices.Length != 0 ? new Vector3[clothesVertices.Length] : throw new AutoMorpherException("Source Vertices is null", "[MeshMatcher] GetMinDistanceToBodySource Vertices is null or no vertices");
|
|
for (int index = 0; index < clothesVertices.Length; ++index)
|
|
{
|
|
Vector3 clothesVertex = clothesVertices[index];
|
|
Vector3 vector3 = Vector3.op_Subtraction(this.bodyBVH.QueryClosest(clothesVertex).closestPoint, clothesVertex);
|
|
minDistanceToBody[index] = vector3;
|
|
}
|
|
return minDistanceToBody;
|
|
}
|
|
|
|
public bool[] GetBodyInsideFlags(Vector3[] worldVertices)
|
|
{
|
|
if (this.bodyBVH == null)
|
|
throw new AutoMorpherException("sourceBodyBVH is null", "[MeshMatcher] GetBodyInsideFlagssourceBodyBVH is null");
|
|
if (worldVertices == null || worldVertices.Length == 0)
|
|
{
|
|
Debug.LogError((object)"clothes is null");
|
|
throw new AutoMorpherException("Source Vertices is null", "[MeshMatcher] GetMinDistanceToBodySource Vertices is null or no vertices");
|
|
}
|
|
bool[] bodyInsideFlags = new bool[worldVertices.Length];
|
|
for (int index = 0; index < worldVertices.Length; ++index)
|
|
{
|
|
BvhTriangleMesh.ClosestHit closestHit = this.bodyBVH.QueryClosest(worldVertices[index]);
|
|
Vector3 vector3 = Vector3.op_Subtraction(closestHit.closestPoint, worldVertices[index]);
|
|
float num = Vector3.Dot(((Vector3)ref vector3).normalized, ((Vector3)ref closestHit.normal).normalized);
|
|
bodyInsideFlags[index] = (double)num > 0.0;
|
|
}
|
|
return bodyInsideFlags;
|
|
}
|
|
|
|
public struct ClosestHit
|
|
{
|
|
public Vector3 closestP;
|
|
public Vector3 direction;
|
|
public Vector3 moveVector;
|
|
public float distance;
|
|
}
|
|
}
|
|
}
|