// Decompiled with JetBrains decompiler // Type: Eden.AutoMorpher.ClothInstanceTotal // 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 ClothInstanceTotal { private readonly List clothInstances; public int TotalVertexCount { get; private set; } public Vector3[] GlobalPositions { get; private set; } public Vector3[] GlobalDeltas { get; private set; } public List[] GlobalAdjacencyTopology { get; private set; } public List[] GlobalAdjacencyDistance { get; private set; } public List[] GlobalAdjacencyMerged { get; private set; } public int[] VertexOffsets { get; private set; } public ClothInstanceTotal( List clothInstances, float distanceBuildRadius, int maxNeighborsPerVertex = 0) { if (clothInstances == null || clothInstances.Count == 0) throw new AutoMorpherException("Cloth Instances are Missing", "[ClothInstanceTotal] ClothInstanceTotal\n - clothInstances is null or empty"); if ((double)distanceBuildRadius <= 0.0) throw new AutoMorpherException("Distance Build Radius is Invalid", "[ClothInstanceTotal] ClothInstanceTotal\n - distanceBuildRadius must be > 0"); this.clothInstances = clothInstances; this.BuildTopologyCache(); this.BuildDistanceAdjacencyCandidates(distanceBuildRadius, maxNeighborsPerVertex); this.BuildMergedAdjacency(); } public void SetGlobalDeltas(Vector3[] globalDeltas) { if (globalDeltas == null || globalDeltas.Length != this.TotalVertexCount) throw new AutoMorpherException("Global Deltas are Invalid", "[ClothInstanceTotal] SetGlobalDeltas\n - globalDeltas is null or length mismatch"); this.GlobalDeltas = globalDeltas; } public void UpdateGlobalBuffersFromClothInstances() { this.ValidateGlobalBufferReady("[ClothInstanceTotal] UpdateGlobalBuffersFromClothInstances"); for (int index1 = 0; index1 < this.clothInstances.Count; ++index1) { ClothInstance clothInstance = this.clothInstances[index1]; if (clothInstance != null) { if (clothInstance.worldVertices == null || clothInstance.deltasLocal == null) throw new AutoMorpherException("Cloth Instance Data is Missing", "[ClothInstanceTotal] UpdateGlobalBuffersFromClothInstances\n - worldVertices or deltasLocal is null"); int vertexOffset = this.VertexOffsets[index1]; int length = clothInstance.worldVertices.Length; if (length != clothInstance.deltasLocal.Length) throw new AutoMorpherException("Cloth Instance Array Length Mismatch", "[ClothInstanceTotal] UpdateGlobalBuffersFromClothInstances\n - worldVertices.Length != deltasLocal.Length"); for (int index2 = 0; index2 < length; ++index2) { this.GlobalPositions[vertexOffset + index2] = clothInstance.worldVertices[index2]; this.GlobalDeltas[vertexOffset + index2] = clothInstance.deltasLocal[index2]; } } } } public void ApplyGlobalDeltasToClothInstances() { this.ValidateGlobalBufferReady("[ClothInstanceTotal] ApplyGlobalDeltasToClothInstances"); for (int index1 = 0; index1 < this.clothInstances.Count; ++index1) { ClothInstance clothInstance = this.clothInstances[index1]; if (clothInstance != null) { if (clothInstance.deltasLocal == null) throw new AutoMorpherException("Cloth Deltas are Missing", "[ClothInstanceTotal] ApplyGlobalDeltasToClothInstances\n - deltasLocal is null"); int vertexOffset = this.VertexOffsets[index1]; int length = clothInstance.deltasLocal.Length; for (int index2 = 0; index2 < length; ++index2) clothInstance.deltasLocal[index2] = this.GlobalDeltas[vertexOffset + index2]; } } } private void ValidateGlobalBufferReady(string functionContext) { if (this.clothInstances == null || this.clothInstances.Count == 0) throw new AutoMorpherException("Cloth Instances are Missing", functionContext + "\n - clothInstances is null or empty"); if (this.TotalVertexCount <= 0 || this.GlobalPositions == null || this.GlobalDeltas == null || this.VertexOffsets == null || this.GlobalAdjacencyMerged == null) throw new AutoMorpherException("Cloth Instance Total Cache is Not Ready", functionContext + "\n - total/global buffers/merged adjacency are not initialized"); } private void BuildTopologyCache() { this.TotalVertexCount = this.CalculateTotalVertexCount(this.clothInstances); this.GlobalPositions = this.TotalVertexCount > 0 ? new Vector3[this.TotalVertexCount] : throw new AutoMorpherException("Total Vertex Count is Zero", "[ClothInstanceTotal] BuildTopologyCache\n - TotalVertexCount <= 0"); this.GlobalDeltas = new Vector3[this.TotalVertexCount]; this.GlobalAdjacencyTopology = new List[this.TotalVertexCount]; this.VertexOffsets = new int[this.clothInstances.Count]; int num1 = 0; for (int index1 = 0; index1 < this.clothInstances.Count; ++index1) { ClothInstance clothInstance = this.clothInstances[index1]; this.VertexOffsets[index1] = num1; if (clothInstance != null) { if (clothInstance.worldVertices == null || clothInstance.deltasLocal == null || clothInstance.vertexAdjacency == null) throw new AutoMorpherException("Cloth Instance Data is Missing", "[ClothInstanceTotal] BuildTopologyCache\n - worldVertices/deltasLocal/vertexAdjacency is null"); int length = clothInstance.worldVertices.Length; if (length != clothInstance.deltasLocal.Length || length != clothInstance.vertexAdjacency.Length) throw new AutoMorpherException("Cloth Instance Array Length Mismatch", "[ClothInstanceTotal] BuildTopologyCache\n - worldVertices/deltasLocal/vertexAdjacency lengths differ"); for (int index2 = 0; index2 < length; ++index2) { this.GlobalPositions[num1 + index2] = clothInstance.worldVertices[index2]; this.GlobalDeltas[num1 + index2] = clothInstance.deltasLocal[index2]; List intList = clothInstance.vertexAdjacency[index2]; // ISSUE: explicit non-virtual call int count = intList != null ? __nonvirtual(intList.Count) : 0; this.GlobalAdjacencyTopology[num1 + index2] = new List(count); } for (int index3 = 0; index3 < length; ++index3) { List intList1 = clothInstance.vertexAdjacency[index3]; if (intList1 != null) { List intList2 = this.GlobalAdjacencyTopology[num1 + index3]; for (int index4 = 0; index4 < intList1.Count; ++index4) { int num2 = intList1[index4]; if ((uint)num2 >= (uint)length) throw new AutoMorpherException("Vertex Adjacency Index is Out of Range", "[ClothInstanceTotal] BuildTopologyCache\n - vertexAdjacency contains invalid neighbor index"); intList2.Add(num1 + num2); } } } num1 += length; } } } private void BuildDistanceAdjacencyCandidates(float radius, int maxNeighborsPerVertex) { if (this.GlobalPositions == null || this.GlobalPositions.Length == 0) throw new AutoMorpherException("Reference Positions are Missing", "[ClothInstanceTotal] BuildDistanceAdjacencyCandidates\n - GlobalPositions is null or empty"); this.GlobalAdjacencyDistance = this.BuildDistanceAdjacencyCandidatesInternal(this.GlobalPositions, radius, maxNeighborsPerVertex); } private void BuildMergedAdjacency() { if (this.GlobalAdjacencyTopology == null || this.GlobalAdjacencyDistance == null) throw new AutoMorpherException("Adjacency Inputs are Missing", "[ClothInstanceTotal] BuildMergedAdjacency\n - GlobalAdjacencyTopology or GlobalAdjacencyDistance is null"); if (this.GlobalAdjacencyTopology.Length != this.GlobalAdjacencyDistance.Length) throw new AutoMorpherException("Adjacency Length Mismatch", "[ClothInstanceTotal] BuildMergedAdjacency\n - topology and distance adjacency length differ"); int length = this.GlobalAdjacencyTopology.Length; this.GlobalAdjacencyMerged = new List[length]; for (int index1 = 0; index1 < length; ++index1) { List intList1 = this.GlobalAdjacencyTopology[index1]; // ISSUE: explicit non-virtual call int count1 = intList1 != null ? __nonvirtual(intList1.Count) : 0; List intList2 = this.GlobalAdjacencyDistance[index1]; // ISSUE: explicit non-virtual call int count2 = intList2 != null ? __nonvirtual(intList2.Count) : 0; List intList3 = new List(count1 + count2); HashSet intSet = new HashSet(); List intList4 = this.GlobalAdjacencyTopology[index1]; if (intList4 != null) { for (int index2 = 0; index2 < intList4.Count; ++index2) { int num = intList4[index2]; if (num != index1 && intSet.Add(num)) intList3.Add(num); } } List intList5 = this.GlobalAdjacencyDistance[index1]; if (intList5 != null) { for (int index3 = 0; index3 < intList5.Count; ++index3) { int num = intList5[index3]; if (num != index1 && intSet.Add(num)) intList3.Add(num); } } this.GlobalAdjacencyMerged[index1] = intList3; } } private int CalculateTotalVertexCount(List clothInstances) { int totalVertexCount = 0; for (int index = 0; index < clothInstances.Count; ++index) { ClothInstance clothInstance = clothInstances[index]; if (clothInstance != null && clothInstance.worldVertices != null) totalVertexCount += clothInstance.worldVertices.Length; } return totalVertexCount; } private List[] BuildDistanceAdjacencyCandidatesInternal( Vector3[] referencePositions, float radius, int maxNeighborsPerVertex) { if (referencePositions == null || referencePositions.Length == 0) throw new AutoMorpherException("Reference Positions are Missing", "[ClothInstanceTotal] BuildDistanceAdjacencyCandidatesInternal\n - referencePositions is null or empty"); if ((double)radius <= 0.0) throw new AutoMorpherException("Radius is Invalid", "[ClothInstanceTotal] BuildDistanceAdjacencyCandidatesInternal\n - radius must be > 0"); int length = referencePositions.Length; List[] intListArray = new List[length]; for (int index = 0; index < length; ++index) intListArray[index] = new List(8); float num1 = 1f / Mathf.Max(radius, 1E-12f); float num2 = radius * radius; Dictionary> dictionary = new Dictionary>(length); for (int index = 0; index < length; ++index) { Vector3 referencePosition = referencePositions[index]; Vector3Int key; // ISSUE: explicit constructor call ((Vector3Int)ref key).\u002Ector(Mathf.FloorToInt(referencePosition.x * num1), Mathf.FloorToInt(referencePosition.y * num1), Mathf.FloorToInt(referencePosition.z * num1)); List intList; if (!dictionary.TryGetValue(key, out intList)) { intList = new List(16 /*0x10*/); dictionary.Add(key, intList); } intList.Add(index); } for (int index1 = 0; index1 < length; ++index1) { Vector3 referencePosition = referencePositions[index1]; Vector3Int vector3Int; // ISSUE: explicit constructor call ((Vector3Int)ref vector3Int).\u002Ector(Mathf.FloorToInt(referencePosition.x * num1), Mathf.FloorToInt(referencePosition.y * num1), Mathf.FloorToInt(referencePosition.z * num1)); List intList1 = intListArray[index1]; for (int index2 = -1; index2 <= 1; ++index2) { for (int index3 = -1; index3 <= 1; ++index3) { for (int index4 = -1; index4 <= 1; ++index4) { Vector3Int key; // ISSUE: explicit constructor call ((Vector3Int)ref key).\u002Ector(((Vector3Int)ref vector3Int).x + index2, ((Vector3Int)ref vector3Int).y + index3, ((Vector3Int)ref vector3Int).z + index4); List intList2; if (dictionary.TryGetValue(key, out intList2)) { for (int index5 = 0; index5 < intList2.Count; ++index5) { int index6 = intList2[index5]; if (index6 != index1) { Vector3 vector3 = Vector3.op_Subtraction(referencePositions[index6], referencePosition); if ((double)((Vector3)ref vector3).sqrMagnitude <= (double)num2) { intList1.Add(index6); if (maxNeighborsPerVertex > 0 && intList1.Count >= maxNeighborsPerVertex) break; } } } if (maxNeighborsPerVertex > 0 && intList1.Count >= maxNeighborsPerVertex) break; } } } } } return intListArray; } } }