Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of StitchEyelessDog v1.1.0
BepInEx/plugins/StitchEyelessDog/StitchDog.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering.HighDefinition; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [BepInPlugin("local.stitcheyelessdog", "Stitch Eyeless Dog", "1.1.0")] public sealed class StitchDog : BaseUnityPlugin { private const string Id = "local.stitcheyelessdog"; private static StitchDog instance; private static readonly int BaseMap = Shader.PropertyToID("_BaseColorMap"); private Texture2D skin; private Texture2D detailsTexture; private Texture2D detailsMask; private StitchDetails details; private Material detailsMaterial; private bool reported; private string directory; private bool useDetails; private Texture2D fallback; private Texture2D bodyMask; private StitchDetails body0; private StitchDetails body1; private Material bodyMaterial; private Material toothMaterial; private bool correctNormals; private void LoadBodyAssets() { fallback = LoadPng(Path.Combine(directory, "StitchFallback.png")); bodyMask = LoadPng(Path.Combine(directory, "StitchMask.png")); body0 = StitchDetails.Load(Path.Combine(directory, "StitchBody0.mesh")); body1 = StitchDetails.Load(Path.Combine(directory, "StitchBody1.mesh")); ((Object)body0.Mesh).name = "Stitch_Body_LOD0"; ((Object)body1.Mesh).name = "Stitch_Body_LOD1"; } private void Awake() { //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown directory = Path.GetDirectoryName(typeof(StitchDog).Assembly.Location); try { skin = LoadPng(Path.Combine(directory, "Stitch.png")); correctNormals = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance", "CorrectSkinnedNormals", true, "Keep lighting normals aligned with the visible deformed mesh; does not change its geometry or animation.").Value; LoadBodyAssets(); useDetails = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance", "UseTerrierDetails", true, "Add small cosmetic folded ears and eye caps to the original dog rig.").Value; if (useDetails) { try { detailsTexture = LoadPng(Path.Combine(directory, "StitchDetails.png")); detailsMask = LoadPng(Path.Combine(directory, "StitchDetailsMask.png")); details = StitchDetails.Load(Path.Combine(directory, "Stitch.details")); } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException || ex is ArgumentException) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Using the fur texture without optional terrier details: " + ex.Message)); } } instance = this; new Harmony("local.stitcheyelessdog").Patch((MethodBase)AccessTools.DeclaredMethod(typeof(MouthDogAI), "Start", Type.EmptyTypes, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(StitchDog), "AfterDogStart", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded Stitch.png; original AI, audio, animation controller and colliders are retained."); } catch (Exception ex2) when (ex2 is IOException || ex2 is UnauthorizedAccessException || ex2 is ArgumentException) { ((BaseUnityPlugin)this).Logger.LogError((object)("Could not load the Stitch skin. The original dog will be used. " + ex2.Message)); } } private static Texture2D LoadPng(string path) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown byte[] array; using (FileStream fileStream = File.OpenRead(path)) { if (fileStream.Length < 33 || fileStream.Length > 33554432) { throw new InvalidDataException("PNG file size is invalid: " + Path.GetFileName(path)); } using BinaryReader binaryReader = new BinaryReader(fileStream); array = binaryReader.ReadBytes((int)fileStream.Length); } byte[] array2 = new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 }; for (int i = 0; i < array2.Length; i++) { if (array[i] != array2[i]) { throw new InvalidDataException("Invalid PNG signature."); } } uint num = BigEndianUInt(array, 16); uint num2 = BigEndianUInt(array, 20); if (BigEndianUInt(array, 8) != 13 || BigEndianUInt(array, 12) != 1229472850 || num == 0 || num2 == 0 || num > 4096 || num2 > 4096) { throw new InvalidDataException("Use a PNG with dimensions up to 4096 x 4096."); } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, false); if (!ImageConversion.LoadImage(val, array, true)) { Object.Destroy((Object)(object)val); throw new InvalidDataException("Unity could not decode the PNG."); } ((Object)val).name = Path.GetFileNameWithoutExtension(path); ((Texture)val).filterMode = (FilterMode)2; ((Texture)val).wrapMode = (TextureWrapMode)1; return val; } private static uint BigEndianUInt(byte[] data, int offset) { return (uint)((data[offset] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | data[offset + 3]); } public static void ReloadForPreview() { if (Object.FindObjectsOfType<MouthDogAI>().Length != 0 || ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.connectedPlayersAmount != 0)) { throw new InvalidOperationException("Preview reload requires no live dogs and no connected peers."); } StitchDog stitchDog = instance; Texture2D val = LoadPng(Path.Combine(stitchDog.directory, "Stitch.png")); Texture2D val2 = null; Texture2D val3 = null; StitchDetails stitchDetails = null; try { if (stitchDog.useDetails) { val2 = LoadPng(Path.Combine(stitchDog.directory, "StitchDetails.png")); val3 = LoadPng(Path.Combine(stitchDog.directory, "StitchDetailsMask.png")); stitchDetails = StitchDetails.Load(Path.Combine(stitchDog.directory, "Stitch.details")); } } catch { Object.Destroy((Object)(object)val); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } if ((Object)(object)val3 != (Object)null) { Object.Destroy((Object)(object)val3); } throw; } Object.Destroy((Object)(object)stitchDog.skin); if ((Object)(object)stitchDog.detailsTexture != (Object)null) { Object.Destroy((Object)(object)stitchDog.detailsTexture); } if ((Object)(object)stitchDog.detailsMask != (Object)null) { Object.Destroy((Object)(object)stitchDog.detailsMask); } if ((Object)(object)stitchDog.detailsMaterial != (Object)null) { Object.Destroy((Object)(object)stitchDog.detailsMaterial); } if (stitchDog.details != null) { stitchDog.details.Release(); } if (stitchDog.body0 != null) { stitchDog.body0.Release(); } if (stitchDog.body1 != null) { stitchDog.body1.Release(); } if ((Object)(object)stitchDog.fallback != (Object)null) { Object.Destroy((Object)(object)stitchDog.fallback); } if ((Object)(object)stitchDog.bodyMask != (Object)null) { Object.Destroy((Object)(object)stitchDog.bodyMask); } if ((Object)(object)stitchDog.bodyMaterial != (Object)null) { Object.Destroy((Object)(object)stitchDog.bodyMaterial); } stitchDog.skin = val; stitchDog.detailsTexture = val2; stitchDog.detailsMask = val3; stitchDog.details = stitchDetails; stitchDog.detailsMaterial = null; stitchDog.bodyMaterial = null; stitchDog.LoadBodyAssets(); } private static void AfterDogStart(MouthDogAI __instance) { try { ApplyTo(((Component)__instance).gameObject); } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)("Stitch appearance could not be applied: " + ex)); } } public static void ApplyTo(GameObject root) { //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Expected O, but got Unknown //IL_043a: 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: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Expected O, but got Unknown //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) StitchDog stitchDog = instance; if ((Object)(object)stitchDog == (Object)null || (Object)(object)stitchDog.skin == (Object)null || (Object)(object)root.GetComponent<StitchDogApplied>() != (Object)null) { return; } int num = 0; Dictionary<Renderer, Renderer> dictionary = new Dictionary<Renderer, Renderer>(); SkinnedMeshRenderer[] componentsInChildren = root.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { Mesh sharedMesh = val.sharedMesh; if ((Object)(object)sharedMesh == (Object)null || (((Object)sharedMesh).name != "ToothDogBody" && ((Object)sharedMesh).name != "ToothDogBodyLOD1")) { continue; } Material sharedMaterial = ((Renderer)val).sharedMaterial; if ((Object)(object)sharedMaterial == (Object)null || !sharedMaterial.HasProperty(BaseMap)) { continue; } StitchDetails stitchDetails = ((((Object)sharedMesh).name == "ToothDogBody") ? stitchDog.body0 : stitchDog.body1); bool flag = stitchDetails?.Matches(val) ?? false; if (flag) { val.sharedMesh = stitchDetails.Mesh; if ((Object)(object)stitchDog.bodyMaterial == (Object)null) { Material val2 = new Material(sharedMaterial) { name = "Stitch_OriginalShapeFur" }; val2.SetTexture(BaseMap, (Texture)(object)stitchDog.skin); val2.SetTexture("_MainTex", (Texture)(object)stitchDog.skin); val2.SetTexture("_MaskMap", (Texture)(object)stitchDog.bodyMask); val2.SetColor("_BaseColor", Color.white); val2.SetFloat("_Metallic", 0f); val2.SetFloat("_MetallicRemapMin", 0f); val2.SetFloat("_MetallicRemapMax", 0f); val2.SetFloat("_SmoothnessRemapMin", 0f); val2.SetFloat("_SmoothnessRemapMax", 1f); val2.EnableKeyword("_MASKMAP"); HDMaterial.ValidateMaterial(val2); stitchDog.bodyMaterial = val2; } ((Renderer)val).sharedMaterial = stitchDog.bodyMaterial; if (stitchDog.correctNormals) { ((Component)val).gameObject.AddComponent<StitchNormals>().Initialize(val); } } MaterialPropertyBlock val3 = new MaterialPropertyBlock(); ((Renderer)val).GetPropertyBlock(val3); val3.SetTexture(BaseMap, (Texture)(object)(flag ? stitchDog.skin : stitchDog.fallback)); val3.SetTexture("_MainTex", (Texture)(object)(flag ? stitchDog.skin : stitchDog.fallback)); ((Renderer)val).SetPropertyBlock(val3); num++; if (stitchDog.details != null && stitchDog.details.Matches(val)) { if ((Object)(object)stitchDog.detailsMaterial == (Object)null) { Material val4 = new Material(sharedMaterial) { name = "Stitch_TerrierDetails" }; val4.SetTexture(BaseMap, (Texture)(object)stitchDog.detailsTexture); val4.SetTexture("_MainTex", (Texture)(object)stitchDog.detailsTexture); val4.SetTexture("_MaskMap", (Texture)(object)stitchDog.detailsMask); val4.SetColor("_BaseColor", Color.white); val4.SetColor("_EmissiveColor", Color.black); val4.SetFloat("_Metallic", 0f); val4.SetFloat("_MetallicRemapMin", 0f); val4.SetFloat("_MetallicRemapMax", 0f); val4.SetFloat("_SmoothnessRemapMin", 0f); val4.SetFloat("_SmoothnessRemapMax", 1f); val4.EnableKeyword("_MASKMAP"); HDMaterial.ValidateMaterial(val4); stitchDog.detailsMaterial = val4; } dictionary.Add((Renderer)(object)val, (Renderer)(object)stitchDog.details.Attach(val, stitchDog.detailsMaterial)); } } if (num == 0) { return; } MeshRenderer[] componentsInChildren2 = root.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val5 in componentsInChildren2) { if (!(((Object)val5).name != "TeethTop") || !(((Object)val5).name != "TeethBottom")) { if ((Object)(object)stitchDog.toothMaterial == (Object)null) { Material val6 = new Material(((Renderer)val5).sharedMaterial) { name = "Stitch_CleanIvoryTeeth" }; val6.SetTexture(BaseMap, (Texture)(object)Texture2D.whiteTexture); val6.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture); val6.SetColor("_BaseColor", new Color(0.8f, 0.76f, 0.64f, 1f)); val6.SetFloat("_Smoothness", 0.24f); val6.SetFloat("_Metallic", 0f); HDMaterial.ValidateMaterial(val6); stitchDog.toothMaterial = val6; } ((Renderer)val5).sharedMaterial = stitchDog.toothMaterial; } } LODGroup[] componentsInChildren3 = root.GetComponentsInChildren<LODGroup>(true); foreach (LODGroup val7 in componentsInChildren3) { LOD[] lODs = val7.GetLODs(); for (int j = 0; j < lODs.Length; j++) { List<Renderer> list = new List<Renderer>(lODs[j].renderers); Renderer[] renderers = lODs[j].renderers; foreach (Renderer val8 in renderers) { if ((Object)(object)val8 != (Object)null && dictionary.TryGetValue(val8, out var value)) { list.Add(value); } } lODs[j].renderers = list.ToArray(); } val7.SetLODs(lODs); } root.AddComponent<StitchDogApplied>(); if (!stitchDog.reported) { stitchDog.reported = true; ((BaseUnityPlugin)stitchDog).Logger.LogInfo((object)$"Applied Stitch to {num} stock LOD(s), with {dictionary.Count} matching cosmetic detail renderer(s)."); } } } public sealed class StitchDogApplied : MonoBehaviour { } internal sealed class StitchDetails { private string[] names; private Mesh mesh; internal Mesh Mesh => mesh; internal void Release() { Object.Destroy((Object)(object)mesh); } private static float Finite(BinaryReader reader) { float num = reader.ReadSingle(); if (float.IsNaN(num) || float.IsInfinity(num)) { throw new InvalidDataException("Non-finite detail coordinate."); } return num; } internal static StitchDetails Load(string path) { //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Expected O, but got Unknown using FileStream fileStream = File.OpenRead(path); using BinaryReader binaryReader = new BinaryReader(fileStream); if (fileStream.Length > 16777216 || Encoding.ASCII.GetString(binaryReader.ReadBytes(8)) != "STITCH01") { throw new InvalidDataException("Invalid Stitch detail header."); } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); int num3 = binaryReader.ReadInt32(); if (num != 22 || num2 < 1 || num2 > 60000 || num3 < 3 || num3 > 300000 || num3 % 3 != 0) { throw new InvalidDataException("Invalid Stitch detail counts."); } StitchDetails stitchDetails = new StitchDetails { names = new string[num] }; for (int i = 0; i < num; i++) { int num4 = binaryReader.ReadInt32(); if (num4 < 1 || num4 > 96) { throw new InvalidDataException("Invalid bone name."); } byte[] array = binaryReader.ReadBytes(num4); if (array.Length != num4) { throw new EndOfStreamException(); } stitchDetails.names[i] = Encoding.UTF8.GetString(array); } Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num]; for (int j = 0; j < num; j++) { for (int k = 0; k < 4; k++) { for (int l = 0; l < 4; l++) { ((Matrix4x4)(ref array2[j]))[k, l] = Finite(binaryReader); } } } Vector3[] array3 = (Vector3[])(object)new Vector3[num2]; Vector3[] array4 = (Vector3[])(object)new Vector3[num2]; Vector2[] array5 = (Vector2[])(object)new Vector2[num2]; for (int m = 0; m < num2; m++) { array3[m] = new Vector3(Finite(binaryReader), Finite(binaryReader), Finite(binaryReader)); } for (int n = 0; n < num2; n++) { array4[n] = new Vector3(Finite(binaryReader), Finite(binaryReader), Finite(binaryReader)); } for (int num5 = 0; num5 < num2; num5++) { array5[num5] = new Vector2(Finite(binaryReader), Finite(binaryReader)); } BoneWeight[] array6 = (BoneWeight[])(object)new BoneWeight[num2]; for (int num6 = 0; num6 < num2; num6++) { ((BoneWeight)(ref array6[num6])).weight0 = Finite(binaryReader); ((BoneWeight)(ref array6[num6])).weight1 = Finite(binaryReader); ((BoneWeight)(ref array6[num6])).weight2 = Finite(binaryReader); ((BoneWeight)(ref array6[num6])).weight3 = Finite(binaryReader); float num7 = ((BoneWeight)(ref array6[num6])).weight0 + ((BoneWeight)(ref array6[num6])).weight1 + ((BoneWeight)(ref array6[num6])).weight2 + ((BoneWeight)(ref array6[num6])).weight3; if (((BoneWeight)(ref array6[num6])).weight0 < 0f || ((BoneWeight)(ref array6[num6])).weight1 < 0f || ((BoneWeight)(ref array6[num6])).weight2 < 0f || ((BoneWeight)(ref array6[num6])).weight3 < 0f || Mathf.Abs(num7 - 1f) > 0.002f) { throw new InvalidDataException("Invalid skin weights."); } } for (int num8 = 0; num8 < num2; num8++) { int num9 = binaryReader.ReadInt32(); int num10 = binaryReader.ReadInt32(); int num11 = binaryReader.ReadInt32(); int num12 = binaryReader.ReadInt32(); if (num9 < 0 || num9 >= num || num10 < 0 || num10 >= num || num11 < 0 || num11 >= num || num12 < 0 || num12 >= num) { throw new InvalidDataException("Invalid bone index."); } ((BoneWeight)(ref array6[num8])).boneIndex0 = num9; ((BoneWeight)(ref array6[num8])).boneIndex1 = num10; ((BoneWeight)(ref array6[num8])).boneIndex2 = num11; ((BoneWeight)(ref array6[num8])).boneIndex3 = num12; } int[] array7 = new int[num3]; for (int num13 = 0; num13 < num3; num13++) { array7[num13] = binaryReader.ReadInt32(); if (array7[num13] < 0 || array7[num13] >= num2) { throw new InvalidDataException("Invalid triangle index."); } } if (fileStream.Position != fileStream.Length) { throw new InvalidDataException("Unexpected detail bytes."); } stitchDetails.mesh = new Mesh { name = "Stitch_TerrierDetails" }; stitchDetails.mesh.vertices = array3; stitchDetails.mesh.normals = array4; stitchDetails.mesh.uv = array5; stitchDetails.mesh.bindposes = array2; stitchDetails.mesh.boneWeights = array6; stitchDetails.mesh.triangles = array7; stitchDetails.mesh.RecalculateBounds(); stitchDetails.mesh.RecalculateTangents(); return stitchDetails; } internal bool Matches(SkinnedMeshRenderer renderer) { if (renderer.bones.Length != names.Length) { return false; } for (int i = 0; i < names.Length; i++) { if ((Object)(object)renderer.bones[i] == (Object)null || ((Object)renderer.bones[i]).name != names[i]) { return false; } } return true; } internal SkinnedMeshRenderer Attach(SkinnedMeshRenderer source, Material material) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Stitch_TerrierDetails"); val.layer = ((Component)source).gameObject.layer; val.transform.SetParent(((Component)source).transform, false); SkinnedMeshRenderer obj = val.AddComponent<SkinnedMeshRenderer>(); obj.sharedMesh = mesh; ((Renderer)obj).sharedMaterial = material; obj.bones = source.bones; obj.rootBone = source.rootBone; obj.quality = (SkinQuality)4; ((Renderer)obj).shadowCastingMode = ((Renderer)source).shadowCastingMode; ((Renderer)obj).receiveShadows = ((Renderer)source).receiveShadows; Bounds localBounds = ((Renderer)source).localBounds; ((Bounds)(ref localBounds)).Encapsulate(mesh.bounds); ((Renderer)obj).localBounds = localBounds; val.AddComponent<StitchDetailVisibility>().Source = source; return obj; } } public sealed class StitchDetailVisibility : MonoBehaviour { public SkinnedMeshRenderer Source; private SkinnedMeshRenderer own; private void Awake() { own = ((Component)this).GetComponent<SkinnedMeshRenderer>(); } private void LateUpdate() { if ((Object)(object)Source == (Object)null) { ((Renderer)own).enabled = false; return; } ((Renderer)own).enabled = ((Renderer)Source).enabled; ((Renderer)own).forceRenderingOff = ((Renderer)Source).forceRenderingOff; ((Component)this).gameObject.layer = ((Component)Source).gameObject.layer; } } public sealed class StitchNormals : MonoBehaviour { private struct VertexKey : IEquatable<VertexKey> { internal Vector3 Position; internal BoneWeight Weight; public bool Equals(VertexKey other) { //IL_0007: 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) if (((Vector3)(ref Position)).Equals(other.Position)) { return ((BoneWeight)(ref Weight)).Equals(other.Weight); } return false; } public override bool Equals(object value) { if (value is VertexKey other) { return Equals(other); } return false; } public override int GetHashCode() { return (((object)Unsafe.As<Vector3, Vector3>(ref Position)/*cast due to .constrained prefix*/).GetHashCode() * 397) ^ ((object)Unsafe.As<BoneWeight, BoneWeight>(ref Weight)/*cast due to .constrained prefix*/).GetHashCode(); } } private SkinnedMeshRenderer target; private Mesh ownMesh; private Vector3[] rest; private BoneWeight[] weights; private Matrix4x4[] binds; private Matrix4x4[] matrices; private Vector3[] world; private Vector3[] inverse0; private Vector3[] inverse1; private Vector3[] inverse2; private float[] inverseDet; private int[] groups; private int[] triangles; private int[][] neighbours; private Vector3[] face; private Vector3[] unit; private List<Vector3> corrected; private float updateAt; private Transform[] bones; public double LastBuildMilliseconds { get; private set; } internal void Initialize(SkinnedMeshRenderer renderer) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) target = renderer; ownMesh = Object.Instantiate<Mesh>(renderer.sharedMesh); ((Object)ownMesh).name = ((Object)renderer.sharedMesh).name; ownMesh.MarkDynamic(); renderer.sharedMesh = ownMesh; Vector3[] vertices = ownMesh.vertices; BoneWeight[] boneWeights = ownMesh.boneWeights; triangles = ownMesh.triangles; binds = ownMesh.bindposes; bones = renderer.bones; matrices = (Matrix4x4[])(object)new Matrix4x4[binds.Length]; groups = new int[vertices.Length]; Dictionary<VertexKey, int> dictionary = new Dictionary<VertexKey, int>(); List<Vector3> list = new List<Vector3>(); List<BoneWeight> list2 = new List<BoneWeight>(); for (int i = 0; i < vertices.Length; i++) { VertexKey key = new VertexKey { Position = vertices[i], Weight = boneWeights[i] }; if (!dictionary.TryGetValue(key, out var value)) { value = list.Count; dictionary.Add(key, value); list.Add(vertices[i]); list2.Add(boneWeights[i]); } groups[i] = value; } rest = list.ToArray(); weights = list2.ToArray(); world = (Vector3[])(object)new Vector3[rest.Length]; inverse0 = (Vector3[])(object)new Vector3[rest.Length]; inverse1 = (Vector3[])(object)new Vector3[rest.Length]; inverse2 = (Vector3[])(object)new Vector3[rest.Length]; inverseDet = new float[rest.Length]; face = (Vector3[])(object)new Vector3[triangles.Length / 3]; unit = (Vector3[])(object)new Vector3[face.Length]; List<int>[] array = new List<int>[rest.Length]; for (int j = 0; j < array.Length; j++) { array[j] = new List<int>(); } for (int k = 0; k < face.Length; k++) { for (int l = 0; l < 3; l++) { List<int> list3 = array[groups[triangles[k * 3 + l]]]; if (!list3.Contains(k)) { list3.Add(k); } } } neighbours = new int[array.Length][]; for (int m = 0; m < array.Length; m++) { neighbours[m] = array[m].ToArray(); } corrected = new List<Vector3>(ownMesh.normals); Rebuild(); } private static Vector3 Column(Matrix4x4 matrix, int column) { //IL_0003: 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_0009: 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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Vector4 column2 = ((Matrix4x4)(ref matrix)).GetColumn(column); return new Vector3(column2.x, column2.y, column2.z); } private void LateUpdate() { if (!((Object)(object)target == (Object)null) && !((Object)(object)ownMesh == (Object)null) && ((Renderer)target).enabled && ((Renderer)target).isVisible && !(Time.unscaledTime < updateAt)) { updateAt = Time.unscaledTime + 1f / 30f; Rebuild(); } } public void ForceRebuild() { if ((Object)(object)target != (Object)null && (Object)(object)ownMesh != (Object)null) { Rebuild(); } } private void Rebuild() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0166: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017f: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0198: 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_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: 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_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0205: 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_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0270: 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_027b: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0292: 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_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) //IL_0472: 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_0486: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_049b: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_0441: 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) long timestamp = Stopwatch.GetTimestamp(); for (int i = 0; i < matrices.Length; i++) { if ((Object)(object)bones[i] == (Object)null) { return; } matrices[i] = bones[i].localToWorldMatrix * binds[i]; } for (int j = 0; j < rest.Length; j++) { BoneWeight val = weights[j]; Matrix4x4 matrix = matrices[((BoneWeight)(ref val)).boneIndex0]; Matrix4x4 matrix2 = matrices[((BoneWeight)(ref val)).boneIndex1]; Matrix4x4 matrix3 = matrices[((BoneWeight)(ref val)).boneIndex2]; Matrix4x4 matrix4 = matrices[((BoneWeight)(ref val)).boneIndex3]; world[j] = ((Matrix4x4)(ref matrix)).MultiplyPoint3x4(rest[j]) * ((BoneWeight)(ref val)).weight0 + ((Matrix4x4)(ref matrix2)).MultiplyPoint3x4(rest[j]) * ((BoneWeight)(ref val)).weight1 + ((Matrix4x4)(ref matrix3)).MultiplyPoint3x4(rest[j]) * ((BoneWeight)(ref val)).weight2 + ((Matrix4x4)(ref matrix4)).MultiplyPoint3x4(rest[j]) * ((BoneWeight)(ref val)).weight3; Vector3 val2 = Column(matrix, 0) * ((BoneWeight)(ref val)).weight0 + Column(matrix2, 0) * ((BoneWeight)(ref val)).weight1 + Column(matrix3, 0) * ((BoneWeight)(ref val)).weight2 + Column(matrix4, 0) * ((BoneWeight)(ref val)).weight3; Vector3 val3 = Column(matrix, 1) * ((BoneWeight)(ref val)).weight0 + Column(matrix2, 1) * ((BoneWeight)(ref val)).weight1 + Column(matrix3, 1) * ((BoneWeight)(ref val)).weight2 + Column(matrix4, 1) * ((BoneWeight)(ref val)).weight3; Vector3 val4 = Column(matrix, 2) * ((BoneWeight)(ref val)).weight0 + Column(matrix2, 2) * ((BoneWeight)(ref val)).weight1 + Column(matrix3, 2) * ((BoneWeight)(ref val)).weight2 + Column(matrix4, 2) * ((BoneWeight)(ref val)).weight3; inverse0[j] = Vector3.Cross(val3, val4); inverse1[j] = Vector3.Cross(val4, val2); inverse2[j] = Vector3.Cross(val2, val3); float num = Vector3.Dot(val2, inverse0[j]); inverseDet[j] = ((Mathf.Abs(num) > 1E-10f) ? (1f / num) : 0f); } for (int k = 0; k < face.Length; k++) { Vector3 val5 = world[groups[triangles[k * 3]]]; Vector3 val6 = world[groups[triangles[k * 3 + 1]]]; Vector3 val7 = world[groups[triangles[k * 3 + 2]]]; face[k] = Vector3.Cross(val6 - val5, val7 - val5); unit[k] = ((Vector3)(ref face[k])).normalized; } for (int l = 0; l < face.Length; l++) { for (int m = 0; m < 3; m++) { int num2 = triangles[l * 3 + m]; int num3 = groups[num2]; Vector3 val8 = Vector3.zero; int[] array = neighbours[num3]; foreach (int num4 in array) { if (Vector3.Dot(unit[l], unit[num4]) > 0.35f) { val8 += face[num4]; } } Vector3 val9 = new Vector3(Vector3.Dot(inverse0[num3], val8), Vector3.Dot(inverse1[num3], val8), Vector3.Dot(inverse2[num3], val8)) * inverseDet[num3]; if (((Vector3)(ref val9)).sqrMagnitude > 1E-12f) { corrected[num2] = ((Vector3)(ref val9)).normalized; } } } ownMesh.SetNormals(corrected); LastBuildMilliseconds = (double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency; } private void OnDestroy() { if ((Object)(object)ownMesh != (Object)null) { Object.Destroy((Object)(object)ownMesh); } } }