681 lines
38 KiB
C#
681 lines
38 KiB
C#
// 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<ClothInstance> 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<int> 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<ClothInstance> 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<int> 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<ClothInstance> 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<int> intList = (List<int>)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<ClothInstance>.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<int> 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<ClothInstance> 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<int> intList = (List<int>)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<ClothInstance>.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<int> 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<ClothInstance> 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<int> 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<int> SelectAnchors(
|
|
ClothInstance clothInstance,
|
|
float worldRadius,
|
|
float minDeltaSq = 1E-05f,
|
|
float maxDelta = 0.1f)
|
|
{
|
|
List<int> intList1 = new List<int>();
|
|
List<int> intList2 = new List<int>();
|
|
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<int>)((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<Vector3Int, List<int>> dictionary = new Dictionary<Vector3Int, List<int>>();
|
|
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<int> 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<int> intList4;
|
|
if (!dictionary.TryGetValue(cellIndex, out intList4))
|
|
{
|
|
intList4 = new List<int>();
|
|
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<int>[] 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<VertexFittingUtil.Node> nodeQueue1 = new Queue<VertexFittingUtil.Node>();
|
|
List<int> intList1 = new List<int>(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<VertexFittingUtil.Node> 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<int> 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<VertexFittingUtil.Node> 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<ClothInstance> 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<int>[] adjacency = new List<int>[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<int>[] 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<int>();
|
|
}
|
|
for (int index3 = 0; index3 < length2; ++index3)
|
|
{
|
|
List<int> intList1 = vertexAdjacency[index3];
|
|
if (intList1 != null)
|
|
{
|
|
int index4 = num1 + index3;
|
|
List<int> 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;
|
|
}
|
|
}
|
|
}
|