// 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 bodyMeshes, IReadOnlyList bodyBakedMeshes, int referenceBodyIndex = 0, Settings settings = null, Dictionary boneTypeMap = null, Dictionary 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 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 value = null; if (cloth.humanoidMatchedBones != null) { cloth.humanoidMatchedBones.TryGetValue((HumanBodyBones)10, out value); } HashSet hashSet = new HashSet(); 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 list = new List(); accIndexByTransform = new Dictionary(); 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 dictionary = new Dictionary(); foreach (KeyValuePair> humanoidMatchedBone in cloth.humanoidMatchedBones) { HumanBodyBones key = humanoidMatchedBone.Key; HashSet 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 dictionary2 = new Dictionary(); Dictionary dictionary3 = new Dictionary(); 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 dictionary4 = new Dictionary(); 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 clothBoneToHuman, Dictionary 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 bodyMeshes, IReadOnlyList 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 dictionary = new Dictionary(); 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[] 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 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 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 hashSet = null; if (accessoryBones != null && accessoryBones.Length != 0) { hashSet = new HashSet(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 val = default(NativeArray); val._002Ector(num, (Allocator)2, (NativeArrayOptions)1); List list = new List(num * 4); NativeArray val2 = default(NativeArray); 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(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 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> equivalentVertices = cloth.equivalentVertices; int num = finalWeights.Length; bool[] array = new bool[num]; foreach (List item in equivalentVertices) { if (item == null || item.Count == 0) { continue; } List 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(); } list.Add(num2); if (!array[num2]) { flag = true; } } } if (list == null || !flag) { continue; } Dictionary weightMap = new Dictionary(); 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> list2 = weightMap.OrderByDescending((KeyValuePair 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 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[] BuildAdjacencyFromTriangles(int vertexCount, int[] triangles) { List[] array = new List[vertexCount]; for (int i = 0; i < vertexCount; i++) { array[i] = new List(); } 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[] 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 hashSet = new HashSet(); 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[] 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 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[] 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 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[] 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 queue = new Queue(); 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[] 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[] 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[] 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 map = new Dictionary(); Queue queue = new Queue(); Dictionary dictionary = new Dictionary(); HashSet hashSet = new HashSet(); 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 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[] adjacency, float tiny, int maxDepth) { Queue queue = new Queue(); Dictionary dictionary = new Dictionary(); HashSet hashSet = new HashSet(); 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 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 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 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> list = map.OrderByDescending((KeyValuePair 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; } }