// 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 LeftLegBones = new HashSet() { (HumanBodyBones) 1, (HumanBodyBones) 3, (HumanBodyBones) 5, (HumanBodyBones) 19 }; private readonly HashSet RightLegBones = new HashSet() { (HumanBodyBones) 2, (HumanBodyBones) 4, (HumanBodyBones) 6, (HumanBodyBones) 20 }; public BvhTriangleMesh BuildBvhMulti( IReadOnlyList 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; } } }