Decompiled source of ProceduralStages v1.11.0

ProceduralStages.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HG;
using Microsoft.CodeAnalysis;
using On.RoR2;
using On.RoR2.UI;
using ProceduralStages;
using R2API;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.ContentManagement;
using RoR2.EntityLogic;
using RoR2.ExpansionManagement;
using RoR2.Navigation;
using RoR2.Networking;
using RoR2.UI;
using RoR2.UI.SkinControllers;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityMeshSimplifier;
using UnityMeshSimplifier.Internal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}
public class AssetExtracter : MonoBehaviour
{
	[Serializable]
	public class PoolEntry
	{
		public DCC dccs;

		[Tooltip("The weight of this entry relative to its siblings")]
		public float weight;
	}

	[Serializable]
	public class ConditionalPoolEntry : PoolEntry
	{
		[Tooltip("ALL expansions in this list must be enabled for this run for this entry to be considered.")]
		public string[] requiredExpansions;
	}

	[Serializable]
	public class Category
	{
		[Tooltip("A name to help identify this category")]
		public string name;

		[Tooltip("The weight of all entries in this category relative to the sibling categories.")]
		public float categoryWeight = 1f;

		[Tooltip("These entries are always considered.")]
		public PoolEntry[] alwaysIncluded;

		[Tooltip("These entries are only considered if their individual conditions are met.")]
		public ConditionalPoolEntry[] includedIfConditionsMet;

		[Tooltip("These entries are considered only if no entries from 'includedIfConditionsMet' have been included.")]
		public PoolEntry[] includedIfNoConditionsMet;
	}

	[Serializable]
	public class DCCS
	{
		public DccsPool[] dccs;
	}

	[Serializable]
	public class DccsPool
	{
		public DccsPoolItem item;

		public Category[] poolCategories;
	}

	[Serializable]
	public class DCC
	{
		public string name;

		public string selectionChatString;

		public int minimumStageCompletion = 1;

		public int maximumStageCompletion = int.MaxValue;

		public Category2[] categories;
	}

	[Serializable]
	public class Category2
	{
		public string name;

		public float selectionWeight;

		public Card[] cards;
	}

	[Serializable]
	public class Card
	{
		public string DirectorCard;

		public string DirectorCardPrefab;

		public float? directorCreditCost;

		public int selectionWeight;

		public string spawnDistance;

		public bool preventOverhead;

		public int minimumStageCompletions;

		public string requiredUnlockable;

		public string forbiddenUnlockable;

		public string requiredUnlockableDef;

		public string forbiddenUnlockableDef;
	}

	private static void FindAllDirectorCardCategorySelection()
	{
		new List<string>
		{
			"RoR2/Base/MixEnemy/dccsMixEnemy.asset", "RoR2/Base/Common/dccsNullifiersOnly.asset", "RoR2/Base/arena/dccsArenaInteractables.asset", "RoR2/Base/arena/dccsArenaInteractablesDLC1.asset", "RoR2/Base/arena/dccsArenaMonsters.asset", "RoR2/Base/arena/dccsArenaMonstersDLC1.asset", "RoR2/Base/artifactworld/dccsArtifactWorldInteractables.asset", "RoR2/Base/artifactworld/dccsArtifactWorldInteractablesDLC1.asset", "RoR2/Base/artifactworld/dccsArtifactWorldMonsters.asset", "RoR2/Base/artifactworld/dccsArtifactWorldMonstersDLC1.asset",
			"RoR2/Base/blackbeach/dccsBlackBeachInteractables.asset", "RoR2/Base/blackbeach/dccsBlackBeachInteractablesDLC1.asset", "RoR2/Base/blackbeach/dccsBlackBeachMonsters.asset", "RoR2/Base/blackbeach/dccsBlackBeachMonstersDLC.asset", "RoR2/Base/dampcave/dccsDampCaveInteractables.asset", "RoR2/Base/dampcave/dccsDampCaveInteractablesDLC1.asset", "RoR2/Base/dampcave/dccsDampCaveMonsters.asset", "RoR2/Base/dampcave/dccsDampCaveMonstersDLC1.asset", "RoR2/Base/foggyswamp/dccsFoggySwampInteractables.asset", "RoR2/Base/foggyswamp/dccsFoggySwampInteractablesDLC1.asset",
			"RoR2/Base/foggyswamp/dccsFoggySwampMonsters.asset", "RoR2/Base/foggyswamp/dccsFoggySwampMonstersDLC.asset", "RoR2/Base/frozenwall/dccsFrozenWallInteractables.asset", "RoR2/Base/frozenwall/dccsFrozenWallInteractablesDLC1.asset", "RoR2/Base/frozenwall/dccsFrozenWallMonsters.asset", "RoR2/Base/frozenwall/dccsFrozenWallMonstersDLC1.asset", "RoR2/Base/goldshores/dccsGoldshoresInteractables.asset", "RoR2/Base/goldshores/dccsGoldshoresInteractablesDLC1.asset", "RoR2/Base/goldshores/dccsGoldshoresMonsters.asset", "RoR2/Base/goldshores/dccsGoldshoresMonstersDLC1.asset",
			"RoR2/Base/golemplains/dccsGolemplainsInteractables.asset", "RoR2/Base/golemplains/dccsGolemplainsInteractablesDLC1.asset", "RoR2/Base/golemplains/dccsGolemplainsMonsters.asset", "RoR2/Base/golemplains/dccsGolemplainsMonstersDLC1.asset", "RoR2/Base/goolake/dccsGooLakeInteractables.asset", "RoR2/Base/goolake/dccsGooLakeInteractablesDLC1.asset", "RoR2/Base/goolake/dccsGooLakeMonsters.asset", "RoR2/Base/goolake/dccsGooLakeMonstersDLC1.asset", "RoR2/Base/moon/dccsMoonInteractables.asset", "RoR2/Base/moon/dccsMoonInteractablesDLC1.asset",
			"RoR2/Base/moon/dccsMoonMonsters.asset", "RoR2/Base/moon/dccsMoonMonstersDLC1.asset", "RoR2/Base/rootjungle/dccsRootJungleInteractables.asset", "RoR2/Base/rootjungle/dccsRootJungleInteractablesDLC1.asset", "RoR2/Base/rootjungle/dccsRootJungleMonsters.asset", "RoR2/Base/rootjungle/dccsRootJungleMonstersDLC1.asset", "RoR2/Base/shipgraveyard/dccsShipgraveyardInteractables.asset", "RoR2/Base/shipgraveyard/dccsShipgraveyardInteractablesDLC1.asset", "RoR2/Base/shipgraveyard/dccsShipgraveyardMonsters.asset", "RoR2/Base/shipgraveyard/dccsShipgraveyardMonstersDLC1.asset",
			"RoR2/Base/skymeadow/dccsSkyMeadowInteractables.asset", "RoR2/Base/skymeadow/dccsSkyMeadowInteractablesDLC1.asset", "RoR2/Base/skymeadow/dccsSkyMeadowMonsters.asset", "RoR2/Base/skymeadow/dccsSkyMeadowMonstersDLC1.asset", "RoR2/Base/wispgraveyard/dccsWispGraveyardInteractables.asset", "RoR2/Base/wispgraveyard/dccsWispGraveyardInteractablesDLC1.asset", "RoR2/Base/wispgraveyard/dccsWispGraveyardMonsters.asset", "RoR2/Base/wispgraveyard/dccsWispGraveyardMonstersDLC1.asset", "RoR2/DLC1/GameModes/InfiniteTowerRun/InfiniteTowerAssets/dccsInfiniteTowerInteractables.asset", "RoR2/DLC1/GameModes/InfiniteTowerRun/InfiniteTowerAssets/dccsITScav.asset",
			"RoR2/DLC1/GameModes/InfiniteTowerRun/InfiniteTowerAssets/dccsITVoidMonsters.asset", "RoR2/DLC1/VoidCamp/dccsVoidCampFlavorProps.asset", "RoR2/DLC1/VoidCamp/dccsVoidCampInteractables.asset", "RoR2/DLC1/VoidCamp/dccsVoidCampMonsters.asset", "RoR2/DLC1/ancientloft/dccsAncientLoftInteractablesDLC1.asset", "RoR2/DLC1/ancientloft/dccsAncientLoftMonstersDLC1.asset", "RoR2/DLC1/itancientloft/dccsITAncientLoftMonsters.asset", "RoR2/DLC1/itdampcave/dccsITDampCaveMonsters.asset", "RoR2/DLC1/itfrozenwall/dccsITFrozenWallMonsters.asset", "RoR2/DLC1/itgolemplains/dccsITGolemplainsMonsters.asset",
			"RoR2/DLC1/itgoolake/dccsITGooLakeMonsters.asset", "RoR2/DLC1/itmoon/dccsITMoonMonsters.asset", "RoR2/DLC1/itskymeadow/dccsITSkyMeadowMonsters.asset", "RoR2/DLC1/snowyforest/dccsSnowyForestInteractablesDLC1.asset", "RoR2/DLC1/snowyforest/dccsSnowyForestMonstersDLC1.asset", "RoR2/DLC1/sulfurpools/dccsSulfurPoolsInteractablesDLC1.asset", "RoR2/DLC1/sulfurpools/dccsSulfurPoolsMonstersDLC1.asset", "RoR2/DLC1/voidraid/dccsVoidDonutMonsters.asset", "RoR2/DLC1/voidstage/dccsVoidStageInteractables.asset", "RoR2/DLC1/voidstage/dccsVoidStageMonsters.asset"
		};
		DccsPool[] dccs = (from x in DccsPoolItem.All.Select((DccsPoolItem x) => new
			{
				Item = x,
				Asset = Addressables.LoadAssetAsync<DccsPool>((object)x.Asset).WaitForCompletion()
			}).ToList()
			select new DccsPool
			{
				item = x.Item,
				poolCategories = x.Asset.poolCategories.Select((Category pc) => new Category
				{
					name = pc.name,
					categoryWeight = pc.categoryWeight,
					alwaysIncluded = pc.alwaysIncluded.Select((PoolEntry y) => new PoolEntry
					{
						dccs = MapDCCS(y),
						weight = y.weight
					}).ToArray(),
					includedIfConditionsMet = pc.includedIfConditionsMet.Select((ConditionalPoolEntry y) => new ConditionalPoolEntry
					{
						requiredExpansions = y.requiredExpansions.Select((ExpansionDef z) => ((Object)z).name).ToArray(),
						dccs = MapDCCS((PoolEntry)(object)y),
						weight = ((PoolEntry)y).weight
					}).ToArray(),
					includedIfNoConditionsMet = pc.includedIfNoConditionsMet.Select((PoolEntry y) => new PoolEntry
					{
						dccs = MapDCCS(y),
						weight = y.weight
					}).ToArray()
				}).ToArray()
			}).ToArray();
		string contents = JsonUtility.ToJson((object)new DCCS
		{
			dccs = dccs
		});
		File.WriteAllText("E:\\dccs.json", contents);
		static DCC MapDCCS(PoolEntry y)
		{
			DirectorCardCategorySelection dccs2 = y.dccs;
			FamilyDirectorCardCategorySelection val = (FamilyDirectorCardCategorySelection)(object)((dccs2 is FamilyDirectorCardCategorySelection) ? dccs2 : null);
			return new DCC
			{
				name = ((Object)y.dccs).name,
				selectionChatString = val?.selectionChatString,
				minimumStageCompletion = (val?.minimumStageCompletion ?? (-1)),
				maximumStageCompletion = (val?.maximumStageCompletion ?? (-1)),
				categories = y.dccs.categories.Select((Category categorie) => new Category2
				{
					name = categorie.name,
					selectionWeight = categorie.selectionWeight,
					cards = categorie.cards.Select(delegate(DirectorCard c)
					{
						Card card = new Card();
						SpawnCard spawnCard = c.spawnCard;
						card.DirectorCard = ((spawnCard != null) ? ((Object)spawnCard).name : null);
						SpawnCard spawnCard2 = c.spawnCard;
						object directorCardPrefab;
						if (spawnCard2 == null)
						{
							directorCardPrefab = null;
						}
						else
						{
							GameObject prefab = spawnCard2.prefab;
							directorCardPrefab = ((prefab != null) ? ((Object)prefab).name : null);
						}
						card.DirectorCardPrefab = (string)directorCardPrefab;
						card.directorCreditCost = c.spawnCard?.directorCreditCost;
						card.selectionWeight = c.selectionWeight;
						card.spawnDistance = ((object)(MonsterSpawnDistance)(ref c.spawnDistance)).ToString();
						card.minimumStageCompletions = c.minimumStageCompletions;
						card.preventOverhead = c.preventOverhead;
						card.requiredUnlockable = c.requiredUnlockable;
						card.forbiddenUnlockable = c.forbiddenUnlockable;
						UnlockableDef requiredUnlockableDef = c.requiredUnlockableDef;
						card.requiredUnlockableDef = ((requiredUnlockableDef != null) ? requiredUnlockableDef.cachedName : null);
						UnlockableDef forbiddenUnlockableDef = c.forbiddenUnlockableDef;
						card.forbiddenUnlockableDef = ((forbiddenUnlockableDef != null) ? forbiddenUnlockableDef.cachedName : null);
						return card;
					}).ToArray()
				}).ToArray()
			};
		}
	}
}
public class NodeGraphRenderer : MonoBehaviour
{
	public HullMask hullMask;

	public NodeFlags nodeFlags;

	public bool showGroundMesh;

	public bool showAirMesh;

	public GameObject groundMeshObject;

	public GameObject airMeshObject;

	public GameObject sceneInfoObject;

	private SceneInfo sceneInfo;

	private NodeGraph _cacheNodeGraph;

	public void Awake()
	{
		sceneInfo = sceneInfoObject.GetComponent<SceneInfo>();
	}

	public void OnValidate()
	{
		UpdateMesh();
	}

	private void Update()
	{
		if ((Object)(object)_cacheNodeGraph != (Object)(object)sceneInfo.groundNodes)
		{
			UpdateMesh();
		}
	}

	private void UpdateMesh()
	{
		Debug.Log((object)"UpdateMesh");
		_cacheNodeGraph = sceneInfo.groundNodes;
		NodeGraph groundNodes = sceneInfo.groundNodes;
		if (showGroundMesh)
		{
			Mesh mesh = GenerateLinkDebugMesh(groundNodes);
			groundMeshObject.GetComponent<MeshFilter>().mesh = mesh;
		}
		else
		{
			groundMeshObject.GetComponent<MeshFilter>().mesh = null;
		}
		NodeGraph airNodes = sceneInfo.airNodes;
		if (showAirMesh && (Object)(object)airNodes != (Object)null)
		{
			Mesh mesh2 = GenerateLinkDebugMesh(airNodes);
			airMeshObject.GetComponent<MeshFilter>().mesh = mesh2;
		}
		else
		{
			airMeshObject.GetComponent<MeshFilter>().mesh = null;
		}
	}

	public Mesh GenerateLinkDebugMesh(NodeGraph nodeGraph)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_0016: 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)
		//IL_001d: 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_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Expected O, but got Unknown
		//IL_0036: 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)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: 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_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: 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_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: 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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: 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_010e: Invalid comparison between Unknown and I4
		//IL_011e: 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_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: 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_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: 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_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: 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_0179: 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_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		WireMeshBuilder val = new WireMeshBuilder();
		try
		{
			Link[] links = nodeGraph.links;
			Vector3 val8 = default(Vector3);
			Color val10 = default(Color);
			foreach (Link val2 in links)
			{
				if ((val2.hullMask & hullMask) == 0)
				{
					continue;
				}
				Node val3 = nodeGraph.nodes[val2.nodeIndexA.nodeIndex];
				Node val4 = nodeGraph.nodes[val2.nodeIndexB.nodeIndex];
				if ((val3.flags & nodeFlags) == 0 || (val4.flags & nodeFlags) == 0 || (val3.forbiddenHulls & hullMask) != 0 || (val4.forbiddenHulls & hullMask) != 0)
				{
					continue;
				}
				Vector3 position = nodeGraph.nodes[val2.nodeIndexA.nodeIndex].position;
				Vector3 position2 = nodeGraph.nodes[val2.nodeIndexB.nodeIndex].position;
				Vector3 val5 = (position + position2) * 0.5f;
				int num;
				Color val6;
				if ((val2.jumpHullMask & hullMask) <= 0)
				{
					num = 0;
				}
				else
				{
					num = 1;
					if (num != 0)
					{
						val6 = Color.cyan;
						goto IL_0123;
					}
				}
				val6 = Color.green;
				goto IL_0123;
				IL_0123:
				Color val7 = val6;
				if (num != 0)
				{
					((Vector3)(ref val8))..ctor(val5.x, position.y + val2.minJumpHeight, val5.z);
					int num2 = 8;
					Vector3 val9 = position;
					for (int j = 1; j <= num2; j++)
					{
						if (j > num2 / 2)
						{
							val7.a = 0.1f;
						}
						Vector3 quadraticCoordinates = nodeGraph.GetQuadraticCoordinates((float)j / (float)num2, position, val8, position2);
						val.AddLine(val9, val7, quadraticCoordinates, val7);
						val9 = quadraticCoordinates;
					}
				}
				else
				{
					((Color)(ref val10))..ctor(val7.r, val7.g, val7.b, 0.1f);
					val.AddLine(position, val7, (position + position2) * 0.5f, val10);
				}
			}
			Mesh val11 = new Mesh();
			val11.indexFormat = (IndexFormat)1;
			val.GenerateMesh(val11);
			return val11;
		}
		finally
		{
			((IDisposable)val)?.Dispose();
		}
	}
}
namespace System.Collections.Generic
{
	[DebuggerDisplay("Count = {Count}")]
	public class PriorityQueue<TElement, TPriority>
	{
		[DebuggerDisplay("Count = {Count}")]
		public sealed class UnorderedItemsCollection : IReadOnlyCollection<(TElement Element, TPriority Priority)>, IEnumerable<(TElement Element, TPriority Priority)>, IEnumerable, ICollection
		{
			public struct Enumerator : IEnumerator<(TElement Element, TPriority Priority)>, IEnumerator, IDisposable
			{
				private readonly PriorityQueue<TElement, TPriority> _queue;

				private readonly int _version;

				private int _index;

				private (TElement, TPriority) _current;

				public (TElement Element, TPriority Priority) Current => _current;

				object IEnumerator.Current => _current;

				internal Enumerator(PriorityQueue<TElement, TPriority> queue)
				{
					_queue = queue;
					_index = 0;
					_version = queue._version;
					_current = default((TElement, TPriority));
				}

				public void Dispose()
				{
				}

				public bool MoveNext()
				{
					PriorityQueue<TElement, TPriority> queue = _queue;
					if (_version == queue._version && (uint)_index < (uint)queue._size)
					{
						_current = queue._nodes[_index];
						_index++;
						return true;
					}
					return MoveNextRare();
				}

				private bool MoveNextRare()
				{
					if (_version != _queue._version)
					{
						throw new InvalidOperationException();
					}
					_index = _queue._size + 1;
					_current = default((TElement, TPriority));
					return false;
				}

				void IEnumerator.Reset()
				{
					if (_version != _queue._version)
					{
						throw new InvalidOperationException();
					}
					_index = 0;
					_current = default((TElement, TPriority));
				}
			}

			internal readonly PriorityQueue<TElement, TPriority> _queue;

			public int Count => _queue._size;

			object ICollection.SyncRoot => this;

			bool ICollection.IsSynchronized => false;

			internal UnorderedItemsCollection(PriorityQueue<TElement, TPriority> queue)
			{
				_queue = queue;
			}

			void ICollection.CopyTo(Array array, int index)
			{
				if (array == null)
				{
					throw new ArgumentNullException("array");
				}
				if (array.Rank != 1)
				{
					throw new ArgumentException("array");
				}
				if (array.GetLowerBound(0) != 0)
				{
					throw new ArgumentException("array");
				}
				if (index < 0 || index > array.Length)
				{
					throw new ArgumentOutOfRangeException("index");
				}
				if (array.Length - index < _queue._size)
				{
					throw new ArgumentException();
				}
				try
				{
					Array.Copy(_queue._nodes, 0, array, index, _queue._size);
				}
				catch (ArrayTypeMismatchException)
				{
					throw new ArgumentException("array");
				}
			}

			public Enumerator GetEnumerator()
			{
				return new Enumerator(_queue);
			}

			IEnumerator<(TElement Element, TPriority Priority)> IEnumerable<(TElement, TPriority)>.GetEnumerator()
			{
				if (_queue.Count != 0)
				{
					return GetEnumerator();
				}
				return new List<(TElement, TPriority)>().GetEnumerator();
			}

			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<(TElement, TPriority)>)this).GetEnumerator();
			}
		}

		private (TElement Element, TPriority Priority)[] _nodes;

		private readonly IComparer<TPriority> _comparer;

		private UnorderedItemsCollection _unorderedItems;

		private int _size;

		private int _version;

		private const int Arity = 4;

		private const int Log2Arity = 2;

		public int Count => _size;

		public IComparer<TPriority> Comparer => _comparer ?? Comparer<TPriority>.Default;

		public UnorderedItemsCollection UnorderedItems => _unorderedItems ?? (_unorderedItems = new UnorderedItemsCollection(this));

		public PriorityQueue()
		{
			_nodes = Array.Empty<(TElement, TPriority)>();
			_comparer = InitializeComparer(null);
		}

		public PriorityQueue(int initialCapacity)
			: this(initialCapacity, (IComparer<TPriority>)null)
		{
		}

		public PriorityQueue(IComparer<TPriority> comparer)
		{
			_nodes = Array.Empty<(TElement, TPriority)>();
			_comparer = InitializeComparer(comparer);
		}

		public PriorityQueue(int initialCapacity, IComparer<TPriority> comparer)
		{
			if (initialCapacity < 0)
			{
				throw new ArgumentOutOfRangeException("initialCapacity");
			}
			_nodes = new(TElement, TPriority)[initialCapacity];
			_comparer = InitializeComparer(comparer);
		}

		public PriorityQueue(IEnumerable<(TElement Element, TPriority Priority)> items)
			: this(items, (IComparer<TPriority>)null)
		{
		}

		public PriorityQueue(IEnumerable<(TElement Element, TPriority Priority)> items, IComparer<TPriority> comparer)
		{
			if (items == null)
			{
				throw new ArgumentNullException("items");
			}
			_nodes = items.ToArray();
			_comparer = InitializeComparer(comparer);
			if (_size > 1)
			{
				Heapify();
			}
		}

		public void Enqueue(TElement element, TPriority priority)
		{
			int size = _size;
			_version++;
			if (_nodes.Length == size)
			{
				Grow(size + 1);
			}
			_size = size + 1;
			if (_comparer == null)
			{
				MoveUpDefaultComparer((element, priority), size);
			}
			else
			{
				MoveUpCustomComparer((element, priority), size);
			}
		}

		public TElement Peek()
		{
			if (_size == 0)
			{
				throw new InvalidOperationException();
			}
			return _nodes[0].Element;
		}

		public TElement Dequeue()
		{
			if (_size == 0)
			{
				throw new InvalidOperationException();
			}
			TElement item = _nodes[0].Element;
			RemoveRootNode();
			return item;
		}

		public TElement DequeueEnqueue(TElement element, TPriority priority)
		{
			if (_size == 0)
			{
				throw new InvalidOperationException();
			}
			(TElement, TPriority) tuple = _nodes[0];
			if (_comparer == null)
			{
				if (Comparer<TPriority>.Default.Compare(priority, tuple.Item2) > 0)
				{
					MoveDownDefaultComparer((element, priority), 0);
				}
				else
				{
					_nodes[0] = (element, priority);
				}
			}
			else if (_comparer.Compare(priority, tuple.Item2) > 0)
			{
				MoveDownCustomComparer((element, priority), 0);
			}
			else
			{
				_nodes[0] = (element, priority);
			}
			_version++;
			return tuple.Item1;
		}

		public bool TryDequeue(out TElement element, out TPriority priority)
		{
			if (_size != 0)
			{
				(element, priority) = _nodes[0];
				RemoveRootNode();
				return true;
			}
			element = default(TElement);
			priority = default(TPriority);
			return false;
		}

		public bool TryPeek(out TElement element, out TPriority priority)
		{
			if (_size != 0)
			{
				(element, priority) = _nodes[0];
				return true;
			}
			element = default(TElement);
			priority = default(TPriority);
			return false;
		}

		public TElement EnqueueDequeue(TElement element, TPriority priority)
		{
			if (_size != 0)
			{
				(TElement, TPriority) tuple = _nodes[0];
				if (_comparer == null)
				{
					if (Comparer<TPriority>.Default.Compare(priority, tuple.Item2) > 0)
					{
						MoveDownDefaultComparer((element, priority), 0);
						_version++;
						return tuple.Item1;
					}
				}
				else if (_comparer.Compare(priority, tuple.Item2) > 0)
				{
					MoveDownCustomComparer((element, priority), 0);
					_version++;
					return tuple.Item1;
				}
			}
			return element;
		}

		public void EnqueueRange(IEnumerable<(TElement Element, TPriority Priority)> items)
		{
			if (items == null)
			{
				throw new ArgumentNullException("items");
			}
			int num = 0;
			ICollection<(TElement, TPriority)> collection = items as ICollection<(TElement, TPriority)>;
			if (collection != null && (num = collection.Count) > _nodes.Length - _size)
			{
				Grow(checked(_size + num));
			}
			if (_size == 0)
			{
				if (collection != null)
				{
					collection.CopyTo(_nodes, 0);
					_size = num;
				}
				else
				{
					int num2 = 0;
					(TElement, TPriority)[] nodes = _nodes;
					foreach (var (item, item2) in items)
					{
						if (nodes.Length == num2)
						{
							Grow(num2 + 1);
							nodes = _nodes;
						}
						nodes[num2++] = (item, item2);
					}
					_size = num2;
				}
				_version++;
				if (_size > 1)
				{
					Heapify();
				}
				return;
			}
			foreach (var (element, priority) in items)
			{
				Enqueue(element, priority);
			}
		}

		public void EnqueueRange(IEnumerable<TElement> elements, TPriority priority)
		{
			if (elements == null)
			{
				throw new ArgumentNullException("elements");
			}
			int count;
			if (elements is ICollection<TElement> collection && (count = collection.Count) > _nodes.Length - _size)
			{
				Grow(checked(_size + count));
			}
			if (_size == 0)
			{
				int num = 0;
				(TElement, TPriority)[] nodes = _nodes;
				foreach (TElement element in elements)
				{
					if (nodes.Length == num)
					{
						Grow(num + 1);
						nodes = _nodes;
					}
					nodes[num++] = (element, priority);
				}
				_size = num;
				_version++;
				if (num > 1)
				{
					Heapify();
				}
				return;
			}
			foreach (TElement element2 in elements)
			{
				Enqueue(element2, priority);
			}
		}

		public bool Remove(TElement element, out TElement removedElement, out TPriority priority, IEqualityComparer<TElement> equalityComparer = null)
		{
			int num = FindIndex(element, equalityComparer);
			if (num < 0)
			{
				removedElement = default(TElement);
				priority = default(TPriority);
				return false;
			}
			(TElement, TPriority)[] nodes = _nodes;
			(TElement, TPriority) tuple = nodes[num];
			removedElement = tuple.Item1;
			priority = tuple.Item2;
			int num2 = --_size;
			if (num < num2)
			{
				(TElement, TPriority) node = nodes[num2];
				if (_comparer == null)
				{
					MoveDownDefaultComparer(node, num);
				}
				else
				{
					MoveDownCustomComparer(node, num);
				}
			}
			nodes[num2] = default((TElement, TPriority));
			_version++;
			return true;
		}

		public void Clear()
		{
			Array.Clear(_nodes, 0, _size);
			_size = 0;
			_version++;
		}

		public int EnsureCapacity(int capacity)
		{
			if (capacity < 0)
			{
				throw new ArgumentOutOfRangeException("capacity");
			}
			if (_nodes.Length < capacity)
			{
				Grow(capacity);
				_version++;
			}
			return _nodes.Length;
		}

		public void TrimExcess()
		{
			int num = (int)((double)_nodes.Length * 0.9);
			if (_size < num)
			{
				Array.Resize(ref _nodes, _size);
				_version++;
			}
		}

		private void Grow(int minCapacity)
		{
			int val = 2 * _nodes.Length;
			val = Math.Max(val, _nodes.Length + 4);
			if (val < minCapacity)
			{
				val = minCapacity;
			}
			Array.Resize(ref _nodes, val);
		}

		private void RemoveRootNode()
		{
			int num = --_size;
			_version++;
			if (num > 0)
			{
				(TElement, TPriority) node = _nodes[num];
				if (_comparer == null)
				{
					MoveDownDefaultComparer(node, 0);
				}
				else
				{
					MoveDownCustomComparer(node, 0);
				}
			}
			_nodes[num] = default((TElement, TPriority));
		}

		private static int GetParentIndex(int index)
		{
			return index - 1 >> 2;
		}

		private static int GetFirstChildIndex(int index)
		{
			return (index << 2) + 1;
		}

		private void Heapify()
		{
			(TElement, TPriority)[] nodes = _nodes;
			int parentIndex = GetParentIndex(_size - 1);
			if (_comparer == null)
			{
				for (int num = parentIndex; num >= 0; num--)
				{
					MoveDownDefaultComparer(nodes[num], num);
				}
			}
			else
			{
				for (int num2 = parentIndex; num2 >= 0; num2--)
				{
					MoveDownCustomComparer(nodes[num2], num2);
				}
			}
		}

		private void MoveUpDefaultComparer((TElement Element, TPriority Priority) node, int nodeIndex)
		{
			(TElement, TPriority)[] nodes = _nodes;
			while (nodeIndex > 0)
			{
				int parentIndex = GetParentIndex(nodeIndex);
				(TElement, TPriority) tuple = nodes[parentIndex];
				if (Comparer<TPriority>.Default.Compare(node.Priority, tuple.Item2) >= 0)
				{
					break;
				}
				nodes[nodeIndex] = tuple;
				nodeIndex = parentIndex;
			}
			nodes[nodeIndex] = node;
		}

		private void MoveUpCustomComparer((TElement Element, TPriority Priority) node, int nodeIndex)
		{
			IComparer<TPriority> comparer = _comparer;
			(TElement, TPriority)[] nodes = _nodes;
			while (nodeIndex > 0)
			{
				int parentIndex = GetParentIndex(nodeIndex);
				(TElement, TPriority) tuple = nodes[parentIndex];
				if (comparer.Compare(node.Priority, tuple.Item2) >= 0)
				{
					break;
				}
				nodes[nodeIndex] = tuple;
				nodeIndex = parentIndex;
			}
			nodes[nodeIndex] = node;
		}

		private void MoveDownDefaultComparer((TElement Element, TPriority Priority) node, int nodeIndex)
		{
			(TElement, TPriority)[] nodes = _nodes;
			int size = _size;
			int num;
			while ((num = GetFirstChildIndex(nodeIndex)) < size)
			{
				(TElement, TPriority) tuple = nodes[num];
				int num2 = num;
				int num3 = Math.Min(num + 4, size);
				while (++num < num3)
				{
					(TElement, TPriority) tuple2 = nodes[num];
					if (Comparer<TPriority>.Default.Compare(tuple2.Item2, tuple.Item2) < 0)
					{
						tuple = tuple2;
						num2 = num;
					}
				}
				if (Comparer<TPriority>.Default.Compare(node.Priority, tuple.Item2) <= 0)
				{
					break;
				}
				nodes[nodeIndex] = tuple;
				nodeIndex = num2;
			}
			nodes[nodeIndex] = node;
		}

		private void MoveDownCustomComparer((TElement Element, TPriority Priority) node, int nodeIndex)
		{
			IComparer<TPriority> comparer = _comparer;
			(TElement, TPriority)[] nodes = _nodes;
			int size = _size;
			int num;
			while ((num = GetFirstChildIndex(nodeIndex)) < size)
			{
				(TElement, TPriority) tuple = nodes[num];
				int num2 = num;
				int num3 = Math.Min(num + 4, size);
				while (++num < num3)
				{
					(TElement, TPriority) tuple2 = nodes[num];
					if (comparer.Compare(tuple2.Item2, tuple.Item2) < 0)
					{
						tuple = tuple2;
						num2 = num;
					}
				}
				if (comparer.Compare(node.Priority, tuple.Item2) <= 0)
				{
					break;
				}
				nodes[nodeIndex] = tuple;
				nodeIndex = num2;
			}
			nodes[nodeIndex] = node;
		}

		private int FindIndex(TElement element, IEqualityComparer<TElement> equalityComparer)
		{
			equalityComparer = equalityComparer ?? (equalityComparer = EqualityComparer<TElement>.Default);
			if (typeof(TElement).IsValueType && equalityComparer == EqualityComparer<TElement>.Default)
			{
				for (int i = 0; i < _nodes.Length; i++)
				{
					if (EqualityComparer<TElement>.Default.Equals(element, _nodes[i].Element))
					{
						return i;
					}
				}
			}
			else
			{
				for (int j = 0; j < _nodes.Length; j++)
				{
					if (equalityComparer.Equals(element, _nodes[j].Element))
					{
						return j;
					}
				}
			}
			return -1;
		}

		private static IComparer<TPriority> InitializeComparer(IComparer<TPriority> comparer)
		{
			if (typeof(TPriority).IsValueType)
			{
				if (comparer == Comparer<TPriority>.Default)
				{
					return null;
				}
				return comparer;
			}
			return comparer ?? Comparer<TPriority>.Default;
		}
	}
}
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_005d: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: 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;
			if ((Object)(object)transform.Find(LODParentGameObjectName) != (Object)null)
			{
				throw new InvalidOperationException("The game object already appears to have LODs. Please remove them first.");
			}
			if ((Object)(object)gameObject.GetComponent<LODGroup>() != (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);
			Transform transform2 = new GameObject(LODParentGameObjectName).transform;
			ParentAndResetTransform(transform2, transform);
			LODGroup val = 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];
				Transform transform3 = new GameObject($"Level{i:00}").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;
			}
			val.animateCrossFading = false;
			val.SetLODs(array2);
			return val;
		}

		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 val = gameObject.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)
			{
				return (Renderer)(object)CreateStaticLevelRenderer($"{rendererIndex:000}_static_{renderer.name}", levelTransform, renderer.transform, mesh, renderer.materials, in level);
			}
			return (Renderer)(object)CreateSkinnedLevelRenderer($"{rendererIndex:000}_skinned_{renderer.name}", 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			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);
			}
			val.GetComponent<MeshFilter>().sharedMesh = mesh;
			MeshRenderer component = val.GetComponent<MeshRenderer>();
			((Renderer)component).sharedMaterials = materials;
			SetupLevelRenderer((Renderer)(object)component, in level);
			return component;
		}

		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_0019: Unknown result type (might be due to invalid IL or missing references)
			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 obj = meshSimplifier.ToMesh();
			obj.bindposes = mesh.bindposes;
			return obj;
		}

		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>();
			foreach (LODBackupComponent lODBackupComponent in components)
			{
				Renderer[] originalRenderers = lODBackupComponent.OriginalRenderers;
				if (originalRenderers != null)
				{
					Renderer[] array = originalRenderers;
					foreach (Renderer val in array)
					{
						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 = MathF.PI;

		public const double PId = Math.PI;

		public const float Deg2Rad = MathF.PI / 180f;

		public const double Deg2Radd = Math.PI / 180.0;

		public const float Rad2Deg = 180f / MathF.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(