Decompiled source of LowSpecGaming v0.3.3
LowSpecGaming.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AK; using AssetShards; using BepInEx; using BepInEx.Configuration; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Hook; using CellMenu; using ChainedPuzzles; using CullingSystem; using Decals; using FluffyUnderware.Curvy; using GTFO.API; using GameData; using HarmonyLib; using IRF; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.Runtime; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using LowSpecGaming.Misc; using LowSpecGaming.Patches; using LowSpecGaming.Settings; using LowSpecGaming.Util; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Rendering; using UnityMeshSimplifier; using UnityMeshSimplifier.Internal; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("LowSpecGaming")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("LowSpecGaming")] [assembly: AssemblyTitle("LowSpecGaming")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] P_0) { TransformFlags = P_0; } } } namespace UnityMeshSimplifier { public static class MathHelper { public const float PI = (float)Math.PI; public const double PId = Math.PI; public const float Deg2Rad = (float)Math.PI / 180f; public const double Deg2Radd = Math.PI / 180.0; public const float Rad2Deg = 180f / (float)Math.PI; public const double Rad2Degd = 180.0 / Math.PI; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Min(double val1, double val2, double val3) { if (!(val1 < val2)) { if (!(val2 < val3)) { return val3; } return val2; } if (!(val1 < val3)) { return val3; } return val1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Clamp(double value, double min, double max) { if (!(value >= min)) { return min; } if (!(value <= max)) { return max; } return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double TriangleArea(ref Vector3d p0, ref Vector3d p1, ref Vector3d p2) { Vector3d from = p1 - p0; Vector3d to = p2 - p0; return from.Magnitude * (Math.Sin((float)(Vector3d.Angle(ref from, ref to) * (Math.PI / 180.0))) * to.Magnitude) * 0.5; } } public class MeshSimplifier { private const int TriangleEdgeCount = 3; private const int TriangleVertexCount = 3; private const double DoubleEpsilon = 0.001; private const double DenomEpilson = 1E-08; private static readonly int UVChannelCount = MeshUtils.UVChannelCount; private SimplificationOptions simplificationOptions = SimplificationOptions.Default; private bool verbose; private int subMeshCount; private int[] subMeshOffsets; private ResizableArray<Triangle> triangles; private ResizableArray<Vertex> vertices; private ResizableArray<Ref> refs; private ResizableArray<Vector3> vertNormals; private ResizableArray<Vector4> vertTangents; private UVChannels<Vector2> vertUV2D; private UVChannels<Vector3> vertUV3D; private UVChannels<Vector4> vertUV4D; private ResizableArray<Color> vertColors; private ResizableArray<BoneWeight> vertBoneWeights; private Matrix4x4[] bindposes; private readonly double[] errArr = new double[3]; private readonly int[] attributeIndexArr = new int[3]; private readonly HashSet<Triangle> triangleHashSet1 = new HashSet<Triangle>(); private readonly HashSet<Triangle> triangleHashSet2 = new HashSet<Triangle>(); public Vector3[] Vertices { get { //IL_002c: 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) int length = vertices.Length; Vector3[] array = (Vector3[])(object)new Vector3[length]; ResizableArray<Vertex> resizableArray = vertices; for (int i = 0; i < length; i++) { array[i] = (Vector3)resizableArray[i].p; } return array; } set { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (value == null) { throw new ArgumentNullException("value"); } vertices.Resize(value.Length); ResizableArray<Vertex> resizableArray = vertices; for (int i = 0; i < value.Length; i++) { resizableArray[i] = new Vertex(i, value[i]); } } } public Vector3[] Normals { get { if (vertNormals == null) { return null; } return vertNormals.Data; } set { InitializeVertexAttribute(value, ref vertNormals, "normals"); } } public Vector4[] Tangents { get { if (vertTangents == null) { return null; } return vertTangents.Data; } set { InitializeVertexAttribute(value, ref vertTangents, "tangents"); } } public Vector2[] UV1 { get { return GetUVs2D(0); } set { SetUVs(0, value); } } public Vector2[] UV2 { get { return GetUVs2D(1); } set { SetUVs(1, value); } } public Vector2[] UV3 { get { return GetUVs2D(2); } set { SetUVs(2, value); } } public Vector2[] UV4 { get { return GetUVs2D(3); } set { SetUVs(3, value); } } public Color[] Colors { get { if (vertColors == null) { return null; } return vertColors.Data; } set { InitializeVertexAttribute(value, ref vertColors, "colors"); } } public MeshSimplifier() { triangles = new ResizableArray<Triangle>(0); vertices = new ResizableArray<Vertex>(0); refs = new ResizableArray<Ref>(0); } public MeshSimplifier(Mesh mesh) : this() { if ((Object)(object)mesh != (Object)null) { Initialize(mesh); } } public int[][] GetAllSubMeshTriangles() { int[][] array = new int[subMeshCount][]; for (int i = 0; i < subMeshCount; i++) { array[i] = GetSubMeshTriangles(i); } return array; } public int[] GetSubMeshTriangles(int subMeshIndex) { if (subMeshIndex < 0) { throw new ArgumentOutOfRangeException("subMeshIndex", "The sub-mesh index is negative."); } if (subMeshOffsets == null) { CalculateSubMeshOffsets(); } if (subMeshIndex >= subMeshOffsets.Length) { throw new ArgumentOutOfRangeException("subMeshIndex", "The sub-mesh index is greater than or equals to the sub mesh count."); } if (subMeshOffsets.Length != subMeshCount) { throw new InvalidOperationException("The sub-mesh triangle offsets array is not the same size as the count of sub-meshes. This should not be possible to happen."); } Triangle[] data = triangles.Data; int length = triangles.Length; int num = subMeshOffsets[subMeshIndex]; if (num >= length) { return new int[0]; } int num2 = ((subMeshIndex + 1 < subMeshCount) ? subMeshOffsets[subMeshIndex + 1] : length); int num3 = num2 - num; if (num3 < 0) { num3 = 0; } int[] array = new int[num3 * 3]; for (int i = num; i < num2; i++) { Triangle triangle = data[i]; int num4 = (i - num) * 3; array[num4] = triangle.v0; array[num4 + 1] = triangle.v1; array[num4 + 2] = triangle.v2; } return array; } private void CalculateSubMeshOffsets() { int num = -1; subMeshOffsets = new int[subMeshCount]; Triangle[] data = triangles.Data; int length = triangles.Length; for (int i = 0; i < length; i++) { Triangle triangle = data[i]; if (triangle.subMeshIndex > num) { for (int j = num + 1; j < triangle.subMeshIndex; j++) { subMeshOffsets[j] = i; } subMeshOffsets[triangle.subMeshIndex] = i; num = triangle.subMeshIndex; } } for (int k = num + 1; k < subMeshCount; k++) { subMeshOffsets[k] = length; } } public void Initialize(Mesh mesh) { if ((Object)(object)mesh == (Object)null) { throw new ArgumentNullException("mesh"); } Vertices = Il2CppArrayBase<Vector3>.op_Implicit((Il2CppArrayBase<Vector3>)(object)mesh.vertices); Normals = Il2CppArrayBase<Vector3>.op_Implicit((Il2CppArrayBase<Vector3>)(object)mesh.normals); Tangents = Il2CppArrayBase<Vector4>.op_Implicit((Il2CppArrayBase<Vector4>)(object)mesh.tangents); Colors = Il2CppArrayBase<Color>.op_Implicit((Il2CppArrayBase<Color>)(object)mesh.colors); Il2CppStructArray<Vector2> uv2 = (mesh.uv = mesh.uv); mesh.uv2 = uv2; ClearSubMeshes(); int num = mesh.subMeshCount; int[][] array = new int[num][]; for (int i = 0; i < num; i++) { array[i] = Il2CppArrayBase<int>.op_Implicit((Il2CppArrayBase<int>)(object)mesh.GetTriangles(i)); } AddSubMeshTriangles(array); } private void InitializeVertexAttribute<T>(T[] attributeValues, ref ResizableArray<T> attributeArray, string attributeName) { if (attributeValues != null && attributeValues.Length == vertices.Length) { if (attributeArray == null) { attributeArray = new ResizableArray<T>(attributeValues.Length, attributeValues.Length); } else { attributeArray.Resize(attributeValues.Length); } T[] data = attributeArray.Data; Array.Copy(attributeValues, 0, data, 0, attributeValues.Length); return; } if (attributeValues != null && attributeValues.Length != 0) { Debug.LogErrorFormat("Failed to set vertex attribute '{0}' with {1} length of array, when {2} was needed.", (Object[])(object)new Object[3] { Object.op_Implicit(attributeName), Object.op_Implicit(attributeValues.Length), Object.op_Implicit(vertices.Length) }); } attributeArray = null; } public void GetUVs(int channel, List<Vector2> uvs) { if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } if (uvs == null) { throw new ArgumentNullException("uvs"); } uvs.Clear(); if (vertUV2D != null && vertUV2D[channel] != null) { Vector2[] data = vertUV2D[channel].Data; if (data != null) { uvs.AddRange(data); } } } public void GetUVs(int channel, List<Vector3> uvs) { if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } if (uvs == null) { throw new ArgumentNullException("uvs"); } uvs.Clear(); if (vertUV3D != null && vertUV3D[channel] != null) { Vector3[] data = vertUV3D[channel].Data; if (data != null) { uvs.AddRange(data); } } } public void GetUVs(int channel, List<Vector4> uvs) { if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } if (uvs == null) { throw new ArgumentNullException("uvs"); } uvs.Clear(); if (vertUV4D != null && vertUV4D[channel] != null) { Vector4[] data = vertUV4D[channel].Data; if (data != null) { uvs.AddRange(data); } } } public void SetUVs(int channel, IList<Vector2> uvs) { if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } if (uvs != null && uvs.Count > 0) { if (vertUV2D == null) { vertUV2D = new UVChannels<Vector2>(); } int count = uvs.Count; ResizableArray<Vector2> resizableArray = vertUV2D[channel]; if (resizableArray != null) { resizableArray.Resize(count); } else { resizableArray = new ResizableArray<Vector2>(count, count); vertUV2D[channel] = resizableArray; } Vector2[] data = resizableArray.Data; uvs.CopyTo(data, 0); } else if (vertUV2D != null) { vertUV2D[channel] = null; } if (vertUV3D != null) { vertUV3D[channel] = null; } if (vertUV4D != null) { vertUV4D[channel] = null; } } public void SetUVs(int channel, IList<Vector3> uvs) { if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } if (uvs != null && uvs.Count > 0) { if (vertUV3D == null) { vertUV3D = new UVChannels<Vector3>(); } int count = uvs.Count; ResizableArray<Vector3> resizableArray = vertUV3D[channel]; if (resizableArray != null) { resizableArray.Resize(count); } else { resizableArray = new ResizableArray<Vector3>(count, count); vertUV3D[channel] = resizableArray; } Vector3[] data = resizableArray.Data; uvs.CopyTo(data, 0); } else if (vertUV3D != null) { vertUV3D[channel] = null; } if (vertUV2D != null) { vertUV2D[channel] = null; } if (vertUV4D != null) { vertUV4D[channel] = null; } } public void SetUVs(int channel, IList<Vector4> uvs) { if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } if (uvs != null && uvs.Count > 0) { if (vertUV4D == null) { vertUV4D = new UVChannels<Vector4>(); } int count = uvs.Count; ResizableArray<Vector4> resizableArray = vertUV4D[channel]; if (resizableArray != null) { resizableArray.Resize(count); } else { resizableArray = new ResizableArray<Vector4>(count, count); vertUV4D[channel] = resizableArray; } Vector4[] data = resizableArray.Data; uvs.CopyTo(data, 0); } else if (vertUV4D != null) { vertUV4D[channel] = null; } if (vertUV2D != null) { vertUV2D[channel] = null; } if (vertUV3D != null) { vertUV3D[channel] = null; } } public void SetUVs(int channel, IList<Vector4> uvs, int uvComponentCount) { if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } if (uvComponentCount < 0 || uvComponentCount > 4) { throw new ArgumentOutOfRangeException("uvComponentCount"); } if (uvs != null && uvs.Count > 0 && uvComponentCount > 0) { if (uvComponentCount <= 2) { Vector2[] uvs2 = MeshUtils.ConvertUVsTo2D(uvs); SetUVs(channel, uvs2); } else if (uvComponentCount == 3) { Vector3[] uvs3 = MeshUtils.ConvertUVsTo3D(uvs); SetUVs(channel, uvs3); } else { SetUVs(channel, uvs); } return; } if (vertUV2D != null) { vertUV2D[channel] = null; } if (vertUV3D != null) { vertUV3D[channel] = null; } if (vertUV4D != null) { vertUV4D[channel] = null; } } public void SetUVsAuto(int channel, IList<Vector4> uvs) { if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } int usedUVComponents = MeshUtils.GetUsedUVComponents(uvs); SetUVs(channel, uvs, usedUVComponents); } public Vector2[] GetUVs2D(int channel) { if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } if (vertUV2D != null && vertUV2D[channel] != null) { return vertUV2D[channel].Data; } return null; } public void ClearSubMeshes() { subMeshCount = 0; subMeshOffsets = null; triangles.Resize(0); } public void AddSubMeshTriangles(int[] triangles) { if (triangles == null) { throw new ArgumentNullException("triangles"); } if (triangles.Length % 3 != 0) { throw new ArgumentException("The index array length must be a multiple of 3 in order to represent triangles.", "triangles"); } int subMeshIndex = subMeshCount++; int length = this.triangles.Length; int num = triangles.Length / 3; this.triangles.Resize(this.triangles.Length + num); Triangle[] data = this.triangles.Data; for (int i = 0; i < num; i++) { int num2 = i * 3; int v = triangles[num2]; int v2 = triangles[num2 + 1]; int v3 = triangles[num2 + 2]; int num3 = length + i; data[num3] = new Triangle(num3, v, v2, v3, subMeshIndex); } } public void AddSubMeshTriangles(int[][] triangles) { if (triangles == null) { throw new ArgumentNullException("triangles"); } int num = 0; for (int i = 0; i < triangles.Length; i++) { if (triangles[i] == null) { throw new ArgumentException($"The index array at index {i} is null."); } if (triangles[i].Length % 3 != 0) { throw new ArgumentException($"The index array length at index {i} must be a multiple of 3 in order to represent triangles.", "triangles"); } num += triangles[i].Length / 3; } int num2 = this.triangles.Length; this.triangles.Resize(this.triangles.Length + num); Triangle[] data = this.triangles.Data; for (int j = 0; j < triangles.Length; j++) { int subMeshIndex = subMeshCount++; int[] array = triangles[j]; int num3 = array.Length / 3; for (int k = 0; k < num3; k++) { int num4 = k * 3; int v = array[num4]; int v2 = array[num4 + 1]; int v3 = array[num4 + 2]; int num5 = num2 + k; data[num5] = new Triangle(num5, v, v2, v3, subMeshIndex); } num2 += num3; } } public void SimplifyMesh(float quality) { quality = Mathf.Clamp01(quality); int deletedTris = 0; ResizableArray<bool> deleted = new ResizableArray<bool>(20); ResizableArray<bool> deleted2 = new ResizableArray<bool>(20); Triangle[] data = triangles.Data; int length = triangles.Length; int num = length; _ = vertices.Data; int num2 = Mathf.RoundToInt((float)length * quality); for (int i = 0; i < simplificationOptions.MaxIterationCount; i++) { if (num - deletedTris <= num2) { break; } if (i % 5 == 0) { UpdateMesh(i); data = triangles.Data; length = triangles.Length; _ = vertices.Data; } for (int j = 0; j < length; j++) { data[j].dirty = false; } double num3 = 1E-09 * Math.Pow(i + 3, simplificationOptions.Agressiveness); if (verbose) { Debug.LogFormat("iteration {0} - triangles {1} threshold {2}", (Object[])(object)new Object[3] { Object.op_Implicit(i), Object.op_Implicit(num - deletedTris), Object.op_Implicit(num3) }); } RemoveVertexPass(num, num2, num3, deleted, deleted2, ref deletedTris); } CompactMesh(); if (verbose) { Debug.LogFormat("Finished simplification with triangle count {0}", (Object[])(object)new Object[1] { Object.op_Implicit(triangles.Length) }); } } public MeshSimplifier SimplifyMeshLossless() { int deletedTris = 0; ResizableArray<bool> deleted = new ResizableArray<bool>(0); ResizableArray<bool> deleted2 = new ResizableArray<bool>(0); Triangle[] data = triangles.Data; int length = triangles.Length; int startTrisCount = length; _ = vertices.Data; for (int i = 0; i < 9999; i++) { UpdateMesh(i); data = triangles.Data; length = triangles.Length; _ = vertices.Data; for (int num = length - 1; num > 0; num--) { data[num].dirty = false; } double threshold = 0.001; if (verbose) { Debug.LogFormat("Lossless iteration {0} - triangles {1}", (Object[])(object)new Object[2] { Object.op_Implicit(i), Object.op_Implicit(length) }); } RemoveVertexPass(startTrisCount, 0, threshold, deleted, deleted2, ref deletedTris); if (deletedTris <= 0) { break; } deletedTris = 0; } CompactMesh(); if (verbose) { Debug.LogFormat("Finished simplification with triangle count {0}", (Object[])(object)new Object[1] { Object.op_Implicit(triangles.Length) }); } return this; } private void UpdateMesh(int iteration) { Triangle[] data = triangles.Data; Vertex[] data2 = vertices.Data; int num = triangles.Length; int length = vertices.Length; if (iteration > 0) { int num2 = 0; for (int i = 0; i < num; i++) { if (!data[i].deleted) { if (num2 != i) { data[num2] = data[i]; data[num2].index = num2; } num2++; } } triangles.Resize(num2); data = triangles.Data; num = num2; } UpdateReferences(); if (iteration != 0) { return; } Ref[] data3 = refs.Data; List<int> list = new List<int>(8); List<int> list2 = new List<int>(8); int num3 = 0; for (int j = 0; j < length; j++) { data2[j].borderEdge = false; data2[j].uvSeamEdge = false; data2[j].uvFoldoverEdge = false; } int num4 = 0; double num5 = double.MaxValue; double num6 = double.MinValue; double num7 = simplificationOptions.VertexLinkDistance * simplificationOptions.VertexLinkDistance; for (int k = 0; k < length; k++) { int tstart = data2[k].tstart; int tcount = data2[k].tcount; list.Clear(); list2.Clear(); num3 = 0; for (int l = 0; l < tcount; l++) { int tid = data3[tstart + l].tid; for (int m = 0; m < 3; m++) { int n = 0; int num8; for (num8 = data[tid][m]; n < num3 && list2[n] != num8; n++) { } if (n == num3) { list.Add(1); list2.Add(num8); num3++; } else { int index = n; int value = list[index] + 1; list[index] = value; } } } for (int num9 = 0; num9 < num3; num9++) { if (list[num9] != 1) { continue; } int num8 = list2[num9]; data2[num8].borderEdge = true; num4++; if (simplificationOptions.EnableSmartLink) { if (data2[num8].p.x < num5) { num5 = data2[num8].p.x; } if (data2[num8].p.x > num6) { num6 = data2[num8].p.x; } } } } if (simplificationOptions.EnableSmartLink) { BorderVertex[] array = new BorderVertex[num4]; int num10 = 0; double num11 = num6 - num5; for (int num12 = 0; num12 < length; num12++) { if (data2[num12].borderEdge) { int hash = (int)(((data2[num12].p.x - num5) / num11 * 2.0 - 1.0) * 2147483647.0); array[num10] = new BorderVertex(num12, hash); num10++; } } Array.Sort(array, 0, num10, BorderVertexComparer.instance); int num13 = Math.Max((int)(Math.Sqrt(num7) / num11 * 2147483647.0), 1); for (int num14 = 0; num14 < num10; num14++) { int index2 = array[num14].index; if (index2 == -1) { continue; } Vector3d p = data2[index2].p; for (int num15 = num14 + 1; num15 < num10; num15++) { int index3 = array[num15].index; if (index3 == -1) { continue; } if (array[num15].hash - array[num14].hash > num13) { break; } Vector3d p2 = data2[index3].p; double num16 = (p.x - p2.x) * (p.x - p2.x); double num17 = (p.y - p2.y) * (p.y - p2.y); double num18 = (p.z - p2.z) * (p.z - p2.z); if (num16 + num17 + num18 <= num7) { array[num15].index = -1; data2[index2].borderEdge = false; data2[index3].borderEdge = false; if (AreUVsTheSame(0, index2, index3)) { data2[index2].uvFoldoverEdge = true; data2[index3].uvFoldoverEdge = true; } else { data2[index2].uvSeamEdge = true; data2[index3].uvSeamEdge = true; } int tcount2 = data2[index3].tcount; int tstart2 = data2[index3].tstart; for (int num19 = 0; num19 < tcount2; num19++) { Ref @ref = data3[tstart2 + num19]; data[@ref.tid][@ref.tvertex] = index2; } } } } UpdateReferences(); } for (int num20 = 0; num20 < length; num20++) { data2[num20].q = default(SymmetricMatrix); } for (int num21 = 0; num21 < num; num21++) { int v = data[num21].v0; int v2 = data[num21].v1; int v3 = data[num21].v2; Vector3d rhs = data2[v].p; Vector3d p3 = data2[v2].p; Vector3d p4 = data2[v3].p; Vector3d lhs = p3 - rhs; Vector3d rhs2 = p4 - rhs; Vector3d.Cross(ref lhs, ref rhs2, out var result); result.Normalize(); data[num21].n = result; SymmetricMatrix symmetricMatrix = new SymmetricMatrix(result.x, result.y, result.z, 0.0 - Vector3d.Dot(ref result, ref rhs)); data2[v].q += symmetricMatrix; data2[v2].q += symmetricMatrix; data2[v3].q += symmetricMatrix; } for (int num22 = 0; num22 < num; num22++) { Triangle triangle = data[num22]; data[num22].err0 = CalculateError(ref data2[triangle.v0], ref data2[triangle.v1], out var result2); data[num22].err1 = CalculateError(ref data2[triangle.v1], ref data2[triangle.v2], out result2); data[num22].err2 = CalculateError(ref data2[triangle.v2], ref data2[triangle.v0], out result2); data[num22].err3 = MathHelper.Min(data[num22].err0, data[num22].err1, data[num22].err2); } } private void UpdateReferences() { int length = triangles.Length; int length2 = vertices.Length; Triangle[] data = triangles.Data; Vertex[] data2 = vertices.Data; for (int i = 0; i < length2; i++) { data2[i].tstart = 0; data2[i].tcount = 0; } for (int j = 0; j < length; j++) { data2[data[j].v0].tcount++; data2[data[j].v1].tcount++; data2[data[j].v2].tcount++; } int num = 0; for (int k = 0; k < length2; k++) { data2[k].tstart = num; num += data2[k].tcount; data2[k].tcount = 0; } refs.Resize(num); Ref[] data3 = refs.Data; for (int l = 0; l < length; l++) { int v = data[l].v0; int v2 = data[l].v1; int v3 = data[l].v2; int tstart = data2[v].tstart; int num2 = data2[v].tcount++; int tstart2 = data2[v2].tstart; int num3 = data2[v2].tcount++; int tstart3 = data2[v3].tstart; int num4 = data2[v3].tcount++; data3[tstart + num2].Set(l, 0); data3[tstart2 + num3].Set(l, 1); data3[tstart3 + num4].Set(l, 2); } } private void RemoveVertexPass(int startTrisCount, int targetTrisCount, double threshold, ResizableArray<bool> deleted0, ResizableArray<bool> deleted1, ref int deletedTris) { Triangle[] data = triangles.Data; int length = triangles.Length; Vertex[] data2 = vertices.Data; for (int i = 0; i < length; i++) { if (data[i].dirty || data[i].deleted || data[i].err3 > threshold) { continue; } data[i].GetErrors(errArr); data[i].GetAttributeIndices(attributeIndexArr); for (int j = 0; j < 3; j++) { if (errArr[j] > threshold) { continue; } int num = (j + 1) % 3; int num2 = data[i][j]; int num3 = data[i][num]; if (data2[num2].borderEdge != data2[num3].borderEdge || data2[num2].uvSeamEdge != data2[num3].uvSeamEdge || data2[num2].uvFoldoverEdge != data2[num3].uvFoldoverEdge || (simplificationOptions.PreserveBorderEdges && data2[num2].borderEdge) || (simplificationOptions.PreserveUVSeamEdges && data2[num2].uvSeamEdge) || (simplificationOptions.PreserveUVFoldoverEdges && data2[num2].uvFoldoverEdge)) { continue; } CalculateError(ref data2[num2], ref data2[num3], out var result); deleted0.Resize(data2[num2].tcount); deleted1.Resize(data2[num3].tcount); if (Flipped(ref result, num2, num3, ref data2[num2], deleted0.Data) || Flipped(ref result, num3, num2, ref data2[num3], deleted1.Data)) { continue; } int num4 = (j + 2) % 3; int num5 = data[i][num4]; CalculateBarycentricCoords(ref result, ref data2[num2].p, ref data2[num3].p, ref data2[num5].p, out var result2); data2[num2].p = result; data2[num2].q += data2[num3].q; int num6 = attributeIndexArr[j]; int i2 = attributeIndexArr[num]; int i3 = attributeIndexArr[num4]; InterpolateVertexAttributes(num6, num6, i2, i3, ref result2); if (data2[num2].uvSeamEdge) { num6 = -1; } int length2 = refs.Length; UpdateTriangles(num2, num6, ref data2[num2], deleted0, ref deletedTris); UpdateTriangles(num2, num6, ref data2[num3], deleted1, ref deletedTris); int num7 = refs.Length - length2; if (num7 <= data2[num2].tcount) { if (num7 > 0) { Ref[] data3 = refs.Data; Array.Copy(data3, length2, data3, data2[num2].tstart, num7); } } else { data2[num2].tstart = length2; } data2[num2].tcount = num7; break; } if (startTrisCount - deletedTris <= targetTrisCount) { break; } } } private void UpdateTriangles(int i0, int ia0, ref Vertex v, ResizableArray<bool> deleted, ref int deletedTriangles) { int tcount = v.tcount; Triangle[] data = triangles.Data; Vertex[] data2 = vertices.Data; for (int j = 0; j < tcount; j++) { Ref item = refs[v.tstart + j]; int tid = item.tid; Triangle triangle = data[tid]; if (triangle.deleted) { continue; } if (deleted[j]) { data[tid].deleted = true; deletedTriangles++; continue; } triangle[item.tvertex] = i0; if (ia0 != -1) { triangle.SetAttributeIndex(item.tvertex, ia0); } triangle.dirty = true; triangle.err0 = CalculateError(ref data2[triangle.v0], ref data2[triangle.v1], out var result); triangle.err1 = CalculateError(ref data2[triangle.v1], ref data2[triangle.v2], out result); triangle.err2 = CalculateError(ref data2[triangle.v2], ref data2[triangle.v0], out result); triangle.err3 = MathHelper.Min(triangle.err0, triangle.err1, triangle.err2); data[tid] = triangle; refs.Add(item); } } private void CompactMesh() { //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) int num = 0; Vertex[] data = vertices.Data; int length = vertices.Length; for (int i = 0; i < length; i++) { data[i].tcount = 0; } Vector3[] array = ((vertNormals != null) ? vertNormals.Data : null); Vector4[] array2 = ((vertTangents != null) ? vertTangents.Data : null); Vector2[][] array3 = ((vertUV2D != null) ? vertUV2D.Data : null); Vector3[][] array4 = ((vertUV3D != null) ? vertUV3D.Data : null); Vector4[][] array5 = ((vertUV4D != null) ? vertUV4D.Data : null); Color[] array6 = ((vertColors != null) ? vertColors.Data : null); int num2 = -1; subMeshOffsets = new int[subMeshCount]; Triangle[] data2 = triangles.Data; int length2 = triangles.Length; for (int j = 0; j < length2; j++) { Triangle triangle = data2[j]; if (triangle.deleted) { continue; } if (triangle.va0 != triangle.v0) { int va = triangle.va0; int v = triangle.v0; data[va].p = data[v].p; if (vertBoneWeights != null) { vertBoneWeights[va] = vertBoneWeights[v]; } triangle.v0 = triangle.va0; } if (triangle.va1 != triangle.v1) { int va2 = triangle.va1; int v2 = triangle.v1; data[va2].p = data[v2].p; if (vertBoneWeights != null) { vertBoneWeights[va2] = vertBoneWeights[v2]; } triangle.v1 = triangle.va1; } if (triangle.va2 != triangle.v2) { int va3 = triangle.va2; int v3 = triangle.v2; data[va3].p = data[v3].p; if (vertBoneWeights != null) { vertBoneWeights[va3] = vertBoneWeights[v3]; } triangle.v2 = triangle.va2; } int num3 = num++; data2[num3] = triangle; data2[num3].index = num3; data[triangle.v0].tcount = 1; data[triangle.v1].tcount = 1; data[triangle.v2].tcount = 1; if (triangle.subMeshIndex > num2) { for (int k = num2 + 1; k < triangle.subMeshIndex; k++) { subMeshOffsets[k] = num3; } subMeshOffsets[triangle.subMeshIndex] = num3; num2 = triangle.subMeshIndex; } } length2 = num; for (int l = num2 + 1; l < subMeshCount; l++) { subMeshOffsets[l] = length2; } triangles.Resize(length2); data2 = triangles.Data; num = 0; for (int m = 0; m < length; m++) { Vertex vertex = data[m]; if (vertex.tcount <= 0) { continue; } data[m].tstart = num; if (num != m) { data[num].index = num; data[num].p = vertex.p; if (array != null) { array[num] = array[m]; } if (array2 != null) { array2[num] = array2[m]; } if (array3 != null) { for (int n = 0; n < UVChannelCount; n++) { Vector2[] array7 = array3[n]; if (array7 != null) { array7[num] = array7[m]; } } } if (array4 != null) { for (int num4 = 0; num4 < UVChannelCount; num4++) { Vector3[] array8 = array4[num4]; if (array8 != null) { array8[num] = array8[m]; } } } if (array5 != null) { for (int num5 = 0; num5 < UVChannelCount; num5++) { Vector4[] array9 = array5[num5]; if (array9 != null) { array9[num] = array9[m]; } } } if (array6 != null) { array6[num] = array6[m]; } } num++; } for (int num6 = 0; num6 < length2; num6++) { Triangle triangle2 = data2[num6]; triangle2.v0 = data[triangle2.v0].tstart; triangle2.v1 = data[triangle2.v1].tstart; triangle2.v2 = data[triangle2.v2].tstart; data2[num6] = triangle2; } length = num; vertices.Resize(length); if (array != null) { vertNormals.Resize(length, trimExess: true); } if (array2 != null) { vertTangents.Resize(length, trimExess: true); } if (array3 != null) { vertUV2D.Resize(length, trimExess: true); } if (array4 != null) { vertUV3D.Resize(length, trimExess: true); } if (array5 != null) { vertUV4D.Resize(length, trimExess: true); } if (array6 != null) { vertColors.Resize(length, trimExess: true); } } private double CalculateError(ref Vertex vert0, ref Vertex vert1, out Vector3d result) { SymmetricMatrix q = vert0.q + vert1.q; bool flag = vert0.borderEdge && vert1.borderEdge; double num = 0.0; double num2 = q.Determinant1(); if (num2 != 0.0 && !flag) { result = new Vector3d(-1.0 / num2 * q.Determinant2(), 1.0 / num2 * q.Determinant3(), -1.0 / num2 * q.Determinant4()); double num3 = 0.0; if (simplificationOptions.PreserveSurfaceCurvature) { num3 = CurvatureError(ref vert0, ref vert1); } num = VertexError(ref q, result.x, result.y, result.z) + num3; } else { Vector3d p = vert0.p; Vector3d p2 = vert1.p; Vector3d vector3d = (p + p2) * 0.5; double num4 = VertexError(ref q, p.x, p.y, p.z); double num5 = VertexError(ref q, p2.x, p2.y, p2.z); double num6 = VertexError(ref q, vector3d.x, vector3d.y, vector3d.z); if (num4 < num5) { if (num4 < num6) { num = num4; result = p; } else { num = num6; result = vector3d; } } else if (num5 < num6) { num = num5; result = p2; } else { num = num6; result = vector3d; } } return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private double CurvatureError(ref Vertex vert0, ref Vertex vert1) { double magnitude = (vert0.p - vert1.p).Magnitude; HashSet<Triangle> hashSet = triangleHashSet1; hashSet.Clear(); GetTrianglesContainingVertex(ref vert0, hashSet); GetTrianglesContainingVertex(ref vert1, hashSet); HashSet<Triangle> hashSet2 = triangleHashSet2; hashSet2.Clear(); GetTrianglesContainingBothVertices(ref vert0, ref vert1, hashSet2); double num = 0.0; foreach (Triangle item in hashSet) { double num2 = 0.0; Vector3d lhs = item.n; foreach (Triangle item2 in hashSet2) { Vector3d rhs = item2.n; double num3 = Vector3d.Dot(ref lhs, ref rhs); if (num3 > num2) { num2 = num3; } } if (num2 > num) { num = num2; } } return magnitude * num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void GetTrianglesContainingVertex(ref Vertex vert, HashSet<Triangle> tris) { int tcount = vert.tcount; int tstart = vert.tstart; for (int i = tstart; i < tstart + tcount; i++) { tris.Add(triangles[refs[i].tid]); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void GetTrianglesContainingBothVertices(ref Vertex vert0, ref Vertex vert1, HashSet<Triangle> tris) { int tcount = vert0.tcount; int tstart = vert0.tstart; for (int i = tstart; i < tstart + tcount; i++) { int tid = refs[i].tid; Triangle item = triangles[tid]; if (vertices[item.v0].index == vert1.index || vertices[item.v1].index == vert1.index || vertices[item.v2].index == vert1.index) { tris.Add(item); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static double VertexError(ref SymmetricMatrix q, double x, double y, double z) { return q.m0 * x * x + 2.0 * q.m1 * x * y + 2.0 * q.m2 * x * z + 2.0 * q.m3 * x + q.m4 * y * y + 2.0 * q.m5 * y * z + 2.0 * q.m6 * y + q.m7 * z * z + 2.0 * q.m8 * z + q.m9; } private void InterpolateVertexAttributes(int dst, int i0, int i1, int i2, ref Vector3 barycentricCoord) { //IL_0016: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0082: 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_009a: 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_00ab: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_025e: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0276: 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_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: 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_0104: 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_0117: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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_016b: 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_017e: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) if (vertNormals != null) { vertNormals[dst] = Vector3.Normalize(vertNormals[i0] * barycentricCoord.x + vertNormals[i1] * barycentricCoord.y + vertNormals[i2] * barycentricCoord.z); } if (vertTangents != null) { vertTangents[dst] = NormalizeTangent(vertTangents[i0] * barycentricCoord.x + vertTangents[i1] * barycentricCoord.y + vertTangents[i2] * barycentricCoord.z); } if (vertUV2D != null) { for (int j = 0; j < UVChannelCount; j++) { ResizableArray<Vector2> resizableArray = vertUV2D[j]; if (resizableArray != null) { resizableArray[dst] = resizableArray[i0] * barycentricCoord.x + resizableArray[i1] * barycentricCoord.y + resizableArray[i2] * barycentricCoord.z; } } } if (vertUV3D != null) { for (int k = 0; k < UVChannelCount; k++) { ResizableArray<Vector3> resizableArray2 = vertUV3D[k]; if (resizableArray2 != null) { resizableArray2[dst] = resizableArray2[i0] * barycentricCoord.x + resizableArray2[i1] * barycentricCoord.y + resizableArray2[i2] * barycentricCoord.z; } } } if (vertUV4D != null) { for (int l = 0; l < UVChannelCount; l++) { ResizableArray<Vector4> resizableArray3 = vertUV4D[l]; if (resizableArray3 != null) { resizableArray3[dst] = resizableArray3[i0] * barycentricCoord.x + resizableArray3[i1] * barycentricCoord.y + resizableArray3[i2] * barycentricCoord.z; } } } if (vertColors != null) { vertColors[dst] = vertColors[i0] * barycentricCoord.x + vertColors[i1] * barycentricCoord.y + vertColors[i2] * barycentricCoord.z; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector4 NormalizeTangent(Vector4 tangent) { //IL_0002: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0038: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(tangent.x, tangent.y, tangent.z); ((Vector3)(ref val)).Normalize(); return new Vector4(val.x, val.y, val.z, tangent.w); } private bool Flipped(ref Vector3d p, int i0, int i1, ref Vertex v0, bool[] deleted) { int tcount = v0.tcount; Ref[] data = refs.Data; Triangle[] data2 = triangles.Data; Vertex[] data3 = vertices.Data; for (int j = 0; j < tcount; j++) { Ref @ref = data[v0.tstart + j]; if (data2[@ref.tid].deleted) { continue; } int tvertex = @ref.tvertex; int num = data2[@ref.tid][(tvertex + 1) % 3]; int num2 = data2[@ref.tid][(tvertex + 2) % 3]; if (num == i1 || num2 == i1) { deleted[j] = true; continue; } Vector3d lhs = data3[num].p - p; lhs.Normalize(); Vector3d rhs = data3[num2].p - p; rhs.Normalize(); if (Math.Abs(Vector3d.Dot(ref lhs, ref rhs)) > 0.999) { return true; } Vector3d.Cross(ref lhs, ref rhs, out var result); result.Normalize(); deleted[j] = false; if (Vector3d.Dot(ref result, ref data2[@ref.tid].n) < 0.2) { return true; } } return false; } private static void CalculateBarycentricCoords(ref Vector3d point, ref Vector3d a, ref Vector3d b, ref Vector3d c, out Vector3 result) { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) Vector3d lhs = b - a; Vector3d rhs = c - a; Vector3d lhs2 = point - a; double num = Vector3d.Dot(ref lhs, ref lhs); double num2 = Vector3d.Dot(ref lhs, ref rhs); double num3 = Vector3d.Dot(ref rhs, ref rhs); double num4 = Vector3d.Dot(ref lhs2, ref lhs); double num5 = Vector3d.Dot(ref lhs2, ref rhs); double num6 = num * num3 - num2 * num2; if (Math.Abs(num6) < 1E-08) { num6 = 1E-08; } double num7 = (num3 * num4 - num2 * num5) / num6; double num8 = (num * num5 - num2 * num4) / num6; double num9 = 1.0 - num7 - num8; result = new Vector3((float)num9, (float)num7, (float)num8); } private bool AreUVsTheSame(int channel, int indexA, int indexB) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0092: 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) if (vertUV2D != null) { ResizableArray<Vector2> resizableArray = vertUV2D[channel]; if (resizableArray != null) { Vector2 val = resizableArray[indexA]; Vector2 val2 = resizableArray[indexB]; return val == val2; } } if (vertUV3D != null) { ResizableArray<Vector3> resizableArray2 = vertUV3D[channel]; if (resizableArray2 != null) { Vector3 val3 = resizableArray2[indexA]; Vector3 val4 = resizableArray2[indexB]; return val3 == val4; } } if (vertUV4D != null) { ResizableArray<Vector4> resizableArray3 = vertUV4D[channel]; if (resizableArray3 != null) { Vector4 val5 = resizableArray3[indexA]; Vector4 val6 = resizableArray3[indexB]; return val5 == val6; } } return false; } public Mesh ToMesh() { Vector3[] array = Vertices; Vector3[] normals = Normals; Vector4[] tangents = Tangents; Color[] colors = Colors; int[][] allSubMeshTriangles = GetAllSubMeshTriangles(); List<Vector2>[] array2 = null; List<Vector3>[] array3 = null; List<Vector4>[] array4 = null; if (vertUV2D != null) { array2 = new List<Vector2>[UVChannelCount]; for (int i = 0; i < UVChannelCount; i++) { if (vertUV2D[i] != null) { List<Vector2> list = new List<Vector2>(array.Length); GetUVs(i, list); array2[i] = list; } } } if (vertUV3D != null) { array3 = new List<Vector3>[UVChannelCount]; for (int j = 0; j < UVChannelCount; j++) { if (vertUV3D[j] != null) { List<Vector3> list2 = new List<Vector3>(array.Length); GetUVs(j, list2); array3[j] = list2; } } } if (vertUV4D != null) { array4 = new List<Vector4>[UVChannelCount]; for (int k = 0; k < UVChannelCount; k++) { if (vertUV4D[k] != null) { List<Vector4> list3 = new List<Vector4>(array.Length); GetUVs(k, list3); array4[k] = list3; } } } return MeshUtils.CreateMesh(array, allSubMeshTriangles, normals, tangents, colors, array2, array3, array4); } } public static class MeshUtils { public static readonly int UVChannelCount = 4; public static Mesh CreateMesh(Vector3[] vertices, int[][] indices, Vector3[] normals, Vector4[] tangents, Color[] colors, List<Vector2>[] uvs) { return CreateMesh(vertices, indices, normals, tangents, colors, uvs, null, null); } public static Mesh CreateMesh(Vector3[] vertices, int[][] indices, Vector3[] normals, Vector4[] tangents, Color[] colors, List<Vector4>[] uvs) { return CreateMesh(vertices, indices, normals, tangents, colors, null, null, uvs); } public static Mesh CreateMesh(Vector3[] vertices, int[][] indices, Vector3[] normals, Vector4[] tangents, Color[] colors, List<Vector2>[] uvs2D, List<Vector3>[] uvs3D, List<Vector4>[] uvs4D) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0030: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) if (vertices == null) { throw new ArgumentNullException("vertices"); } if (indices == null) { throw new ArgumentNullException("indices"); } Mesh val = new Mesh(); int num = indices.Length; IndexFormat indexFormat; Vector2Int[] subMeshIndexMinMax = GetSubMeshIndexMinMax(indices, out indexFormat); val.indexFormat = indexFormat; val.subMeshCount = num; val.vertices = Il2CppStructArray<Vector3>.op_Implicit(vertices); if (normals != null && normals.Length != 0) { val.normals = Il2CppStructArray<Vector3>.op_Implicit(normals); } if (tangents != null && tangents.Length != 0) { val.tangents = Il2CppStructArray<Vector4>.op_Implicit(tangents); } if (colors != null && colors.Length != 0) { val.colors = Il2CppStructArray<Color>.op_Implicit(colors); } if (uvs2D != null) { for (int i = 0; i < uvs2D.Length; i++) { if (uvs2D[i] != null && uvs2D[i].Count > 0) { val.SetUVs(i, Il2CppStructArray<Vector2>.op_Implicit(uvs2D[i].ToArray())); } } } if (uvs3D != null) { for (int j = 0; j < uvs3D.Length; j++) { if (uvs3D[j] != null && uvs3D[j].Count > 0) { val.SetUVs(j, Il2CppStructArray<Vector3>.op_Implicit(uvs3D[j].ToArray())); } } } if (uvs4D != null) { for (int k = 0; k < uvs4D.Length; k++) { if (uvs4D[k] != null && uvs4D[k].Count > 0) { val.SetUVs(k, Il2CppStructArray<Vector4>.op_Implicit(uvs4D[k].ToArray())); } } } for (int l = 0; l < num; l++) { int[] array = indices[l]; Vector2Int val2 = subMeshIndexMinMax[l]; if ((int)indexFormat == 0 && ((Vector2Int)(ref val2)).y > 65535) { int x = ((Vector2Int)(ref val2)).x; for (int m = 0; m < array.Length; m++) { array[m] -= x; } val.SetTriangles(Il2CppStructArray<int>.op_Implicit(array), l, false, x); } else { val.SetTriangles(Il2CppStructArray<int>.op_Implicit(array), l, false, 0); } } val.RecalculateBounds(); return val; } public static IList<Vector4>[] GetMeshUVs(Mesh mesh) { if ((Object)(object)mesh == (Object)null) { throw new ArgumentNullException("mesh"); } IList<Vector4>[] array = new IList<Vector4>[UVChannelCount]; for (int i = 0; i < UVChannelCount; i++) { array[i] = GetMeshUVs(mesh, i); } return array; } public static IList<Vector2> GetMeshUVs2D(Mesh mesh, int channel) { if ((Object)(object)mesh == (Object)null) { throw new ArgumentNullException("mesh"); } if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } new List<Vector2>(mesh.vertexCount); return (IList<Vector2>)mesh.uv; } public static IList<Vector3> GetMeshUVs3D(Mesh mesh, int channel) { if ((Object)(object)mesh == (Object)null) { throw new ArgumentNullException("mesh"); } if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } List<Vector3> val = new List<Vector3>(mesh.vertexCount); mesh.GetUVs(channel, val); return (IList<Vector3>)val.ToArray(); } public static IList<Vector4> GetMeshUVs(Mesh mesh, int channel) { if ((Object)(object)mesh == (Object)null) { throw new ArgumentNullException("mesh"); } if (channel < 0 || channel >= UVChannelCount) { throw new ArgumentOutOfRangeException("channel"); } List<Vector4> val = new List<Vector4>(mesh.vertexCount); mesh.GetUVs(channel, val); return (IList<Vector4>)val.ToArray(); } public static int GetUsedUVComponents(IList<Vector4> uvs) { //IL_0019: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (uvs == null || uvs.Count == 0) { return 0; } int num = 0; foreach (Vector4 uv in uvs) { if (num < 1 && uv.x != 0f) { num = 1; } if (num < 2 && uv.y != 0f) { num = 2; } if (num < 3 && uv.z != 0f) { num = 3; } if (num < 4 && uv.w != 0f) { num = 4; break; } } return num; } public static Vector2[] ConvertUVsTo2D(IList<Vector4> uvs) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_002b: 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) if (uvs == null) { return null; } Vector2[] array = (Vector2[])(object)new Vector2[uvs.Count]; for (int i = 0; i < array.Length; i++) { Vector4 val = uvs[i]; array[i] = new Vector2(val.x, val.y); } return array; } public static Vector3[] ConvertUVsTo3D(IList<Vector4> uvs) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_002b: 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_0036: Unknown result type (might be due to invalid IL or missing references) if (uvs == null) { return null; } Vector3[] array = (Vector3[])(object)new Vector3[uvs.Count]; for (int i = 0; i < array.Length; i++) { Vector4 val = uvs[i]; array[i] = new Vector3(val.x, val.y, val.z); } return array; } public static Vector2Int[] GetSubMeshIndexMinMax(int[][] indices, out IndexFormat indexFormat) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (indices == null) { throw new ArgumentNullException("indices"); } Vector2Int[] array = (Vector2Int[])(object)new Vector2Int[indices.Length]; indexFormat = (IndexFormat)0; for (int i = 0; i < indices.Length; i++) { GetIndexMinMax(indices[i], out var minIndex, out var maxIndex); array[i] = new Vector2Int(minIndex, maxIndex); if (maxIndex - minIndex > 65535) { indexFormat = (IndexFormat)1; } } return array; } private static void GetIndexMinMax(int[] indices, out int minIndex, out int maxIndex) { if (indices == null || indices.Length == 0) { minIndex = (maxIndex = 0); return; } minIndex = int.MaxValue; maxIndex = int.MinValue; for (int i = 0; i < indices.Length; i++) { if (indices[i] < minIndex) { minIndex = indices[i]; } if (indices[i] > maxIndex) { maxIndex = indices[i]; } } } } internal class ResizableArray<T> { private T[] items; private int length; private static T[] emptyArr = new T[0]; public int Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return length; } } public T[] Data { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return items; } } public T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return items[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { items[index] = value; } } public ResizableArray(int capacity) : this(capacity, 0) { } public ResizableArray(int capacity, int length) { if (capacity < 0) { throw new ArgumentOutOfRangeException("capacity"); } if (length < 0 || length > capacity) { throw new ArgumentOutOfRangeException("length"); } if (capacity > 0) { items = new T[capacity]; } else { items = emptyArr; } this.length = length; } public ResizableArray(T[] initialArray) { if (initialArray == null) { throw new ArgumentNullException("initialArray"); } if (initialArray.Length != 0) { items = new T[initialArray.Length]; length = initialArray.Length; Array.Copy(initialArray, 0, items, 0, initialArray.Length); } else { items = emptyArr; length = 0; } } private void IncreaseCapacity(int capacity) { T[] destinationArray = new T[capacity]; Array.Copy(items, 0, destinationArray, 0, Math.Min(length, capacity)); items = destinationArray; } public void Clear() { Array.Clear(items, 0, length); length = 0; } public void Resize(int length, bool trimExess = false, bool clearMemory = false) { if (length < 0) { throw new ArgumentOutOfRangeException("length"); } if (length > items.Length) { IncreaseCapacity(length); } else if (length < this.length && clearMemory) { Array.Clear(items, length, this.length - length); } this.length = length; if (trimExess) { TrimExcess(); } } public void TrimExcess() { if (items.Length != length) { T[] destinationArray = new T[length]; Array.Copy(items, 0, destinationArray, 0, length); items = destinationArray; } } public void Add(T item) { if (length >= items.Length) { IncreaseCapacity(items.Length << 1); } items[length++] = item; } public T[] ToArray() { T[] array = new T[length]; Array.Copy(items, 0, array, 0, length); return array; } } public struct SimplificationOptions { public static readonly SimplificationOptions Default = new SimplificationOptions { PreserveBorderEdges = false, PreserveUVSeamEdges = false, PreserveUVFoldoverEdges = false, PreserveSurfaceCurvature = false, EnableSmartLink = true, VertexLinkDistance = double.Epsilon, MaxIterationCount = 100, Agressiveness = 7.0, ManualUVComponentCount = false, UVComponentCount = 2 }; public bool PreserveBorderEdges; public bool PreserveUVSeamEdges; public bool PreserveUVFoldoverEdges; public bool PreserveSurfaceCurvature; public bool EnableSmartLink; public double VertexLinkDistance; public int MaxIterationCount; public double Agressiveness; public bool ManualUVComponentCount; public int UVComponentCount; } public struct SymmetricMatrix { public double m0; public double m1; public double m2; public double m3; public double m4; public double m5; public double m6; public double m7; public double m8; public double m9; public double this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return index switch { 0 => m0, 1 => m1, 2 => m2, 3 => m3, 4 => m4, 5 => m5, 6 => m6, 7 => m7, 8 => m8, 9 => m9, _ => throw new ArgumentOutOfRangeException("index"), }; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public SymmetricMatrix(double c) { m0 = c; m1 = c; m2 = c; m3 = c; m4 = c; m5 = c; m6 = c; m7 = c; m8 = c; m9 = c; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public SymmetricMatrix(double m0, double m1, double m2, double m3, double m4, double m5, double m6, double m7, double m8, double m9) { this.m0 = m0; this.m1 = m1; this.m2 = m2; this.m3 = m3; this.m4 = m4; this.m5 = m5; this.m6 = m6; this.m7 = m7; this.m8 = m8; this.m9 = m9; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public SymmetricMatrix(double a, double b, double c, double d) { m0 = a * a; m1 = a * b; m2 = a * c; m3 = a * d; m4 = b * b; m5 = b * c; m6 = b * d; m7 = c * c; m8 = c * d; m9 = d * d; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static SymmetricMatrix operator +(SymmetricMatrix a, SymmetricMatrix b) { return new SymmetricMatrix(a.m0 + b.m0, a.m1 + b.m1, a.m2 + b.m2, a.m3 + b.m3, a.m4 + b.m4, a.m5 + b.m5, a.m6 + b.m6, a.m7 + b.m7, a.m8 + b.m8, a.m9 + b.m9); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal double Determinant1() { return m0 * m4 * m7 + m2 * m1 * m5 + m1 * m5 * m2 - m2 * m4 * m2 - m0 * m5 * m5 - m1 * m1 * m7; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal double Determinant2() { return m1 * m5 * m8 + m3 * m4 * m7 + m2 * m6 * m5 - m3 * m5 * m5 - m1 * m6 * m7 - m2 * m4 * m8; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal double Determinant3() { return m0 * m5 * m8 + m3 * m1 * m7 + m2 * m6 * m2 - m3 * m5 * m2 - m0 * m6 * m7 - m2 * m1 * m8; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal double Determinant4() { return m0 * m4 * m8 + m3 * m1 * m5 + m1 * m6 * m2 - m3 * m4 * m2 - m0 * m6 * m5 - m1 * m1 * m8; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public double Determinant(int a11, int a12, int a13, int a21, int a22, int a23, int a31, int a32, int a33) { return this[a11] * this[a22] * this[a33] + this[a13] * this[a21] * this[a32] + this[a12] * this[a23] * this[a31] - this[a13] * this[a22] * this[a31] - this[a11] * this[a23] * this[a32] - this[a12] * this[a21] * this[a33]; } } public struct Vector3d : IEquatable<Vector3d> { public static readonly Vector3d zero = new Vector3d(0.0, 0.0, 0.0); public const double Epsilon = double.Epsilon; public double x; public double y; public double z; public double Magnitude { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return Math.Sqrt(x * x + y * y + z * z); } } public double MagnitudeSqr { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return x * x + y * y + z * z; } } public Vector3d Normalized { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { Normalize(ref this, out var result); return result; } } public double this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return index switch { 0 => x, 1 => y, 2 => z, _ => throw new ArgumentOutOfRangeException("index", "Invalid Vector3d index!"), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { switch (index) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new ArgumentOutOfRangeException("index", "Invalid Vector3d index!"); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3d(double value) { x = value; y = value; z = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3d(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3d(Vector3 vector) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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) x = vector.x; y = vector.y; z = vector.z; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3d operator +(Vector3d a, Vector3d b) { return new Vector3d(a.x + b.x, a.y + b.y, a.z + b.z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3d operator -(Vector3d a, Vector3d b) { return new Vector3d(a.x - b.x, a.y - b.y, a.z - b.z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3d operator *(Vector3d a, double d) { return new Vector3d(a.x * d, a.y * d, a.z * d); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3d operator *(double d, Vector3d a) { return new Vector3d(a.x * d, a.y * d, a.z * d); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3d operator /(Vector3d a, double d) { return new Vector3d(a.x / d, a.y / d, a.z / d); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3d operator -(Vector3d a) { return new Vector3d(0.0 - a.x, 0.0 - a.y, 0.0 - a.z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Vector3d lhs, Vector3d rhs) { return (lhs - rhs).MagnitudeSqr < double.Epsilon; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(Vector3d lhs, Vector3d rhs) { return (lhs - rhs).MagnitudeSqr >= double.Epsilon; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Vector3d(Vector3 v) { //IL_0000: 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_000e: Unknown result type (might be due to invalid IL or missing references) return new Vector3d(v.x, v.y, v.z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static explicit operator Vector3(Vector3d v) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) return new Vector3((float)v.x, (float)v.y, (float)v.z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Set(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Scale(ref Vector3d scale) { x *= scale.x; y *= scale.y; z *= scale.z; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Normalize() { double magnitude = Magnitude; if (magnitude > double.Epsilon) { x /= magnitude; y /= magnitude; z /= magnitude; } else { x = (y = (z = 0.0)); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Clamp(double min, double max) { if (x < min) { x = min; } else if (x > max) { x = max; } if (y < min) { y = min; } else if (y > max) { y = max; } if (z < min) { z = min; } else if (z > max) { z = max; } } public override int GetHashCode() { return x.GetHashCode() ^ (y.GetHashCode() << 2) ^ (z.GetHashCode() >> 2); } public override bool Equals(object obj) { if (!(obj is Vector3d vector3d)) { return false; } if (x == vector3d.x && y == vector3d.y) { return z == vector3d.z; } return false; } public bool Equals(Vector3d other) { if (x == other.x && y == other.y) { return z == other.z; } return false; } public override string ToString() { return $"({x:F1}, {y:F1}, {z:F1})"; } public string ToString(string format) { return $"({x.ToString(format)}, {y.ToString(format)}, {z.ToString(format)})"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Dot(ref Vector3d lhs, ref Vector3d rhs) { return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Cross(ref Vector3d lhs, ref Vector3d rhs, out Vector3d result) { result = new Vector3d(lhs.y * rhs.z - lhs.z * rhs.y, lhs.z * rhs.x - lhs.x * rhs.z, lhs.x * rhs.y - lhs.y * rhs.x); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Angle(ref Vector3d from, ref Vector3d to) { Vector3d lhs = from.Normalized; Vector3d rhs = to.Normalized; return Math.Acos(MathHelper.Clamp(Dot(ref lhs, ref rhs), -1.0, 1.0)) * (180.0 / Math.PI); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Lerp(ref Vector3d a, ref Vector3d b, double t, out Vector3d result) { result = new Vector3d(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Scale(ref Vector3d a, ref Vector3d b, out Vector3d result) { result = new Vector3d(a.x * b.x, a.y * b.y, a.z * b.z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Normalize(ref Vector3d value, out Vector3d result) { double magnitude = value.Magnitude; if (magnitude > double.Epsilon) { result = new Vector3d(value.x / magnitude, value.y / magnitude, value.z / magnitude); } else { result = zero; } } } } namespace UnityMeshSimplifier.Internal { internal struct BorderVertex { public int index; public int hash; [MethodImpl(MethodImplOptions.AggressiveInlining)] public BorderVertex(int index, int hash) { this.index = index; this.hash = hash; } } internal class BorderVertexComparer : IComparer<BorderVertex> { public static readonly BorderVertexComparer instance = new BorderVertexComparer(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public int Compare(BorderVertex x, BorderVertex y) { return x.hash.CompareTo(y.hash); } } internal struct Ref { public int tid; public int tvertex; [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Set(int tid, int tvertex) { this.tid = tid; this.tvertex = tvertex; } } internal struct Triangle : IEquatable<Triangle> { public int index; public int v0; public int v1; public int v2; public int subMeshIndex; public int va0; public int va1; public int va2; public double err0; public double err1; public double err2; public double err3; public bool deleted; public bool dirty; public Vector3d n; public int this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return index switch { 1 => v1, 0 => v0, _ => v2, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { switch (index) { case 0: v0 = value; break; case 1: v1 = value; break; case 2: v2 = value; break; default: throw new ArgumentOutOfRangeException("index"); } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Triangle(int index, int v0, int v1, int v2, int subMeshIndex) { this.index = index; this.v0 = v0; this.v1 = v1; this.v2 = v2; this.subMeshIndex = subMeshIndex; va0 = v0; va1 = v1; va2 = v2; err0 = (err1 = (err2 = (err3 = 0.0))); deleted = (dirty = false); n = default(Vector3d); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void GetAttributeIndices(int[] attributeIndices) { attributeIndices[0] = va0; attributeIndices[1] = va1; attributeIndices[2] = va2; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SetAttributeIndex(int index, int value) { switch (index) { case 0: va0 = value; break; case 1: va1 = value; break; case 2: va2 = value; break; default: throw new ArgumentOutOfRangeException("index"); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void GetErrors(double[] err) { err[0] = err0; err[1] = err1; err[2] = err2; } public override int GetHashCode() { return index; } public override bool Equals(object obj) { if (obj is Triangle triangle) { return index == triangle.index; } return false; } public bool Equals(Triangle other) { return index == other.index; } } internal class UVChannels<TVec> { private static readonly int UVChannelCount = MeshUtils.UVChannelCount; private ResizableArray<TVec>[] channels; private TVec[][] channelsData; public TVec[][] Data { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { for (int i = 0; i < UVChannelCount; i++) { if (channels[i] != null) { channelsData[i] = channels[i].Data; } else { channelsData[i] = null; } } return channelsData; } } public ResizableArray<TVec> this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return channels[index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { channels[index] = value; } } public UVChannels() { channels = new ResizableArray<TVec>[UVChannelCount]; channelsData = new TVec[UVChannelCount][]; } public void Resize(int capacity, bool trimExess = false) { for (int i = 0; i < UVChannelCount; i++) { if (channels[i] != null) { channels[i].Resize(capacity, trimExess); } } } } internal struct Vertex : IEquatable<Vertex> { public int index; public Vector3d p; public int tstart; public int tcount; public SymmetricMatrix q; public bool borderEdge; public bool uvSeamEdge; public bool uvFoldoverEdge; [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vertex(int index, Vector3d p) { this.index = index; this.p = p; tstart = 0; tcount = 0; q = default(SymmetricMatrix); borderEdge = true; uvSeamEdge = false; uvFoldoverEdge = false; } public override int GetHashCode() { return index; } public override bool Equals(object obj) { if (obj is Vertex vertex) { return index == vertex.index; } return false; } public bool Equals(Vertex other) { return index == other.index; } } } namespace LowSpecGaming { [BepInPlugin("Mushroom.LowSpecGaming", "LowSpecGaming", "0.3.3")] public class EntryPoint : BasePlugin { public static ConfigEntry<DynamicResolution> dynamicResolution; public static ConfigEntry<IRFDrawing> irfDrawing; public static ConfigEntry<GameEnvironment> gameEnvironment; public static ConfigEntry<BioScanBlink> BioScanUpdate; public static ConfigEntry<HateSpitter> hateSpitter; public static ConfigEntry<EnemyBehaviourCulling> enemyBehaviourCulling; public static ConfigEntry<string> currentFolderPath; public static ConfigEntry<bool> dumpTexture; public static ConfigEntry<TextureSize> textureSize; public static ConfigEntry<OneFlashLight> oneFlashLight; public static ConfigEntry<MeshSimply> meshSimply; public static ConfigEntry<ShaderReplace> shaderReplace; public static ConfigEntry<Experimental> redundantComponents; public static ConfigFile configFile; public static EntryPoint e; public override void Load() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) e = this; Harmony val = new Harmony("Mushroom.LowSpecGaming"); ((BasePlugin)this).Log.LogInfo((object)"Mushroom Low Spec Gaming is IN~!!"); GetTheSettings(); ClassInjector.RegisterTypeInIl2Cpp<LowSpecGaming>(); ClassInjector.RegisterTypeInIl2Cpp<LowSpecCamera>(); SightPatch.sightPaths = new Dictionary<string, string[]>(); SightPatch.GetSightFolders(); LogIt(Paths.BepInExRootPath); val.PatchAll(); LevelAPI.OnBuildDone += C_CullingClusterPatch.GetAllClusters; LevelAPI.OnLevelCleanup += C_CullingClusterPatch.CleanAllClusters; } public static void GetTheSettings() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "mushroom.lowspecgaming.cfg"), true); dynamicResolution = configFile.Bind<DynamicResolution>("Setup", "dynamicResolution", DynamicResolution.Stable, "Scales down your resolution whenever you move your camera, will improve this in the future"); irfDrawing = configFile.Bind<IRFDrawing>("Setup", "irfDrawing", IRFDrawing.Draw, "whether or not to draw IRF like trees, I hope this doesn't break the Kraken"); gameEnvironment = configFile.Bind<GameEnvironment>("Setup", "gameEnvironment", GameEnvironment.Full, "Reduce fog distance, shadow distance, no more dust particles (requires restart to take effect)"); BioScanUpdate = configFile.Bind<BioScanBlink>("Setup", "BioScanUpdate", BioScanBlink.DontBlink, "Whether or not Bio Scans would blink, courtesy to McCad, this is his online code"); hateSpitter = configFile.Bind<HateSpitter>("Setup", "hateSpitter", HateSpitter.HATE, "If you hate spitters, make them low quality"); enemyBehaviourCulling = configFile.Bind<EnemyBehaviourCulling>("Setup", "enemyBehaviourCulling", EnemyBehaviourCulling.Full, "Reduce Enemy Update in order to save performance, will improve this feature in the future for better performance"); textureSize = configFile.Bind<TextureSize>("Setup", "textureSize", TextureSize.Full, "Texture size, for the potata army"); oneFlashLight = configFile.Bind<OneFlashLight>("Setup", "oneFlashLight", OneFlashLight.All, "All for vanilla, use One to load only 1 and also the best flashlight for all guns (DMR)"); meshSimply = configFile.Bind<MeshSimply>("Setup", "meshSimply", MeshSimply.NoSimply, "VERY EXPERIMENTAL, turn on to reduce vertices for about 20%, improves GPU performance"); shaderReplace = configFile.Bind<ShaderReplace>("Setup", "shaderReplace", ShaderReplace.Vanilla, "VERY EXPERIMENTAL, use very basic shader"); redundantComponents = configFile.Bind<Experimental>("Setup", "redundantComponents", Experimental.TurnOn, "VERY EXPERIMENTAL, turn off some redundant compenents in game || You might gain 5fps"); currentFolderPath = configFile.Bind<string>("Setup", "currentFolderPath", "", "Manual Path to the current folder that has the plugin if it fails to load normally, This will be removed soon"); dumpTexture = configFile.Bind<bool>("Setup", "dumpTexture", false, "Dump and extract sight textures in order to load hi res textures even at low res texture settings"); } public static void LogIt(object data) { ((BasePlugin)e).Log.LogInfo(data); } public override bool Unload() { return ((BasePlugin)this).Unload(); } public static void DecompressFolder(string compressedFilePath, string decompressedFolderPath) { ZipFile.ExtractToDirectory(compressedFilePath, decompressedFolderPath); LogIt("Folder decompressed successfully."); } } public enum BioScanBlink { Blink, DontBlink } public enum GameEnvironment { Full, Reduced } public enum IRFDrawing { Draw, HalfDraw, DontDraw } public enum DynamicResolution { Stable, Dynamic } public enum HateSpitter { HATE, LOVE } public enum EnemyBehaviourCulling { Full, Reduced } public enum MeshSimply { Simply, NoSimply } public enum ShaderReplace { Replace, Vanilla } public enum Experimental { TurnOn, TurnOff } public enum TextureSize { Full, Half, Quater, Eigth, Low, PentaLow, VeryLow, SuperLow, UltraLow, POTATA, YouLiveLikeThis } public enum OneFlashLight { All, One } public static class PluginInfo { public const string PLUGIN_GUID = "Mushroom.LowSpecGaming"; public const string PLUGIN_NAME = "LowSpecGaming"; public const string PLUGIN_VERSION = "0.3.3"; public const string AUTHOR = "time1pm"; public const string BRANCH = "beta"; public const string INTERNAL_VERSION = "000799"; } internal class LowSpecGaming : MonoBehaviour { public static List<Texture2D> lightTextures; public static Texture2D text; public void Start() { EntryPoint.GetTheSettings(); lightTextures = new List<Texture2D>(); LevelAPI.OnEnterLevel += HateTheGameFeel; LevelAPI.OnEnterLevel += ClusterRenderingOff; EntryPoint.LogIt("Applying settings in 12s"); ((MonoBehaviour)this).Invoke("ApplySettings", 12f); ((MonoBehaviour)this).Invoke("GetFlashLights", 10f); } public void GetFlashLights() { //IL_009c: 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) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown if (!EntryPoint.dumpTexture.Value) { return; } foreach (FlashlightSettingsDataBlock allBlock in GameDataBlockBase<FlashlightSettingsDataBlock>.GetAllBlocks()) { lightTextures.Add(((Il2CppObjectBase)AssetShardManager.GetLoadedAsset(allBlock.cookie, false)).Cast<Texture2D>()); } foreach (Texture2D lightTexture in lightTextures) { try { RenderTexture temporary = RenderTexture.GetTemporary(((Texture)lightTexture).width, ((Texture)lightTexture).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)1); RenderTexture active = RenderTexture.active; Graphics.Blit((Texture)(object)lightTexture, temporary); RenderTexture.active = active; Texture2D val = new Texture2D(((Texture)lightTexture).width, ((Texture)lightTexture).height); _ = RenderTexture.active; RenderTexture.active = temporary; val.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0); val.Apply(); RenderTexture.ReleaseTemporary(temporary); byte[] bytes = Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)ImageConversion.EncodeToPNG(val)); string text = Paths.BepInExRootPath + "\\LowSpec\\"; if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } if (!Directory.Exists(text + "FlashLights\\")) { Directory.CreateDirectory(text + "FlashLights\\"); } File.WriteAllBytes(text + "FlashLights\\" + ((Object)lightTexture).name + ".png", bytes); } catch { EntryPoint.LogIt("Skipping Texture"); } } } public void ApplySettings() { int value = 10; EntryPoint.LogIt("Apply Settings"); StartUpSettings.PotatoTexture(ref value); } private static void HateTheGameFeel() { if (EntryPoint.gameEnvironment.Value != 0) { ((Behaviour)((Component)PreLitVolume.Current).gameObject.GetComponent<AmbientParticles>()).enabled = false; PreLitVolume.Current.m_fogDistance = 45f; PreLitVolume.Current.FogPostBlur = 1; PreLitVolume.Current.FogShadowSamples = 0; PreLitVolume.Current.IndirectBlurSamples = 0; PreLitVolume.Current.IndirectDownsampling = 0; QualitySettings.shadowDistance = 15f; QualitySettings.softParticles = false; } } public static void ClusterRenderingOff() { ((Behaviour)ClusteredRendering.Current).enabled = false; } } } namespace LowSpecGaming.Util { public static class C_Combine { public static bool simplify; public static List<Renderer> CombineMeshes(Renderer[] renderersToCombine) { return CombineMeshes(renderersToCombine.ToList()); } [MethodImpl(MethodImplOptions.AggressiveOptimization)] public static List<Renderer> CombineMeshes(List<Renderer> renderersToCombine) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown if (renderersToCombine.Count < 2) { return renderersToCombine; } Material val; try { val = renderersToCombine[0].sharedMaterial; foreach (Renderer item2 in renderersToCombine) { if ((Object)(object)item2.sharedMaterial != (Object)(object)val) { return renderersToCombine; } } } catch { val = renderersToCombine[0].material; } List<CombineInstance> list = new List<CombineInstance>(); foreach (Renderer item3 in renderersToCombine) { MeshFilter component = ((Component)item3).GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null) { return renderersToCombine; } CombineInstance val2 = default(CombineInstance); ((CombineInstance)(ref val2)).mesh = component.sharedMesh; ((CombineInstance)(ref val2)).transform = ((Component)item3).transform.localToWorldMatrix; CombineInstance item = val2; list.Add(item); item3.enabled = false; item3.forceRenderingOff = true; Object.Destroy((Object)(object)component); } GameObject val3 = new GameObject(((Object)((Component)renderersToCombine[0]).gameObject).name + "_Combined"); val3.isStatic = true; C_CullingClusterPatch.CombinedGameObjects.Add(val3); MeshFilter val4 = val3.AddComponent<MeshFilter>(); MeshRenderer val5 = val3.AddComponent<MeshRenderer>(); Mesh val6 = new Mesh(); val6.CombineMeshes(Il2CppStructArray<CombineInstance>.op_Implicit(list.ToArray()), true, true); if (simplify) { MeshSimplifier meshSimplifier = new MeshSimplifier(val6); meshSimplifier.SimplifyMesh(0.8f); val4.mesh = meshSimplifier.ToMesh(); } else { val4.mesh = val6; } ((Renderer)val5).sharedMaterial = val; ((Renderer)val5).enabled = false; ((Renderer)val5).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val5).receiveShadows = false; ((Renderer)val5).lightProbeUsage = (LightProbeUsage)0; ((Renderer)val5).reflectionProbeUsage = (ReflectionProbeUsage)0; return new List<Renderer> { (Renderer)(object)val5 }; } public static List<Renderer> CombineShadowMeshes(List<Renderer> renderersToCombine) { //IL_0073: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown if (renderersToCombine.Count < 2) { return renderersToCombine; } Material sharedMaterial; try { sharedMaterial = renderersToCombine[0].sharedMaterial; } catch { sharedMaterial = renderersToCombine[0].material; } string name = ((Object)((Component)renderersToCombine[0]).gameObject).name; List<CombineInstance> list = new List<CombineInstance>(); foreach (Renderer item2 in renderersToCombine) { MeshFilter component = ((Component)item2).GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null) { return renderersToCombine; } CombineInstance val = default(CombineInstance); ((CombineInstance)(ref val)).mesh = component.sharedMesh; ((CombineInstance)(ref val)).transform = ((Component)item2).transform.localToWorldMatrix; CombineInstance item = val; list.Add(item); item2.enabled = false; item2.forceRenderingOff = true; Object.Destroy((Object)(object)component); } GameObject val2 = new GameObject(name + "_Combined"); val2.isStatic = true; C_CullingClusterPatch.CombinedGameObjects.Add(val2); MeshFilter obj2 = val2.AddComponent<MeshFilter>(); MeshRenderer val3 = val2.AddComponent<MeshRenderer>(); Mesh val4 = new Mesh(); val4.CombineMeshes(Il2CppStructArray<CombineInstance>.op_Implicit(list.ToArray()), true, true); obj2.mesh = val4; ((Renderer)val3).sharedMaterial = sharedMaterial; ((Renderer)val3).enabled = false; ((Renderer)val3).forceRenderingOff = true; ((Renderer)val3).shadowCastingMode = (ShadowCastingMode)1; ((Renderer)val3).receiveShadows = false; ((Renderer)val3).lightProbeUsage = (LightProbeUsage)0; ((Renderer)val3).reflectionProbeUsage = (ReflectionProbeUsage)0; return new List<Renderer> { (Renderer)(object)val3 }; } } } namespace LowSpecGaming.Settings { [HarmonyPatch] internal class GlobalSettingsPatch { private static GameObject newButton; private static GameObject newMenu; private static CM_ScrollWindow[] menu_list; private static CM_Item[] button_list; [HarmonyPostfix] [HarmonyPatch(typeof(CM_PageSettings), "Setup")] public static void UpdateSettings(CM_PageSettings __instance) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = ((Component)GameObject.Find("GUI").transform.GetChild(0).GetChild(3).GetChild(10) .GetChild(3) .GetChild(20)).gameObject; button_list = Il2CppArrayBase<CM_Item>.op_Implicit(((Component)GameObject.Find("GUI").transform.GetChild(0).GetChild(3).GetChild(10) .GetChild(3)).GetComponentsInChildren<CM_Item>()); GameObject gameObject2 = ((Component)GameObject.Find("GUI").transform.GetChild(0).GetChild(3).GetChild(10) .GetChild(3) .GetChild(21)).gameObject; newButton = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent); newMenu = Object.Instantiate<GameObject>(gameObject2, gameObject2.transform.parent); newButton.transform.position = gameObject.transform.position - new Vector3(0f, 160f, 0f); newButton.transform.localScale = gameObject.transform.localScale; newMenu.transform.position = gameObject2.transform.position; newMenu.transform.localScale = gameObject2.transform.localScale; newMenu.SetActive(false); ((TMP_Text)newButton.GetComponent<TextMeshPro>()).SetText("LowSpecGaming", true); newButton.GetComponent<CM_Item>().SetOnBtnPressCallback(Action<int>.op_Implicit((Action<int>)SetMenuActive)); CM_Item[] array = button_list; for (int i = 0; i < array.Length; i++) { array[i].OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)SetMenuInactive); } } public static void SetMenuActive(int a) { menu_list = Il2CppArrayBase<CM_ScrollWindow>.op_Implicit(((Component)GameObject.Find("GUI").transform.GetChild(0).GetChild(3).GetChild(10) .GetChild(3)).GetComponentsInChildren<CM_ScrollWindow>()); CM_ScrollWindow[] array = menu_list; for (int i = 0; i < array.Length; i++) { ((Component)array[i]).gameObject.SetActive(false); } newMenu.SetActive(true); } public static void SetMenuInactive(int a) { newMenu.SetActive(false); } } [HarmonyPatch] internal class StartUpSettings { [HarmonyPostfix] [HarmonyPatch(typeof(StartMainGame), "Start")] public static void MakeItWork(StartMainGame __instance) { ((Component)__instance).gameObject.AddComponent<LowSpecGaming>(); QualitySettings.masterTextureLimit = 0; } [HarmonyPrefix] [HarmonyPatch(typeof(CellSettingsApply), "ApplyTextureSize")] public static bool PotatoTexture(ref int value) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) EntryPoint.GetTheSettings(); LowSpecCamera.dynamic = EntryPoint.dynamicResolution.Value == DynamicResolution.Dynamic; LowSpecCamera.markerLayer = ((Component)GameObject.Find("GUI").transform.GetChild(0).GetChild(0)).GetComponent<UI_Canvas>(); LowSpecCamera.canvasScale = CellSettingsManager.SettingsData.Video.Resolution.Value.y / 1080f; SpitterPatch.hate = EntryPoint.hateSpitter.Value == HateSpitter.HATE; BioScanPatch.update = EntryPoint.BioScanUpdate.Value == BioScanBlink.Blink; IRFPatch.draw = EntryPoint.irfDrawing.Value == IRFDrawing.Draw; ClusterRestruct.shader = EntryPoint.shaderReplace.Value == ShaderReplace.Replace; C_Combine.simplify = EntryPoint.meshSimply.Value == MeshSimply.Simply; if (EntryPoint.dumpTexture.Value) { QualitySettings.masterTextureLimit = 0; } else { value = (int)EntryPoint.textureSize.Value; if (QualitySettings.masterTextureLimit != value) { QualitySettings.masterTextureLimit = value; } } return false; } } } namespace LowSpecGaming.Patches { public static class ClusterRestruct { public static bool shader; public static Shader diffuse = Shader.Find("Diffuse"); public static Renderer[] Restruct(Renderer[] initialRenderers) { if (initialRenderers.Length < 2) { C_CullingClusterPatch.initial_renderer += initialRenderers.Length; C_CullingClusterPatch.after_renderer += initialRenderers.Length; for (int i = 0; i < initialRenderers.Length; i++) { Material material = initialRenderers[i].material; if ((Object)(object)material == (Object)null) { break; } if (shader && ((Object)material.shader).name == "GTFO/CMS_WorldProp") { material.shader = diffuse; material.enableInstancing = true; } } return initialRenderers; } return Restruct(initialRenderers.ToList()); } public static Renderer[] Restruct(List<Renderer> initialRenderers) { int count = initialRenderers.Count; Dictionary<string, List<Renderer>> dictionary = new Dictionary<string, List<Renderer>>(); for (int i = 0; i < initialRenderers.Count; i++) { MeshFilter component = ((Component)initialRenderers[i]).GetComponent<MeshFilter>(); if (!((Object)(object)component == (Object)null)) { string key = component.mesh.vertexCount.ToString(); if (!dictionary.TryGetValue(key, out var _)) { dictionary[key] = new List<Renderer>(); } dictionary[key].Add(initialRenderers[i]); } } List<Renderer> list = new List<Renderer>(); List<string> list2 = new List<string>(); foreach (string key2 in dictionary.Keys) { list2.Add(key2); } foreach (string item in list2) { if (item != null) { int length = item.Length; if (length != 3) { if (length == 4) { switch (item[1]) { case '2': break; case '0': goto IL_01f2; case '4': goto IL_0202; case '3': goto IL_0212; case '1': goto IL_0222; default: goto IL_0235; } if (item == "1200") { goto IL_0230; } } } else { switch (item[2]) { case '0': break; case '8': goto IL_017a; case '4': goto IL_01b2; case '5': goto IL_01c2; case '3': goto IL_01d2; default: goto IL_0235; } if (item == "340") { goto IL_0230; } } } goto IL_0235; IL_01c2: if (item == "105") { goto IL_0230; } goto IL_0235; IL_01b2: if (item == "764") { goto IL_0230; } goto IL_0235; IL_017a: switch (item) { case "408": ca