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

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;
}
}
}