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

519 lines
28 KiB
C#

// 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<int>[] vertexAdjacency;
public List<List<int>> equivalentVertices;
public bool[] isInsideVertex;
public bool[] excludedVertices;
public bool[] isLeftLegVertex;
public bool[] isRightLegVertex;
public Vector3[] bakedWorldNormals;
public Vector4[] bakedWorldTangents;
public Dictionary<HumanBodyBones, HashSet<Transform>> humanoidMatchedBones;
public ClothInstance(SkinnedMeshRenderer clotheSMR, bool duplicateMesh = true)
{
this.smr = clotheSMR;
if (duplicateMesh)
{
string name = ((Object)this.smr.sharedMesh).name;
this.editableMesh = Object.Instantiate<Mesh>(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<HumanBodyBones, HashSet<Transform>>();
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<int>[] 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<int>[] adj = new List<int>[length];
for (int index = 0; index < length; ++index)
adj[index] = new List<int>();
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<Vector3Int, List<int>> dictionary = new Dictionary<Vector3Int, List<int>>();
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<int> intList;
if (!dictionary.TryGetValue(key, out intList))
{
intList = new List<int>();
dictionary[key] = intList;
}
intList.Add(index);
}
foreach (KeyValuePair<Vector3Int, List<int>> keyValuePair in dictionary)
{
Vector3Int key1 = keyValuePair.Key;
List<int> 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<int> 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<Vector3Int, List<int>> dictionary = new Dictionary<Vector3Int, List<int>>();
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<int> intList;
if (!dictionary.TryGetValue(key, out intList))
{
intList = new List<int>();
dictionary[key] = intList;
}
intList.Add(index);
}
foreach (KeyValuePair<Vector3Int, List<int>> keyValuePair in dictionary)
{
Vector3Int key3 = keyValuePair.Key;
List<int> 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<int> 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<int>[] adj, int from, int to)
{
List<int> 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<List<int>>();
else
this.equivalentVertices.Clear();
float num1 = maxDistance;
float num2 = maxDistance * maxDistance;
Dictionary<Vector3Int, List<int>> dictionary1 = new Dictionary<Vector3Int, List<int>>();
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<int> intList;
if (!dictionary1.TryGetValue(key, out intList))
{
intList = new List<int>();
dictionary1[key] = intList;
}
intList.Add(index);
}
foreach (KeyValuePair<Vector3Int, List<int>> keyValuePair in dictionary1)
{
List<int> 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<int, List<int>> dictionary2 = new Dictionary<int, List<int>>();
for (int index = 0; index < count; ++index)
{
int key = Find(index);
List<int> intList2;
if (!dictionary2.TryGetValue(key, out intList2))
{
intList2 = new List<int>();
dictionary2[key] = intList2;
}
intList2.Add(intList1[index]);
}
foreach (List<int> 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<int>[])null;
if (this.equivalentVertices != null)
{
for (int index = 0; index < this.equivalentVertices.Count; ++index)
this.equivalentVertices[index]?.Clear();
this.equivalentVertices.Clear();
this.equivalentVertices = (List<List<int>>)null;
}
this.humanoidMatchedBones = (Dictionary<HumanBodyBones, HashSet<Transform>>)null;
this.smr = (SkinnedMeshRenderer)null;
this.editableMesh = (Mesh)null;
}
}
}