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

1916 lines
72 KiB
C#

// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts,
// for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies.
// EdenAutoMorpherScript, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// Eden.AutoMorpher.WeightTransferUtil
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Eden.AutoMorpher;
using Unity.Collections;
using UnityEditor;
using UnityEngine;
public class WeightTransferUtil
{
[Serializable]
public class Settings
{
[Header("최근접 표면 매칭")]
public float maxDistance = 0.1f;
public float maxNormalAngleDeg = 35f;
public bool allowFlippedNormal = true;
[Header("추가 스무딩")]
public bool enableSmoothing = true;
public int smoothingIterations = 4;
[Range(0f, 1f)]
public float smoothingAlpha = 0.25f;
[Header("본 수 제한 & 임계값")]
public bool enforceFourBoneLimit = true;
public float tinyWeight = 0.0001f;
public bool weightInClothes;
}
private bool NameContainsAny(string lowerName, string[] patterns)
{
for (int i = 0; i < patterns.Length; i++)
{
if (lowerName.Contains(patterns[i]))
{
return true;
}
}
return false;
}
private bool IsBreastOrButtBone(Transform t)
{
if ((Object)(object)t == (Object)null)
{
return false;
}
string[] patterns = new string[6] { "breast", "boob", "bust", "oppai", "chichi", "mune" };
string[] patterns2 = new string[6] { "butt", "buttock", "buttox", "glute", "glutes", "gluteus" };
string lowerName = ((Object)t).name.ToLowerInvariant();
if (NameContainsAny(lowerName, patterns))
{
return true;
}
if (NameContainsAny(lowerName, patterns2))
{
return true;
}
return false;
}
public IEnumerator RetargetAndTransfer(ClothInstance cloth, Animator avatarAnimator, IReadOnlyList<SkinnedMeshRenderer> bodyMeshes, IReadOnlyList<Mesh> bodyBakedMeshes, int referenceBodyIndex = 0, Settings settings = null, Dictionary<Transform, ClothBoneType> boneTypeMap = null, Dictionary<Transform, Transform> bodyToClothesMap = null)
{
if (cloth == null || (Object)(object)cloth.smr == (Object)null || (Object)(object)cloth.editableMesh == (Object)null)
{
throw new AutoMorpherException("Cloth Instance is Invalid", "[WeightTransferUtil] RetargetAndTransfer\n - cloth is null or cloth.smr is null or cloth.editableMesh is null");
}
if (cloth.worldVertices == null || cloth.worldVertices.Length == 0)
{
throw new AutoMorpherException("Cloth World Vertices are Missing", "[WeightTransferUtil] RetargetAndTransfer\n - cloth.worldVertices is null or empty");
}
if ((Object)(object)cloth.bakedMesh == (Object)null)
{
throw new AutoMorpherException("Cloth Baked Mesh is Missing", "[WeightTransferUtil] RetargetAndTransfer\n - cloth.bakedMesh is null");
}
if ((Object)(object)avatarAnimator == (Object)null || !avatarAnimator.isHuman)
{
throw new AutoMorpherException("Avatar Animator is Invalid", "[WeightTransferUtil] RetargetAndTransfer\n - avatarAnimator is null or not a Humanoid");
}
if (bodyMeshes == null || bodyMeshes.Count == 0)
{
throw new AutoMorpherException("Body Meshes are Missing", "[WeightTransferUtil] RetargetAndTransfer\n - bodyMeshes is null or empty");
}
if (referenceBodyIndex < 0 || referenceBodyIndex >= bodyMeshes.Count)
{
referenceBodyIndex = 0;
}
SkinnedMeshRenderer bodyRefSmr = bodyMeshes[referenceBodyIndex];
if ((Object)(object)bodyRefSmr == (Object)null || (Object)(object)bodyRefSmr.sharedMesh == (Object)null)
{
throw new AutoMorpherException("Reference Body Mesh is Invalid", "[WeightTransferUtil] RetargetAndTransfer\n - bodyRefSmr is null or bodyRefSmr.sharedMesh is null\n - referenceBodyIndex : " + referenceBodyIndex);
}
if (settings == null)
{
settings = new Settings();
}
Transform[] accessoryBones = null;
float[,] accessoryWeights = null;
BoneWeight[] prevBoneWeights = null;
yield return null;
Transform[] bones;
Dictionary<Transform, int> accIndexByTransform;
float tiny;
if (boneTypeMap != null && (Object)(object)cloth.smr != (Object)null && (Object)(object)cloth.editableMesh != (Object)null)
{
bones = cloth.smr.bones;
if (bones != null && bones.Length != 0)
{
HashSet<Transform> value = null;
if (cloth.humanoidMatchedBones != null)
{
cloth.humanoidMatchedBones.TryGetValue((HumanBodyBones)10, out value);
}
HashSet<Transform> hashSet = new HashSet<Transform>();
foreach (Transform val in bones)
{
if (!((Object)(object)val == (Object)null) && boneTypeMap.TryGetValue(val, out var value2) && value2 == ClothBoneType.Accessory)
{
hashSet.Add(val);
}
}
if (value != null)
{
foreach (Transform item in value)
{
if (!((Object)(object)item == (Object)null) && Array.IndexOf(bones, item) >= 0)
{
hashSet.Add(item);
}
}
}
List<Transform> list = new List<Transform>();
accIndexByTransform = new Dictionary<Transform, int>();
foreach (Transform val2 in bones)
{
if (!((Object)(object)val2 == (Object)null) && hashSet.Contains(val2) && !IsBreastOrButtBone(val2) && !accIndexByTransform.ContainsKey(val2))
{
accIndexByTransform[val2] = list.Count;
list.Add(val2);
}
}
if (list.Count > 0)
{
accessoryBones = list.ToArray();
int vertexCount = cloth.editableMesh.vertexCount;
accessoryWeights = new float[vertexCount, accessoryBones.Length];
BoneWeight[] boneWeights = cloth.editableMesh.boneWeights;
if (boneWeights != null && boneWeights.Length == vertexCount)
{
tiny = 1E-06f;
for (int k = 0; k < vertexCount; k++)
{
BoneWeight val3 = boneWeights[k];
Acc(((BoneWeight)(ref val3)).boneIndex0, ((BoneWeight)(ref val3)).weight0, k);
Acc(((BoneWeight)(ref val3)).boneIndex1, ((BoneWeight)(ref val3)).weight1, k);
Acc(((BoneWeight)(ref val3)).boneIndex2, ((BoneWeight)(ref val3)).weight2, k);
Acc(((BoneWeight)(ref val3)).boneIndex3, ((BoneWeight)(ref val3)).weight3, k);
}
}
}
}
}
int bodyBoneCount = bodyRefSmr.bones.Length;
yield return null;
RetargetClothToAvatarSkeleton(cloth, avatarAnimator, bodyRefSmr, accessoryBones);
TransferFromBodyToCloth(avatarAnimator, cloth, bodyMeshes, bodyBakedMeshes, settings, accessoryBones, accessoryWeights, bodyBoneCount, prevBoneWeights);
if (settings.weightInClothes)
{
MoveBodyWeightsToClothesBones(cloth.smr, cloth.smr.sharedMesh, bodyToClothesMap, accessoryBones);
}
void Acc(int boneIndex, float w, int v)
{
if (!(w <= tiny) && boneIndex >= 0 && boneIndex < bones.Length)
{
Transform val4 = bones[boneIndex];
if (!((Object)(object)val4 == (Object)null) && accIndexByTransform.TryGetValue(val4, out var value3))
{
accessoryWeights[v, value3] += w;
}
}
}
}
private void RetargetClothToAvatarSkeleton(ClothInstance cloth, Animator avatarAnimator, SkinnedMeshRenderer bodyRefSmr, Transform[] accessoryBones = null)
{
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: Unknown result type (might be due to invalid IL or missing references)
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Invalid comparison between Unknown and I4
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
//IL_045a: Unknown result type (might be due to invalid IL or missing references)
//IL_045f: Unknown result type (might be due to invalid IL or missing references)
//IL_0443: Unknown result type (might be due to invalid IL or missing references)
//IL_0448: Unknown result type (might be due to invalid IL or missing references)
//IL_044a: Unknown result type (might be due to invalid IL or missing references)
//IL_044f: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
//IL_047c: Unknown result type (might be due to invalid IL or missing references)
//IL_0481: Unknown result type (might be due to invalid IL or missing references)
//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
//IL_0238: Unknown result type (might be due to invalid IL or missing references)
//IL_023d: Unknown result type (might be due to invalid IL or missing references)
//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
//IL_030e: Unknown result type (might be due to invalid IL or missing references)
//IL_0313: Unknown result type (might be due to invalid IL or missing references)
//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0303: Unknown result type (might be due to invalid IL or missing references)
//IL_04af: Unknown result type (might be due to invalid IL or missing references)
//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
SkinnedMeshRenderer smr = cloth.smr;
Mesh sharedMesh = cloth.smr.sharedMesh;
if ((Object)(object)sharedMesh == (Object)null)
{
throw new AutoMorpherException("Cloth Mesh is Missing", "[WeightTransferUtil] RetargetClothToAvatarSkeleton\n - clothMesh is null");
}
Transform[] bones = smr.bones;
Transform[] bones2 = bodyRefSmr.bones;
if (bones == null || bones.Length == 0 || bones2 == null || bones2.Length == 0)
{
throw new AutoMorpherException("Cloth or Target Bones are Missing", "[WeightTransferUtil] RetargetClothToAvatarSkeleton\n - clothBones is null/empty or targetBones is null/empty\n - clothBones.Length : " + ((bones == null) ? (-1) : bones.Length) + "\n - targetBones.Length : " + ((bones2 == null) ? (-1) : bones2.Length));
}
Matrix4x4 localToWorldMatrix = ((Component)smr).transform.localToWorldMatrix;
if (accessoryBones == null || accessoryBones.Length == 0)
{
Dictionary<Transform, HumanBodyBones> dictionary = new Dictionary<Transform, HumanBodyBones>();
foreach (KeyValuePair<HumanBodyBones, HashSet<Transform>> humanoidMatchedBone in cloth.humanoidMatchedBones)
{
HumanBodyBones key = humanoidMatchedBone.Key;
HashSet<Transform> value = humanoidMatchedBone.Value;
if (value == null)
{
continue;
}
foreach (Transform item in value)
{
if (!((Object)(object)item == (Object)null) && !dictionary.ContainsKey(item))
{
dictionary.Add(item, key);
}
}
}
Dictionary<HumanBodyBones, int> dictionary2 = new Dictionary<HumanBodyBones, int>();
Dictionary<Transform, int> dictionary3 = new Dictionary<Transform, int>();
for (int i = 0; i < bones2.Length; i++)
{
Transform val = bones2[i];
if ((Object)(object)val != (Object)null && !dictionary3.ContainsKey(val))
{
dictionary3.Add(val, i);
}
}
foreach (HumanBodyBones value4 in Enum.GetValues(typeof(HumanBodyBones)))
{
if ((int)value4 != 55)
{
Transform boneTransform = avatarAnimator.GetBoneTransform(value4);
if (!((Object)(object)boneTransform == (Object)null) && dictionary3.TryGetValue(boneTransform, out var value2))
{
dictionary2[value4] = value2;
}
}
}
BoneWeight[] boneWeights = sharedMesh.boneWeights;
if (boneWeights == null || boneWeights.Length == 0)
{
Debug.LogWarning((object)"[WeightTransferUtil] clothMesh.boneWeights 가 비어 있음. 리타겟할 weight 가 없음.");
return;
}
int vertexCount = sharedMesh.vertexCount;
int num = bones2.Length;
float[,] array = new float[vertexCount, num];
for (int j = 0; j < vertexCount; j++)
{
BoneWeight val3 = boneWeights[j];
AccumulateRetargetWeight(array, j, ((BoneWeight)(ref val3)).boneIndex0, ((BoneWeight)(ref val3)).weight0, bones, dictionary, dictionary2);
AccumulateRetargetWeight(array, j, ((BoneWeight)(ref val3)).boneIndex1, ((BoneWeight)(ref val3)).weight1, bones, dictionary, dictionary2);
AccumulateRetargetWeight(array, j, ((BoneWeight)(ref val3)).boneIndex2, ((BoneWeight)(ref val3)).weight2, bones, dictionary, dictionary2);
AccumulateRetargetWeight(array, j, ((BoneWeight)(ref val3)).boneIndex3, ((BoneWeight)(ref val3)).weight3, bones, dictionary, dictionary2);
}
BoneWeight[] boneWeights2 = CollapseWeightsToBoneWeights(array, 4, 0.0001f);
Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[bones2.Length];
for (int k = 0; k < bones2.Length; k++)
{
Transform val4 = bones2[k];
if ((Object)(object)val4 != (Object)null)
{
array2[k] = val4.worldToLocalMatrix * localToWorldMatrix;
}
else
{
array2[k] = Matrix4x4.identity;
}
}
sharedMesh.boneWeights = boneWeights2;
sharedMesh.bindposes = array2;
smr.rootBone = bodyRefSmr.rootBone;
smr.bones = bones2;
EditorUtility.SetDirty((Object)(object)sharedMesh);
EditorUtility.SetDirty((Object)(object)smr);
return;
}
Transform[] bones3 = bodyRefSmr.bones;
if (bones3 == null || bones3.Length == 0)
{
throw new AutoMorpherException("Target Body Bones are Missing", "[WeightTransferUtil] RetargetClothToAvatarSkeleton\n - bodyRefSmr.bones is null or empty");
}
Transform[] bones4 = smr.bones;
Matrix4x4[] bindposes = sharedMesh.bindposes;
Dictionary<Transform, int> dictionary4 = new Dictionary<Transform, int>();
if (bones4 != null)
{
for (int l = 0; l < bones4.Length; l++)
{
Transform val5 = bones4[l];
if (!((Object)(object)val5 == (Object)null) && !dictionary4.ContainsKey(val5))
{
dictionary4.Add(val5, l);
}
}
}
int num2 = bones3.Length;
int num3 = accessoryBones.Length;
Transform[] array3 = (Transform[])(object)new Transform[num2 + num3];
for (int m = 0; m < num2; m++)
{
array3[m] = bones3[m];
}
for (int n = 0; n < num3; n++)
{
array3[num2 + n] = accessoryBones[n];
}
Matrix4x4[] array4 = (Matrix4x4[])(object)new Matrix4x4[array3.Length];
for (int num4 = 0; num4 < num2; num4++)
{
Transform val6 = bones3[num4];
if ((Object)(object)val6 != (Object)null)
{
array4[num4] = val6.worldToLocalMatrix * localToWorldMatrix;
}
else
{
array4[num4] = Matrix4x4.identity;
}
}
for (int num5 = 0; num5 < num3; num5++)
{
Transform val7 = accessoryBones[num5];
Matrix4x4 val8 = Matrix4x4.identity;
if ((Object)(object)val7 != (Object)null && dictionary4.TryGetValue(val7, out var value3))
{
val8 = ((bindposes == null || value3 < 0 || value3 >= bindposes.Length) ? (val7.worldToLocalMatrix * localToWorldMatrix) : bindposes[value3]);
}
array4[num2 + num5] = val8;
}
sharedMesh.bindposes = array4;
sharedMesh.boneWeights = (BoneWeight[])(object)new BoneWeight[sharedMesh.vertexCount];
smr.rootBone = bodyRefSmr.rootBone;
smr.bones = array3;
EditorUtility.SetDirty((Object)(object)sharedMesh);
EditorUtility.SetDirty((Object)(object)smr);
}
private void AccumulateRetargetWeight(float[,] W, int vertIndex, int clothBoneIndex, float weight, Transform[] clothBones, Dictionary<Transform, HumanBodyBones> clothBoneToHuman, Dictionary<HumanBodyBones, int> humanToTargetBoneIndex)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
if (!(weight <= 0f) && clothBoneIndex >= 0 && clothBoneIndex < clothBones.Length)
{
Transform val = clothBones[clothBoneIndex];
if (!((Object)(object)val == (Object)null) && clothBoneToHuman.TryGetValue(val, out var value) && humanToTargetBoneIndex.TryGetValue(value, out var value2))
{
W[vertIndex, value2] += weight;
}
}
}
private void TransferFromBodyToCloth(Animator avatarAnimator, ClothInstance cloth, IReadOnlyList<SkinnedMeshRenderer> bodyMeshes, IReadOnlyList<Mesh> bodyBakedMeshes, Settings settings, Transform[] accessoryBones, float[,] accessoryWeights, int bodyBoneCount, BoneWeight[] prevBoneWeights = null)
{
//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
//IL_020a: Unknown result type (might be due to invalid IL or missing references)
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
//IL_023f: Unknown result type (might be due to invalid IL or missing references)
//IL_0244: Unknown result type (might be due to invalid IL or missing references)
//IL_0246: Unknown result type (might be due to invalid IL or missing references)
//IL_024b: Unknown result type (might be due to invalid IL or missing references)
//IL_0250: Unknown result type (might be due to invalid IL or missing references)
//IL_0264: Unknown result type (might be due to invalid IL or missing references)
//IL_0269: Unknown result type (might be due to invalid IL or missing references)
//IL_026e: Unknown result type (might be due to invalid IL or missing references)
//IL_0279: Unknown result type (might be due to invalid IL or missing references)
//IL_027e: Unknown result type (might be due to invalid IL or missing references)
//IL_0283: Unknown result type (might be due to invalid IL or missing references)
//IL_0287: Unknown result type (might be due to invalid IL or missing references)
//IL_028c: Unknown result type (might be due to invalid IL or missing references)
//IL_0295: Unknown result type (might be due to invalid IL or missing references)
//IL_0297: Unknown result type (might be due to invalid IL or missing references)
//IL_0302: Unknown result type (might be due to invalid IL or missing references)
//IL_0307: Unknown result type (might be due to invalid IL or missing references)
Vector3[] worldVertices = cloth.worldVertices;
if (worldVertices == null || worldVertices.Length == 0)
{
throw new AutoMorpherException("Cloth World Vertices are Missing", "[WeightTransferUtil] TransferFromBodyToCloth\n - cloth.worldVertices is null or empty");
}
int[] triangles = cloth.editableMesh.triangles;
Vector3[] clothWorldNormals = GetClothWorldNormals(cloth);
if (clothWorldNormals == null || clothWorldNormals.Length != worldVertices.Length)
{
throw new AutoMorpherException("Cloth World Normals Calculation Failed", "[WeightTransferUtil] TransferFromBodyToCloth\n - targetNormalsWorld is null or length mismatch\n - targetVertsWorld.Length : " + ((worldVertices == null) ? (-1) : worldVertices.Length) + "\n - targetNormalsWorld.Length : " + ((clothWorldNormals == null) ? (-1) : clothWorldNormals.Length));
}
Transform[] bones = cloth.smr.bones;
int num = bones.Length;
Dictionary<Transform, int> dictionary = new Dictionary<Transform, int>();
for (int i = 0; i < bones.Length; i++)
{
Transform val = bones[i];
if ((Object)(object)val != (Object)null && !dictionary.ContainsKey(val))
{
dictionary.Add(val, i);
}
}
int num2 = 0;
int num3 = 0;
foreach (SkinnedMeshRenderer bodyMesh in bodyMeshes)
{
if (!((Object)(object)bodyMesh == (Object)null) && !((Object)(object)bodyMesh.sharedMesh == (Object)null))
{
num2 += bodyMesh.sharedMesh.vertexCount;
num3 += bodyMesh.sharedMesh.triangles.Length;
}
}
if (num2 == 0 || num3 == 0)
{
throw new AutoMorpherException("Valid Body Mesh is Missing", "[WeightTransferUtil] TransferFromBodyToCloth\n - bodyMeshes has no valid mesh (totalVerts == 0 or totalTris == 0)");
}
Vector3[] array = (Vector3[])(object)new Vector3[num2];
Vector3[] array2 = (Vector3[])(object)new Vector3[num2];
int[] array3 = new int[num3];
float[,] W = new float[num2, num];
int num4 = 0;
int num5 = 0;
Vector3 val3 = default(Vector3);
for (int j = 0; j < bodyMeshes.Count; j++)
{
SkinnedMeshRenderer val2 = bodyMeshes[j];
if ((Object)(object)val2 == (Object)null || (Object)(object)val2.sharedMesh == (Object)null)
{
continue;
}
Mesh sharedMesh = val2.sharedMesh;
Mesh obj = bodyBakedMeshes[j];
Vector3[] vertices = obj.vertices;
Vector3[] normals = obj.normals;
int[] triangles2 = obj.triangles;
int vertexCount = obj.vertexCount;
Vector3 lossyScale = ((Component)val2).transform.lossyScale;
((Vector3)(ref val3))._002Ector(1f / Mathf.Max(lossyScale.x, 1E-08f), 1f / Mathf.Max(lossyScale.y, 1E-08f), 1f / Mathf.Max(lossyScale.z, 1E-08f));
Matrix4x4 val4 = ((Component)val2).transform.localToWorldMatrix * Matrix4x4.Scale(val3);
for (int k = 0; k < vertexCount; k++)
{
array[num4 + k] = ((Matrix4x4)(ref val4)).MultiplyPoint3x4(vertices[k]);
Vector3 val5 = ((Matrix4x4)(ref val4)).MultiplyVector(normals[k]);
Vector3 normalized = ((Vector3)(ref val5)).normalized;
array2[num4 + k] = normalized;
}
for (int l = 0; l < triangles2.Length; l++)
{
array3[num5 + l] = triangles2[l] + num4;
}
BoneWeight[] boneWeights = sharedMesh.boneWeights;
Transform[] bones2 = val2.bones;
if (boneWeights != null && boneWeights.Length == vertexCount && bones2 != null)
{
for (int m = 0; m < vertexCount; m++)
{
BoneWeight val6 = boneWeights[m];
AccumulateBodyWeight(ref W, num4 + m, ((BoneWeight)(ref val6)).boneIndex0, ((BoneWeight)(ref val6)).weight0, bones2, dictionary);
AccumulateBodyWeight(ref W, num4 + m, ((BoneWeight)(ref val6)).boneIndex1, ((BoneWeight)(ref val6)).weight1, bones2, dictionary);
AccumulateBodyWeight(ref W, num4 + m, ((BoneWeight)(ref val6)).boneIndex2, ((BoneWeight)(ref val6)).weight2, bones2, dictionary);
AccumulateBodyWeight(ref W, num4 + m, ((BoneWeight)(ref val6)).boneIndex3, ((BoneWeight)(ref val6)).weight3, bones2, dictionary);
}
}
num4 += vertexCount;
num5 += triangles2.Length;
}
List<int>[] array4 = cloth.vertexAdjacency;
if (array4 == null || array4.Length != worldVertices.Length)
{
array4 = BuildAdjacencyFromTriangles(worldVertices.Length, triangles);
}
float[,] weights = FindMatchesClosestSurface(array, array3, array2, worldVertices, clothWorldNormals, W, settings.maxDistance * settings.maxDistance, settings.maxNormalAngleDeg, settings.allowFlippedNormal, out var matchedMask);
weights = InpaintApprox(worldVertices, triangles, weights, matchedMask, array4, 20, 0.7f);
if (settings.enableSmoothing && settings.smoothingIterations > 0 && settings.smoothingAlpha > 0f)
{
weights = SmoothWeightsApprox(worldVertices, weights, matchedMask, array4, settings.smoothingIterations, settings.smoothingAlpha, settings.maxDistance);
}
ApplyLegVertexConstraints(avatarAnimator, cloth, weights, bodyBoneCount, settings.tinyWeight);
int vertexCount2 = cloth.editableMesh.vertexCount;
num = cloth.smr.bones.Length;
if (accessoryBones != null && accessoryBones.Length != 0 && accessoryWeights != null && bodyBoneCount > 0)
{
HashSet<Transform> value = null;
if (cloth.humanoidMatchedBones != null)
{
cloth.humanoidMatchedBones.TryGetValue((HumanBodyBones)10, out value);
}
Transform val7 = null;
if ((Object)(object)avatarAnimator != (Object)null)
{
val7 = avatarAnimator.GetBoneTransform((HumanBodyBones)10);
}
if (value != null && (Object)(object)val7 != (Object)null)
{
int num6 = Array.IndexOf(cloth.smr.bones, val7);
if (num6 >= 0 && num6 < bodyBoneCount)
{
foreach (Transform item in value)
{
if ((Object)(object)item == (Object)null)
{
continue;
}
int num7 = Array.IndexOf(accessoryBones, item);
if (num7 < 0)
{
continue;
}
for (int n = 0; n < vertexCount2; n++)
{
float num8 = accessoryWeights[n, num7];
if (!(num8 <= settings.tinyWeight))
{
weights[n, num6] += num8;
accessoryWeights[n, num7] = 0f;
}
}
}
}
}
}
BoneWeight[] array5;
if (accessoryBones != null && accessoryBones.Length != 0 && accessoryWeights != null && bodyBoneCount > 0 && bodyBoneCount + accessoryBones.Length == num)
{
array5 = MergeBodyAndAccessoryWeights(weights, accessoryWeights, bodyBoneCount, settings.tinyWeight, settings.enforceFourBoneLimit);
}
else
{
if (settings.enforceFourBoneLimit)
{
EnforceMaxBonesPerVertex(weights, 4, settings.tinyWeight);
}
else
{
ZeroSmallWeights(weights, settings.tinyWeight);
}
NormalizeWeightsPerVertex(weights, settings.tinyWeight);
array5 = CollapseWeightsToBoneWeights(weights, 4, settings.tinyWeight);
}
Mesh sharedMesh2 = cloth.smr.sharedMesh;
if (sharedMesh2.vertexCount != array5.Length)
{
throw new AutoMorpherException("Vertex Count and Weight Length Mismatch", "[WeightTransferUtil] TransferFromBodyToCloth\n - mesh.vertexCount : " + sharedMesh2.vertexCount + "\n - finalWeights.Length : " + array5.Length);
}
EnsureNonZeroAndNormalizeFinalWeights(cloth, array5, array4, settings.tinyWeight);
ApplyEquivalentVertexWeights(cloth, array5);
NormalizeAllBoneWeightsInPlace(array5, settings.tinyWeight);
sharedMesh2.boneWeights = array5;
cloth.smr.sharedMesh = sharedMesh2;
if (!TryApplyBoneWeightsWithValidation(sharedMesh2, array5, 1E-10f, out var zeroWeightVertexCount))
{
Debug.LogWarning((object)$"[WeightValidation] Zero-weight vertices detected: {zeroWeightVertexCount}");
}
}
public void MoveBodyWeightsToClothesBones(SkinnedMeshRenderer clothesSmr, Mesh clothesMesh, Dictionary<Transform, Transform> bodyToClothesMap, Transform[] accessoryBones)
{
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)clothesSmr == (Object)null)
{
throw new AutoMorpherException("Clothes SMR is Missing", "[WeightTransferUtil] MoveBodyWeightsToClothesBones\n - clothesSmr is null");
}
if ((Object)(object)clothesMesh == (Object)null)
{
throw new AutoMorpherException("Clothes Mesh is Missing", "[WeightTransferUtil] MoveBodyWeightsToClothesBones\n - clothesMesh is null");
}
if (bodyToClothesMap == null)
{
throw new AutoMorpherException("Body To Clothes Map is Missing", "[WeightTransferUtil] MoveBodyWeightsToClothesBones\n - bodyToClothesMap is null");
}
Transform clothesFallbackRoot = (((Object)(object)clothesSmr.rootBone != (Object)null) ? clothesSmr.rootBone : ((Component)clothesSmr).transform);
HashSet<Transform> hashSet = null;
if (accessoryBones != null && accessoryBones.Length != 0)
{
hashSet = new HashSet<Transform>(accessoryBones);
}
Transform[] bones = clothesSmr.bones;
if (bones == null || bones.Length == 0)
{
throw new AutoMorpherException("Clothes Bones are Missing", "[WeightTransferUtil] MoveBodyWeightsToClothesBones\n - clothesSmr.bones is null or empty");
}
Transform[] array = (Transform[])(object)new Transform[bones.Length];
for (int i = 0; i < bones.Length; i++)
{
Transform val = bones[i];
if ((Object)(object)val == (Object)null)
{
array[i] = clothesFallbackRoot;
continue;
}
if (hashSet != null && hashSet.Contains(val))
{
array[i] = val;
continue;
}
Transform val2 = EnsureClothesBoneExists(val);
array[i] = (((Object)(object)val2 != (Object)null) ? val2 : clothesFallbackRoot);
}
clothesSmr.bones = array;
if ((Object)(object)clothesSmr.rootBone != (Object)null && (hashSet == null || !hashSet.Contains(clothesSmr.rootBone)))
{
Transform val3 = EnsureClothesBoneExists(clothesSmr.rootBone);
if ((Object)(object)val3 != (Object)null)
{
clothesSmr.rootBone = val3;
}
}
Transform val4 = (((Object)(object)clothesSmr.rootBone != (Object)null) ? clothesSmr.rootBone : ((Component)clothesSmr).transform);
Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[array.Length];
for (int j = 0; j < array.Length; j++)
{
Transform val5 = array[j];
if ((Object)(object)val5 == (Object)null)
{
throw new AutoMorpherException("Remapped Bone is Null", "[WeightTransferUtil] MoveBodyWeightsToClothesBones\n - remappedBones contains null bone after fallback");
}
array2[j] = val5.worldToLocalMatrix * val4.localToWorldMatrix;
}
clothesMesh.bindposes = array2;
Transform EnsureClothesBoneExists(Transform bodyBone)
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)bodyBone == (Object)null)
{
return null;
}
if (bodyToClothesMap.TryGetValue(bodyBone, out var value) && (Object)(object)value != (Object)null)
{
return value;
}
Transform val6 = null;
if ((Object)(object)bodyBone.parent != (Object)null)
{
val6 = EnsureClothesBoneExists(bodyBone.parent);
}
if ((Object)(object)val6 == (Object)null)
{
val6 = clothesFallbackRoot;
}
Transform transform = new GameObject(((Object)bodyBone).name).transform;
transform.SetParent(val6, false);
transform.localPosition = bodyBone.localPosition;
transform.localRotation = bodyBone.localRotation;
transform.localScale = bodyBone.localScale;
bodyToClothesMap[bodyBone] = transform;
return transform;
}
}
private bool TryApplyBoneWeightsWithValidation(Mesh mesh, BoneWeight[] weights, float tiny, out int zeroWeightVertexCount)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
bool result = true;
zeroWeightVertexCount = 0;
int num = weights.Length;
NativeArray<byte> val = default(NativeArray<byte>);
val._002Ector(num, (Allocator)2, (NativeArrayOptions)1);
List<BoneWeight1> list = new List<BoneWeight1>(num * 4);
NativeArray<BoneWeight1> val2 = default(NativeArray<BoneWeight1>);
try
{
for (int i = 0; i < num; i++)
{
BoneWeight val3 = weights[i];
int count = 0;
AddIfValid(list, ((BoneWeight)(ref val3)).boneIndex0, ((BoneWeight)(ref val3)).weight0, tiny, ref count);
AddIfValid(list, ((BoneWeight)(ref val3)).boneIndex1, ((BoneWeight)(ref val3)).weight1, tiny, ref count);
AddIfValid(list, ((BoneWeight)(ref val3)).boneIndex2, ((BoneWeight)(ref val3)).weight2, tiny, ref count);
AddIfValid(list, ((BoneWeight)(ref val3)).boneIndex3, ((BoneWeight)(ref val3)).weight3, tiny, ref count);
if (count == 0)
{
zeroWeightVertexCount++;
}
val[i] = (byte)count;
}
if (zeroWeightVertexCount > 0)
{
return false;
}
val2 = new NativeArray<BoneWeight1>(list.Count, (Allocator)2, (NativeArrayOptions)1);
for (int j = 0; j < list.Count; j++)
{
val2[j] = list[j];
}
mesh.SetBoneWeights(val, val2);
}
catch (Exception ex)
{
Debug.LogWarning((object)("[SetBoneWeights] Failed: " + ex.Message));
result = false;
}
finally
{
if (val2.IsCreated)
{
val2.Dispose();
}
if (val.IsCreated)
{
val.Dispose();
}
}
return result;
}
private void AddIfValid(List<BoneWeight1> list, int boneIndex, float weight, float tiny, ref int count)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (boneIndex >= 0 && !(weight <= tiny))
{
BoneWeight1 item = default(BoneWeight1);
((BoneWeight1)(ref item)).boneIndex = boneIndex;
((BoneWeight1)(ref item)).weight = weight;
list.Add(item);
count++;
}
}
private void ApplyEquivalentVertexWeights(ClothInstance cloth, BoneWeight[] finalWeights)
{
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
if (cloth == null || cloth.equivalentVertices == null || cloth.equivalentVertices.Count == 0 || finalWeights == null || finalWeights.Length == 0)
{
return;
}
List<List<int>> equivalentVertices = cloth.equivalentVertices;
int num = finalWeights.Length;
bool[] array = new bool[num];
foreach (List<int> item in equivalentVertices)
{
if (item == null || item.Count == 0)
{
continue;
}
List<int> list = null;
bool flag = false;
for (int i = 0; i < item.Count; i++)
{
int num2 = item[i];
if (num2 >= 0 && num2 < num)
{
if (list == null)
{
list = new List<int>();
}
list.Add(num2);
if (!array[num2])
{
flag = true;
}
}
}
if (list == null || !flag)
{
continue;
}
Dictionary<int, float> weightMap = new Dictionary<int, float>();
foreach (int item2 in list)
{
BoneWeight val = finalWeights[item2];
Accumulate(((BoneWeight)(ref val)).boneIndex0, ((BoneWeight)(ref val)).weight0);
Accumulate(((BoneWeight)(ref val)).boneIndex1, ((BoneWeight)(ref val)).weight1);
Accumulate(((BoneWeight)(ref val)).boneIndex2, ((BoneWeight)(ref val)).weight2);
Accumulate(((BoneWeight)(ref val)).boneIndex3, ((BoneWeight)(ref val)).weight3);
}
if (weightMap.Count == 0)
{
continue;
}
List<KeyValuePair<int, float>> list2 = weightMap.OrderByDescending((KeyValuePair<int, float> kv) => kv.Value).Take(4).ToList();
float num3 = 0f;
for (int num4 = 0; num4 < Math.Min(4, list2.Count); num4++)
{
num3 += list2[num4].Value;
}
if (num3 <= 1E-08f)
{
continue;
}
BoneWeight val2 = default(BoneWeight);
for (int num5 = 0; num5 < Math.Min(4, list2.Count); num5++)
{
int key = list2[num5].Key;
float num6 = list2[num5].Value / num3;
switch (num5)
{
case 0:
((BoneWeight)(ref val2)).boneIndex0 = key;
((BoneWeight)(ref val2)).weight0 = num6;
break;
case 1:
((BoneWeight)(ref val2)).boneIndex1 = key;
((BoneWeight)(ref val2)).weight1 = num6;
break;
case 2:
((BoneWeight)(ref val2)).boneIndex2 = key;
((BoneWeight)(ref val2)).weight2 = num6;
break;
case 3:
((BoneWeight)(ref val2)).boneIndex3 = key;
((BoneWeight)(ref val2)).weight3 = num6;
break;
}
}
foreach (int item3 in list)
{
finalWeights[item3] = val2;
array[item3] = true;
}
void Accumulate(int boneIndex, float w)
{
if (!(w <= 0f) && boneIndex >= 0)
{
if (weightMap.TryGetValue(boneIndex, out var value))
{
weightMap[boneIndex] = value + w;
}
else
{
weightMap[boneIndex] = w;
}
}
}
}
}
private void ApplyLegVertexConstraints(Animator avatarAnimator, ClothInstance cloth, float[,] weights, int bodyBoneCount, float tinyWeight)
{
if (cloth == null || (Object)(object)cloth.smr == (Object)null)
{
return;
}
bool[] isLeftLegVertex = cloth.isLeftLegVertex;
bool[] isRightLegVertex = cloth.isRightLegVertex;
if (isLeftLegVertex == null && isRightLegVertex == null)
{
return;
}
Transform[] bones = cloth.smr.bones;
if (bones == null)
{
return;
}
int length = weights.GetLength(0);
int length2 = weights.GetLength(1);
Transform boneTransform = avatarAnimator.GetBoneTransform((HumanBodyBones)1);
Transform boneTransform2 = avatarAnimator.GetBoneTransform((HumanBodyBones)2);
bool[] array = new bool[length2];
bool[] array2 = new bool[length2];
int num = Mathf.Min(bodyBoneCount, bones.Length);
for (int i = 0; i < num; i++)
{
Transform val = bones[i];
if (!((Object)(object)val == (Object)null))
{
if (val.IsChildOf(boneTransform))
{
array[i] = true;
}
else if (val.IsChildOf(boneTransform2))
{
array2[i] = true;
}
}
}
for (int j = 0; j < length; j++)
{
bool flag = isLeftLegVertex != null && j < isLeftLegVertex.Length && isLeftLegVertex[j];
bool flag2 = isRightLegVertex != null && j < isRightLegVertex.Length && isRightLegVertex[j];
if (!flag && !flag2)
{
continue;
}
for (int k = 0; k < length2; k++)
{
if (weights[j, k] <= tinyWeight)
{
continue;
}
if (flag)
{
if (array2[k])
{
weights[j, k] = 0f;
}
}
else if (flag2 && array[k])
{
weights[j, k] = 0f;
}
}
}
}
private Vector3[] GetClothWorldNormals(ClothInstance cloth)
{
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
if (cloth.worldVertices == null)
{
return null;
}
int num = cloth.worldVertices.Length;
if ((Object)(object)cloth.bakedMesh == (Object)null || cloth.bakedMesh.vertexCount != num)
{
throw new AutoMorpherException("Cloth Baked Mesh is Invalid", "[WeightTransferUtil] GetClothWorldNormals\n - bakedMesh is null or vertexCount mismatch\n - bakedMesh.vertexCount : " + (((Object)(object)cloth.bakedMesh == (Object)null) ? (-1) : cloth.bakedMesh.vertexCount) + "\n - worldVertices.Length : " + num);
}
Vector3[] array = (Vector3[])(object)new Vector3[num];
Mesh bakedMesh = cloth.bakedMesh;
Vector3[] normals = bakedMesh.normals;
if (normals == null || normals.Length != num)
{
bakedMesh.RecalculateNormals();
normals = bakedMesh.normals;
}
for (int i = 0; i < num; i++)
{
Vector3 val = ((Matrix4x4)(ref cloth.worldNoScale)).MultiplyVector(normals[i]);
Vector3 normalized = ((Vector3)(ref val)).normalized;
array[i] = normalized;
}
return array;
}
private void AccumulateBodyWeight(ref float[,] W, int vIndex, int localBoneIndex, float weight, Transform[] bodyBones, Dictionary<Transform, int> targetBoneIndexByTransform)
{
if (!(weight <= 0f) && bodyBones != null && localBoneIndex >= 0 && localBoneIndex < bodyBones.Length)
{
Transform val = bodyBones[localBoneIndex];
if (!((Object)(object)val == (Object)null) && targetBoneIndexByTransform.TryGetValue(val, out var value))
{
W[vIndex, value] += weight;
}
}
}
private List<int>[] BuildAdjacencyFromTriangles(int vertexCount, int[] triangles)
{
List<int>[] array = new List<int>[vertexCount];
for (int i = 0; i < vertexCount; i++)
{
array[i] = new List<int>();
}
int num = triangles.Length / 3;
for (int j = 0; j < num; j++)
{
int num2 = triangles[j * 3];
int num3 = triangles[j * 3 + 1];
int num4 = triangles[j * 3 + 2];
AddEdge(array, num2, num3);
AddEdge(array, num3, num4);
AddEdge(array, num4, num2);
}
return array;
}
private void AddEdge(List<int>[] adj, int a, int b)
{
if (!adj[a].Contains(b))
{
adj[a].Add(b);
}
if (!adj[b].Contains(a))
{
adj[b].Add(a);
}
}
private float[,] FindMatchesClosestSurface(Vector3[] sourceVerts, int[] sourceTris, Vector3[] sourceNormals, Vector3[] targetVerts, Vector3[] targetNormals, float[,] sourceWeights, float distanceThresholdSqr, float angleThresholdDeg, bool flipVertexNormal, out bool[] matchedMask)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
//IL_0202: Unknown result type (might be due to invalid IL or missing references)
int num = targetVerts.Length;
int length = sourceWeights.GetLength(1);
float[,] array = new float[num, length];
matchedMask = new bool[num];
int num2 = sourceTris.Length / 3;
float num3 = angleThresholdDeg * (MathF.PI / 180f);
for (int i = 0; i < num; i++)
{
Vector3 val = targetVerts[i];
float num4 = float.PositiveInfinity;
int num5 = -1;
Vector3 val2 = Vector3.zero;
Vector3 val4;
for (int j = 0; j < num2; j++)
{
int num6 = sourceTris[j * 3];
int num7 = sourceTris[j * 3 + 1];
int num8 = sourceTris[j * 3 + 2];
Vector3 a = sourceVerts[num6];
Vector3 b = sourceVerts[num7];
Vector3 c = sourceVerts[num8];
Vector3 bary;
Vector3 val3 = ClosestPointOnTriangle(val, a, b, c, out bary);
val4 = val - val3;
float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
if (sqrMagnitude < num4)
{
num4 = sqrMagnitude;
num5 = j;
val2 = bary;
}
}
if (num5 < 0)
{
matchedMask[i] = false;
continue;
}
bool num9 = num4 <= distanceThresholdSqr;
int num10 = sourceTris[num5 * 3];
int num11 = sourceTris[num5 * 3 + 1];
int num12 = sourceTris[num5 * 3 + 2];
Vector3 val5 = sourceNormals[num10];
Vector3 val6 = sourceNormals[num11];
Vector3 val7 = sourceNormals[num12];
val4 = val5 * val2.x + val6 * val2.y + val7 * val2.z;
Vector3 normalized = ((Vector3)(ref val4)).normalized;
Vector3 normalized2 = ((Vector3)(ref targetNormals[i])).normalized;
float num13 = Mathf.Acos(Mathf.Clamp(Vector3.Dot(normalized, normalized2), -1f, 1f));
bool flag = num13 <= num3;
if (flipVertexNormal && MathF.PI - num13 <= num3)
{
flag = true;
}
bool flag2 = num9 && flag;
matchedMask[i] = flag2;
for (int k = 0; k < length; k++)
{
float num14 = sourceWeights[num10, k];
float num15 = sourceWeights[num11, k];
float num16 = sourceWeights[num12, k];
array[i, k] = num14 * val2.x + num15 * val2.y + num16 * val2.z;
}
}
return array;
}
private Vector3 ClosestPointOnTriangle(Vector3 p, Vector3 a, Vector3 b, Vector3 c, out Vector3 bary)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_0244: Unknown result type (might be due to invalid IL or missing references)
//IL_0249: Unknown result type (might be due to invalid IL or missing references)
//IL_024e: Unknown result type (might be due to invalid IL or missing references)
//IL_0251: Unknown result type (might be due to invalid IL or missing references)
//IL_0256: Unknown result type (might be due to invalid IL or missing references)
//IL_0259: Unknown result type (might be due to invalid IL or missing references)
//IL_025e: Unknown result type (might be due to invalid IL or missing references)
//IL_0263: Unknown result type (might be due to invalid IL or missing references)
//IL_0267: Unknown result type (might be due to invalid IL or missing references)
//IL_026c: Unknown result type (might be due to invalid IL or missing references)
//IL_0186: Unknown result type (might be due to invalid IL or missing references)
//IL_018b: Unknown result type (might be due to invalid IL or missing references)
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Unknown result type (might be due to invalid IL or missing references)
//IL_020b: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = b - a;
Vector3 val2 = c - a;
Vector3 val3 = p - a;
float num = Vector3.Dot(val, val3);
float num2 = Vector3.Dot(val2, val3);
if (num <= 0f && num2 <= 0f)
{
bary = new Vector3(1f, 0f, 0f);
return a;
}
Vector3 val4 = p - b;
float num3 = Vector3.Dot(val, val4);
float num4 = Vector3.Dot(val2, val4);
if (num3 >= 0f && num4 <= num3)
{
bary = new Vector3(0f, 1f, 0f);
return b;
}
float num5 = num * num4 - num3 * num2;
if (num5 <= 0f && num >= 0f && num3 <= 0f)
{
float num6 = num / (num - num3);
bary = new Vector3(1f - num6, num6, 0f);
return a + val * num6;
}
Vector3 val5 = p - c;
float num7 = Vector3.Dot(val, val5);
float num8 = Vector3.Dot(val2, val5);
if (num8 >= 0f && num7 <= num8)
{
bary = new Vector3(0f, 0f, 1f);
return c;
}
float num9 = num7 * num2 - num * num8;
if (num9 <= 0f && num2 >= 0f && num8 <= 0f)
{
float num10 = num2 / (num2 - num8);
bary = new Vector3(1f - num10, 0f, num10);
return a + val2 * num10;
}
float num11 = num3 * num8 - num7 * num4;
if (num11 <= 0f && num4 - num3 >= 0f && num7 - num8 >= 0f)
{
float num12 = (num4 - num3) / (num4 - num3 + (num7 - num8));
bary = new Vector3(0f, 1f - num12, num12);
return b + (c - b) * num12;
}
float num13 = 1f / (num11 + num9 + num5);
float num14 = num9 * num13;
float num15 = num5 * num13;
float num16 = 1f - num14 - num15;
bary = new Vector3(num16, num14, num15);
return a * num16 + b * num14 + c * num15;
}
private void ZeroSmallWeights(float[,] weights, float tiny)
{
int length = weights.GetLength(0);
int length2 = weights.GetLength(1);
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length2; j++)
{
if (weights[i, j] <= tiny)
{
weights[i, j] = 0f;
}
}
}
}
private void EnforceMaxBonesPerVertex(float[,] weights, int maxBonesPerVertex, float tinyWeight)
{
int length = weights.GetLength(0);
int length2 = weights.GetLength(1);
for (int i = 0; i < length; i++)
{
List<(int, float)> list = new List<(int, float)>();
for (int j = 0; j < length2; j++)
{
float num = weights[i, j];
if (num > tinyWeight)
{
list.Add((j, num));
}
}
list.Sort(((int bone, float w) a, (int bone, float w) b) => b.w.CompareTo(a.w));
HashSet<int> hashSet = new HashSet<int>();
int num2 = Mathf.Min(maxBonesPerVertex, list.Count);
for (int num3 = 0; num3 < num2; num3++)
{
hashSet.Add(list[num3].Item1);
}
for (int num4 = 0; num4 < length2; num4++)
{
if (!hashSet.Contains(num4) || weights[i, num4] <= tinyWeight)
{
weights[i, num4] = 0f;
}
}
}
}
private void NormalizeWeightsPerVertex(float[,] weights, float tiny)
{
int length = weights.GetLength(0);
int length2 = weights.GetLength(1);
for (int i = 0; i < length; i++)
{
float num = 0f;
for (int j = 0; j < length2; j++)
{
num += weights[i, j];
}
if (!(num < tiny))
{
float num2 = 1f / num;
for (int k = 0; k < length2; k++)
{
weights[i, k] *= num2;
}
}
}
}
private BoneWeight[] CollapseWeightsToBoneWeights(float[,] weights, int maxBonesPerVert, float tiny)
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
int length = weights.GetLength(0);
int length2 = weights.GetLength(1);
BoneWeight[] array = (BoneWeight[])(object)new BoneWeight[length];
for (int i = 0; i < length; i++)
{
List<(int, float)> list = new List<(int, float)>();
for (int j = 0; j < length2; j++)
{
float num = weights[i, j];
if (num > tiny)
{
list.Add((j, num));
}
}
if (list.Count == 0)
{
array[i] = default(BoneWeight);
continue;
}
list.Sort(((int idx, float w) a, (int idx, float w) b) => b.w.CompareTo(a.w));
int num2 = Mathf.Min(maxBonesPerVert, list.Count);
float num3 = 0f;
for (int num4 = 0; num4 < num2; num4++)
{
num3 += list[num4].Item2;
}
if (num3 < tiny)
{
num3 = 1f;
}
float num5 = 1f / num3;
BoneWeight val = default(BoneWeight);
for (int num6 = 0; num6 < num2; num6++)
{
int item = list[num6].Item1;
float num7 = list[num6].Item2 * num5;
switch (num6)
{
case 0:
((BoneWeight)(ref val)).boneIndex0 = item;
((BoneWeight)(ref val)).weight0 = num7;
break;
case 1:
((BoneWeight)(ref val)).boneIndex1 = item;
((BoneWeight)(ref val)).weight1 = num7;
break;
case 2:
((BoneWeight)(ref val)).boneIndex2 = item;
((BoneWeight)(ref val)).weight2 = num7;
break;
case 3:
((BoneWeight)(ref val)).boneIndex3 = item;
((BoneWeight)(ref val)).weight3 = num7;
break;
}
}
array[i] = val;
}
return array;
}
private float[,] InpaintApprox(Vector3[] verts, int[] triangles, float[,] weights, bool[] matched, List<int>[] adjacency, int iterations, float alpha)
{
int num = verts.Length;
int length = weights.GetLength(1);
float[,] array = (float[,])weights.Clone();
float[,] array2 = new float[num, length];
for (int i = 0; i < iterations; i++)
{
for (int j = 0; j < num; j++)
{
if (matched[j])
{
for (int k = 0; k < length; k++)
{
array2[j, k] = array[j, k];
}
continue;
}
List<int> list = adjacency[j];
if (list == null || list.Count == 0)
{
for (int l = 0; l < length; l++)
{
array2[j, l] = array[j, l];
}
continue;
}
for (int m = 0; m < length; m++)
{
float num2 = 0f;
for (int n = 0; n < list.Count; n++)
{
int num3 = list[n];
num2 += array[num3, m];
}
float num4 = num2 / (float)list.Count;
array2[j, m] = Mathf.Lerp(array[j, m], num4, alpha);
}
}
float[,] array3 = array2;
float[,] array4 = array;
array = array3;
array2 = array4;
}
return array;
}
private float[,] SmoothWeightsApprox(Vector3[] verts, float[,] weights, bool[] matched, List<int>[] adjacency, int numSmoothIterSteps, float smoothAlpha, float distanceThreshold)
{
int num = verts.Length;
int length = weights.GetLength(1);
bool[] array = new bool[num];
for (int i = 0; i < num; i++)
{
if (!matched[i])
{
FloodFillWithinDistance(verts, adjacency, i, distanceThreshold, array);
}
}
float[,] array2 = (float[,])weights.Clone();
float[,] array3 = new float[num, length];
for (int j = 0; j < numSmoothIterSteps; j++)
{
for (int k = 0; k < num; k++)
{
if (!array[k])
{
for (int l = 0; l < length; l++)
{
array3[k, l] = array2[k, l];
}
continue;
}
List<int> list = adjacency[k];
if (list == null || list.Count == 0)
{
for (int m = 0; m < length; m++)
{
array3[k, m] = array2[k, m];
}
continue;
}
for (int n = 0; n < length; n++)
{
float num2 = 0f;
for (int num3 = 0; num3 < list.Count; num3++)
{
int num4 = list[num3];
num2 += array2[num4, n];
}
float num5 = num2 / (float)list.Count;
array3[k, n] = Mathf.Lerp(array2[k, n], num5, smoothAlpha);
}
}
float[,] array4 = array3;
float[,] array5 = array2;
array2 = array4;
array3 = array5;
}
return array2;
}
private void FloodFillWithinDistance(Vector3[] verts, List<int>[] adjacency, int startIndex, float maxDistance, bool[] visited)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
Queue<int> queue = new Queue<int>();
queue.Enqueue(startIndex);
visited[startIndex] = true;
while (queue.Count > 0)
{
int num = queue.Dequeue();
foreach (int item in adjacency[num])
{
if (!visited[item])
{
Vector3 val = verts[startIndex] - verts[item];
if (((Vector3)(ref val)).magnitude < maxDistance)
{
visited[item] = true;
queue.Enqueue(item);
}
}
}
}
}
private BoneWeight[] MergeBodyAndAccessoryWeights(float[,] bodyWeights, float[,] accessoryWeights, int bodyBoneCount, float tiny, bool enforceFour)
{
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_029a: Unknown result type (might be due to invalid IL or missing references)
//IL_034e: Unknown result type (might be due to invalid IL or missing references)
//IL_0350: Unknown result type (might be due to invalid IL or missing references)
int length = bodyWeights.GetLength(0);
bodyWeights.GetLength(1);
int length2 = accessoryWeights.GetLength(1);
BoneWeight[] array = (BoneWeight[])(object)new BoneWeight[length];
for (int i = 0; i < length; i++)
{
List<(int, float)> list = new List<(int, float)>();
float num = 0f;
for (int j = 0; j < length2; j++)
{
float num2 = accessoryWeights[i, j];
if (num2 > tiny)
{
int item = bodyBoneCount + j;
list.Add((item, num2));
num += num2;
}
}
List<(int, float)> list2 = new List<(int, float)>();
float num3 = 0f;
for (int k = 0; k < bodyBoneCount; k++)
{
float num4 = bodyWeights[i, k];
if (num4 > tiny)
{
list2.Add((k, num4));
num3 += num4;
}
}
if (num3 > tiny && num < 1f - tiny)
{
float num5 = Mathf.Max(0f, 1f - num);
float num6 = num5 / num3;
for (int l = 0; l < list2.Count; l++)
{
list2[l] = (list2[l].Item1, list2[l].Item2 * num6);
}
num3 = num5;
}
else
{
for (int m = 0; m < list2.Count; m++)
{
list2[m] = (list2[m].Item1, 0f);
}
num3 = 0f;
}
List<(int, float)> list3 = new List<(int, float)>();
list3.AddRange(list);
list3.AddRange(list2);
list3.RemoveAll(((int bone, float w) t) => t.w <= tiny);
if (list3.Count == 0)
{
array[i] = default(BoneWeight);
continue;
}
if (enforceFour && list3.Count > 4)
{
list3.Sort(delegate((int bone, float w) a, (int bone, float w) b)
{
bool flag = a.bone >= bodyBoneCount;
bool flag2 = b.bone >= bodyBoneCount;
return (flag != flag2) ? ((!flag) ? 1 : (-1)) : b.w.CompareTo(a.w);
});
list3 = list3.GetRange(0, 4);
}
float num7 = 0f;
foreach (var item3 in list3)
{
num7 += item3.Item2;
}
if (num7 < tiny)
{
num7 = 1f;
}
float num8 = 1f / num7;
BoneWeight val = default(BoneWeight);
for (int num9 = 0; num9 < list3.Count && num9 < 4; num9++)
{
int item2 = list3[num9].Item1;
float num10 = list3[num9].Item2 * num8;
switch (num9)
{
case 0:
((BoneWeight)(ref val)).boneIndex0 = item2;
((BoneWeight)(ref val)).weight0 = num10;
break;
case 1:
((BoneWeight)(ref val)).boneIndex1 = item2;
((BoneWeight)(ref val)).weight1 = num10;
break;
case 2:
((BoneWeight)(ref val)).boneIndex2 = item2;
((BoneWeight)(ref val)).weight2 = num10;
break;
case 3:
((BoneWeight)(ref val)).boneIndex3 = item2;
((BoneWeight)(ref val)).weight3 = num10;
break;
}
}
array[i] = val;
}
return array;
}
private void EnsureNonZeroAndNormalizeFinalWeights(ClothInstance cloth, BoneWeight[] weights, List<int>[] adjacency, float tiny)
{
if (cloth != null && weights != null && weights.Length != 0)
{
PreNormalizeBoneWeightsInPlace(weights, tiny);
FillZeroWeightsFromNeighbors(weights, adjacency, tiny);
NormalizeAllBoneWeightsInPlace(weights, tiny);
}
}
private void PreNormalizeBoneWeightsInPlace(BoneWeight[] weights, float tiny)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < weights.Length; i++)
{
BoneWeight val = weights[i];
float num = Sum(in weights[i]);
if (!(num < tiny))
{
float num2 = 1f / num;
((BoneWeight)(ref val)).weight0 = ((BoneWeight)(ref val)).weight0 * num2;
((BoneWeight)(ref val)).weight1 = ((BoneWeight)(ref val)).weight1 * num2;
((BoneWeight)(ref val)).weight2 = ((BoneWeight)(ref val)).weight2 * num2;
((BoneWeight)(ref val)).weight3 = ((BoneWeight)(ref val)).weight3 * num2;
weights[i] = val;
}
}
}
private void FillZeroWeightsFromNeighbors(BoneWeight[] weights, List<int>[] adjacency, float tiny)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
int num = weights.Length;
for (int i = 0; i < num; i++)
{
if (!(Sum(in weights[i]) >= tiny))
{
BoneWeight bw = AverageFromNeighbors(i, weights, adjacency, tiny, 1);
if (Sum(in bw) >= tiny)
{
weights[i] = bw;
}
}
}
for (int j = 0; j < num; j++)
{
if (!(Sum(in weights[j]) >= tiny))
{
int num2 = FindNearestNonZeroVertexBfs(j, weights, adjacency, tiny, 8);
if (num2 >= 0)
{
weights[j] = weights[num2];
continue;
}
BoneWeight val = default(BoneWeight);
((BoneWeight)(ref val)).boneIndex0 = 0;
((BoneWeight)(ref val)).weight0 = 1f;
weights[j] = val;
}
}
}
private BoneWeight AverageFromNeighbors(int v, BoneWeight[] weights, List<int>[] adjacency, float tiny, int maxRing)
{
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
Dictionary<int, float> map = new Dictionary<int, float>();
Queue<int> queue = new Queue<int>();
Dictionary<int, int> dictionary = new Dictionary<int, int>();
HashSet<int> hashSet = new HashSet<int>();
queue.Enqueue(v);
dictionary[v] = 0;
hashSet.Add(v);
while (queue.Count > 0)
{
int num = queue.Dequeue();
int num2 = dictionary[num];
if (num2 >= maxRing)
{
continue;
}
List<int> list = adjacency[num];
if (list == null)
{
continue;
}
foreach (int item in list)
{
if (item >= 0 && item < weights.Length && hashSet.Add(item))
{
dictionary[item] = num2 + 1;
queue.Enqueue(item);
BoneWeight bw = weights[item];
if (!(Sum(in bw) < tiny))
{
Acc(map, ((BoneWeight)(ref bw)).boneIndex0, ((BoneWeight)(ref bw)).weight0, tiny);
Acc(map, ((BoneWeight)(ref bw)).boneIndex1, ((BoneWeight)(ref bw)).weight1, tiny);
Acc(map, ((BoneWeight)(ref bw)).boneIndex2, ((BoneWeight)(ref bw)).weight2, tiny);
Acc(map, ((BoneWeight)(ref bw)).boneIndex3, ((BoneWeight)(ref bw)).weight3, tiny);
}
}
}
}
return BuildTop4Normalized(map, tiny);
}
private int FindNearestNonZeroVertexBfs(int start, BoneWeight[] weights, List<int>[] adjacency, float tiny, int maxDepth)
{
Queue<int> queue = new Queue<int>();
Dictionary<int, int> dictionary = new Dictionary<int, int>();
HashSet<int> hashSet = new HashSet<int>();
queue.Enqueue(start);
dictionary[start] = 0;
hashSet.Add(start);
while (queue.Count > 0)
{
int num = queue.Dequeue();
int num2 = dictionary[num];
if (num2 > 0 && Sum(in weights[num]) >= tiny)
{
return num;
}
if (num2 >= maxDepth)
{
continue;
}
List<int> list = adjacency[num];
if (list == null)
{
continue;
}
foreach (int item in list)
{
if (item >= 0 && item < weights.Length && hashSet.Add(item))
{
dictionary[item] = num2 + 1;
queue.Enqueue(item);
}
}
}
return -1;
}
private void NormalizeAllBoneWeightsInPlace(BoneWeight[] weights, float tiny)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < weights.Length; i++)
{
float num = Sum(in weights[i]);
if (!(num < tiny))
{
float num2 = 1f / num;
BoneWeight val = weights[i];
((BoneWeight)(ref val)).weight0 = ((BoneWeight)(ref val)).weight0 * num2;
((BoneWeight)(ref val)).weight1 = ((BoneWeight)(ref val)).weight1 * num2;
((BoneWeight)(ref val)).weight2 = ((BoneWeight)(ref val)).weight2 * num2;
((BoneWeight)(ref val)).weight3 = ((BoneWeight)(ref val)).weight3 * num2;
weights[i] = val;
}
}
}
private float Sum(in BoneWeight bw)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
BoneWeight val = bw;
float weight = ((BoneWeight)(ref val)).weight0;
val = bw;
float num = weight + ((BoneWeight)(ref val)).weight1;
val = bw;
float num2 = num + ((BoneWeight)(ref val)).weight2;
val = bw;
return num2 + ((BoneWeight)(ref val)).weight3;
}
private void Acc(Dictionary<int, float> map, int boneIndex, float w, float tiny)
{
if (boneIndex >= 0 && !(w <= tiny))
{
if (map.TryGetValue(boneIndex, out var value))
{
map[boneIndex] = value + w;
}
else
{
map[boneIndex] = w;
}
}
}
private BoneWeight BuildTop4Normalized(Dictionary<int, float> map, float tiny)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
if (map == null || map.Count == 0)
{
return default(BoneWeight);
}
List<KeyValuePair<int, float>> list = map.OrderByDescending((KeyValuePair<int, float> kv) => kv.Value).Take(4).ToList();
float num = 0f;
for (int num2 = 0; num2 < list.Count; num2++)
{
num += list[num2].Value;
}
if (num < tiny)
{
return default(BoneWeight);
}
float num3 = 1f / num;
BoneWeight result = default(BoneWeight);
for (int num4 = 0; num4 < list.Count; num4++)
{
int key = list[num4].Key;
float num5 = list[num4].Value * num3;
switch (num4)
{
case 0:
((BoneWeight)(ref result)).boneIndex0 = key;
((BoneWeight)(ref result)).weight0 = num5;
break;
case 1:
((BoneWeight)(ref result)).boneIndex1 = key;
((BoneWeight)(ref result)).weight1 = num5;
break;
case 2:
((BoneWeight)(ref result)).boneIndex2 = key;
((BoneWeight)(ref result)).weight2 = num5;
break;
case 3:
((BoneWeight)(ref result)).boneIndex3 = key;
((BoneWeight)(ref result)).weight3 = num5;
break;
}
}
return result;
}
}