// Decompiled with JetBrains decompiler // Type: Eden.AutoMorpher.ClothInstance // 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; using System.Collections.Generic; using UnityEngine; namespace Eden.AutoMorpher { [Serializable] public class ClothInstance { public SkinnedMeshRenderer smr; public Mesh editableMesh; public Mesh bakedMesh; public Matrix4x4 worldNoScale; public Vector3[] worldVertices; public Vector3[] minDistanceVector; public float[] minDistance; public Vector3[] deltas; public Vector3[] deltasLocal; public List[] vertexAdjacency; public List> equivalentVertices; public bool[] isInsideVertex; public bool[] excludedVertices; public bool[] isLeftLegVertex; public bool[] isRightLegVertex; public Vector3[] bakedWorldNormals; public Vector4[] bakedWorldTangents; public Dictionary> humanoidMatchedBones; public ClothInstance(SkinnedMeshRenderer clotheSMR, bool duplicateMesh = true) { this.smr = clotheSMR; if (duplicateMesh) { string name = ((Object)this.smr.sharedMesh).name; this.editableMesh = Object.Instantiate(clotheSMR.sharedMesh); ((Object)this.editableMesh).name = name + "_EditableMesh"; this.smr.sharedMesh = this.editableMesh; } else this.editableMesh = this.smr.sharedMesh; this.UpdateWorldVertices(); int vertexCount = this.editableMesh.vertexCount; this.minDistanceVector = new Vector3[vertexCount]; this.deltas = new Vector3[vertexCount]; this.minDistance = new float[vertexCount]; this.isInsideVertex = new bool[vertexCount]; this.excludedVertices = new bool[vertexCount]; this.isLeftLegVertex = new bool[vertexCount]; this.isRightLegVertex = new bool[vertexCount]; this.humanoidMatchedBones = new Dictionary>(); this.vertexAdjacency = this.BuildVertexAdjacency(this.editableMesh); this.BuildEquivalentVerticesFromWorld(); } public void UpdateWorldVertices() { if (Object.op_Equality((Object)this.bakedMesh, (Object)null)) this.bakedMesh = new Mesh(); else this.bakedMesh.Clear(); this.smr.BakeMesh(this.bakedMesh); int vertexCount = this.editableMesh.vertexCount; Vector3 lossyScale = ((Component)this.smr).transform.lossyScale; Vector3 vector3_1; // ISSUE: explicit constructor call ((Vector3)ref vector3_1).\u002Ector(1f / Mathf.Max(lossyScale.x, 1E-08f), 1f / Mathf.Max(lossyScale.y, 1E-08f), 1f / Mathf.Max(lossyScale.z, 1E-08f)); this.worldNoScale = Matrix4x4.op_Multiply(((Component)this.smr).transform.localToWorldMatrix, Matrix4x4.Scale(vector3_1)); this.worldVertices = new Vector3[vertexCount]; this.deltasLocal = new Vector3[vertexCount]; for (int index = 0; index < vertexCount; ++index) { this.worldVertices[index] = ((Matrix4x4)ref this.worldNoScale).MultiplyPoint3x4(this.bakedMesh.vertices[index]); this.deltasLocal[index] = Vector3.zero; } Vector3[] normals = this.bakedMesh.normals; Vector4[] tangents = this.bakedMesh.tangents; this.bakedWorldNormals = new Vector3[vertexCount]; this.bakedWorldTangents = tangents == null || tangents.Length != vertexCount ? (Vector4[])null : new Vector4[vertexCount]; for (int index1 = 0; index1 < vertexCount; ++index1) { Vector3[] bakedWorldNormals = this.bakedWorldNormals; int index2 = index1; Vector3 vector3_2 = ((Component)this.smr).transform.TransformDirection(normals[index1]); Vector3 normalized1 = ((Vector3)ref vector3_2).normalized; bakedWorldNormals[index2] = normalized1; if (this.bakedWorldTangents != null) { vector3_2 = ((Component)this.smr).transform.TransformDirection(new Vector3(tangents[index1].x, tangents[index1].y, tangents[index1].z)); Vector3 normalized2 = ((Vector3)ref vector3_2).normalized; this.bakedWorldTangents[index1] = new Vector4(normalized2.x, normalized2.y, normalized2.z, tangents[index1].w); } } } public List[] BuildVertexAdjacency(Mesh mesh, float seamThreshold = 0.0001f, float proximityThreshold = 0.0f) { int length = !Object.op_Equality((Object)mesh, (Object)null) ? mesh.vertexCount : throw new AutoMorpherException("Mesh is Missing", "[VertexAdjacencyUtil] BuildVertexAdjacency\n - mesh is null"); int[] triangles = mesh.triangles; Vector3[] vertices = mesh.vertices; List[] adj = new List[length]; for (int index = 0; index < length; ++index) adj[index] = new List(); int num1 = triangles.Length / 3; for (int index = 0; index < num1; ++index) { int num2 = triangles[index * 3]; int num3 = triangles[index * 3 + 1]; int num4 = triangles[index * 3 + 2]; AddNeighbor(adj, num2, num3); AddNeighbor(adj, num3, num2); AddNeighbor(adj, num3, num4); AddNeighbor(adj, num4, num3); AddNeighbor(adj, num4, num2); AddNeighbor(adj, num2, num4); } if ((double)seamThreshold > 0.0) { float num5 = seamThreshold * 2f; float num6 = seamThreshold * seamThreshold; Dictionary> dictionary = new Dictionary>(); for (int index = 0; index < length; ++index) { Vector3 vector3 = vertices[index]; Vector3Int key; // ISSUE: explicit constructor call ((Vector3Int)ref key).\u002Ector(Mathf.FloorToInt(vector3.x / num5), Mathf.FloorToInt(vector3.y / num5), Mathf.FloorToInt(vector3.z / num5)); List intList; if (!dictionary.TryGetValue(key, out intList)) { intList = new List(); dictionary[key] = intList; } intList.Add(index); } foreach (KeyValuePair> keyValuePair in dictionary) { Vector3Int key1 = keyValuePair.Key; List intList1 = keyValuePair.Value; for (int index1 = -1; index1 <= 1; ++index1) { for (int index2 = -1; index2 <= 1; ++index2) { for (int index3 = -1; index3 <= 1; ++index3) { if (index1 >= 0 && (index1 != 0 || index2 >= 0) && (index1 != 0 || index2 != 0 || index3 >= 0)) { Vector3Int key2; // ISSUE: explicit constructor call ((Vector3Int)ref key2).\u002Ector(((Vector3Int)ref key1).x + index1, ((Vector3Int)ref key1).y + index2, ((Vector3Int)ref key1).z + index3); List intList2; Vector3 vector3_1; if (dictionary.TryGetValue(key2, out intList2)) { if (Vector3Int.op_Equality(key2, key1)) { for (int index4 = 0; index4 < intList1.Count; ++index4) { int index5 = intList1[index4]; Vector3 vector3_2 = vertices[index5]; for (int index6 = index4 + 1; index6 < intList1.Count; ++index6) { int index7 = intList1[index6]; vector3_1 = Vector3.op_Subtraction(vertices[index7], vector3_2); if ((double)((Vector3)ref vector3_1).sqrMagnitude <= (double)num6) { AddNeighbor(adj, index5, index7); AddNeighbor(adj, index7, index5); } } } } else { for (int index8 = 0; index8 < intList1.Count; ++index8) { int index9 = intList1[index8]; Vector3 vector3_3 = vertices[index9]; for (int index10 = 0; index10 < intList2.Count; ++index10) { int index11 = intList2[index10]; vector3_1 = Vector3.op_Subtraction(vertices[index11], vector3_3); if ((double)((Vector3)ref vector3_1).sqrMagnitude <= (double)num6) { AddNeighbor(adj, index9, index11); AddNeighbor(adj, index11, index9); } } } } } } } } } } } if ((double)proximityThreshold > 0.0) { float num7 = proximityThreshold * 2f; float num8 = proximityThreshold * proximityThreshold; Dictionary> dictionary = new Dictionary>(); for (int index = 0; index < length; ++index) { Vector3 vector3 = vertices[index]; Vector3Int key; // ISSUE: explicit constructor call ((Vector3Int)ref key).\u002Ector(Mathf.FloorToInt(vector3.x / num7), Mathf.FloorToInt(vector3.y / num7), Mathf.FloorToInt(vector3.z / num7)); List intList; if (!dictionary.TryGetValue(key, out intList)) { intList = new List(); dictionary[key] = intList; } intList.Add(index); } foreach (KeyValuePair> keyValuePair in dictionary) { Vector3Int key3 = keyValuePair.Key; List intList3 = keyValuePair.Value; for (int index12 = -1; index12 <= 1; ++index12) { for (int index13 = -1; index13 <= 1; ++index13) { for (int index14 = -1; index14 <= 1; ++index14) { if (index12 >= 0 && (index12 != 0 || index13 >= 0) && (index12 != 0 || index13 != 0 || index14 >= 0)) { Vector3Int key4; // ISSUE: explicit constructor call ((Vector3Int)ref key4).\u002Ector(((Vector3Int)ref key3).x + index12, ((Vector3Int)ref key3).y + index13, ((Vector3Int)ref key3).z + index14); List intList4; Vector3 vector3_4; if (dictionary.TryGetValue(key4, out intList4)) { if (Vector3Int.op_Equality(key4, key3)) { for (int index15 = 0; index15 < intList3.Count; ++index15) { int index16 = intList3[index15]; Vector3 vector3_5 = vertices[index16]; for (int index17 = index15 + 1; index17 < intList3.Count; ++index17) { int index18 = intList3[index17]; vector3_4 = Vector3.op_Subtraction(vertices[index18], vector3_5); if ((double)((Vector3)ref vector3_4).sqrMagnitude <= (double)num8) { AddNeighbor(adj, index16, index18); AddNeighbor(adj, index18, index16); } } } } else { for (int index19 = 0; index19 < intList3.Count; ++index19) { int index20 = intList3[index19]; Vector3 vector3_6 = vertices[index20]; for (int index21 = 0; index21 < intList4.Count; ++index21) { int index22 = intList4[index21]; vector3_4 = Vector3.op_Subtraction(vertices[index22], vector3_6); if ((double)((Vector3)ref vector3_4).sqrMagnitude <= (double)num8) { AddNeighbor(adj, index20, index22); AddNeighbor(adj, index22, index20); } } } } } } } } } } } return adj; static void AddNeighbor(List[] adj, int from, int to) { List intList = adj[from]; if (intList.Contains(to)) return; intList.Add(to); } } public void ApplyWorldVerticesToMesh() { if (Object.op_Equality((Object)this.editableMesh, (Object)null) || Object.op_Equality((Object)this.smr, (Object)null) || this.worldVertices == null) return; Mesh editableMesh = this.editableMesh; int vertexCount = editableMesh.vertexCount; Vector3[] vertices = editableMesh.vertices; SkinningUtil skinningUtil = new SkinningUtil(); Vector3[] vector3Array1 = (Vector3[])null; int blendShapeCount = editableMesh.blendShapeCount; if (blendShapeCount > 0) { vector3Array1 = new Vector3[vertexCount]; Vector3[] vector3Array2 = new Vector3[vertexCount]; Vector3[] vector3Array3 = new Vector3[vertexCount]; Vector3[] vector3Array4 = new Vector3[vertexCount]; for (int index1 = 0; index1 < blendShapeCount; ++index1) { float blendShapeWeight = this.smr.GetBlendShapeWeight(index1); if (!Mathf.Approximately(blendShapeWeight, 0.0f)) { int num1 = editableMesh.GetBlendShapeFrameCount(index1) - 1; float shapeFrameWeight = editableMesh.GetBlendShapeFrameWeight(index1, num1); editableMesh.GetBlendShapeFrameVertices(index1, num1, vector3Array2, vector3Array3, vector3Array4); float num2 = (double)shapeFrameWeight != 0.0 ? blendShapeWeight / shapeFrameWeight : 0.0f; if (!Mathf.Approximately(num2, 0.0f)) { for (int index2 = 0; index2 < vertexCount; ++index2) { ref Vector3 local = ref vector3Array1[index2]; local = Vector3.op_Addition(local, Vector3.op_Multiply(vector3Array2[index2], num2)); } } } } } for (int vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex) { Vector3 vector3 = skinningUtil.WorldPosToBindPos_Full(this.smr, editableMesh, vertexIndex, this.worldVertices[vertexIndex]); if (vector3Array1 != null) vector3 = Vector3.op_Subtraction(vector3, vector3Array1[vertexIndex]); vertices[vertexIndex] = vector3; } editableMesh.vertices = vertices; Vector3[] vector3Array5 = (Vector3[])null; Vector3[] vector3Array6 = (Vector3[])null; if (blendShapeCount > 0) { vector3Array5 = new Vector3[vertexCount]; vector3Array6 = new Vector3[vertexCount]; Vector3[] vector3Array7 = new Vector3[vertexCount]; Vector3[] vector3Array8 = new Vector3[vertexCount]; Vector3[] vector3Array9 = new Vector3[vertexCount]; for (int index3 = 0; index3 < blendShapeCount; ++index3) { float blendShapeWeight = this.smr.GetBlendShapeWeight(index3); if (!Mathf.Approximately(blendShapeWeight, 0.0f)) { int num3 = editableMesh.GetBlendShapeFrameCount(index3) - 1; float shapeFrameWeight = editableMesh.GetBlendShapeFrameWeight(index3, num3); editableMesh.GetBlendShapeFrameVertices(index3, num3, vector3Array7, vector3Array8, vector3Array9); float num4 = (double)shapeFrameWeight != 0.0 ? blendShapeWeight / shapeFrameWeight : 0.0f; if (!Mathf.Approximately(num4, 0.0f)) { for (int index4 = 0; index4 < vertexCount; ++index4) { ref Vector3 local1 = ref vector3Array5[index4]; local1 = Vector3.op_Addition(local1, Vector3.op_Multiply(vector3Array8[index4], num4)); ref Vector3 local2 = ref vector3Array6[index4]; local2 = Vector3.op_Addition(local2, Vector3.op_Multiply(vector3Array9[index4], num4)); } } } } } if (this.bakedWorldNormals == null || this.bakedWorldNormals.Length != vertexCount) return; Vector3[] vector3Array10 = new Vector3[vertexCount]; bool flag = this.bakedWorldTangents != null && this.bakedWorldTangents.Length == vertexCount; Vector4[] vector4Array = flag ? new Vector4[vertexCount] : (Vector4[])null; for (int vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex) { Vector3 vector3_1 = skinningUtil.WorldDirToBindDir_Full(this.smr, editableMesh, vertexIndex, this.bakedWorldNormals[vertexIndex]); if (vector3Array5 != null) vector3_1 = Vector3.op_Subtraction(vector3_1, vector3Array5[vertexIndex]); vector3Array10[vertexIndex] = ((Vector3)ref vector3_1).normalized; if (flag) { Vector3 targetWorldDir; // ISSUE: explicit constructor call ((Vector3)ref targetWorldDir).\u002Ector(this.bakedWorldTangents[vertexIndex].x, this.bakedWorldTangents[vertexIndex].y, this.bakedWorldTangents[vertexIndex].z); Vector3 vector3_2 = skinningUtil.WorldDirToBindDir_Full(this.smr, editableMesh, vertexIndex, targetWorldDir); if (vector3Array6 != null) vector3_2 = Vector3.op_Subtraction(vector3_2, vector3Array6[vertexIndex]); vector3_2 = ((Vector3)ref vector3_2).normalized; vector4Array[vertexIndex] = new Vector4(vector3_2.x, vector3_2.y, vector3_2.z, this.bakedWorldTangents[vertexIndex].w); } } editableMesh.normals = vector3Array10; if (vector4Array == null) return; editableMesh.tangents = vector4Array; } public void BuildEquivalentVerticesFromWorld(float maxDistance = 1E-05f) { if (this.worldVertices == null || this.worldVertices.Length == 0) { Debug.LogWarning((object)"[ClothInstance] BuildEquivalentVerticesFromWorld: worldVertices is null or empty. Call UpdateWorldVertices() first."); } else { int length = this.worldVertices.Length; if (this.equivalentVertices == null) this.equivalentVertices = new List>(); else this.equivalentVertices.Clear(); float num1 = maxDistance; float num2 = maxDistance * maxDistance; Dictionary> dictionary1 = new Dictionary>(); for (int index = 0; index < length; ++index) { Vector3 worldVertex = this.worldVertices[index]; Vector3Int key; // ISSUE: explicit constructor call ((Vector3Int)ref key).\u002Ector(Mathf.FloorToInt(worldVertex.x / num1), Mathf.FloorToInt(worldVertex.y / num1), Mathf.FloorToInt(worldVertex.z / num1)); List intList; if (!dictionary1.TryGetValue(key, out intList)) { intList = new List(); dictionary1[key] = intList; } intList.Add(index); } foreach (KeyValuePair> keyValuePair in dictionary1) { List intList1 = keyValuePair.Value; int count = intList1.Count; if (count >= 2) { int[] parent = new int[count]; for (int index = 0; index < count; ++index) parent[index] = index; for (int index1 = 0; index1 < count; ++index1) { Vector3 worldVertex1 = this.worldVertices[intList1[index1]]; for (int index2 = index1 + 1; index2 < count; ++index2) { Vector3 worldVertex2 = this.worldVertices[intList1[index2]]; Vector3 vector3 = Vector3.op_Subtraction(worldVertex1, worldVertex2); if ((double)((Vector3)ref vector3).sqrMagnitude <= (double)num2) Union(index1, index2); } } Dictionary> dictionary2 = new Dictionary>(); for (int index = 0; index < count; ++index) { int key = Find(index); List intList2; if (!dictionary2.TryGetValue(key, out intList2)) { intList2 = new List(); dictionary2[key] = intList2; } intList2.Add(intList1[index]); } foreach (List intList3 in dictionary2.Values) { if (intList3.Count >= 2) this.equivalentVertices.Add(intList3); } int Find(int x) { if (parent[x] != x) parent[x] = Find(parent[x]); return parent[x]; } void Union(int a, int b) { int num = Find(a); int index = Find(b); if (num == index) return; parent[index] = num; } } } } } ~ClothInstance() => this.Dispose(); public void Dispose() { if (Object.op_Inequality((Object)this.bakedMesh, (Object)null)) { Object.DestroyImmediate((Object)this.bakedMesh); this.bakedMesh = (Mesh)null; } this.worldVertices = (Vector3[])null; this.minDistanceVector = (Vector3[])null; this.minDistance = (float[])null; this.deltas = (Vector3[])null; this.deltasLocal = (Vector3[])null; this.isInsideVertex = (bool[])null; this.excludedVertices = (bool[])null; this.isLeftLegVertex = (bool[])null; this.isRightLegVertex = (bool[])null; this.vertexAdjacency = (List[])null; if (this.equivalentVertices != null) { for (int index = 0; index < this.equivalentVertices.Count; ++index) this.equivalentVertices[index]?.Clear(); this.equivalentVertices.Clear(); this.equivalentVertices = (List>)null; } this.humanoidMatchedBones = (Dictionary>)null; this.smr = (SkinnedMeshRenderer)null; this.editableMesh = (Mesh)null; } } }