Decompiled source of SphereOpt v0.9.1
SphereOpt.dll
Decompiled 10 months 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.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; using UnityMeshSimplifier; using UnityMeshSimplifier.Internal; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("Whinarn.UnityMeshSimplifier.Editor")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("SphereOpt")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Optimize Dyson Sphere rendering")] [assembly: AssemblyFileVersion("0.9.1.0")] [assembly: AssemblyInformationalVersion("0.9.1+b8dacadbd47d41028b256118022b5c46d05be0a9")] [assembly: AssemblyProduct("SphereOpt")] [assembly: AssemblyTitle("SphereOpt")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.9.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } namespace UnityMeshSimplifier { [Serializable] [StructLayout(LayoutKind.Auto)] public struct BlendShape { public string ShapeName; public BlendShapeFrame[] Frames; public BlendShape(string shapeName, BlendShapeFrame[] frames) { ShapeName = shapeName; Frames = frames; } } [Serializable] [StructLayout(LayoutKind.Auto)] public struct BlendShapeFrame { public float FrameWeight; public Vector3[] DeltaVertices; public Vector3[] DeltaNormals; public Vector3[] DeltaTangents; public BlendShapeFrame(float frameWeight, Vector3[] deltaVertices, Vector3[] deltaNormals, Vector3[] deltaTangents) { FrameWeight = frameWeight; DeltaVertices = deltaVertices; DeltaNormals = deltaNormals; DeltaTangents = deltaTangents; } } [AddComponentMenu("")] internal class LODBackupComponent : MonoBehaviour { [SerializeField] private Renderer[] originalRenderers; public Renderer[] OriginalRenderers { get { return originalRenderers; } set { originalRenderers = value; } } } [AddComponentMenu("Rendering/LOD Generator Helper")] public sealed class LODGeneratorHelper : MonoBehaviour { [SerializeField] [Tooltip("The fade mode used by the created LOD group.")] private LODFadeMode fadeMode; [SerializeField] [Tooltip("If the cross-fading should be animated by time.")] private bool animateCrossFading; [SerializeField] [Tooltip("If the renderers under this game object and any children should be automatically collected.")] private bool autoCollectRenderers = true; [SerializeField] [Tooltip("The simplification options.")] private SimplificationOptions simplificationOptions = SimplificationOptions.Default; [SerializeField] [Tooltip("The path within the assets directory to save the generated assets. Leave this empty to use the default path.")] private string saveAssetsPath = string.Empty; [SerializeField] [Tooltip("The LOD levels.")] private LODLevel[] levels; [SerializeField] private bool isGenerated; public LODFadeMode FadeMode { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return fadeMode; } set { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) fadeMode = value; } } public bool AnimateCrossFading { get { return animateCrossFading; } set { animateCrossFading = value; } } public bool AutoCollectRenderers { get { return autoCollectRenderers; } set { autoCollectRenderers = value; } } public SimplificationOptions SimplificationOptions { get { return simplificationOptions; } set { simplificationOptions = value; } } public string SaveAssetsPath { get { return saveAssetsPath; } set { saveAssetsPath = value; } } public LODLevel[] Levels { get { return levels; } set { levels = value; } } public bool IsGenerated => isGenerated; private void Reset() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) fadeMode = (LODFadeMode)0; animateCrossFading = false; autoCollectRenderers = true; simplificationOptions = SimplificationOptions.Default; levels = new LODLevel[3] { new LODLevel(0.5f, 1f) { CombineMeshes = false, CombineSubMeshes = false, SkinQuality = (SkinQuality)0, ShadowCastingMode = (ShadowCastingMode)1, ReceiveShadows = true, SkinnedMotionVectors = true, LightProbeUsage = (LightProbeUsage)1, ReflectionProbeUsage = (ReflectionProbeUsage)1 }, new LODLevel(0.17f, 0.65f) { CombineMeshes = true, CombineSubMeshes = false, SkinQuality = (SkinQuality)0, ShadowCastingMode = (ShadowCastingMode)1, ReceiveShadows = true, SkinnedMotionVectors = true, LightProbeUsage = (LightProbeUsage)1, ReflectionProbeUsage = (ReflectionProbeUsage)3 }, new LODLevel(0.02f, 0.4225f) { CombineMeshes = true, CombineSubMeshes = true, SkinQuality = (SkinQuality)2, ShadowCastingMode = (ShadowCastingMode)0, ReceiveShadows = false, SkinnedMotionVectors = false, LightProbeUsage = (LightProbeUsage)0, ReflectionProbeUsage = (ReflectionProbeUsage)0 } }; } } public sealed class ValidateSimplificationOptionsException : Exception { private readonly string propertyName; public string PropertyName => propertyName; public override string Message => base.Message + Environment.NewLine + "Property name: " + propertyName; public ValidateSimplificationOptionsException(string propertyName, string message) : base(message) { this.propertyName = propertyName; } public ValidateSimplificationOptionsException(string propertyName, string message, Exception innerException) : base(message, innerException) { this.propertyName = propertyName; } } public static class LODGenerator { private struct RendererInfo { public string name; public bool isStatic; public bool isNewMesh; public Transform transform; public Mesh mesh; public Material[] materials; public Transform rootBone; public Transform[] bones; } public static readonly string LODParentGameObjectName = "_UMS_LODs_"; public static readonly string LODAssetDefaultParentPath = "Assets/UMS_LODs/"; public static readonly string AssetsRootPath = "Assets/"; public static readonly string LODAssetUserData = "UnityMeshSimplifierLODAsset"; public static LODGroup GenerateLODs(LODGeneratorHelper generatorHelper) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)generatorHelper == (Object)null) { throw new ArgumentNullException("generatorHelper"); } GameObject gameObject = ((Component)generatorHelper).gameObject; LODLevel[] levels = generatorHelper.Levels; bool autoCollectRenderers = generatorHelper.AutoCollectRenderers; SimplificationOptions simplificationOptions = generatorHelper.SimplificationOptions; string saveAssetsPath = generatorHelper.SaveAssetsPath; LODGroup val = GenerateLODs(gameObject, levels, autoCollectRenderers, simplificationOptions, saveAssetsPath); if ((Object)(object)val == (Object)null) { return null; } val.animateCrossFading = generatorHelper.AnimateCrossFading; val.fadeMode = generatorHelper.FadeMode; return val; } public static LODGroup GenerateLODs(GameObject gameObject, LODLevel[] levels, bool autoCollectRenderers, SimplificationOptions simplificationOptions) { return GenerateLODs(gameObject, levels, autoCollectRenderers, simplificationOptions, null); } public static LODGroup GenerateLODs(GameObject gameObject, LODLevel[] levels, bool autoCollectRenderers, SimplificationOptions simplificationOptions, string saveAssetsPath) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gameObject == (Object)null) { throw new ArgumentNullException("gameObject"); } if (levels == null) { throw new ArgumentNullException("levels"); } Transform transform = gameObject.transform; Transform val = transform.Find(LODParentGameObjectName); if ((Object)(object)val != (Object)null) { throw new InvalidOperationException("The game object already appears to have LODs. Please remove them first."); } LODGroup component = gameObject.GetComponent<LODGroup>(); if ((Object)(object)component != (Object)null) { throw new InvalidOperationException("The game object already appears to have a LOD Group. Please remove it first."); } MeshSimplifier.ValidateOptions(simplificationOptions); saveAssetsPath = ValidateSaveAssetsPath(saveAssetsPath); GameObject val2 = new GameObject(LODParentGameObjectName); Transform transform2 = val2.transform; ParentAndResetTransform(transform2, transform); LODGroup val3 = gameObject.AddComponent<LODGroup>(); Renderer[] array = null; if (autoCollectRenderers) { array = GetChildRenderersForLOD(gameObject); } List<Renderer> list = new List<Renderer>((array != null) ? array.Length : 10); LOD[] array2 = (LOD[])(object)new LOD[levels.Length]; for (int i = 0; i < levels.Length; i++) { LODLevel level = levels[i]; GameObject val4 = new GameObject($"Level{i:00}"); Transform transform3 = val4.transform; ParentAndResetTransform(transform3, transform2); Renderer[] array3 = array ?? level.Renderers; List<Renderer> list2 = new List<Renderer>((array3 != null) ? array3.Length : 0); if (array3 != null && array3.Length != 0) { MeshRenderer[] renderers = (from renderer in array3 let meshFilter = ((Component)renderer).GetComponent<MeshFilter>() where renderer.enabled && (Object)/*isinst with value type is only supported in some contexts*/ != (Object)null && (Object)(object)meshFilter != (Object)null && (Object)(object)meshFilter.sharedMesh != (Object)null select <>h__TransparentIdentifier0).Select(<>h__TransparentIdentifier0 => { Renderer renderer4 = <>h__TransparentIdentifier0.renderer; return (MeshRenderer)(object)((renderer4 is MeshRenderer) ? renderer4 : null); }).ToArray(); SkinnedMeshRenderer[] renderers2 = (from renderer in array3 where renderer.enabled && (Object)(object)((renderer is SkinnedMeshRenderer) ? renderer : null) != (Object)null && (Object)(object)((SkinnedMeshRenderer)((renderer is SkinnedMeshRenderer) ? renderer : null)).sharedMesh != (Object)null select (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null)).ToArray(); RendererInfo[] array4; RendererInfo[] array5; if (level.CombineMeshes) { array4 = CombineStaticMeshes(transform, i, renderers); array5 = CombineSkinnedMeshes(transform, i, renderers2); } else { array4 = GetStaticRenderers(renderers); array5 = GetSkinnedRenderers(renderers2); } if (array4 != null) { for (int j = 0; j < array4.Length; j++) { RendererInfo renderer2 = array4[j]; Renderer item = CreateLevelRenderer(gameObject, i, in level, transform3, j, in renderer2, in simplificationOptions, saveAssetsPath); list2.Add(item); } } if (array5 != null) { for (int k = 0; k < array5.Length; k++) { RendererInfo renderer3 = array5[k]; Renderer item2 = CreateLevelRenderer(gameObject, i, in level, transform3, k, in renderer3, in simplificationOptions, saveAssetsPath); list2.Add(item2); } } Renderer[] array6 = array3; foreach (Renderer item3 in array6) { if (!list.Contains(item3)) { list.Add(item3); } } } array2[i] = new LOD(level.ScreenRelativeTransitionHeight, list2.ToArray()); } CreateBackup(gameObject, list.ToArray()); foreach (Renderer item4 in list) { item4.enabled = false; } val3.animateCrossFading = false; val3.SetLODs(array2); return val3; } public static bool DestroyLODs(LODGeneratorHelper generatorHelper) { if ((Object)(object)generatorHelper == (Object)null) { throw new ArgumentNullException("generatorHelper"); } return DestroyLODs(((Component)generatorHelper).gameObject); } public static bool DestroyLODs(GameObject gameObject) { if ((Object)(object)gameObject == (Object)null) { throw new ArgumentNullException("gameObject"); } RestoreBackup(gameObject); Transform transform = gameObject.transform; Transform val = transform.Find(LODParentGameObjectName); if ((Object)(object)val == (Object)null) { return false; } DestroyObject((Object)(object)((Component)val).gameObject); LODGroup component = gameObject.GetComponent<LODGroup>(); if ((Object)(object)component != (Object)null) { DestroyObject((Object)(object)component); } return true; } private static RendererInfo[] GetStaticRenderers(MeshRenderer[] renderers) { List<RendererInfo> list = new List<RendererInfo>(renderers.Length); foreach (MeshRenderer val in renderers) { MeshFilter component = ((Component)val).GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)"A renderer was missing a mesh filter and was ignored.", (Object)(object)val); continue; } Mesh sharedMesh = component.sharedMesh; if ((Object)(object)sharedMesh == (Object)null) { Debug.LogWarning((object)"A renderer was missing a mesh and was ignored.", (Object)(object)val); continue; } list.Add(new RendererInfo { name = ((Object)val).name, isStatic = true, isNewMesh = false, transform = ((Component)val).transform, mesh = sharedMesh, materials = ((Renderer)val).sharedMaterials }); } return list.ToArray(); } private static RendererInfo[] GetSkinnedRenderers(SkinnedMeshRenderer[] renderers) { List<RendererInfo> list = new List<RendererInfo>(renderers.Length); foreach (SkinnedMeshRenderer val in renderers) { Mesh sharedMesh = val.sharedMesh; if ((Object)(object)sharedMesh == (Object)null) { Debug.LogWarning((object)"A renderer was missing a mesh and was ignored.", (Object)(object)val); continue; } list.Add(new RendererInfo { name = ((Object)val).name, isStatic = false, isNewMesh = false, transform = ((Component)val).transform, mesh = sharedMesh, materials = ((Renderer)val).sharedMaterials, rootBone = val.rootBone, bones = val.bones }); } return list.ToArray(); } private static RendererInfo[] CombineStaticMeshes(Transform transform, int levelIndex, MeshRenderer[] renderers) { if (renderers.Length == 0) { return null; } List<RendererInfo> list = new List<RendererInfo>(renderers.Length); Material[] resultMaterials; Mesh val = MeshCombiner.CombineMeshes(transform, renderers, out resultMaterials); ((Object)val).name = $"{((Object)transform).name}_static{levelIndex:00}"; string name = $"{((Object)transform).name}_combined_static"; list.Add(new RendererInfo { name = name, isStatic = true, isNewMesh = true, transform = null, mesh = val, materials = resultMaterials, rootBone = null, bones = null }); return list.ToArray(); } private static RendererInfo[] CombineSkinnedMeshes(Transform transform, int levelIndex, SkinnedMeshRenderer[] renderers) { if (renderers.Length == 0) { return null; } List<RendererInfo> list = new List<RendererInfo>(renderers.Length); IEnumerable<SkinnedMeshRenderer> enumerable = renderers.Where((SkinnedMeshRenderer renderer) => (Object)(object)renderer.sharedMesh != (Object)null && renderer.sharedMesh.blendShapeCount > 0); IEnumerable<SkinnedMeshRenderer> enumerable2 = renderers.Where((SkinnedMeshRenderer renderer) => (Object)(object)renderer.sharedMesh == (Object)null); SkinnedMeshRenderer[] array = renderers.Where((SkinnedMeshRenderer renderer) => (Object)(object)renderer.sharedMesh != (Object)null && renderer.sharedMesh.blendShapeCount == 0).ToArray(); foreach (SkinnedMeshRenderer item in enumerable2) { Debug.LogWarning((object)"A renderer was missing a mesh and was ignored.", (Object)(object)item); } foreach (SkinnedMeshRenderer item2 in enumerable) { list.Add(new RendererInfo { name = ((Object)item2).name, isStatic = false, isNewMesh = false, transform = ((Component)item2).transform, mesh = item2.sharedMesh, materials = ((Renderer)item2).sharedMaterials, rootBone = item2.rootBone, bones = item2.bones }); } if (array.Length != 0) { Material[] resultMaterials; Transform[] resultBones; Mesh val = MeshCombiner.CombineMeshes(transform, array, out resultMaterials, out resultBones); ((Object)val).name = $"{((Object)transform).name}_skinned{levelIndex:00}"; Transform rootBone = FindBestRootBone(transform, array); string name = $"{((Object)transform).name}_combined_skinned"; list.Add(new RendererInfo { name = name, isStatic = false, isNewMesh = false, transform = null, mesh = val, materials = resultMaterials, rootBone = rootBone, bones = resultBones }); } return list.ToArray(); } private static void ParentAndResetTransform(Transform transform, Transform parentTransform) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) transform.SetParent(parentTransform); transform.localPosition = Vector3.zero; transform.localRotation = Quaternion.identity; transform.localScale = Vector3.one; } private static void ParentAndOffsetTransform(Transform transform, Transform parentTransform, Transform originalTransform) { //IL_0002: 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_001a: Unknown result type (might be due to invalid IL or missing references) transform.position = originalTransform.position; transform.rotation = originalTransform.rotation; transform.localScale = originalTransform.lossyScale; transform.SetParent(parentTransform, true); } private static Renderer CreateLevelRenderer(GameObject gameObject, int levelIndex, in LODLevel level, Transform levelTransform, int rendererIndex, in RendererInfo renderer, in SimplificationOptions simplificationOptions, string saveAssetsPath) { Mesh mesh = renderer.mesh; if (level.Quality < 1f) { mesh = SimplifyMesh(mesh, level.Quality, in simplificationOptions); if (renderer.isNewMesh) { DestroyObject((Object)(object)renderer.mesh); } } if (renderer.isStatic) { string name = $"{rendererIndex:000}_static_{renderer.name}"; return (Renderer)(object)CreateStaticLevelRenderer(name, levelTransform, renderer.transform, mesh, renderer.materials, in level); } string name2 = $"{rendererIndex:000}_skinned_{renderer.name}"; return (Renderer)(object)CreateSkinnedLevelRenderer(name2, levelTransform, renderer.transform, mesh, renderer.materials, renderer.rootBone, renderer.bones, in level); } private static MeshRenderer CreateStaticLevelRenderer(string name, Transform parentTransform, Transform originalTransform, Mesh mesh, Material[] materials, in LODLevel level) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[2] { typeof(MeshFilter), typeof(MeshRenderer) }); Transform transform = val.transform; if ((Object)(object)originalTransform != (Object)null) { ParentAndOffsetTransform(transform, parentTransform, originalTransform); } else { ParentAndResetTransform(transform, parentTransform); } MeshFilter component = val.GetComponent<MeshFilter>(); component.sharedMesh = mesh; MeshRenderer component2 = val.GetComponent<MeshRenderer>(); ((Renderer)component2).sharedMaterials = materials; SetupLevelRenderer((Renderer)(object)component2, in level); return component2; } private static SkinnedMeshRenderer CreateSkinnedLevelRenderer(string name, Transform parentTransform, Transform originalTransform, Mesh mesh, Material[] materials, Transform rootBone, Transform[] bones, in LODLevel level) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(SkinnedMeshRenderer) }); Transform transform = val.transform; if ((Object)(object)originalTransform != (Object)null) { ParentAndOffsetTransform(transform, parentTransform, originalTransform); } else { ParentAndResetTransform(transform, parentTransform); } SkinnedMeshRenderer component = val.GetComponent<SkinnedMeshRenderer>(); component.sharedMesh = mesh; ((Renderer)component).sharedMaterials = materials; component.rootBone = rootBone; component.bones = bones; SetupLevelRenderer((Renderer)(object)component, in level); return component; } private static Transform FindBestRootBone(Transform transform, SkinnedMeshRenderer[] skinnedMeshRenderers) { //IL_003a: 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_0045: 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) if (skinnedMeshRenderers == null || skinnedMeshRenderers.Length == 0) { return null; } Transform result = null; float num = float.MaxValue; for (int i = 0; i < skinnedMeshRenderers.Length; i++) { if (!((Object)(object)skinnedMeshRenderers[i] == (Object)null) && !((Object)(object)skinnedMeshRenderers[i].rootBone == (Object)null)) { Transform rootBone = skinnedMeshRenderers[i].rootBone; Vector3 val = rootBone.position - transform.position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { result = rootBone; num = sqrMagnitude; } } } return result; } private static void SetupLevelRenderer(Renderer renderer, in LODLevel level) { //IL_000a: 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_0046: 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_007e: Unknown result type (might be due to invalid IL or missing references) renderer.shadowCastingMode = level.ShadowCastingMode; renderer.receiveShadows = level.ReceiveShadows; renderer.motionVectorGenerationMode = level.MotionVectorGenerationMode; renderer.lightProbeUsage = level.LightProbeUsage; renderer.reflectionProbeUsage = level.ReflectionProbeUsage; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val != (Object)null) { val.quality = level.SkinQuality; val.skinnedMotionVectors = level.SkinnedMotionVectors; } } private static Renderer[] GetChildRenderersForLOD(GameObject gameObject) { List<Renderer> list = new List<Renderer>(); CollectChildRenderersForLOD(gameObject.transform, list); return list.ToArray(); } private static void CollectChildRenderersForLOD(Transform transform, List<Renderer> resultRenderers) { Renderer[] components = ((Component)transform).GetComponents<Renderer>(); resultRenderers.AddRange(components); int childCount = transform.childCount; for (int i = 0; i < childCount; i++) { Transform child = transform.GetChild(i); if (((Component)child).gameObject.activeSelf && !string.Equals(((Object)child).name, LODParentGameObjectName) && !((Object)(object)((Component)child).GetComponent<LODGroup>() != (Object)null) && !((Object)(object)((Component)child).GetComponent<LODGeneratorHelper>() != (Object)null)) { CollectChildRenderersForLOD(child, resultRenderers); } } } private static Mesh SimplifyMesh(Mesh mesh, float quality, in SimplificationOptions options) { MeshSimplifier meshSimplifier = new MeshSimplifier(); meshSimplifier.SimplificationOptions = options; meshSimplifier.Initialize(mesh); meshSimplifier.SimplifyMesh(quality); Mesh val = meshSimplifier.ToMesh(); val.bindposes = mesh.bindposes; return val; } private static void DestroyObject(Object obj) { if (obj == (Object)null) { throw new ArgumentNullException("obj"); } Object.Destroy(obj); } private static void CreateBackup(GameObject gameObject, Renderer[] originalRenderers) { LODBackupComponent lODBackupComponent = gameObject.AddComponent<LODBackupComponent>(); ((Object)lODBackupComponent).hideFlags = (HideFlags)2; lODBackupComponent.OriginalRenderers = originalRenderers; } private static void RestoreBackup(GameObject gameObject) { LODBackupComponent[] components = gameObject.GetComponents<LODBackupComponent>(); LODBackupComponent[] array = components; foreach (LODBackupComponent lODBackupComponent in array) { Renderer[] originalRenderers = lODBackupComponent.OriginalRenderers; if (originalRenderers != null) { Renderer[] array2 = originalRenderers; foreach (Renderer val in array2) { if ((Object)(object)val != (Object)null) { val.enabled = true; } } } DestroyObject((Object)(object)lODBackupComponent); } } private static string ValidateSaveAssetsPath(string saveAssetsPath) { if (string.IsNullOrEmpty(saveAssetsPath)) { return null; } Debug.LogWarning((object)"Unable to save assets when not running in the Unity Editor."); return null; } } [Serializable] public struct LODLevel { [SerializeField] [Range(0f, 1f)] [Tooltip("The screen relative height to use for the transition.")] private float screenRelativeTransitionHeight; [SerializeField] [Range(0f, 1f)] [Tooltip("The width of the cross-fade transition zone (proportion to the current LOD's whole length).")] private float fadeTransitionWidth; [SerializeField] [Range(0f, 1f)] [Tooltip("The desired quality for this level.")] private float quality; [SerializeField] [Tooltip("If all renderers and meshes under this level should be combined into one, where possible.")] private bool combineMeshes; [SerializeField] [Tooltip("If all sub-meshes should be combined into one, where possible.")] private bool combineSubMeshes; [SerializeField] [Tooltip("The renderers used in this level.")] private Renderer[] renderers; [SerializeField] [Tooltip("The skin quality to use for renderers on this level.")] private SkinQuality skinQuality; [SerializeField] [Tooltip("The shadow casting mode for renderers on this level.")] private ShadowCastingMode shadowCastingMode; [SerializeField] [Tooltip("If renderers on this level should receive shadows.")] private bool receiveShadows; [SerializeField] [Tooltip("The motion vector generation mode for renderers on this level.")] private MotionVectorGenerationMode motionVectorGenerationMode; [SerializeField] [Tooltip("If renderers on this level should use skinned motion vectors.")] private bool skinnedMotionVectors; [SerializeField] [Tooltip("The light probe usage for renderers on this level.")] private LightProbeUsage lightProbeUsage; [SerializeField] [Tooltip("The reflection probe usage for renderers on this level.")] private ReflectionProbeUsage reflectionProbeUsage; public float ScreenRelativeTransitionHeight { get { return screenRelativeTransitionHeight; } set { screenRelativeTransitionHeight = Mathf.Clamp01(value); } } public float FadeTransitionWidth { get { return fadeTransitionWidth; } set { fadeTransitionWidth = Mathf.Clamp01(value); } } public float Quality { get { return quality; } set { quality = Mathf.Clamp01(value); } } public bool CombineMeshes { get { return combineMeshes; } set { combineMeshes = value; } } public bool CombineSubMeshes { get { return combineSubMeshes; } set { combineSubMeshes = value; } } public Renderer[] Renderers { get { return renderers; } set { renderers = value; } } public SkinQuality SkinQuality { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return skinQuality; } set { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) skinQuality = value; } } public ShadowCastingMode ShadowCastingMode { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return shadowCastingMode; } set { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) shadowCastingMode = value; } } public bool ReceiveShadows { get { return receiveShadows; } set { receiveShadows = value; } } public MotionVectorGenerationMode MotionVectorGenerationMode { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return motionVectorGenerationMode; } set { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) motionVectorGenerationMode = value; } } public bool SkinnedMotionVectors { get { return skinnedMotionVectors; } set { skinnedMotionVectors = value; } } public LightProbeUsage LightProbeUsage { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return lightProbeUsage; } set { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) lightProbeUsage = value; } } public ReflectionProbeUsage ReflectionProbeUsage { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return reflectionProbeUsage; } set { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) reflectionProbeUsage = value; } } public LODLevel(float screenRelativeTransitionHeight, float quality) : this(screenRelativeTransitionHeight, 0f, quality, combineMeshes: false, combineSubMeshes: false, null) { } public LODLevel(float screenRelativeTransitionHeight, float fadeTransitionWidth, float quality, bool combineMeshes, bool combineSubMeshes) : this(screenRelativeTransitionHeight, fadeTransitionWidth, quality, combineMeshes, combineSubMeshes, null) { } public LODLevel(float screenRelativeTransitionHeight, float fadeTransitionWidth, float quality, bool combineMeshes, bool combineSubMeshes, Renderer[] renderers) { //IL_0039: 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_004e: 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_0063: Unknown result type (might be due to invalid IL or missing references) this.screenRelativeTransitionHeight = Mathf.Clamp01(screenRelativeTransitionHeight); this.fadeTransitionWidth = fadeTransitionWidth; this.quality = Mathf.Clamp01(quality); this.combineMeshes = combineMeshes; this.combineSubMeshes = combineSubMeshes; this.renderers = renderers; skinQuality = (SkinQuality)0; shadowCastingMode = (ShadowCastingMode)1; receiveShadows = true; motionVectorGenerationMode = (MotionVectorGenerationMode)1; skinnedMotionVectors = true; lightProbeUsage = (LightProbeUsage)1; reflectionProbeUsage = (ReflectionProbeUsage)1; } } 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(Vector3d.Angle(ref from, ref to) * (Math.PI / 180.0)) * to.Magnitude) * 0.5; } } 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; } } } public static class MeshCombiner { public static Mesh CombineMeshes(Transform rootTransform, MeshRenderer[] renderers, out Material[] resultMaterials) { //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rootTransform == (Object)null) { throw new ArgumentNullException("rootTransform"); } if (renderers == null) { throw new ArgumentNullException("renderers"); } Mesh[] array = (Mesh[])(object)new Mesh[renderers.Length]; Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[renderers.Length]; Material[][] array3 = new Material[renderers.Length][]; for (int i = 0; i < renderers.Length; i++) { MeshRenderer val = renderers[i]; if ((Object)(object)val == (Object)null) { throw new ArgumentException($"The renderer at index {i} is null.", "renderers"); } Transform transform = ((Component)val).transform; MeshFilter component = ((Component)val).GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null) { throw new ArgumentException($"The renderer at index {i} has no mesh filter.", "renderers"); } if ((Object)(object)component.sharedMesh == (Object)null) { throw new ArgumentException($"The mesh filter for renderer at index {i} has no mesh.", "renderers"); } if (!CanReadMesh(component.sharedMesh)) { throw new ArgumentException($"The mesh in the mesh filter for renderer at index {i} is not readable.", "renderers"); } array[i] = component.sharedMesh; array2[i] = rootTransform.worldToLocalMatrix * transform.localToWorldMatrix; array3[i] = ((Renderer)val).sharedMaterials; } return CombineMeshes(array, array2, array3, out resultMaterials); } public static Mesh CombineMeshes(Transform rootTransform, SkinnedMeshRenderer[] renderers, out Material[] resultMaterials, out Transform[] resultBones) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rootTransform == (Object)null) { throw new ArgumentNullException("rootTransform"); } if (renderers == null) { throw new ArgumentNullException("renderers"); } Mesh[] array = (Mesh[])(object)new Mesh[renderers.Length]; Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[renderers.Length]; Material[][] array3 = new Material[renderers.Length][]; Transform[][] array4 = new Transform[renderers.Length][]; for (int i = 0; i < renderers.Length; i++) { SkinnedMeshRenderer val = renderers[i]; if ((Object)(object)val == (Object)null) { throw new ArgumentException($"The renderer at index {i} is null.", "renderers"); } if ((Object)(object)val.sharedMesh == (Object)null) { throw new ArgumentException($"The renderer at index {i} has no mesh.", "renderers"); } if (!CanReadMesh(val.sharedMesh)) { throw new ArgumentException($"The mesh in the renderer at index {i} is not readable.", "renderers"); } Transform transform = ((Component)val).transform; array[i] = val.sharedMesh; array2[i] = transform.worldToLocalMatrix * transform.localToWorldMatrix; array3[i] = ((Renderer)val).sharedMaterials; array4[i] = val.bones; } return CombineMeshes(array, array2, array3, array4, out resultMaterials, out resultBones); } public static Mesh CombineMeshes(Mesh[] meshes, Matrix4x4[] transforms, Material[][] materials, out Material[] resultMaterials) { if (meshes == null) { throw new ArgumentNullException("meshes"); } if (transforms == null) { throw new ArgumentNullException("transforms"); } if (materials == null) { throw new ArgumentNullException("materials"); } Transform[] resultBones; return CombineMeshes(meshes, transforms, materials, null, out resultMaterials, out resultBones); } public static Mesh CombineMeshes(Mesh[] meshes, Matrix4x4[] transforms, Material[][] materials, Transform[][] bones, out Material[] resultMaterials, out Transform[] resultBones) { //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) if (meshes == null) { throw new ArgumentNullException("meshes"); } if (transforms == null) { throw new ArgumentNullException("transforms"); } if (materials == null) { throw new ArgumentNullException("materials"); } if (transforms.Length != meshes.Length) { throw new ArgumentException("The array of transforms doesn't have the same length as the array of meshes.", "transforms"); } if (materials.Length != meshes.Length) { throw new ArgumentException("The array of materials doesn't have the same length as the array of meshes.", "materials"); } if (bones != null && bones.Length != meshes.Length) { throw new ArgumentException("The array of bones doesn't have the same length as the array of meshes.", "bones"); } int num = 0; int num2 = 0; for (int i = 0; i < meshes.Length; i++) { Mesh val = meshes[i]; if ((Object)(object)val == (Object)null) { throw new ArgumentException($"The mesh at index {i} is null.", "meshes"); } if (!CanReadMesh(val)) { throw new ArgumentException($"The mesh at index {i} is not readable.", "meshes"); } num += val.vertexCount; num2 += val.subMeshCount; Material[] array = materials[i]; if (array == null) { throw new ArgumentException($"The materials for mesh at index {i} is null.", "materials"); } if (array.Length != val.subMeshCount) { throw new ArgumentException($"The materials for mesh at index {i} doesn't match the submesh count ({array.Length} != {val.subMeshCount}).", "materials"); } for (int j = 0; j < array.Length; j++) { if ((Object)(object)array[j] == (Object)null) { throw new ArgumentException($"The material at index {j} for mesh at index {i} is null.", "materials"); } } if (bones == null) { continue; } Transform[] array2 = bones[i]; if (array2 == null) { throw new ArgumentException($"The bones for mesh at index {i} is null.", "meshBones"); } for (int k = 0; k < array2.Length; k++) { if ((Object)(object)array2[k] == (Object)null) { throw new ArgumentException($"The bone at index {k} for mesh at index {i} is null.", "meshBones"); } } } List<Vector3> list = new List<Vector3>(num); List<int[]> list2 = new List<int[]>(num2); List<Vector3> dest = null; List<Vector4> dest2 = null; List<Color> dest3 = null; List<BoneWeight> dest4 = null; List<Vector4>[] array3 = new List<Vector4>[MeshUtils.UVChannelCount]; List<Matrix4x4> list3 = null; List<Transform> list4 = null; List<Material> list5 = new List<Material>(num2); Dictionary<Material, int> dictionary = new Dictionary<Material, int>(num2); int num3 = 0; for (int l = 0; l < meshes.Length; l++) { Mesh val2 = meshes[l]; Matrix4x4 transform = transforms[l]; Material[] array4 = materials[l]; Transform[] array5 = ((bones != null) ? bones[l] : null); int subMeshCount = val2.subMeshCount; int vertexCount = val2.vertexCount; Vector3[] vertices = val2.vertices; Vector3[] normals = val2.normals; Vector4[] tangents = val2.tangents; IList<Vector4>[] meshUVs = MeshUtils.GetMeshUVs(val2); Color[] colors = val2.colors; BoneWeight[] boneWeights = val2.boneWeights; Matrix4x4[] bindposes = val2.bindposes; if (array5 != null && boneWeights != null && boneWeights.Length != 0 && bindposes != null && bindposes.Length != 0 && array5.Length == bindposes.Length) { if (list3 == null) { list3 = new List<Matrix4x4>(bindposes); list4 = new List<Transform>(array5); } int[] array6 = new int[array5.Length]; for (int m = 0; m < array5.Length; m++) { int num4 = list4.IndexOf(array5[m]); if (num4 == -1 || bindposes[m] != list3[num4]) { num4 = list4.Count; list4.Add(array5[m]); list3.Add(bindposes[m]); } array6[m] = num4; } RemapBones(boneWeights, array6); } TransformVertices(vertices, ref transform); TransformNormals(normals, ref transform); TransformTangents(tangents, ref transform); CopyVertexPositions(list, vertices); CopyVertexAttributes(ref dest, normals, num3, vertexCount, num, new Vector3(1f, 0f, 0f)); CopyVertexAttributes(ref dest2, tangents, num3, vertexCount, num, new Vector4(0f, 0f, 1f, 1f)); CopyVertexAttributes(ref dest3, colors, num3, vertexCount, num, new Color(1f, 1f, 1f, 1f)); CopyVertexAttributes(ref dest4, boneWeights, num3, vertexCount, num, default(BoneWeight)); for (int n = 0; n < meshUVs.Length; n++) { CopyVertexAttributes(ref array3[n], meshUVs[n], num3, vertexCount, num, new Vector4(0f, 0f, 0f, 0f)); } for (int num5 = 0; num5 < subMeshCount; num5++) { Material val3 = array4[num5]; int[] triangles = val2.GetTriangles(num5, true); if (num3 > 0) { for (int num6 = 0; num6 < triangles.Length; num6++) { triangles[num6] += num3; } } if (dictionary.TryGetValue(val3, out var value)) { list2[value] = MergeArrays(list2[value], triangles); continue; } int count = list2.Count; dictionary.Add(val3, count); list5.Add(val3); list2.Add(triangles); } num3 += vertexCount; } Vector3[] vertices2 = list.ToArray(); int[][] indices = list2.ToArray(); Vector3[] normals2 = dest?.ToArray(); Vector4[] tangents2 = dest2?.ToArray(); Color[] colors2 = dest3?.ToArray(); BoneWeight[] boneWeights2 = dest4?.ToArray(); List<Vector4>[] uvs = array3.ToArray(); Matrix4x4[] bindposes2 = list3?.ToArray(); resultMaterials = list5.ToArray(); resultBones = list4?.ToArray(); return MeshUtils.CreateMesh(vertices2, indices, normals2, tangents2, colors2, boneWeights2, uvs, bindposes2, null); } private static void CopyVertexPositions(ICollection<Vector3> list, Vector3[] arr) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (arr != null && arr.Length != 0) { for (int i = 0; i < arr.Length; i++) { list.Add(arr[i]); } } } private static void CopyVertexAttributes<T>(ref List<T> dest, IEnumerable<T> src, int previousVertexCount, int meshVertexCount, int totalVertexCount, T defaultValue) { if (src == null || src.Count() == 0) { if (dest != null) { for (int i = 0; i < meshVertexCount; i++) { dest.Add(defaultValue); } } return; } if (dest == null) { dest = new List<T>(totalVertexCount); for (int j = 0; j < previousVertexCount; j++) { dest.Add(defaultValue); } } dest.AddRange(src); } private static T[] MergeArrays<T>(T[] arr1, T[] arr2) { T[] array = new T[arr1.Length + arr2.Length]; Array.Copy(arr1, 0, array, 0, arr1.Length); Array.Copy(arr2, 0, array, arr1.Length, arr2.Length); return array; } private static void TransformVertices(Vector3[] vertices, ref Matrix4x4 transform) { //IL_0009: 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_0013: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < vertices.Length; i++) { vertices[i] = ((Matrix4x4)(ref transform)).MultiplyPoint3x4(vertices[i]); } } private static void TransformNormals(Vector3[] normals, ref Matrix4x4 transform) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (normals != null) { for (int i = 0; i < normals.Length; i++) { normals[i] = ((Matrix4x4)(ref transform)).MultiplyVector(normals[i]); } } } private static void TransformTangents(Vector4[] tangents, ref Matrix4x4 transform) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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) if (tangents != null) { for (int i = 0; i < tangents.Length; i++) { Vector3 val = ((Matrix4x4)(ref transform)).MultiplyVector(new Vector3(tangents[i].x, tangents[i].y, tangents[i].z)); tangents[i] = new Vector4(val.x, val.y, val.z, tangents[i].w); } } } private static void RemapBones(BoneWeight[] boneWeights, int[] boneIndices) { for (int i = 0; i < boneWeights.Length; i++) { if (((BoneWeight)(ref boneWeights[i])).weight0 > 0f) { ((BoneWeight)(ref boneWeights[i])).boneIndex0 = boneIndices[((BoneWeight)(ref boneWeights[i])).boneIndex0]; } if (((BoneWeight)(ref boneWeights[i])).weight1 > 0f) { ((BoneWeight)(ref boneWeights[i])).boneIndex1 = boneIndices[((BoneWeight)(ref boneWeights[i])).boneIndex1]; } if (((BoneWeight)(ref boneWeights[i])).weight2 > 0f) { ((BoneWeight)(ref boneWeights[i])).boneIndex2 = boneIndices[((BoneWeight)(ref boneWeights[i])).boneIndex2]; } if (((BoneWeight)(ref boneWeights[i])).weight3 > 0f) { ((BoneWeight)(ref boneWeights[i])).boneIndex3 = boneIndices[((BoneWeight)(ref boneWeights[i])).boneIndex3]; } } } private static bool CanReadMesh(Mesh mesh) { return mesh.isReadable; } } public sealed 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 ResizableArray<BlendShapeContainer> blendShapes; 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 SimplificationOptions SimplificationOptions { get { return simplificationOptions; } set { ValidateOptions(value); simplificationOptions = value; } } [Obsolete("Use MeshSimplifier.SimplificationOptions instead.", false)] public bool PreserveBorderEdges { get { return simplificationOptions.PreserveBorderEdges; } set { SimplificationOptions simplificationOptions = this.simplificationOptions; simplificationOptions.PreserveBorderEdges = value; SimplificationOptions = simplificationOptions; } } [Obsolete("Use MeshSimplifier.SimplificationOptions instead.", false)] public bool PreserveUVSeamEdges { get { return simplificationOptions.PreserveUVSeamEdges; } set { SimplificationOptions simplificationOptions = this.simplificationOptions; simplificationOptions.PreserveUVSeamEdges = value; SimplificationOptions = simplificationOptions; } } [Obsolete("Use MeshSimplifier.SimplificationOptions instead.", false)] public bool PreserveUVFoldoverEdges { get { return simplificationOptions.PreserveUVFoldoverEdges; } set { SimplificationOptions simplificationOptions = this.simplificationOptions; simplificationOptions.PreserveUVFoldoverEdges = value; SimplificationOptions = simplificationOptions; } } [Obsolete("Use MeshSimplifier.SimplificationOptions instead.", false)] public bool PreserveSurfaceCurvature { get { return simplificationOptions.PreserveSurfaceCurvature; } set { SimplificationOptions simplificationOptions = this.simplificationOptions; simplificationOptions.PreserveSurfaceCurvature = value; SimplificationOptions = simplificationOptions; } } [Obsolete("Use MeshSimplifier.SimplificationOptions instead.", false)] public bool EnableSmartLink { get { return simplificationOptions.EnableSmartLink; } set { SimplificationOptions simplificationOptions = this.simplificationOptions; simplificationOptions.EnableSmartLink = value; SimplificationOptions = simplificationOptions; } } [Obsolete("Use MeshSimplifier.SimplificationOptions instead.", false)] public int MaxIterationCount { get { return simplificationOptions.MaxIterationCount; } set { SimplificationOptions simplificationOptions = this.simplificationOptions; simplificationOptions.MaxIterationCount = value; SimplificationOptions = simplificationOptions; } } [Obsolete("Use MeshSimplifier.SimplificationOptions instead.", false)] public double Agressiveness { get { return simplificationOptions.Agressiveness; } set { SimplificationOptions simplificationOptions = this.simplificationOptions; simplificationOptions.Agressiveness = value; SimplificationOptions = simplificationOptions; } } public bool Verbose { get { return verbose; } set { verbose = value; } } [Obsolete("Use MeshSimplifier.SimplificationOptions instead.", false)] public double VertexLinkDistance { get { return simplificationOptions.VertexLinkDistance; } set { SimplificationOptions simplificationOptions = this.simplificationOptions; simplificationOptions.VertexLinkDistance = ((value > double.Epsilon) ? value : double.Epsilon); SimplificationOptions = simplificationOptions; } } [Obsolete("Use MeshSimplifier.SimplificationOptions instead.", false)] public double VertexLinkDistanceSqr { get { return simplificationOptions.VertexLinkDistance * simplificationOptions.VertexLinkDistance; } set { SimplificationOptions simplificationOptions = this.simplificationOptions; simplificationOptions.VertexLinkDistance = Math.Sqrt(value); SimplificationOptions = simplificationOptions; } } public Vector3[] Vertices { get { //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) int length = vertices.Length; Vector3[] array = (Vector3[])(object)new Vector3[length]; Vertex[] data = vertices.Data; for (int i = 0; i < length; i++) { array[i] = (Vector3)data[i].p; } return array; } set { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (value == null) { throw new ArgumentNullException("value"); } bindposes = null; vertices.Resize(value.Length); Vertex[] data = vertices.Data; for (int i = 0; i < value.Length; i++) { data[i] = new Vertex(i, value[i]); } } } public int SubMeshCount => subMeshCount; public int BlendShapeCount { get { if (blendShapes == null) { return 0; } return blendShapes.Length; } } 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 BoneWeight[] BoneWeights { get { if (vertBoneWeights == null) { return null; } return vertBoneWeights.Data; } set { InitializeVertexAttribute(value, ref vertBoneWeights, "boneWeights"); } } 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); } } 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.", new object[3] { attributeName, attributeValues.Length, vertices.Length }); } attributeArray = null; } [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; } [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; } 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; } private static void CalculateBarycentricCoords(ref Vector3d point, ref Vector3d a, ref Vector3d b, ref Vector3d c, out Vector3 result) { //IL_00d0: 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) 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); } [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(); double value = Vector3d.Dot(ref lhs, ref rhs); if (Math.Abs(value) > 0.999) { return true; } Vector3d.Cross(ref lhs, ref rhs, out var result); result.Normalize(); deleted[j] = false; value = Vector3d.Dot(ref result, ref data2[@ref.tid].n); if (value < 0.2) { return true; } } return false; } 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 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; } if (blendShapes != null) { for (int m = 0; m < blendShapes.Length; m++) { blendShapes[m].InterpolateVertexAttributes(dst, i0, i1, i2, ref barycentricCoord); } } } 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; } 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 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); double num13 = Math.Sqrt(num7); int num14 = Math.Max((int)(num13 / num11 * 2147483647.0), 1); for (int num15 = 0; num15 < num10; num15++) { int index2 = array[num15].index; if (index2 == -1) { continue; } Vector3d p = data2[index2].p; for (int num16 = num15 + 1; num16 < num10; num16++) { int index3 = array[num16].index; if (index3 == -1) { continue; } if (array[num16].hash - array[num15].hash > num14) { break; } Vector3d p2 = data2[index3].p; double num17 = (p.x - p2.x) * (p.x - p2.x); double num18 = (p.y - p2.y) * (p.y - p2.y); double num19 = (p.z - p2.z) * (p.z - p2.z); double num20 = num17 + num18 + num19; if (num20 <= num7) { array[num16].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 num21 = 0; num21 < tcount2; num21++) { Ref @ref = data3[tstart2 + num21]; data[@ref.tid][@ref.tvertex] = index2; } } } } UpdateReferences(); } for (int num22 = 0; num22 < length; num22++) { data2[num22].q = default(SymmetricMatrix); } for (int num23 = 0; num23 < num; num23++) { int v = data[num23].v0; int v2 = data[num23].v1; int v3 = data[num23].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[num23].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 num24 = 0; num24 < num; num24++) { Triangle triangle = data[num24]; data[num24].err0 = CalculateError(ref data2[triangle.v0], ref data2[triangle.v1], out var result2); data[num24].err1 = CalculateError(ref data2[triangle.v1], ref data2[triangle.v2], out result2); data[num24].err2 = CalculateError(ref data2[triangle.v2], ref data2[triangle.v0], out result2); data[num24].err3 = MathHelper.Min(data[num24].err0, data[num24].err1, data[num24].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 CompactMesh() { //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_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_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_042a: 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) 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); BoneWeight[] array7 = ((vertBoneWeights != null) ? vertBoneWeights.Data : null); BlendShapeContainer[] array8 = ((blendShapes != null) ? blendShapes.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 (array7 != null) { array7[va] = array7[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 (array7 != null) { array7[va2] = array7[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 (array7 != null) { array7[va3] = array7[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[] array9 = array3[n]; if (array9 != null) { array9[num] = array9[m]; } } } if (array4 != null) { for (int num4 = 0; num4 < UVChannelCount; num4++) { Vector3[] array10 = array4[num4]; if (array10 != null) { array10[num] = array10[m]; } } } if (array5 != null) { for (int num5 = 0; num5 < UVChannelCount; num5++) { Vector4[] array11 = array5[num5]; if (array11 != null) { array11[num] = array11[m]; } } } if (array6 != null) { array6[num] = array6[m]; } if (array7 != null) { array7[num] = array7[m]; } if (array8 != null) { for (int num6 = 0; num6 < blendShapes.Length; num6++) { array8[num6].MoveVertexElement(num, m); } } } num++; } for (int num7 = 0; num7 < length2; num7++) { Triangle triangle2 = data2[num7]; triangle2.v0 = data[triangle2.v0].tstart; triangle2.v1 = data[triangle2.v1].tstart; triangle2.v2 = data[triangle2.v2].tstart; data2[num7] = 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); } if (array7 != null) { vertBoneWeights.Resize(length, trimExess: true); } if (array8 != null) { for (int num8 = 0; num8 < blendShapes.Length; num8++) { array8[num8].Resize(length); } } } 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; } } [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); } } } 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 ArgumentOutOfRangeExce