// Decompiled with JetBrains decompiler // Type: Eden.AutoMorpher.VertexFittingUtil // 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 System.Diagnostics; using UnityEngine; namespace Eden.AutoMorpher { public class VertexFittingUtil { public void ExpandClothes_World_Test( List clothInstances, MeshMatcher meshMatcher, EdenAutoMorpherConfig config, ClothInstanceTotal clothInstanceTotal) { using (AutoMorpherDev.Profile("[Expand] BVH Mesh Matching time")) { foreach (ClothInstance clothInstance in clothInstances) clothInstance.deltas = meshMatcher.ExpandVertexMatch(clothInstance, config.minMargin, config.skipFootFitting); } foreach (ClothInstance clothInstance in clothInstances) clothInstance.deltasLocal = clothInstance.deltas; Vector3[] globalDeltas = clothInstanceTotal.GlobalDeltas; clothInstanceTotal.UpdateGlobalBuffersFromClothInstances(); this.SmoothDeltasByDistance(clothInstanceTotal.GlobalPositions, ref globalDeltas, clothInstanceTotal.GlobalAdjacencyMerged, config.worldRadius, 1, config.smoothingIteration, gaussianSigma: config.sigma); clothInstanceTotal.SetGlobalDeltas(globalDeltas); clothInstanceTotal.ApplyGlobalDeltasToClothInstances(); foreach (ClothInstance clothInstance in clothInstances) { for (int index = 0; index < clothInstance.worldVertices.Length; ++index) { if (!clothInstance.excludedVertices[index] || !clothInstance.isInsideVertex[index]) { ref Vector3 local = ref clothInstance.worldVertices[index]; local = Vector3.op_Addition(local, clothInstance.deltasLocal[index]); } clothInstance.deltasLocal[index] = Vector3.zero; } foreach (List equivalentVertex in clothInstance.equivalentVertices) { Vector3 vector3_1 = Vector3.zero; for (int index = 0; index < equivalentVertex.Count; ++index) vector3_1 = Vector3.op_Addition(vector3_1, clothInstance.worldVertices[equivalentVertex[index]]); Vector3 vector3_2 = Vector3.op_Division(vector3_1, (float)equivalentVertex.Count); for (int index = 0; index < equivalentVertex.Count; ++index) clothInstance.worldVertices[equivalentVertex[index]] = vector3_2; } } } public void ShrinkClothes_World_Test( List clothInstances, MeshMatcher meshMatcher, EdenAutoMorpherConfig config, ClothInstanceTotal clothInstanceTotal) { using (AutoMorpherDev.Profile("[Expand] BVH Mesh Matching time")) { foreach (ClothInstance clothInstance in clothInstances) clothInstance.deltas = meshMatcher.ShrinkVertexMatch(clothInstance, config.minMargin); } foreach (ClothInstance clothInstance in clothInstances) clothInstance.deltasLocal = clothInstance.deltas; Vector3[] globalDeltas = clothInstanceTotal.GlobalDeltas; clothInstanceTotal.UpdateGlobalBuffersFromClothInstances(); this.SmoothDeltasByDistance(clothInstanceTotal.GlobalPositions, ref globalDeltas, clothInstanceTotal.GlobalAdjacencyMerged, config.worldRadius, iterations: config.smoothingIteration, gaussianSigma: config.sigma); clothInstanceTotal.SetGlobalDeltas(globalDeltas); clothInstanceTotal.ApplyGlobalDeltasToClothInstances(); this.SmoothAllClothesDeltasByDistance(clothInstances, config.worldRadius, config.smoothingIteration, config.sigma); foreach (ClothInstance clothInstance in clothInstances) { for (int index = 0; index < clothInstance.worldVertices.Length; ++index) { if (!clothInstance.excludedVertices[index] || !clothInstance.isInsideVertex[index]) { ref Vector3 local = ref clothInstance.worldVertices[index]; local = Vector3.op_Addition(local, clothInstance.deltasLocal[index]); } clothInstance.deltasLocal[index] = Vector3.zero; } foreach (List equivalentVertex in clothInstance.equivalentVertices) { Vector3 vector3_1 = Vector3.zero; for (int index = 0; index < equivalentVertex.Count; ++index) vector3_1 = Vector3.op_Addition(vector3_1, clothInstance.worldVertices[equivalentVertex[index]]); Vector3 vector3_2 = Vector3.op_Division(vector3_1, (float)equivalentVertex.Count); for (int index = 0; index < equivalentVertex.Count; ++index) clothInstance.worldVertices[equivalentVertex[index]] = vector3_2; } } } public void ExpandClothes_World( ClothInstance clothInstance, List clothInstances, MeshMatcher meshMatcher, EdenAutoMorpherConfig config, float fittingRadius) { if (AutoMorpherDev.isDeveloperMode) Debug.Log((object)$"[Expand] Start {((Object)((Component)clothInstance.smr).gameObject).name}//==============================================================================================================="); Stopwatch stopwatch1 = AutoMorpherDev.isDeveloperMode ? Stopwatch.StartNew() : (Stopwatch)null; Stopwatch.StartNew(); using (AutoMorpherDev.Profile("[Expand] BVH Mesh Matching time")) clothInstance.deltas = meshMatcher.ExpandVertexMatch(clothInstance, config.minMargin, config.skipFootFitting); List intList = (List)null; using (AutoMorpherDev.Profile("[Expand] Select Anchors time")) intList = this.SelectAnchors(clothInstance, fittingRadius); if (AutoMorpherDev.isDeveloperMode) Debug.Log((object)$"[Expand] Anchor Count {intList.Count}"); if (intList.Count == 0) { if (!AutoMorpherDev.isDeveloperMode) return; stopwatch1.Stop(); Debug.Log((object)$"[Expand] TOTAL ShrinkClothes time: {stopwatch1.ElapsedMilliseconds} ms"); Debug.Log((object)$"[Expand] End {((Object)((Component)clothInstance.smr).gameObject).name}//==============================================================================================================="); } else { Stopwatch stopwatch2 = AutoMorpherDev.isDeveloperMode ? Stopwatch.StartNew() : (Stopwatch)null; float num1 = 0.0f; float num2 = 0.0f; VertexMoverUtil vertexMoverUtil = new VertexMoverUtil(); foreach (int targetVertexIdx in intList) { if (!clothInstance.excludedVertices[targetVertexIdx]) { Stopwatch stopwatch3 = AutoMorpherDev.isDeveloperMode ? Stopwatch.StartNew() : (Stopwatch)null; if (AutoMorpherDev.isDeveloperMode) { Debug.Log((object)$"[Expand] Selected Expand Vertes: {((Object)((Component)clothInstance.smr).gameObject).name} / {targetVertexIdx}"); Debug.Log((object)$"[Expand] SelectedCEnter {targetVertexIdx} {clothInstance.deltas[targetVertexIdx]} {clothInstance.worldVertices[targetVertexIdx]}"); } Vector3[] vector3Array1 = vertexMoverUtil.MoveVertices(clothInstance, targetVertexIdx, clothInstance.isLeftLegVertex[targetVertexIdx], clothInstance.isRightLegVertex[targetVertexIdx], fittingRadius, config.sigma, clothInstance.deltas[targetVertexIdx]); if (vector3Array1 == null) { if (AutoMorpherDev.isDeveloperMode) { stopwatch3.Stop(); num1 += (float)stopwatch3.ElapsedMilliseconds; } } else { for (int index = 0; index < clothInstance.worldVertices.Length && index < vector3Array1.Length; ++index) { if (Vector3.op_Inequality(vector3Array1[index], Vector3.zero)) { ref Vector3 local = ref clothInstance.deltasLocal[index]; local = Vector3.op_Addition(local, vector3Array1[index]); } } if (AutoMorpherDev.isDeveloperMode) { stopwatch3.Stop(); num1 += (float)stopwatch3.ElapsedMilliseconds; } Stopwatch stopwatch4 = AutoMorpherDev.isDeveloperMode ? Stopwatch.StartNew() : (Stopwatch)null; using (List.Enumerator enumerator = clothInstances.GetEnumerator()) { label_38: while (enumerator.MoveNext()) { ClothInstance current = enumerator.Current; if (current != clothInstance) { Vector3[] vector3Array2 = vertexMoverUtil.MoveVertices(current, clothInstance.worldVertices[targetVertexIdx], clothInstance.isLeftLegVertex[targetVertexIdx], clothInstance.isRightLegVertex[targetVertexIdx], fittingRadius, config.sigma, clothInstance.deltas[targetVertexIdx]); if (vector3Array2 != null) { int index = 0; while (true) { if (index < current.worldVertices.Length && index < vector3Array2.Length) { if (Vector3.op_Inequality(vector3Array2[index], Vector3.zero)) { ref Vector3 local = ref current.deltasLocal[index]; local = Vector3.op_Addition(local, vector3Array2[index]); } ++index; } else goto label_38; } } } } } if (AutoMorpherDev.isDeveloperMode) { stopwatch4.Stop(); num2 += (float)stopwatch4.ElapsedMilliseconds; } } } } this.SmoothAllClothesDeltasByDistance(clothInstances, fittingRadius, config.smoothingIteration, config.sigma); foreach (ClothInstance clothInstance1 in clothInstances) { for (int index = 0; index < clothInstance1.worldVertices.Length; ++index) { if (!clothInstance1.excludedVertices[index]) { ref Vector3 local = ref clothInstance1.worldVertices[index]; local = Vector3.op_Addition(local, clothInstance1.deltasLocal[index]); } clothInstance1.deltasLocal[index] = Vector3.zero; } foreach (List equivalentVertex in clothInstance1.equivalentVertices) { Vector3 vector3_1 = Vector3.zero; for (int index = 0; index < equivalentVertex.Count; ++index) vector3_1 = Vector3.op_Addition(vector3_1, clothInstance1.worldVertices[equivalentVertex[index]]); Vector3 vector3_2 = Vector3.op_Division(vector3_1, (float)equivalentVertex.Count); for (int index = 0; index < equivalentVertex.Count; ++index) clothInstance1.worldVertices[equivalentVertex[index]] = vector3_2; } } if (!AutoMorpherDev.isDeveloperMode) return; stopwatch2.Stop(); Debug.Log((object)$"[Expand] Renderer Move Vector Calculate: {((Object)((Component)clothInstance.smr).gameObject).name} : {num1}"); Debug.Log((object)$"[Expand] Other Renderer Move Vector Calculate: {((Object)((Component)clothInstance.smr).gameObject).name} : {num2}"); Debug.Log((object)$"[Expand] Total Move Vector Calculate: {((Object)((Component)clothInstance.smr).gameObject).name} : {stopwatch2.ElapsedMilliseconds}"); stopwatch1.Stop(); Debug.Log((object)$"[Expand] TOTAL ShrinkClothes time: {stopwatch1.ElapsedMilliseconds} ms"); Debug.Log((object)$"[Expand] End {((Object)((Component)clothInstance.smr).gameObject).name}//==============================================================================================================="); } } public void ShrinkClothes_World( ClothInstance clothInstance, List clothInstances, MeshMatcher meshMatcher, EdenAutoMorpherConfig config, float fittingRadius) { if (AutoMorpherDev.isDeveloperMode) Debug.Log((object)$"[Shrink] Start {((Object)((Component)clothInstance.smr).gameObject).name}//==============================================================================================================="); Stopwatch stopwatch1 = AutoMorpherDev.isDeveloperMode ? Stopwatch.StartNew() : (Stopwatch)null; using (AutoMorpherDev.Profile("[Shrink] BVH Mesh Matching time")) clothInstance.deltas = meshMatcher.ShrinkVertexMatch(clothInstance, config.minMargin); List intList = (List)null; using (AutoMorpherDev.Profile("[Shrink] Select Anchors time")) intList = this.SelectAnchors(clothInstance, fittingRadius); if (AutoMorpherDev.isDeveloperMode) Debug.Log((object)$"[Shrink] Anchor Count {intList.Count}"); if (intList.Count == 0) { if (!AutoMorpherDev.isDeveloperMode) return; stopwatch1.Stop(); Debug.Log((object)$"[Shrink] TOTAL ShrinkClothes time: {stopwatch1.ElapsedMilliseconds} ms"); Debug.Log((object)$"[Shrink] End {((Object)((Component)clothInstance.smr).gameObject).name}//==============================================================================================================="); } else { Stopwatch stopwatch2 = AutoMorpherDev.isDeveloperMode ? Stopwatch.StartNew() : (Stopwatch)null; float num1 = 0.0f; float num2 = 0.0f; VertexMoverUtil vertexMoverUtil = new VertexMoverUtil(); foreach (int targetVertexIdx in intList) { if (!clothInstance.excludedVertices[targetVertexIdx]) { Stopwatch stopwatch3 = AutoMorpherDev.isDeveloperMode ? Stopwatch.StartNew() : (Stopwatch)null; if (AutoMorpherDev.isDeveloperMode) { Debug.Log((object)$"[Shrink] Selected Expand Vertes: {((Object)((Component)clothInstance.smr).gameObject).name} / {targetVertexIdx}"); Debug.Log((object)$"[Shrink] SelectedCEnter {targetVertexIdx} {clothInstance.deltas[targetVertexIdx]} {clothInstance.worldVertices[targetVertexIdx]}"); } Vector3[] vector3Array1 = vertexMoverUtil.MoveVertices(clothInstance, targetVertexIdx, clothInstance.isLeftLegVertex[targetVertexIdx], clothInstance.isRightLegVertex[targetVertexIdx], fittingRadius, config.sigma, clothInstance.deltas[targetVertexIdx]); if (vector3Array1 == null) { stopwatch3.Stop(); num1 += (float)stopwatch3.ElapsedMilliseconds; } else { for (int index = 0; index < clothInstance.worldVertices.Length && index < vector3Array1.Length; ++index) { if (Vector3.op_Inequality(vector3Array1[index], Vector3.zero)) { ref Vector3 local = ref clothInstance.deltasLocal[index]; local = Vector3.op_Addition(local, vector3Array1[index]); } } if (AutoMorpherDev.isDeveloperMode) { stopwatch3.Stop(); num1 += (float)stopwatch3.ElapsedMilliseconds; } Stopwatch stopwatch4 = AutoMorpherDev.isDeveloperMode ? Stopwatch.StartNew() : (Stopwatch)null; using (List.Enumerator enumerator = clothInstances.GetEnumerator()) { label_37: while (enumerator.MoveNext()) { ClothInstance current = enumerator.Current; if (current != clothInstance) { Vector3[] vector3Array2 = vertexMoverUtil.MoveVertices(current, clothInstance.worldVertices[targetVertexIdx], clothInstance.isLeftLegVertex[targetVertexIdx], clothInstance.isRightLegVertex[targetVertexIdx], fittingRadius, config.sigma, clothInstance.deltas[targetVertexIdx]); if (vector3Array2 != null) { int index = 0; while (true) { if (index < current.worldVertices.Length && index < vector3Array2.Length) { if (Vector3.op_Inequality(vector3Array2[index], Vector3.zero)) { ref Vector3 local = ref current.deltasLocal[index]; local = Vector3.op_Addition(local, vector3Array2[index]); } ++index; } else goto label_37; } } } } } if (AutoMorpherDev.isDeveloperMode) { stopwatch4.Stop(); num2 += (float)stopwatch4.ElapsedMilliseconds; } } } } this.SmoothAllClothesDeltasByDistance(clothInstances, fittingRadius, config.smoothingIteration, config.sigma); foreach (ClothInstance clothInstance1 in clothInstances) { for (int index = 0; index < clothInstance1.worldVertices.Length; ++index) { if (!clothInstance1.excludedVertices[index]) { ref Vector3 local = ref clothInstance1.worldVertices[index]; local = Vector3.op_Addition(local, clothInstance1.deltasLocal[index]); } clothInstance1.deltasLocal[index] = Vector3.zero; } foreach (List equivalentVertex in clothInstance1.equivalentVertices) { Vector3 vector3_1 = Vector3.zero; for (int index = 0; index < equivalentVertex.Count; ++index) vector3_1 = Vector3.op_Addition(vector3_1, clothInstance1.worldVertices[equivalentVertex[index]]); Vector3 vector3_2 = Vector3.op_Division(vector3_1, (float)equivalentVertex.Count); for (int index = 0; index < equivalentVertex.Count; ++index) clothInstance1.worldVertices[equivalentVertex[index]] = vector3_2; } } if (!AutoMorpherDev.isDeveloperMode) return; stopwatch2.Stop(); Debug.Log((object)$"[Shrink] Renderer Move Vector Calculate: {((Object)((Component)clothInstance.smr).gameObject).name} : {num1}"); Debug.Log((object)$"[Shrink] Other Renderer Move Vector Calculate: {((Object)((Component)clothInstance.smr).gameObject).name} : {num2}"); Debug.Log((object)$"[Shrink] Total Move Vector Calculate: {((Object)((Component)clothInstance.smr).gameObject).name} : {stopwatch2.ElapsedMilliseconds}"); stopwatch1.Stop(); Debug.Log((object)$"[Shrink] TOTAL ShrinkClothes time: {stopwatch1.ElapsedMilliseconds} ms"); Debug.Log((object)$"[Shrink] End {((Object)((Component)clothInstance.smr).gameObject).name}//==============================================================================================================="); } } public void ExpandFitClothes_World( ClothInstance clothInstance, List clothInstances, MeshMatcher meshMatcher, float worldRadius, float sigma, float minMargin) { Debug.Log((object)$"[Expand] {((Object)((Component)clothInstance.smr).gameObject).name}//==============================================================================================================="); Stopwatch stopwatch1 = Stopwatch.StartNew(); Stopwatch stopwatch2 = Stopwatch.StartNew(); clothInstance.deltas = meshMatcher.ExpandVertexMatch(clothInstance, minMargin); stopwatch2.Stop(); Debug.Log((object)$"[Expand] BVH Mesh Matching time: {stopwatch2.ElapsedMilliseconds} ms"); for (int index = 0; index < clothInstance.worldVertices.Length; ++index) { ref Vector3 local = ref clothInstance.worldVertices[index]; local = Vector3.op_Addition(local, clothInstance.deltas[index]); clothInstance.deltasLocal[index] = Vector3.zero; } foreach (List equivalentVertex in clothInstance.equivalentVertices) { Vector3 vector3_1 = Vector3.zero; for (int index = 0; index < equivalentVertex.Count; ++index) vector3_1 = Vector3.op_Addition(vector3_1, clothInstance.worldVertices[equivalentVertex[index]]); Vector3 vector3_2 = Vector3.op_Division(vector3_1, (float)equivalentVertex.Count); for (int index = 0; index < equivalentVertex.Count; ++index) clothInstance.worldVertices[equivalentVertex[index]] = vector3_2; } stopwatch1.Stop(); Debug.Log((object)$"[Expand] TOTAL ShrinkClothes time: {stopwatch1.ElapsedMilliseconds} ms"); Debug.Log((object)$"[Expand] {((Object)((Component)clothInstance.smr).gameObject).name}//==============================================================================================================="); } private List SelectAnchors( ClothInstance clothInstance, float worldRadius, float minDeltaSq = 1E-05f, float maxDelta = 0.1f) { List intList1 = new List(); List intList2 = new List(); int length = clothInstance.worldVertices.Length; for (int index = 0; index < length; ++index) { if (!clothInstance.isInsideVertex[index] && (double)((Vector3)ref clothInstance.deltas[index]).sqrMagnitude > (double)minDeltaSq) intList2.Add(index); } if (intList2.Count == 0) return intList1; intList2.Sort((Comparison)((a, b) => { float sqrMagnitude = ((Vector3)ref clothInstance.deltas[a]).sqrMagnitude; float num = ((Vector3)ref clothInstance.deltas[b]).sqrMagnitude - sqrMagnitude; if ((double)Mathf.Abs(num) <= 9.9999999747524271E-07) return clothInstance.minDistance[a].CompareTo(clothInstance.minDistance[b]); return (double)num <= 0.0 ? -1 : 1; })); float num1 = worldRadius * 2f; float num2 = num1 * num1; float cellSize = num1; Dictionary> dictionary = new Dictionary>(); foreach (int index1 in intList2) { Vector3Int cellIndex = GetCellIndex(clothInstance.worldVertices[index1]); bool flag = false; for (int index2 = -1; index2 <= 1 && !flag; ++index2) { for (int index3 = -1; index3 <= 1 && !flag; ++index3) { for (int index4 = -1; index4 <= 1 && !flag; ++index4) { Vector3Int key; // ISSUE: explicit constructor call ((Vector3Int)ref key).\u002Ector(((Vector3Int)ref cellIndex).x + index2, ((Vector3Int)ref cellIndex).y + index3, ((Vector3Int)ref cellIndex).z + index4); List intList3; if (dictionary.TryGetValue(key, out intList3)) { for (int index5 = 0; index5 < intList3.Count; ++index5) { int index6 = intList3[index5]; Vector3 vector3 = Vector3.op_Subtraction(clothInstance.worldVertices[index1], clothInstance.worldVertices[index6]); if ((double)((Vector3)ref vector3).sqrMagnitude < (double)num2) { flag = true; break; } } } } } } if (!flag) { intList1.Add(index1); List intList4; if (!dictionary.TryGetValue(cellIndex, out intList4)) { intList4 = new List(); dictionary[cellIndex] = intList4; } intList4.Add(index1); } } return intList1; Vector3Int GetCellIndex(Vector3 p) { return new Vector3Int(Mathf.FloorToInt(p.x / cellSize), Mathf.FloorToInt(p.y / cellSize), Mathf.FloorToInt(p.z / cellSize)); } } public void SmoothDeltasByDistance( Vector3[] positions, ref Vector3[] deltas, List[] adjacency, float radius, int maxDepth = 3, int iterations = 1, float smoothFactor = 0.5f, float gaussianSigma = -1f) { if (positions == null || deltas == null || adjacency == null || positions.Length != deltas.Length || positions.Length != adjacency.Length) return; int length = positions.Length; if (length == 0) return; if ((double)gaussianSigma <= 0.0) gaussianSigma = radius * 0.5f; float num1 = radius * radius; float num2 = 2f * gaussianSigma * gaussianSigma; Vector3[] vector3Array = new Vector3[length]; Queue nodeQueue1 = new Queue(); List intList1 = new List(32 /*0x20*/); int[] numArray = new int[length]; int num3 = 1; for (int index1 = 0; index1 < iterations; ++index1) { for (int index2 = 0; index2 < length; ++index2) { if (Vector3.op_Equality(deltas[index2], Vector3.zero)) { vector3Array[index2] = Vector3.zero; } else { intList1.Clear(); nodeQueue1.Clear(); ++num3; numArray[index2] = num3; Queue nodeQueue2 = nodeQueue1; VertexFittingUtil.Node node1 = new VertexFittingUtil.Node(); node1.index = index2; node1.depth = 0; VertexFittingUtil.Node node2 = node1; nodeQueue2.Enqueue(node2); Vector3 position1 = positions[index2]; Vector3 vector3_1; while (nodeQueue1.Count > 0) { VertexFittingUtil.Node node3 = nodeQueue1.Dequeue(); int index3 = node3.index; int depth = node3.depth; Vector3 position2 = positions[index3]; vector3_1 = Vector3.op_Subtraction(position2, position1); float sqrMagnitude = ((Vector3)ref vector3_1).sqrMagnitude; if (index3 != index2 && (double)sqrMagnitude <= (double)num1) intList1.Add(index3); if (depth < maxDepth) { List intList2 = adjacency[index3]; if (intList2 != null) { for (int index4 = 0; index4 < intList2.Count; ++index4) { int index5 = intList2[index4]; if (numArray[index5] != num3) { vector3_1 = Vector3.op_Subtraction(positions[index5], position2); if ((double)((Vector3)ref vector3_1).sqrMagnitude <= (double)num1) { numArray[index5] = num3; Queue nodeQueue3 = nodeQueue1; node1 = new VertexFittingUtil.Node(); node1.index = index5; node1.depth = depth + 1; VertexFittingUtil.Node node4 = node1; nodeQueue3.Enqueue(node4); } } } } } } if (intList1.Count == 0) { vector3Array[index2] = deltas[index2]; } else { Vector3 vector3_2 = Vector3.zero; float num4 = 0.0f; for (int index6 = 0; index6 < intList1.Count; ++index6) { int index7 = intList1[index6]; vector3_1 = Vector3.op_Subtraction(positions[index7], position1); float sqrMagnitude = ((Vector3)ref vector3_1).sqrMagnitude; if ((double)sqrMagnitude <= (double)num1) { float num5 = Mathf.Exp(-sqrMagnitude / num2); vector3_2 = Vector3.op_Addition(vector3_2, Vector3.op_Multiply(deltas[index7], num5)); num4 += num5; } } if ((double)num4 > 9.99999993922529E-09) { Vector3 vector3_3 = Vector3.op_Division(vector3_2, num4); vector3Array[index2] = Vector3.Lerp(deltas[index2], vector3_3, smoothFactor); } else vector3Array[index2] = deltas[index2]; } } } for (int index8 = 0; index8 < length; ++index8) deltas[index8] = vector3Array[index8]; } } public void SmoothAllClothesDeltasByDistance( List clothesInstances, float radius, int iterations = 1, float gaussianSigma = -1f, int maxDepth = 3, float smoothFactor = 0.5f) { if (clothesInstances == null || clothesInstances.Count == 0) return; int length1 = 0; for (int index = 0; index < clothesInstances.Count; ++index) { ClothInstance clothesInstance = clothesInstances[index]; if (clothesInstance != null && clothesInstance.worldVertices != null) length1 += clothesInstance.worldVertices.Length; } if (length1 == 0) return; Vector3[] positions = new Vector3[length1]; Vector3[] deltas = new Vector3[length1]; List[] adjacency = new List[length1]; int[] numArray = new int[clothesInstances.Count]; int num1 = 0; for (int index1 = 0; index1 < clothesInstances.Count; ++index1) { ClothInstance clothesInstance = clothesInstances[index1]; if (clothesInstance != null) { numArray[index1] = num1; Vector3[] worldVertices = clothesInstance.worldVertices; Vector3[] deltasLocal = clothesInstance.deltasLocal; List[] vertexAdjacency = clothesInstance.vertexAdjacency; int length2 = worldVertices.Length; for (int index2 = 0; index2 < length2; ++index2) { positions[num1 + index2] = worldVertices[index2]; deltas[num1 + index2] = deltasLocal[index2]; adjacency[num1 + index2] = new List(); } for (int index3 = 0; index3 < length2; ++index3) { List intList1 = vertexAdjacency[index3]; if (intList1 != null) { int index4 = num1 + index3; List intList2 = adjacency[index4]; for (int index5 = 0; index5 < intList1.Count; ++index5) { int num2 = intList1[index5]; int num3 = num1 + num2; intList2.Add(num3); } } } num1 += length2; } } this.SmoothDeltasByDistance(positions, ref deltas, adjacency, radius, maxDepth, iterations, smoothFactor, gaussianSigma); for (int index6 = 0; index6 < clothesInstances.Count; ++index6) { ClothInstance clothesInstance = clothesInstances[index6]; if (clothesInstance != null) { int num4 = numArray[index6]; int length3 = clothesInstance.deltasLocal.Length; for (int index7 = 0; index7 < length3; ++index7) clothesInstance.deltasLocal[index7] = deltas[num4 + index7]; } } } private struct Node { public int index; public int depth; } } }