Decompiled source of LethalElementsBeta v1.2.11

voxx.LethalElementsPlugin.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TriangleNet.Geometry;
using TriangleNet.Meshing;
using TriangleNet.Smoothing;
using TriangleNet.Topology;
using TriangleNet.Unity;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Rendering.RendererUtils;
using UnityEngine.SceneManagement;
using UnityEngine.VFX;
using UnityEngine.VFX.Utility;
using VoxxWeatherPlugin.Behaviours;
using VoxxWeatherPlugin.Patches;
using VoxxWeatherPlugin.Utils;
using VoxxWeatherPlugin.Weathers;
using WeatherRegistry;
using voxx.LethalElementsPlugin.NetcodePatcher;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("voxx.LethalElementsPlugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A plugin adding new weather types to Lethal Company")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0+3dd8b0e245d3a070f4f0dcdd64b4faf922612d60")]
[assembly: AssemblyProduct("voxx.LethalElementsPlugin")]
[assembly: AssemblyTitle("voxx.LethalElementsPlugin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace VoxxWeatherPlugin
{
	[BepInPlugin("voxx.LethalElementsPlugin", "voxx.LethalElementsPlugin", "1.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class VoxxWeatherPlugin : BaseUnityPlugin
	{
		private Harmony harmony;

		public static VoxxWeatherPlugin instance;

		internal static ManualLogSource StaticLogger;

		private void Awake()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			instance = this;
			StaticLogger = ((BaseUnityPlugin)this).Logger;
			NetcodePatcher();
			Configuration.Initialize(((BaseUnityPlugin)this).Info.Metadata);
			harmony = new Harmony("voxx.LethalElementsPlugin");
			if (Configuration.EnableSolarFlareWeather.Value)
			{
				WeatherTypeLoader.RegisterFlareWeather();
				harmony.PatchAll(typeof(FlarePatches));
				if (!Configuration.DistortOnlyVoiceDuringSolarFlare.Value)
				{
					harmony.PatchAll(typeof(FlareOptionalWalkiePatches));
					((BaseUnityPlugin)this).Logger.LogInfo((object)"voxx.LethalElementsPlugin optional solar flare patches successfully applied!");
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)"voxx.LethalElementsPlugin solar flare patches successfully applied!");
			}
			if (Configuration.EnableHeatwaveWeather.Value)
			{
				WeatherTypeLoader.RegisterHeatwaveWeather();
				harmony.PatchAll(typeof(HeatwavePatches));
				((BaseUnityPlugin)this).Logger.LogInfo((object)"voxx.LethalElementsPlugin heatwave patches successfully applied!");
			}
			if ((Configuration.EnableBlizzardWeather.Value || Configuration.EnableSnowfallWeather.Value) && WeatherTypeLoader.LoadSnowManager())
			{
				harmony.PatchAll(typeof(SnowPatches));
				((BaseUnityPlugin)this).Logger.LogInfo((object)"voxx.LethalElementsPlugin snow patches successfully applied!");
				if (Configuration.EnableSnowfallWeather.Value)
				{
					WeatherTypeLoader.RegisterSnowfallWeather();
				}
				if (Configuration.EnableBlizzardWeather.Value)
				{
					harmony.PatchAll(typeof(BlizzardPatches));
					((BaseUnityPlugin)this).Logger.LogInfo((object)"voxx.LethalElementsPlugin blizzard patches successfully applied!");
					WeatherTypeLoader.RegisterBlizzardWeather();
				}
				MethodInfo method = typeof(SnowPatches).GetMethod("EnemySnowHindrancePatch", BindingFlags.Static | BindingFlags.NonPublic);
				DynamicHarmonyPatcher.PatchAllTypes(typeof(EnemyAI), "Update", method, PatchType.Postfix, harmony, SnowPatches.unaffectedEnemyTypes);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"voxx.LethalElementsPlugin enemy snow hindrance patches successfully applied!");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin voxx.LethalElementsPlugin is loaded!");
		}

		private static void NetcodePatcher()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	public static class Debug
	{
		private static ManualLogSource Logger => VoxxWeatherPlugin.StaticLogger;

		public static void Log(string message)
		{
			Logger.LogInfo((object)message);
		}

		public static void LogError(string message)
		{
			Logger.LogError((object)message);
		}

		public static void LogWarning(string message)
		{
			Logger.LogWarning((object)message);
		}

		public static void LogDebug(string message)
		{
			Logger.LogDebug((object)message);
		}

		public static void LogMessage(string message)
		{
			Logger.LogMessage((object)message);
		}

		public static void LogFatal(string message)
		{
			Logger.LogFatal((object)message);
		}
	}
	public enum PatchType
	{
		Prefix,
		Postfix,
		Transpiler
	}
	public class DynamicHarmonyPatcher
	{
		public static void PatchAllTypes(Type baseType, string methodToPatch, MethodInfo patchMethod, PatchType patchType, Harmony harmonyInstance, HashSet<Type>? blackList = null)
		{
			List<Type> list = FindDerivedTypes(baseType, methodToPatch);
			if (blackList != null)
			{
				list.RemoveAll(blackList.Contains);
			}
			PatchMethodsInTypes(list, methodToPatch, patchMethod, patchType, harmonyInstance);
		}

		private static List<Type> FindDerivedTypes(Type baseType, string methodName)
		{
			List<Type> list = new List<Type>();
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			Assembly[] array = assemblies;
			foreach (Assembly assembly in array)
			{
				try
				{
					Type[] types = assembly.GetTypes();
					foreach (Type type in types)
					{
						if (baseType.IsAssignableFrom(type) && type != baseType && !type.IsAbstract && !type.IsInterface)
						{
							MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
							if (method != null && method.DeclaringType != baseType)
							{
								list.Add(type);
							}
						}
					}
				}
				catch (Exception)
				{
					Debug.LogDebug("Error loading types from assembly: " + assembly.FullName);
				}
			}
			return list;
		}

		private static void PatchMethodsInTypes(List<Type> typesToPatch, string methodName, MethodInfo patchMethod, PatchType patchType, Harmony harmonyInstance)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			if (typesToPatch == null || typesToPatch.Count == 0)
			{
				Debug.LogWarning("No types to patch provided.");
				return;
			}
			if (string.IsNullOrEmpty(methodName))
			{
				Debug.LogError("Method name cannot be null or empty.");
				return;
			}
			if (patchMethod == null)
			{
				Debug.LogError("Patch method cannot be null.");
				return;
			}
			if (harmonyInstance == null)
			{
				Debug.LogError("Harmony instance cannot be null.");
				return;
			}
			foreach (Type item in typesToPatch)
			{
				try
				{
					MethodInfo method = item.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (method == null)
					{
						Debug.LogWarning("Method '" + methodName + "' not found on type '" + item.FullName + "'. Skipping.");
						continue;
					}
					HarmonyMethod val = new HarmonyMethod(patchMethod);
					switch (patchType)
					{
					case PatchType.Prefix:
						harmonyInstance.Patch((MethodBase)method, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						break;
					case PatchType.Postfix:
						harmonyInstance.Patch((MethodBase)method, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						break;
					case PatchType.Transpiler:
						harmonyInstance.Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null);
						break;
					default:
						Debug.LogError($"Invalid patch type: '{patchType}'.");
						break;
					}
					Debug.LogDebug("Patched '" + methodName + "' in '" + item.FullName + "' using method " + patchMethod.Name);
				}
				catch (Exception arg)
				{
					Debug.LogError($"Error patching '{methodName}' in '{item.FullName}': {arg}");
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "voxx.LethalElementsPlugin";

		public const string PLUGIN_NAME = "voxx.LethalElementsPlugin";

		public const string PLUGIN_VERSION = "1.3.0";
	}
}
namespace VoxxWeatherPlugin.Utils
{
	public static class Configuration
	{
		public static ConfigEntry<bool> EnableHeatwaveWeather;

		public static ConfigEntry<bool> EnableSolarFlareWeather;

		public static ConfigEntry<bool> EnableSnowfallWeather;

		public static ConfigEntry<bool> EnableBlizzardWeather;

		public static ConfigEntry<float> HeatwaveParticlesSpawnRate;

		public static ConfigEntry<float> TimeUntilStrokeMin;

		public static ConfigEntry<float> TimeUntilStrokeMax;

		public static ConfigEntry<float> HeathazeDistortionStrength;

		public static ConfigEntry<float> HeathazeFilterMultiplier;

		public static ConfigEntry<uint> AuroraHeight;

		public static ConfigEntry<float> AuroraSpawnAreaBox;

		public static ConfigEntry<float> AuroraVisibilityThreshold;

		public static ConfigEntry<float> AuroraSpawnRate;

		public static ConfigEntry<float> AuroraSize;

		public static ConfigEntry<bool> DistortOnlyVoiceDuringSolarFlare;

		public static ConfigEntry<float> BatteryDrainMultiplier;

		public static ConfigEntry<bool> DrainBatteryInFacility;

		public static ConfigEntry<bool> DoorMalfunctionEnabled;

		public static ConfigEntry<float> DoorMalfunctionChance;

		public static ConfigEntry<float> NoiseStaticLevel;

		public static ConfigEntry<float> minSnowHeight;

		public static ConfigEntry<float> maxSnowHeight;

		public static ConfigEntry<float> minTimeToFullSnow;

		public static ConfigEntry<float> maxTimeToFullSnow;

		public static ConfigEntry<bool> freezeWater;

		public static ConfigEntry<float> underSnowFilterMultiplier;

		public static ConfigEntry<float> frostbiteFilterMultiplier;

		public static ConfigEntry<int> frostbiteDamage;

		public static ConfigEntry<float> frostbiteDamageInterval;

		public static ConfigEntry<float> timeToWarmUp;

		public static ConfigEntry<bool> enableEasterEgg;

		public static ConfigEntry<float> minTimeUntilFrostbite;

		public static ConfigEntry<float> maxTimeUntilFrostbite;

		public static ConfigEntry<float> minWindForce;

		public static ConfigEntry<float> maxWindForce;

		public static ConfigEntry<float> minWaveInterval;

		public static ConfigEntry<float> maxWaveInterval;

		public static ConfigEntry<int> minWaveCount;

		public static ConfigEntry<int> maxWaveCount;

		public static ConfigEntry<int> chillingWaveDamage;

		public static ConfigEntry<bool> useOpaqueSnowMaterial;

		public static ConfigEntry<bool> addFootprints;

		public static ConfigEntry<int> trackedEntityNumber;

		public static ConfigEntry<int> depthBufferResolution;

		public static ConfigEntry<int> trackerMapResolution;

		public static ConfigEntry<int> snowDepthMapResolution;

		public static ConfigEntry<bool> bakeSnowDepthMipmaps;

		public static ConfigEntry<int> PCFKernelSize;

		public static ConfigEntry<int> BlurKernelSize;

		public static ConfigEntry<int> minTesselationFactor;

		public static ConfigEntry<int> maxTesselationFactor;

		public static ConfigEntry<bool> adaptiveTesselation;

		public static ConfigEntry<bool> softSnowEdges;

		public static ConfigEntry<bool> enableSnowTracks;

		public static ConfigEntry<bool> enableVFXCollisions;

		public static ConfigEntry<bool> subdivideMesh;

		public static ConfigEntry<bool> smoothMesh;

		public static ConfigEntry<bool> useLevelBounds;

		public static ConfigEntry<bool> refineMesh;

		public static ConfigEntry<bool> carveHoles;

		public static ConfigEntry<bool> useMeshCollider;

		public static ConfigEntry<int> targetVertexCount;

		public static ConfigEntry<int> minMeshStep;

		public static ConfigEntry<int> maxMeshStep;

		public static ConfigEntry<float> falloffRatio;

		public static ConfigFile Config { get; private set; }

		internal static void Initialize(BepInPlugin metadata)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Expected O, but got Unknown
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Expected O, but got Unknown
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Expected O, but got Unknown
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Expected O, but got Unknown
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Expected O, but got Unknown
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Expected O, but got Unknown
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Expected O, but got Unknown
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Expected O, but got Unknown
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Expected O, but got Unknown
			//IL_04ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Expected O, but got Unknown
			//IL_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0534: Expected O, but got Unknown
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Expected O, but got Unknown
			//IL_0598: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a2: Expected O, but got Unknown
			//IL_05d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05de: Expected O, but got Unknown
			//IL_062f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0639: Expected O, but got Unknown
			//IL_066b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0675: Expected O, but got Unknown
			//IL_06a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b1: Expected O, but got Unknown
			//IL_06e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ed: Expected O, but got Unknown
			//IL_071f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0729: Expected O, but got Unknown
			//IL_075b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0765: Expected O, but got Unknown
			//IL_078c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0796: Expected O, but got Unknown
			//IL_07bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c7: Expected O, but got Unknown
			//IL_07ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f9: Expected O, but got Unknown
			//IL_0862: Unknown result type (might be due to invalid IL or missing references)
			//IL_086c: Expected O, but got Unknown
			//IL_089e: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a8: Expected O, but got Unknown
			//IL_08d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e1: Expected O, but got Unknown
			//IL_0913: Unknown result type (might be due to invalid IL or missing references)
			//IL_091d: Expected O, but got Unknown
			//IL_0964: Unknown result type (might be due to invalid IL or missing references)
			//IL_096e: Expected O, but got Unknown
			//IL_0995: Unknown result type (might be due to invalid IL or missing references)
			//IL_099f: Expected O, but got Unknown
			//IL_09c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_09d0: Expected O, but got Unknown
			//IL_09f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a02: Expected O, but got Unknown
			//IL_0b62: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b6c: Expected O, but got Unknown
			//IL_0b96: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ba0: Expected O, but got Unknown
			//IL_0bcb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bd5: Expected O, but got Unknown
			//IL_0c07: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c11: Expected O, but got Unknown
			string configPath = Paths.ConfigPath;
			Config = new ConfigFile(Utility.CombinePaths(new string[2]
			{
				configPath,
				metadata.GUID + ".cfg"
			}), false, metadata);
			EnableHeatwaveWeather = Config.Bind<bool>("Weather", "EnableHeatwaveWeather", true, "Enable or disable Heatwave weather");
			EnableSolarFlareWeather = Config.Bind<bool>("Weather", "EnableSolarFlareWeather", true, "Enable or disable Solar Flare weather");
			EnableSnowfallWeather = Config.Bind<bool>("Weather", "EnableSnowfallWeather", true, "Enable or disable Snowfall weather");
			EnableBlizzardWeather = Config.Bind<bool>("Weather", "EnableBlizzardWeather", true, "Enable or disable Blizzard weather");
			HeatwaveParticlesSpawnRate = Config.Bind<float>("Heatwave", "ParticlesSpawnRate", 20f, new ConfigDescription("Spawn rate of Heatwave particles. Particles per second", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 42f), Array.Empty<object>()));
			TimeUntilStrokeMin = Config.Bind<float>("Heatwave", "TimeUntilStrokeMin", 40f, new ConfigDescription("Minimal time in seconds until heatstroke (min)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 9999f), Array.Empty<object>()));
			TimeUntilStrokeMax = Config.Bind<float>("Heatwave", "TimeUntilStrokeMax", 80f, new ConfigDescription("Maximal time in seconds until heatstroke (max). Must be higher than min! Actual time is random between min and max", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 9999f), Array.Empty<object>()));
			HeathazeDistortionStrength = Config.Bind<float>("Heatwave", "HeathazeDistortionStrength", 8f, new ConfigDescription("Strength of the heat haze distortion effect. Higher values make the distortion more intense", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 99f), Array.Empty<object>()));
			HeathazeFilterMultiplier = Config.Bind<float>("Heatwave", "HeathazeFilterMultiplier", 1f, new ConfigDescription("Multiplier for the heat haze filter. Lower values make the filter less intense. 0 will disable the filter", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			AuroraHeight = Config.Bind<uint>("SolarFlare", "AuroraHeight", 120u, "Height of the Aurora effect above the ground");
			AuroraSpawnAreaBox = Config.Bind<float>("SolarFlare", "AuroraSpawnArea", 500f, "Size of the Aurora spawn area. The Aurora effect will spawn randomly within this square area. VFX may disappear at certain angles if the area is too small or too large.");
			AuroraVisibilityThreshold = Config.Bind<float>("SolarFlare", "AuroraVisibilityThreshold", 9f, "Light threshold when Aurora becomes visible (in Lux). Increase to make it more visible.");
			AuroraSpawnRate = Config.Bind<float>("SolarFlare", "AuroraSpawnRate", 0.1f, new ConfigDescription("Spawn rate of Aurora effects. Auroras per second", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 32f), Array.Empty<object>()));
			AuroraSize = Config.Bind<float>("SolarFlare", "AuroraSize", 100f, "Size of the Aurora 'strips' in the sky");
			DistortOnlyVoiceDuringSolarFlare = Config.Bind<bool>("SolarFlare", "DistortOnlyVoice", true, "Distort only player voice during Solar Flare (true) or all sounds (false) on a walkie-talkie");
			BatteryDrainMultiplier = Config.Bind<float>("SolarFlare", "BatteryDrainMultiplier", 1f, new ConfigDescription("Multiplier for additional battery drain during Solar Flare. 1.0 is normal drain, 0.5 is half drain, 2.0 is double drain, 0 no additional drain, etc. Default value is equal to 60 - 200 % faster drain depending on the type of flare.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			DrainBatteryInFacility = Config.Bind<bool>("SolarFlare", "DrainBatteryInFacility", false, "Drain item battery even when inside a facility during Solar Flare");
			DoorMalfunctionEnabled = Config.Bind<bool>("SolarFlare", "DoorMalfunctionEnabled", true, "Enable or disable door malfunction during Average and Strong Solar Flare");
			DoorMalfunctionChance = Config.Bind<float>("SolarFlare", "DoorMalfunctionChance", 0.5f, new ConfigDescription("Chance of metal doors opening/closing by themselves during Solar Flare. 0.1 is 10% chance, 0.5 is 50% chance, 1.0 is 100% chance. Low chance might cause you to get soft locked behind a door in the facility!", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			NoiseStaticLevel = Config.Bind<float>("SolarFlare", "NoiseStaticLevel", 0.001f, new ConfigDescription("Level of static noise from the walkie talkie during Solar Flare. This is signal amplitude, the actual volume in dB will follow a logarithmic scale. For example the volume for value 0.1 relative to 0.2 is not reduced by 100%, it's actually by ~log10(0.2/0.1) %", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			minSnowHeight = Config.Bind<float>("Snowfall", "minSnowHeight", 1.7f, new ConfigDescription("Minimum snow height at the end of the day in meters. For blizzard weather only 60% of this value is used.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			maxSnowHeight = Config.Bind<float>("Snowfall", "maxSnowHeight", 3f, new ConfigDescription("Maximum snow height at the end of the day in meters. For blizzard weather only 60% of this value is used. Actual snow height is random between min and max.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			minTimeToFullSnow = Config.Bind<float>("Snowfall", "minTimeToFullSnow", 0.5f, new ConfigDescription("Minimum fraction of the day until snow reaches max height. Actual time is random between min and max. Blizzard weather will only use 20% of this value.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			maxTimeToFullSnow = Config.Bind<float>("Snowfall", "maxTimeToFullSnow", 0.8f, new ConfigDescription("Maximum fraction of the day until snow reaches max height. Actual time is random between min and max. Blizzard weather will only use 20% of this value.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			freezeWater = Config.Bind<bool>("Snowfall", "freezeWater", true, "Freeze water during snowfall and blizzard weather");
			underSnowFilterMultiplier = Config.Bind<float>("Snowfall", "underSnowFilterMultiplier", 1f, new ConfigDescription("Multiplier for the effect visible when player's head is covered in snow. Lower values make the filter less intense. 0 will disable the filter", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			frostbiteFilterMultiplier = Config.Bind<float>("Snowfall", "frostbiteFilterMultiplier", 1f, new ConfigDescription("Multiplier for the frostbite filter. Lower values make the filter less intense. 0 will disable the filter", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			frostbiteDamage = Config.Bind<int>("Snowfall", "frostbiteDamage", 10, new ConfigDescription("Maximum damage dealt by frostbite effect. When first signs of frostbite occur damage is set to 50% of this value and then grows to 100%.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 99), Array.Empty<object>()));
			frostbiteDamageInterval = Config.Bind<float>("Snowfall", "frostbiteDamageInterval", 20f, new ConfigDescription("Time in seconds between frostbite damage ticks.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 9999f), Array.Empty<object>()));
			timeToWarmUp = Config.Bind<float>("Snowfall", "timeToWarmUp", 20f, new ConfigDescription("Time in seconds to warm up from the MAXIMUM frostbite effect.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 9999f), Array.Empty<object>()));
			enableEasterEgg = Config.Bind<bool>("Snowfall", "enableEasterEgg", true, "Allow festivities during snowfall weather during special time of the year.");
			minTimeUntilFrostbite = Config.Bind<float>("Blizzard", "minTimeUntilFrostbite", 40f, new ConfigDescription("Minimum time in seconds until frostbite reaches full intensity, effect starts to affect the player at 50% of chosen time. Actual time is random between min and max. Snowfall weather will only use 40% of this value as a constant.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 9999f), Array.Empty<object>()));
			maxTimeUntilFrostbite = Config.Bind<float>("Blizzard", "maxTimeUntilFrostbite", 100f, new ConfigDescription("Maximum time in seconds until frostbite reaches full intensity, effect starts to affect the player at 50% of chosen time. Actual time is random between min and max.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 9999f), Array.Empty<object>()));
			minWindForce = Config.Bind<float>("Blizzard", "minWindForce", 0.25f, new ConfigDescription("Minimum wind force during blizzard weather. Actual wind force is random between min and max.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			maxWindForce = Config.Bind<float>("Blizzard", "maxWindForce", 0.6f, new ConfigDescription("Maximum wind force during blizzard weather. At very high values you might not be able to move while standing in deep snow! Actual wind force is random between min and max.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			minWaveInterval = Config.Bind<float>("Blizzard", "minWaveInterval", 60f, new ConfigDescription("Minimum time in seconds between chilling waves of frost. Actual time is random between min and max.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 9999f), Array.Empty<object>()));
			maxWaveInterval = Config.Bind<float>("Blizzard", "maxWaveInterval", 180f, new ConfigDescription("Maximum time in seconds between chilling waves of frost. Actual time is random between min and max.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 9999f), Array.Empty<object>()));
			minWaveCount = Config.Bind<int>("Blizzard", "minWaveCount", 1, new ConfigDescription("Minimum number of chilling waves of frost that will strike in succession. Actual number is random between min and max.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 99), Array.Empty<object>()));
			maxWaveCount = Config.Bind<int>("Blizzard", "maxWaveCount", 5, new ConfigDescription("Maximum number of chilling waves of frost that will strike in succession. Actual number is random between min and max.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 99), Array.Empty<object>()));
			chillingWaveDamage = Config.Bind<int>("Blizzard", "chillingWaveDamage", 20, new ConfigDescription("Damage dealt by each chilling wave of frost if you get caught in one.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 99), Array.Empty<object>()));
			useOpaqueSnowMaterial = Config.Bind<bool>("Snow Graphics", "useOpaqueSnowMaterial", false, "Use opaque snow material. Disabling this will use a transparent snow material, which will allow for more realistic snow overlay rendering, but will not work with the posterization effect.");
			addFootprints = Config.Bind<bool>("Snow Graphics", "addFootprints", false, "Override level settings and enable vanilla footprints during the weather. Disabling this will use the level settings for footprints.");
			trackedEntityNumber = Config.Bind<int>("Snow Graphics", "trackedEntityNumber", 64, new ConfigDescription("Number of entities that will be tracked for snow depth, INCLUDING all players. If there are more entities than this number their speed won't be affected by snow. For a better efficiency should be an even number.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 256), Array.Empty<object>()));
			depthBufferResolution = Config.Bind<int>("Snow Graphics", "depthBufferResolution", 2048, new ConfigDescription("Resolution of the depth buffer used to capture the level and remove snow under objects. Higher values increase quality but also memory usage. MUST be a power of 2 : 512, 1024, 2048, etc.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(256, 8192), Array.Empty<object>()));
			trackerMapResolution = Config.Bind<int>("Snow Graphics", "trackerMapResolution", 256, new ConfigDescription("Resolution of the map used to render snow tracks. Higher values increase quality but also memory usage. MUST be a power of 2!", (AcceptableValueBase)(object)new AcceptableValueRange<int>(32, 1024), Array.Empty<object>()));
			snowDepthMapResolution = Config.Bind<int>("Snow Graphics", "snowDepthMapResolution", 1024, new ConfigDescription("Resolution of the baked texture used to store snow depth data. Higher values increase quality but also memory usage. MUST be a power of 2!", (AcceptableValueBase)(object)new AcceptableValueRange<int>(256, 8192), Array.Empty<object>()));
			bakeSnowDepthMipmaps = Config.Bind<bool>("Snow Graphics", "bakeSnowDepthMipmaps", false, "Generate mipmaps for the snow depth map. Disabling this will reduce memory usage at the cost of quality.");
			PCFKernelSize = Config.Bind<int>("Snow Graphics", "PCFKernelSize", 12, new ConfigDescription("Kernel size for Percentage Closer Filtering. Higher values increase will produce smoother snow 'shadows' under objects. High values will baking and thus level loading times.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
			BlurKernelSize = Config.Bind<int>("Snow Graphics", "BlurKernelSize", 3, new ConfigDescription("Kernel size for the depth buffer blur used for VSM 'shadow' mapping, that is used for snow overlay rendering (non fluffy snow). Higher values will produce smoother snow transitions under objects, but will lower accuracy of VFX collisions.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 32), Array.Empty<object>()));
			minTesselationFactor = Config.Bind<int>("Snow Graphics", "minTesselationFactor", 4, new ConfigDescription("Minimum tesselation factor for snow material. Higher values increase quality but also memory usage. Number represents how many times each triangle is divided, and how detailed snow geometry will appear.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 32), Array.Empty<object>()));
			maxTesselationFactor = Config.Bind<int>("Snow Graphics", "maxTesselationFactor", 16, new ConfigDescription("Maximum tesselation factor for snow material. Higher values increase quality but also memory usage. Number represents how many times each triangle is divided.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 32), Array.Empty<object>()));
			adaptiveTesselation = Config.Bind<bool>("Snow Graphics", "adaptiveTesselation", true, "Enable adaptive tesselation for snow material. This will apply max tesselation factor only to areas with rapid snow height changes, like around snow tracks, trees or roofs.");
			softSnowEdges = Config.Bind<bool>("Snow Graphics", "softSnowEdges", false, "Enable soft snow edges. This will use depth buffer to blend snow with covered objects better. May cause visual artifacts in areas of rapid relief changes.");
			enableSnowTracks = Config.Bind<bool>("Snow Graphics", "enableSnowTracks", true, "Enable snow tracks. This will render snow tracks on the ground where player or enemies walk and will affect walking speed. Disabling this will improve performance.");
			enableVFXCollisions = Config.Bind<bool>("Snow Graphics", "Enable VFX Collisions", true, "Enable VFX collisions for blizzard wind. This will render an additional depth buffer to make snow particles collide with the terrain and objects. Disabling this will improve performance.");
			subdivideMesh = Config.Bind<bool>("Mesh & Terrain Processing", "subdivideMesh", true, "Subdivide EXISTING terrain meshes to create more detailed snow geometry. Disabling this will slightly reduce memory usage but may cause visual artifacts.");
			smoothMesh = Config.Bind<bool>("Mesh & Terrain Processing", "smoothMesh", true, "Smooth EXISTING terrain meshes to create a better vertex distribution for tesselation. Disabling this if collision glitches on steep terrain appear.");
			useLevelBounds = Config.Bind<bool>("Mesh & Terrain Processing", "useLevelBounds", true, "Use level bounds to limit mesh and terrain processing to the playable area. Disabling this will process the whole level, which will improve the entire levels geometry, but will increase loading times");
			refineMesh = Config.Bind<bool>("Mesh & Terrain Processing", "refineMesh", true, "TerraMesh. Refine the mesh produced FROM TERRAIN to remove possible thin triangles. Disabling this may slightly speed up loading, but will cause degraded mesh quality.");
			carveHoles = Config.Bind<bool>("Mesh & Terrain Processing", "carveHoles", true, "TerraMesh. Copy holes from terrain onto the mesh. Disabling this will cause terrain holes to be filled instead.");
			useMeshCollider = Config.Bind<bool>("Mesh & Terrain Processing", "useMeshCollider", false, "TerraMesh. Use mesh collider for the produced mesh, this will also copy trees from terrain. Disabling this will use the default terrain collider.");
			targetVertexCount = Config.Bind<int>("Mesh & Terrain Processing", "targetVertexCount", -1, new ConfigDescription("TerraMesh. Target vertex count for the produced mesh within specified bounds. -1 means minMeshStep is used to determine quality of the mesh, at values > 0 minMeshStep will be recalculated, so that the number of vertices could match this target value.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 500000), Array.Empty<object>()));
			minMeshStep = Config.Bind<int>("Mesh & Terrain Processing", "minMeshStep", 1, new ConfigDescription("TerraMesh. Minimum step size for the produced mesh. Higher values increase speed but reduce quality. 1 is the highest quality and will copy terrain exactly. 2 will skip every second vertex, etc.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 128), Array.Empty<object>()));
			maxMeshStep = Config.Bind<int>("Mesh & Terrain Processing", "maxMeshStep", 32, new ConfigDescription("TerraMesh. Maximum step size for the produced mesh. Outside of calculated playable level bounds the step size will be gradually increased to this value. Step size will rounded up to the nearest power of 2.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 128), Array.Empty<object>()));
			falloffRatio = Config.Bind<float>("Mesh & Terrain Processing", "falloffRatio", 3f, new ConfigDescription("TerraMesh. How fast the step size increases outside of calculated playable level bounds. Higher values increase speed but reduce quality. 1 is linear falloff, 2 is quadratic, 3 is cubic, etc.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 16f), Array.Empty<object>()));
		}
	}
	internal struct EdgePair : IEquatable<EdgePair>
	{
		public readonly int P1;

		public readonly int P2;

		public EdgePair(int p1, int p2)
		{
			P1 = Mathf.Min(p1, p2);
			P2 = Mathf.Max(p1, p2);
		}

		public bool Equals(EdgePair other)
		{
			if (P1 == other.P1)
			{
				return P2 == other.P2;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is EdgePair other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return (P1, P2).GetHashCode();
		}
	}
	[Serializable]
	public struct EntitySnowData
	{
		public Vector3 w;

		public Vector2 uv;

		public int textureIndex;

		public float snowThickness;

		public EntitySnowData()
		{
			//IL_0006: 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)
			w = default(Vector3);
			uv = default(Vector2);
			textureIndex = 0;
			snowThickness = 0f;
			Reset();
		}

		public void Reset()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			w = Vector3.zero;
			uv = Vector2.zero;
			textureIndex = -1;
			snowThickness = 0f;
		}
	}
	internal class QuadTree
	{
		public Bounds bounds;

		public QuadTree[]? children;

		public bool isLeaf = true;

		public QuadTree(Bounds bounds)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			this.bounds = bounds;
		}

		public bool Contains(Vector3 point)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return ((Bounds)(ref bounds)).Contains(point);
		}

		public void Subdivide()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			isLeaf = false;
			children = new QuadTree[4];
			float num = ((Bounds)(ref bounds)).size.x * 0.25f;
			float num2 = ((Bounds)(ref bounds)).size.z * 0.25f;
			Bounds val2 = default(Bounds);
			for (int i = 0; i < 4; i++)
			{
				Vector3 val = ((Bounds)(ref bounds)).center + new Vector3((float)(i % 2 * 2 - 1) * num, 0f, (float)(i / 2 * 2 - 1) * num2);
				((Bounds)(ref val2))..ctor(val, new Vector3(((Bounds)(ref bounds)).size.x * 0.5f, ((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z * 0.5f));
				children[i] = new QuadTree(val2);
			}
		}

		public void Subdivide(Bounds levelBounds, Vector2 stepSize, float minCellStep, float maxCellStep, float falloffSpeed, float maxDistance)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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)
			Vector3 val = ((Bounds)(ref levelBounds)).ClosestPoint(((Bounds)(ref bounds)).center) - ((Bounds)(ref levelBounds)).center;
			float num = Mathf.Max(Mathf.Abs(val.x), Mathf.Abs(val.z));
			Vector3 val2 = ((Bounds)(ref bounds)).center - ((Bounds)(ref levelBounds)).center;
			float num2 = Mathf.Max(Mathf.Abs(val2.x), Mathf.Abs(val2.z));
			float num3 = minCellStep;
			if (num2 > num)
			{
				num3 = Mathf.Lerp(minCellStep, maxCellStep, falloffSpeed * (num2 - num) / maxDistance);
			}
			num3 = Mathf.Max(num3, 1f);
			if (((Bounds)(ref bounds)).size.x > num3 * stepSize.x || ((Bounds)(ref bounds)).size.z > num3 * stepSize.y)
			{
				Subdivide();
				QuadTree[] array = children;
				foreach (QuadTree quadTree in array)
				{
					quadTree.Subdivide(levelBounds, stepSize, minCellStep, maxCellStep, falloffSpeed, maxDistance);
				}
			}
		}

		public void GetLeafNodes(List<QuadTree> leafNodes)
		{
			if (isLeaf)
			{
				leafNodes.Add(this);
			}
			else if (children != null)
			{
				QuadTree[] array = children;
				foreach (QuadTree quadTree in array)
				{
					quadTree.GetLeafNodes(leafNodes);
				}
			}
		}
	}
	public static class RandomExtensions
	{
		public static float NextDouble(this Random random, float min, float max)
		{
			if (min > max)
			{
				float num = max;
				max = min;
				min = num;
				Debug.LogWarning("Minimum value for random range must be less than maximum value. Switching them around!");
			}
			return (float)random.NextDouble() * (max - min) + min;
		}

		internal static void PostprocessMeshTerrain(this GameObject meshTerrainObject, Bounds levelBounds, SnowfallWeather snowfallData)
		{
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: 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_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: 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_0841: Unknown result type (might be due to invalid IL or missing references)
			//IL_0848: Expected O, but got Unknown
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_056a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0575: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0580: Unknown result type (might be due to invalid IL or missing references)
			//IL_0582: Unknown result type (might be due to invalid IL or missing references)
			//IL_0584: Unknown result type (might be due to invalid IL or missing references)
			//IL_0586: Unknown result type (might be due to invalid IL or missing references)
			//IL_058b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_0598: Unknown result type (might be due to invalid IL or missing references)
			//IL_059a: Unknown result type (might be due to invalid IL or missing references)
			//IL_059f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0860: Unknown result type (might be due to invalid IL or missing references)
			//IL_0869: Unknown result type (might be due to invalid IL or missing references)
			//IL_0954: Unknown result type (might be due to invalid IL or missing references)
			//IL_0959: Unknown result type (might be due to invalid IL or missing references)
			//IL_0960: Unknown result type (might be due to invalid IL or missing references)
			//IL_0969: Expected O, but got Unknown
			//IL_0969: Unknown result type (might be due to invalid IL or missing references)
			//IL_096e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0979: Unknown result type (might be due to invalid IL or missing references)
			//IL_098d: Expected O, but got Unknown
			//IL_09fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a03: Expected O, but got Unknown
			//IL_0930: Unknown result type (might be due to invalid IL or missing references)
			//IL_093b: Expected O, but got Unknown
			//IL_0658: Unknown result type (might be due to invalid IL or missing references)
			//IL_065a: Unknown result type (might be due to invalid IL or missing references)
			//IL_065c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0666: Unknown result type (might be due to invalid IL or missing references)
			//IL_066b: Unknown result type (might be due to invalid IL or missing references)
			//IL_066d: Unknown result type (might be due to invalid IL or missing references)
			//IL_066f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0671: Unknown result type (might be due to invalid IL or missing references)
			//IL_067b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0680: Unknown result type (might be due to invalid IL or missing references)
			//IL_0682: Unknown result type (might be due to invalid IL or missing references)
			//IL_0684: Unknown result type (might be due to invalid IL or missing references)
			//IL_0686: Unknown result type (might be due to invalid IL or missing references)
			//IL_0690: Unknown result type (might be due to invalid IL or missing references)
			//IL_0695: Unknown result type (might be due to invalid IL or missing references)
			//IL_069b: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0708: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_071c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ac9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0add: Unknown result type (might be due to invalid IL or missing references)
			//IL_0761: Unknown result type (might be due to invalid IL or missing references)
			//IL_0727: Unknown result type (might be due to invalid IL or missing references)
			//IL_073c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0745: Unknown result type (might be due to invalid IL or missing references)
			//IL_0747: Unknown result type (might be due to invalid IL or missing references)
			//IL_0749: Unknown result type (might be due to invalid IL or missing references)
			//IL_0753: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b0e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b22: Unknown result type (might be due to invalid IL or missing references)
			//IL_0775: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b53: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b67: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0780: Unknown result type (might be due to invalid IL or missing references)
			//IL_0795: Unknown result type (might be due to invalid IL or missing references)
			//IL_079e: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ac: Unknown result type (might be due to invalid IL or missing references)
			Stopwatch stopwatch = new Stopwatch();
			if ((Object)(object)meshTerrainObject == (Object)null)
			{
				Debug.LogError("Object to modify and level bounds must be supplied.");
			}
			Mesh sharedMesh = meshTerrainObject.GetComponent<MeshFilter>().sharedMesh;
			var (val, num) = meshTerrainObject.ExtractLargestSubmesh();
			((Object)val).name = ((Object)sharedMesh).name + "_Postprocessed";
			Debug.LogDebug("Extracted submesh with " + val.vertexCount + " vertices and " + val.triangles.Length / 3 + " triangles from submesh " + num + " of " + ((Object)meshTerrainObject).name);
			Bounds bounds = default(Bounds);
			if (snowfallData.UseBounds)
			{
				((Bounds)(ref bounds))..ctor(meshTerrainObject.transform.InverseTransformPoint(((Bounds)(ref levelBounds)).center), meshTerrainObject.transform.InverseTransformVector(((Bounds)(ref levelBounds)).size));
				((Bounds)(ref bounds)).size = new Vector3(Mathf.Abs(((Bounds)(ref bounds)).size.x), Mathf.Abs(((Bounds)(ref bounds)).size.y), Mathf.Abs(((Bounds)(ref bounds)).size.z));
				Bounds bounds2 = val.bounds;
				if (!((Bounds)(ref bounds2)).Intersects(bounds))
				{
					Debug.LogDebug("Object's bounds do not intersect with level bounds. No vertices will be processed.");
					return;
				}
			}
			else
			{
				bounds = val.bounds;
			}
			Vector3 val2 = ((Bounds)(ref bounds)).center;
			string? text = ((object)(Vector3)(ref val2)).ToString();
			val2 = ((Bounds)(ref bounds)).size;
			Debug.LogDebug("Bounds for triangulation: " + text + " " + ((object)(Vector3)(ref val2)).ToString());
			Vector3[] vertices = val.vertices;
			int[] triangles = val.triangles;
			int num2 = 0;
			Vector3 val3 = meshTerrainObject.transform.InverseTransformDirection(Vector3.up);
			val3.x *= Mathf.Sign(meshTerrainObject.transform.lossyScale.x);
			val3.y *= Mathf.Sign(meshTerrainObject.transform.lossyScale.y);
			val3.z *= Mathf.Sign(meshTerrainObject.transform.lossyScale.z);
			if (Mathf.Abs(Vector3.Dot(val3, Vector3.right)) > 0.5f)
			{
				num2 = 0;
			}
			else if (Mathf.Abs(Vector3.Dot(val3, Vector3.up)) > 0.5f)
			{
				num2 = 1;
			}
			else if (Mathf.Abs(Vector3.Dot(val3, Vector3.forward)) > 0.5f)
			{
				num2 = 2;
			}
			string text2 = num2.ToString();
			val2 = val3;
			Debug.LogDebug("Object's up axis: " + text2 + ". Object's up direction: " + ((object)(Vector3)(ref val2)).ToString());
			val2 = meshTerrainObject.transform.lossyScale;
			float num3 = Mathf.Abs(((Vector3)(ref val2))[(num2 + 1) % 3]);
			val2 = meshTerrainObject.transform.lossyScale;
			float num4 = Mathf.Max(num3, Mathf.Abs(((Vector3)(ref val2))[(num2 + 2) % 3]));
			float num5 = snowfallData.baseEdgeLength / num4;
			Debug.LogDebug("Max scale: " + num4 + " Max edge length: " + num5 + "m");
			HashSet<int> hashSet = new HashSet<int>();
			Queue<(int, int, int)> queue = new Queue<(int, int, int)>();
			Dictionary<Vector3, int> uniqueVertices = new Dictionary<Vector3, int>();
			List<int> list = new List<int>();
			Dictionary<EdgePair, int> dictionary = new Dictionary<EdgePair, int>();
			Dictionary<int, int> dictionary2 = new Dictionary<int, int>();
			Dictionary<int, int> dictionary3 = new Dictionary<int, int>();
			Debug.LogDebug("Filtering vertices and triangles... Count: " + triangles.Length / 3 + " Vertices: " + vertices.Length);
			stopwatch.Start();
			for (int i = 0; i < triangles.Length; i += 3)
			{
				int p = triangles[i];
				int p2 = triangles[i + 1];
				int p3 = triangles[i + 2];
				(p, p2, p3) = CheckForDuplicateVertices(uniqueVertices, vertices, p, p2, p3);
				if (((Bounds)(ref bounds)).Contains(vertices[p]) && ((Bounds)(ref bounds)).Contains(vertices[p2]) && ((Bounds)(ref bounds)).Contains(vertices[p3]))
				{
					hashSet.Add(p);
					hashSet.Add(p2);
					hashSet.Add(p3);
					if (snowfallData.SubdivideMesh)
					{
						queue.Enqueue((p, p2, p3));
					}
					UpdateEdgeCounts(dictionary, p, p2);
					UpdateEdgeCounts(dictionary, p2, p3);
					UpdateEdgeCounts(dictionary, p3, p);
				}
				else
				{
					list.Add(p);
					list.Add(p2);
					list.Add(p3);
				}
			}
			stopwatch.Stop();
			Debug.LogDebug("Vertex and triangle filtering/deduplication time: " + stopwatch.ElapsedMilliseconds + "ms");
			Debug.LogDebug("Vertices in bounds: " + hashSet.Count + " Triangles in bounds: " + queue.Count);
			List<Vector3> list2 = new List<Vector3>(vertices);
			List<Vector2> list3 = new List<Vector2>(val.uv);
			if (snowfallData.SubdivideMesh)
			{
				Debug.LogDebug($"Refining {queue.Count} triangles...");
				stopwatch.Restart();
				Dictionary<Vector3, int> dictionary4 = new Dictionary<Vector3, int>();
				while (queue.Count > 0)
				{
					(int, int, int) tuple3 = queue.Dequeue();
					int item = tuple3.Item1;
					int item2 = tuple3.Item2;
					int item3 = tuple3.Item3;
					Vector3 val4 = list2[item];
					Vector3 val5 = list2[item2];
					Vector3 val6 = list2[item3];
					val2 = val4 - val5;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					val2 = val5 - val6;
					float sqrMagnitude2 = ((Vector3)(ref val2)).sqrMagnitude;
					val2 = val6 - val4;
					float sqrMagnitude3 = ((Vector3)(ref val2)).sqrMagnitude;
					EdgePair key = new EdgePair(item, item2);
					EdgePair key2 = new EdgePair(item2, item3);
					EdgePair key3 = new EdgePair(item3, item);
					float num6 = num5 * num5;
					bool flag = sqrMagnitude > num6 && sqrMagnitude2 > num6 && sqrMagnitude3 > num6;
					bool flag2 = (dictionary.ContainsKey(key) && dictionary[key] == 1) || (dictionary.ContainsKey(key2) && dictionary[key2] == 1) || (dictionary.ContainsKey(key3) && dictionary[key3] == 1);
					if (flag && !flag2)
					{
						Vector3 val7 = (val4 + val5) / 2f;
						Vector3 val8 = (val5 + val6) / 2f;
						Vector3 val9 = (val6 + val4) / 2f;
						Vector2 val10 = list3[item];
						Vector2 val11 = list3[item2];
						Vector2 val12 = list3[item3];
						int num7 = list2.Count;
						if (!dictionary4.ContainsKey(val7))
						{
							dictionary4[val7] = num7;
							hashSet.Add(num7);
							list2.Add(val7);
							list3.Add((val10 + val11) / 2f);
						}
						else
						{
							num7 = dictionary4[val7];
						}
						int num8 = list2.Count;
						if (!dictionary4.ContainsKey(val8))
						{
							dictionary4[val8] = num8;
							hashSet.Add(num8);
							list2.Add(val8);
							list3.Add((val11 + val12) / 2f);
						}
						else
						{
							num8 = dictionary4[val8];
						}
						int num9 = list2.Count;
						if (!dictionary4.ContainsKey(val9))
						{
							dictionary4[val9] = num9;
							hashSet.Add(num9);
							list2.Add(val9);
							list3.Add((val12 + val10) / 2f);
						}
						else
						{
							num9 = dictionary4[val9];
						}
						queue.Enqueue((item, num7, num9));
						queue.Enqueue((num7, item2, num8));
						queue.Enqueue((num8, item3, num9));
						queue.Enqueue((num7, num8, num9));
					}
				}
				stopwatch.Stop();
				Debug.LogDebug("Refinement time: " + stopwatch.ElapsedMilliseconds + "ms");
			}
			Polygon val13 = new Polygon();
			foreach (int item7 in hashSet)
			{
				Vertex val14 = UnityExtentions.ToTriangleNetVertex(list2[item7], list3[item7], num2);
				val13.Add(val14);
				dictionary2[val13.Points.Count - 1] = item7;
				dictionary3[item7] = val13.Points.Count - 1;
			}
			if (snowfallData.constrainEdges)
			{
				foreach (KeyValuePair<EdgePair, int> item8 in dictionary)
				{
					if (item8.Value == 1)
					{
						val13.Add((ISegment)new Segment(val13.Points[dictionary3[item8.Key.P1]], val13.Points[dictionary3[item8.Key.P2]]), false);
					}
				}
			}
			ConstraintOptions val15 = new ConstraintOptions
			{
				ConformingDelaunay = true,
				SegmentSplitting = 2
			};
			QualityOptions val16 = new QualityOptions
			{
				MinimumAngle = 30f,
				SteinerPoints = (snowfallData.SubdivideMesh ? (-1) : 0)
			};
			Debug.LogDebug($"Triangulating {val13.Points.Count} vertices...");
			stopwatch.Restart();
			IMesh val17 = ExtensionMethods.Triangulate((IPolygon)(object)val13, val15, val16);
			stopwatch.Stop();
			Debug.LogDebug("Triangulation time: " + stopwatch.ElapsedMilliseconds + "ms");
			if (snowfallData.SmoothMesh)
			{
				stopwatch.Restart();
				LaplacianSmoother val18 = new LaplacianSmoother(1f);
				val18.Smooth(val17, snowfallData.smoothingIterations);
				stopwatch.Stop();
				Debug.LogDebug("Smoothing time: " + stopwatch.ElapsedMilliseconds + "ms");
			}
			List<int> list4 = new List<int>(list);
			Debug.LogDebug("Modified triangles: " + val17.Triangles.Count);
			foreach (Triangle triangle in val17.Triangles)
			{
				int vertexID = ((ITriangle)triangle).GetVertexID(0);
				int vertexID2 = ((ITriangle)triangle).GetVertexID(1);
				int vertexID3 = ((ITriangle)triangle).GetVertexID(2);
				if (!dictionary2.ContainsKey(vertexID))
				{
					dictionary2[vertexID] = list2.Count;
					list2.Add(UnityExtentions.ToVector3(((ITriangle)triangle).GetVertex(0), num2));
					list3.Add(((Point)((ITriangle)triangle).GetVertex(0)).UV);
				}
				if (!dictionary2.ContainsKey(vertexID2))
				{
					dictionary2[vertexID2] = list2.Count;
					list2.Add(UnityExtentions.ToVector3(((ITriangle)triangle).GetVertex(1), num2));
					list3.Add(((Point)((ITriangle)triangle).GetVertex(1)).UV);
				}
				if (!dictionary2.ContainsKey(vertexID3))
				{
					dictionary2[vertexID3] = list2.Count;
					list2.Add(UnityExtentions.ToVector3(((ITriangle)triangle).GetVertex(2), num2));
					list3.Add(((Point)((ITriangle)triangle).GetVertex(2)).UV);
				}
				int item4 = dictionary2[vertexID];
				int item5 = dictionary2[vertexID2];
				int item6 = dictionary2[vertexID3];
				if (num2 == 1)
				{
					list4.Add(item4);
					list4.Add(item6);
					list4.Add(item5);
				}
				else
				{
					list4.Add(item4);
					list4.Add(item5);
					list4.Add(item6);
				}
			}
			Debug.LogDebug("Original UVs: " + val.uv.Length + " New UVs: " + list3.Count);
			Debug.LogDebug("Original vertices: " + vertices.Length + " New vertices: " + list2.Count);
			val.vertices = list2.ToArray();
			val.triangles = list4.ToArray();
			val.uv2 = UnwrapUVs(val.vertices, num2, normalize: true);
			if (snowfallData.replaceUvs)
			{
				val.uv = val.uv2;
			}
			else
			{
				val.uv = list3.ToArray();
			}
			val.Optimize();
			val.RecalculateNormals();
			val.RecalculateTangents();
			val.RecalculateBounds();
			MeshFilter component = meshTerrainObject.GetComponent<MeshFilter>();
			component.sharedMesh = val;
			MeshCollider component2 = meshTerrainObject.GetComponent<MeshCollider>();
			component2.sharedMesh = val;
		}

		private static Vector2[] UnwrapUVs(Vector3[] vertices, int upAxis, bool normalize)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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)
			Vector2[] array = (Vector2[])(object)new Vector2[vertices.Length];
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(float.MaxValue, float.MaxValue);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(float.MinValue, float.MinValue);
			for (int i = 0; i < vertices.Length; i++)
			{
				switch (upAxis)
				{
				case 0:
					array[i] = new Vector2(vertices[i].y, vertices[i].z);
					break;
				case 1:
					array[i] = new Vector2(vertices[i].x, vertices[i].z);
					break;
				default:
					array[i] = new Vector2(vertices[i].x, vertices[i].y);
					break;
				}
				val = Vector2.Min(val, array[i]);
				val2 = Vector2.Max(val2, array[i]);
			}
			if (normalize)
			{
				Vector2 val3 = val2 - val;
				for (int j = 0; j < array.Length; j++)
				{
					array[j] = new Vector2((array[j].x - val.x) / val3.x, (array[j].y - val.y) / val3.y);
				}
			}
			return array;
		}

		private static void UpdateEdgeCounts(Dictionary<EdgePair, int> edgeCounts, int p1, int p2)
		{
			EdgePair key = new EdgePair(p1, p2);
			if (edgeCounts.ContainsKey(key))
			{
				edgeCounts[key]++;
			}
			else
			{
				edgeCounts[key] = 1;
			}
		}

		private static (int, int, int) CheckForDuplicateVertices(Dictionary<Vector3, int> uniqueVertices, Vector3[] vertices, int p1, int p2, int p3)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0060: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			if (!uniqueVertices.ContainsKey(vertices[p1]))
			{
				uniqueVertices[vertices[p1]] = p1;
			}
			else
			{
				p1 = uniqueVertices[vertices[p1]];
			}
			if (!uniqueVertices.ContainsKey(vertices[p2]))
			{
				uniqueVertices[vertices[p2]] = p2;
			}
			else
			{
				p2 = uniqueVertices[vertices[p2]];
			}
			if (!uniqueVertices.ContainsKey(vertices[p3]))
			{
				uniqueVertices[vertices[p3]] = p3;
			}
			else
			{
				p3 = uniqueVertices[vertices[p3]];
			}
			return (p1, p2, p3);
		}

		public static (Mesh submesh, int submeshIndex) ExtractLargestSubmesh(this GameObject meshObject)
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Expected O, but got Unknown
			//IL_0163: 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)
			Mesh sharedMesh = meshObject.GetComponent<MeshFilter>().sharedMesh;
			Transform transform = meshObject.transform;
			Mesh meshCopy = sharedMesh.MakeReadableCopy();
			int subMeshCount = meshCopy.subMeshCount;
			if (subMeshCount <= 1)
			{
				return (meshCopy, 0);
			}
			int num = Enumerable.Range(0, subMeshCount).OrderByDescending(delegate(int i)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				SubMeshDescriptor subMesh = meshCopy.GetSubMesh(i);
				return ((SubMeshDescriptor)(ref subMesh)).vertexCount;
			}).First();
			int[] triangles = meshCopy.GetTriangles(num);
			HashSet<int> hashSet = new HashSet<int>(triangles);
			Dictionary<int, int> oldToNewVertexMap = new Dictionary<int, int>();
			Vector3[] vertices = meshCopy.vertices;
			Vector2[] uv = meshCopy.uv;
			Vector3[] normals = meshCopy.normals;
			Vector4[] tangents = meshCopy.tangents;
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = ((meshCopy.normals.Length != 0) ? new List<Vector3>() : null);
			List<Vector2> list3 = ((meshCopy.uv.Length != 0) ? new List<Vector2>() : null);
			List<Vector4> list4 = ((meshCopy.tangents.Length != 0) ? new List<Vector4>() : null);
			foreach (int item in hashSet)
			{
				oldToNewVertexMap[item] = list.Count;
				list.Add(transform.InverseTransformPoint(vertices[item]));
				list2?.Add(normals[item]);
				list3?.Add(uv[item]);
				list4?.Add(tangents[item]);
			}
			int[] triangles2 = triangles.Select((int oldIndex) => oldToNewVertexMap[oldIndex]).ToArray();
			Mesh val = new Mesh
			{
				name = ((Object)meshCopy).name + "_Submesh" + num,
				vertices = list.ToArray(),
				triangles = triangles2,
				indexFormat = meshCopy.indexFormat
			};
			if (list2 != null)
			{
				val.normals = list2.ToArray();
			}
			if (list3 != null)
			{
				val.uv = list3.ToArray();
			}
			if (list4 != null)
			{
				val.tangents = list4.ToArray();
			}
			val.RecalculateBounds();
			Object.Destroy((Object)(object)meshCopy);
			return (val, num);
		}

		public static Mesh MakeReadableCopy(this Mesh nonReadableMesh)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			if (nonReadableMesh.isReadable)
			{
				return nonReadableMesh;
			}
			Mesh val = new Mesh();
			val.indexFormat = nonReadableMesh.indexFormat;
			nonReadableMesh.vertexBufferTarget = (Target)1;
			if (nonReadableMesh.vertexBufferCount > 0)
			{
				GraphicsBuffer vertexBuffer = nonReadableMesh.GetVertexBuffer(0);
				int num = vertexBuffer.stride * vertexBuffer.count;
				byte[] array = new byte[num];
				vertexBuffer.GetData((Array)array);
				val.SetVertexBufferParams(nonReadableMesh.vertexCount, nonReadableMesh.GetVertexAttributes());
				val.SetVertexBufferData<byte>(array, 0, 0, num, 0, (MeshUpdateFlags)0);
				vertexBuffer.Release();
			}
			nonReadableMesh.indexBufferTarget = (Target)2;
			val.subMeshCount = nonReadableMesh.subMeshCount;
			GraphicsBuffer indexBuffer = nonReadableMesh.GetIndexBuffer();
			int num2 = indexBuffer.stride * indexBuffer.count;
			byte[] array2 = new byte[num2];
			indexBuffer.GetData((Array)array2);
			val.SetIndexBufferParams(indexBuffer.count, nonReadableMesh.indexFormat);
			val.SetIndexBufferData<byte>(array2, 0, 0, num2, (MeshUpdateFlags)0);
			indexBuffer.Release();
			uint num3 = 0u;
			for (int i = 0; i < val.subMeshCount; i++)
			{
				uint indexCount = nonReadableMesh.GetIndexCount(i);
				val.SetSubMesh(i, new SubMeshDescriptor((int)num3, (int)indexCount, (MeshTopology)0), (MeshUpdateFlags)0);
				num3 += indexCount;
			}
			val.RecalculateNormals();
			val.RecalculateBounds();
			((Object)val).name = "Readable " + ((Object)nonReadableMesh).name;
			return val;
		}

		internal static Texture2D? BakeMask(this GameObject objectToBake, SnowfallWeather snowfallData, int textureIndex = -1, int submeshIndex = 0)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			Mesh sharedMesh = objectToBake.GetComponent<MeshFilter>().sharedMesh;
			if ((Object)(object)sharedMesh == (Object)null)
			{
				Debug.LogError("No mesh found on object to bake!");
				return null;
			}
			Debug.LogDebug("Baking mask for " + ((Object)objectToBake).name + " with texture index " + textureIndex + " and submesh index " + submeshIndex);
			snowfallData.RefreshBakeMaterial();
			RenderTexture temporary = RenderTexture.GetTemporary(snowfallData.BakeResolution, snowfallData.BakeResolution, 0, (RenderTextureFormat)11);
			((Texture)temporary).wrapMode = (TextureWrapMode)1;
			((Texture)temporary).filterMode = (FilterMode)2;
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			GL.Clear(true, true, Color.clear);
			Matrix4x4 localToWorldMatrix = objectToBake.transform.localToWorldMatrix;
			Material? bakeMaterial = snowfallData.bakeMaterial;
			if (bakeMaterial != null && bakeMaterial.SetPass(0))
			{
				Graphics.DrawMeshNow(sharedMesh, localToWorldMatrix, submeshIndex);
			}
			RenderTexture temporary2 = RenderTexture.GetTemporary(snowfallData.BakeResolution, snowfallData.BakeResolution, 0, (RenderTextureFormat)11);
			((Texture)temporary2).wrapMode = (TextureWrapMode)1;
			((Texture)temporary2).filterMode = (FilterMode)2;
			RenderTexture temporary3 = RenderTexture.GetTemporary(snowfallData.BakeResolution, snowfallData.BakeResolution, 0, (RenderTextureFormat)11);
			((Texture)temporary3).wrapMode = (TextureWrapMode)1;
			((Texture)temporary3).filterMode = (FilterMode)2;
			Graphics.Blit((Texture)(object)temporary, temporary2, snowfallData.bakeMaterial, 1);
			Graphics.Blit((Texture)(object)temporary2, temporary3, snowfallData.bakeMaterial, 2);
			RenderTexture.active = temporary3;
			Texture2D val = new Texture2D(snowfallData.BakeResolution, snowfallData.BakeResolution, (TextureFormat)20, false);
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)2;
			val.ReadPixels(new Rect(0f, 0f, (float)snowfallData.BakeResolution, (float)snowfallData.BakeResolution), 0, 0);
			if (textureIndex != -1)
			{
				Graphics.CopyTexture((Texture)(object)val, 0, 0, (Texture)(object)snowfallData.snowMasks, textureIndex, 0);
				Object.DestroyImmediate((Object)(object)val);
			}
			else
			{
				val.Apply(false);
			}
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			RenderTexture.ReleaseTemporary(temporary2);
			RenderTexture.ReleaseTemporary(temporary3);
			return val;
		}

		internal static GameObject Meshify(this Terrain terrain, SnowfallWeather snowfallData, Bounds? levelBounds)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: 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_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: 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_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_0844: Unknown result type (might be due to invalid IL or missing references)
			//IL_0860: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Expected O, but got Unknown
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: 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_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_0507: Unknown result type (might be due to invalid IL or missing references)
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Expected O, but got Unknown
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0527: Unknown result type (might be due to invalid IL or missing references)
			//IL_0928: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a6d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a77: Expected O, but got Unknown
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_093f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aa1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ab5: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Expected O, but got Unknown
			//IL_0956: Unknown result type (might be due to invalid IL or missing references)
			//IL_096f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ae5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0af7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b11: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b13: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b1e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b23: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b2e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b33: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b38: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b41: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b4f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b56: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b5d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b64: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b7a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b92: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c0a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c2d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c44: Unknown result type (might be due to invalid IL or missing references)
			//IL_061a: Unknown result type (might be due to invalid IL or missing references)
			//IL_062e: Unknown result type (might be due to invalid IL or missing references)
			//IL_065e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d01: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d1a: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d57: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d72: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d8a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dcf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0707: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("MeshTerrain_" + ((Object)terrain).name);
			MeshFilter val2 = val.AddComponent<MeshFilter>();
			MeshRenderer val3 = val.AddComponent<MeshRenderer>();
			((Component)val3).gameObject.layer = ((Component)terrain).gameObject.layer;
			((Component)val3).gameObject.tag = ((Component)terrain).gameObject.tag;
			val.transform.SetParent(((Component)terrain).transform.parent);
			terrain.renderingLayerMask |= (uint)(snowfallData.snowOverlayCustomPass?.renderingLayers ?? ((SnowOverlayCustomPass.RenderingLayers)0));
			((Renderer)val3).renderingLayerMask = terrain.renderingLayerMask;
			val.isStatic = true;
			Mesh val4 = new Mesh();
			((Object)val4).name = "MeshTerrain_" + ((Object)terrain).name;
			List<Vector3> list = new List<Vector3>();
			List<Vector2> list2 = new List<Vector2>();
			List<int> list3 = new List<int>();
			val.transform.position = ((Component)terrain).transform.position;
			float x = terrain.terrainData.size.x;
			float z = terrain.terrainData.size.z;
			float y = terrain.terrainData.size.y;
			float num = x / (float)(terrain.terrainData.heightmapResolution - 1);
			float num2 = z / (float)(terrain.terrainData.heightmapResolution - 1);
			float num3 = 1f / (float)(terrain.terrainData.heightmapResolution - 1);
			float num4 = 1f / (float)(terrain.terrainData.heightmapResolution - 1);
			HashSet<Vector3> hashSet = new HashSet<Vector3>();
			if (levelBounds.HasValue)
			{
				Bounds bounds = terrain.terrainData.bounds;
				((Bounds)(ref bounds)).center = ((Bounds)(ref bounds)).center + ((Component)terrain).transform.position;
				float num5 = Mathf.Max(((Bounds)(ref bounds)).extents.x, ((Bounds)(ref bounds)).extents.z);
				Bounds value = levelBounds.Value;
				Vector3 center = ((Bounds)(ref value)).center;
				value = levelBounds.Value;
				float x2 = ((Bounds)(ref value)).extents.x;
				value = levelBounds.Value;
				float num6 = Mathf.Max(x2, ((Bounds)(ref value)).extents.z);
				int num7 = snowfallData.MinMeshStep;
				if (snowfallData.TargetVertexCount > 0)
				{
					num7 = Mathf.CeilToInt(Mathf.Sqrt(num6 * num6 / (num * num2 * (float)snowfallData.TargetVertexCount)));
				}
				QuadTree quadTree = new QuadTree(bounds);
				quadTree.Subdivide(levelBounds.Value, new Vector2(num, num2), num7, snowfallData.MaxMeshStep, snowfallData.FalloffSpeed, num5 - num6);
				HashSet<Vector3> hashSet2 = new HashSet<Vector3>();
				List<QuadTree> list4 = new List<QuadTree>();
				quadTree.GetLeafNodes(list4);
				Vector3 val6 = default(Vector3);
				Vector2 item = default(Vector2);
				foreach (QuadTree item4 in list4)
				{
					Vector3[] array = (Vector3[])(object)new Vector3[4]
					{
						new Vector3(((Bounds)(ref item4.bounds)).min.x, 0f, ((Bounds)(ref item4.bounds)).min.z),
						new Vector3(((Bounds)(ref item4.bounds)).min.x, 0f, ((Bounds)(ref item4.bounds)).max.z),
						new Vector3(((Bounds)(ref item4.bounds)).max.x, 0f, ((Bounds)(ref item4.bounds)).min.z),
						new Vector3(((Bounds)(ref item4.bounds)).max.x, 0f, ((Bounds)(ref item4.bounds)).max.z)
					};
					Vector3[] array2 = array;
					foreach (Vector3 val5 in array2)
					{
						if (!hashSet2.Add(val5))
						{
							continue;
						}
						float num8 = terrain.SampleHeight(val5);
						((Vector3)(ref val6))..ctor(val5.x - ((Component)terrain).transform.position.x, num8, val5.z - ((Component)terrain).transform.position.z);
						list.Add(val6);
						((Vector2)(ref item))..ctor(val6.x / x, val6.z / z);
						list2.Add(item);
						if (snowfallData.CarveHoles)
						{
							int num9 = (int)(val6.x / num);
							int num10 = (int)(val6.z / num2);
							num9 = Mathf.Clamp(num9, 0, terrain.terrainData.holesResolution - 1);
							num10 = Mathf.Clamp(num10, 0, terrain.terrainData.holesResolution - 1);
							if (!terrain.terrainData.GetHoles(num9, num10, 1, 1)[0, 0])
							{
								hashSet.Add(val6);
							}
						}
					}
				}
				Debug.LogDebug("Sampled vertices: " + list.Count);
				Polygon val7 = new Polygon();
				for (int j = 0; j < list.Count; j++)
				{
					Vertex val8 = UnityExtentions.ToTriangleNetVertex(list[j], list2[j], 1);
					val7.Add(val8);
				}
				ConstraintOptions val9 = new ConstraintOptions
				{
					ConformingDelaunay = false,
					SegmentSplitting = 2
				};
				QualityOptions val10 = new QualityOptions
				{
					MinimumAngle = 20f,
					SteinerPoints = (snowfallData.RefineMesh ? (-1) : 0)
				};
				Stopwatch stopwatch = new Stopwatch();
				stopwatch.Restart();
				IMesh val11 = ExtensionMethods.Triangulate((IPolygon)(object)val7, val9, val10);
				stopwatch.Stop();
				Debug.LogDebug("Triangulation time: " + stopwatch.ElapsedMilliseconds + "ms");
				Debug.LogDebug("Final vertices: " + val11.Vertices.Count);
				list = new List<Vector3>();
				Dictionary<int, int> dictionary = new Dictionary<int, int>();
				list2 = new List<Vector2>();
				foreach (Triangle triangle in val11.Triangles)
				{
					int vertexID = ((ITriangle)triangle).GetVertexID(0);
					int vertexID2 = ((ITriangle)triangle).GetVertexID(1);
					int vertexID3 = ((ITriangle)triangle).GetVertexID(2);
					if (!dictionary.ContainsKey(vertexID))
					{
						dictionary[vertexID] = list.Count;
						list.Add(UnityExtentions.ToVector3(((ITriangle)triangle).GetVertex(0), 1));
						list2.Add(((Point)((ITriangle)triangle).GetVertex(0)).UV);
					}
					if (!dictionary.ContainsKey(vertexID2))
					{
						dictionary[vertexID2] = list.Count;
						list.Add(UnityExtentions.ToVector3(((ITriangle)triangle).GetVertex(1), 1));
						list2.Add(((Point)((ITriangle)triangle).GetVertex(1)).UV);
					}
					if (!dictionary.ContainsKey(vertexID3))
					{
						dictionary[vertexID3] = list.Count;
						list.Add(UnityExtentions.ToVector3(((ITriangle)triangle).GetVertex(2), 1));
						list2.Add(((Point)((ITriangle)triangle).GetVertex(2)).UV);
					}
					if (!snowfallData.CarveHoles || (!hashSet.Contains(list[dictionary[vertexID]]) && !hashSet.Contains(list[dictionary[vertexID2]]) && !hashSet.Contains(list[dictionary[vertexID3]])))
					{
						list3.Add(dictionary[vertexID]);
						list3.Add(dictionary[vertexID3]);
						list3.Add(dictionary[vertexID2]);
					}
				}
			}
			else
			{
				int num11 = snowfallData.MinMeshStep;
				if (snowfallData.TargetVertexCount > 0)
				{
					num11 = Mathf.CeilToInt(Mathf.Sqrt((float)(terrain.terrainData.heightmapResolution * terrain.terrainData.heightmapResolution / snowfallData.TargetVertexCount)));
				}
				int num12 = Mathf.Max(num11, 1);
				int num13 = Mathf.FloorToInt((float)(terrain.terrainData.heightmapResolution / num12));
				int num14 = Mathf.FloorToInt((float)(terrain.terrainData.heightmapResolution / num12));
				Vector3 item2 = default(Vector3);
				Vector2 item3 = default(Vector2);
				for (int k = 0; k <= num14; k++)
				{
					for (int l = 0; l <= num13; l++)
					{
						int num15 = l * num12;
						int num16 = k * num12;
						num15 = Mathf.Min(num15, terrain.terrainData.heightmapResolution - 1);
						num16 = Mathf.Min(num16, terrain.terrainData.heightmapResolution - 1);
						float height = terrain.terrainData.GetHeight(num15, num16);
						((Vector3)(ref item2))..ctor((float)num15 * num, height, (float)num16 * num2);
						list.Add(item2);
						((Vector2)(ref item3))..ctor((float)num15 * num3, (float)num16 * num4);
						list2.Add(item3);
						if (snowfallData.CarveHoles)
						{
							num15 = Mathf.Clamp(num15, 0, terrain.terrainData.holesResolution - 1);
							num16 = Mathf.Clamp(num16, 0, terrain.terrainData.holesResolution - 1);
							if (!terrain.terrainData.GetHoles(num15, num16, 1, 1)[0, 0])
							{
								hashSet.Add(item2);
							}
						}
					}
				}
				Debug.LogDebug("Sampled vertices: " + list.Count);
				for (int m = 0; m < num14; m++)
				{
					for (int n = 0; n < num13; n++)
					{
						int num17 = m * (num13 + 1) + n;
						if (!snowfallData.CarveHoles || (!hashSet.Contains(list[num17]) && !hashSet.Contains(list[num17 + 1]) && !hashSet.Contains(list[num17 + (num13 + 1)]) && !hashSet.Contains(list[num17 + (num13 + 1) + 1])))
						{
							list3.Add(num17);
							list3.Add(num17 + (num13 + 1));
							list3.Add(num17 + (num13 + 1) + 1);
							list3.Add(num17);
							list3.Add(num17 + (num13 + 1) + 1);
							list3.Add(num17 + 1);
						}
					}
				}
			}
			val4.indexFormat = (IndexFormat)(list.Count > 65535);
			val4.vertices = list.ToArray();
			val4.uv = list2.ToArray();
			val4.triangles = list3.ToArray();
			val4.Optimize();
			val4.RecalculateBounds();
			val4.RecalculateNormals();
			val4.RecalculateTangents();
			if (snowfallData.UseMeshCollider)
			{
				MeshCollider val12 = val.AddComponent<MeshCollider>();
				val12.sharedMesh = val4;
				((Collider)((Component)terrain).GetComponent<TerrainCollider>()).enabled = false;
			}
			val2.mesh = val4;
			((Renderer)val3).sharedMaterial = new Material(snowfallData.terraMeshShader);
			terrain.drawHeightmap = false;
			if (snowfallData.copyTrees || snowfallData.UseMeshCollider)
			{
				terrain.treeDistance = 0f;
				Transform transform = new GameObject("Trees").transform;
				transform.position = val.transform.position;
				transform.parent = val.transform;
				TreeInstance[] treeInstances = terrain.terrainData.treeInstances;
				MeshRenderer val15 = default(MeshRenderer);
				foreach (TreeInstance val13 in treeInstances)
				{
					GameObject prefab = terrain.terrainData.treePrototypes[val13.prototypeIndex].prefab;
					GameObject val14 = Object.Instantiate<GameObject>(prefab, transform);
					Vector3 position = Vector3.Scale(val13.position, terrain.terrainData.size) + ((Component)terrain).transform.position;
					val14.transform.position = position;
					val14.transform.localScale = new Vector3(val13.widthScale, val13.heightScale, val13.widthScale);
					val14.transform.rotation = Quaternion.Euler(0f, val13.rotation * 180f / MathF.PI, 0f);
					val14.isStatic = true;
					val14.layer = LayerMask.GetMask(new string[1] { "Terrain" });
					if (val14.TryGetComponent<MeshRenderer>(ref val15))
					{
						MeshRenderer obj = val15;
						((Renderer)obj).renderingLayerMask = ((Renderer)obj).renderingLayerMask | (uint)(snowfallData.snowOverlayCustomPass?.renderingLayers ?? ((SnowOverlayCustomPass.RenderingLayers)0));
					}
				}
			}
			if (snowfallData.copyDetail)
			{
				Transform transform2 = new GameObject("Grass").transform;
				transform2.parent = val.transform;
				TerrainData terrainData = terrain.terrainData;
				float num19 = terrainData.size.x / (float)terrainData.detailWidth;
				float num20 = terrainData.size.z / (float)terrainData.detailHeight;
				Debug.LogDebug("Detail Prototypes: " + terrainData.detailPrototypes.Length);
				Vector3 val17 = default(Vector3);
				for (int num21 = 0; num21 < terrainData.detailPrototypes.Length; num21++)
				{
					DetailPrototype val16 = terrainData.detailPrototypes[num21];
					int[,] detailLayer = terrainData.GetDetailLayer(0, 0, terrainData.detailWidth, terrainData.detailHeight, num21);
					float density = val16.density;
					Debug.LogDebug("Target Coverage: " + val16.targetCoverage);
					for (int num22 = 0; num22 < terrainData.detailWidth; num22++)
					{
						for (int num23 = 0; num23 < terrainData.detailHeight; num23++)
						{
							float num24 = (float)detailLayer[num23, num22] / 255f;
							float num25 = (float)num22 * num19 + ((Component)terrain).transform.position.x;
							float num26 = (float)num23 * num20 + ((Component)terrain).transform.position.z;
							float num27 = Mathf.PerlinNoise(num25, num26);
							if (num27 * num24 * density > 0.9f)
							{
								((Vector3)(ref val17))..ctor(num25, 0f, num26);
								val17.y = terrain.SampleHeight(val17);
								GameObject val18 = Object.Instantiate<GameObject>(terrainData.detailPrototypes[num21].prototype, val17, Quaternion.Euler(0f, (float)Random.Range(0, 359), 0f), transform2);
								float num28 = Random.Range(val16.minWidth, val16.maxWidth);
								float num29 = Random.Range(val16.minHeight, val16.maxHeight);
								val18.transform.localScale = new Vector3(num28, num29, num28);
							}
						}
					}
				}
			}
			return val;
		}

		public static Texture2D[] GetSplatmapsAsTextures(this Terrain terrain)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//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)
			TerrainData terrainData = terrain.terrainData;
			int alpham

Triangle.Net.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using Microsoft.CodeAnalysis;
using TriangleNet.Geometry;
using TriangleNet.IO;
using TriangleNet.Logging;
using TriangleNet.Meshing;
using TriangleNet.Meshing.Algorithm;
using TriangleNet.Meshing.Data;
using TriangleNet.Meshing.Iterators;
using TriangleNet.Smoothing;
using TriangleNet.Tools;
using TriangleNet.Topology;
using TriangleNet.Topology.DCEL;
using TriangleNet.Unity;
using TriangleNet.Voronoi;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[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]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
public class TriangulateMeshInBounds : MonoBehaviour
{
	public GameObject objectToModify;

	internal GameObject objectModified;

	public Collider boundsCollider;

	public bool useBounds = true;

	public bool refineMesh = false;

	public bool smoothMesh = false;

	public float baseEdgeLength = 4f;

	[Header("Debug")]
	internal Dictionary<EdgePair, int> edgeCounts;

	private Dictionary<Vector3, int> uniqueVertices;

	internal HashSet<int> vertexIndicesInBounds;

	[SerializeField]
	internal int smoothingIterations = 1;

	[SerializeField]
	internal bool constrainEdges = true;

	[SerializeField]
	internal bool replaceUvs = false;

	[ContextMenu("Modify Mesh")]
	public void ModifyMesh()
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: 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_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0295: Unknown result type (might be due to invalid IL or missing references)
		//IL_029a: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02da: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0310: Unknown result type (might be due to invalid IL or missing references)
		//IL_0312: Unknown result type (might be due to invalid IL or missing references)
		//IL_0335: Unknown result type (might be due to invalid IL or missing references)
		//IL_0337: Unknown result type (might be due to invalid IL or missing references)
		//IL_035a: Unknown result type (might be due to invalid IL or missing references)
		//IL_035c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_039b: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0501: Unknown result type (might be due to invalid IL or missing references)
		//IL_0647: Unknown result type (might be due to invalid IL or missing references)
		//IL_064c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0652: Unknown result type (might be due to invalid IL or missing references)
		//IL_0657: Unknown result type (might be due to invalid IL or missing references)
		//IL_065d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0662: Unknown result type (might be due to invalid IL or missing references)
		//IL_0664: Unknown result type (might be due to invalid IL or missing references)
		//IL_0666: Unknown result type (might be due to invalid IL or missing references)
		//IL_0668: Unknown result type (might be due to invalid IL or missing references)
		//IL_066d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0678: Unknown result type (might be due to invalid IL or missing references)
		//IL_067a: Unknown result type (might be due to invalid IL or missing references)
		//IL_067c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0681: Unknown result type (might be due to invalid IL or missing references)
		//IL_068c: Unknown result type (might be due to invalid IL or missing references)
		//IL_068e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0690: Unknown result type (might be due to invalid IL or missing references)
		//IL_0695: Unknown result type (might be due to invalid IL or missing references)
		//IL_09ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_09b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_075a: Unknown result type (might be due to invalid IL or missing references)
		//IL_075c: Unknown result type (might be due to invalid IL or missing references)
		//IL_075e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0768: Unknown result type (might be due to invalid IL or missing references)
		//IL_076d: Unknown result type (might be due to invalid IL or missing references)
		//IL_076f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0771: Unknown result type (might be due to invalid IL or missing references)
		//IL_0773: Unknown result type (might be due to invalid IL or missing references)
		//IL_077d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0782: Unknown result type (might be due to invalid IL or missing references)
		//IL_0784: Unknown result type (might be due to invalid IL or missing references)
		//IL_0786: Unknown result type (might be due to invalid IL or missing references)
		//IL_0788: Unknown result type (might be due to invalid IL or missing references)
		//IL_0792: Unknown result type (might be due to invalid IL or missing references)
		//IL_0797: Unknown result type (might be due to invalid IL or missing references)
		//IL_079d: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_07ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_07c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_081b: Unknown result type (might be due to invalid IL or missing references)
		//IL_07d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_07f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_07fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_07fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0800: Unknown result type (might be due to invalid IL or missing references)
		//IL_080a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c2f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c44: Unknown result type (might be due to invalid IL or missing references)
		//IL_0830: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c80: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c95: Unknown result type (might be due to invalid IL or missing references)
		//IL_0886: Unknown result type (might be due to invalid IL or missing references)
		//IL_0843: Unknown result type (might be due to invalid IL or missing references)
		//IL_085d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0867: Unknown result type (might be due to invalid IL or missing references)
		//IL_0869: Unknown result type (might be due to invalid IL or missing references)
		//IL_086b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0875: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cd1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ce6: Unknown result type (might be due to invalid IL or missing references)
		//IL_089b: Unknown result type (might be due to invalid IL or missing references)
		//IL_08f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_08c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_08e0: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)objectModified != (Object)null)
		{
			Object.DestroyImmediate((Object)(object)objectModified);
		}
		Stopwatch stopwatch = new Stopwatch();
		if ((Object)(object)objectToModify == (Object)null || (Object)(object)boundsCollider == (Object)null)
		{
			Debug.LogError((object)"Object to modify and bounds collider must be assigned.");
			return;
		}
		objectModified = Object.Instantiate<GameObject>(objectToModify);
		objectModified.transform.position = objectToModify.transform.position;
		objectModified.transform.rotation = objectToModify.transform.rotation;
		objectModified.transform.localScale = objectToModify.transform.lossyScale;
		((Object)objectModified).name = ((Object)objectToModify).name + "_Modified";
		Mesh sharedMesh = objectToModify.GetComponent<MeshFilter>().sharedMesh;
		var (val, num) = ExtractLargestSubmesh(objectModified);
		((Object)val).name = ((Object)sharedMesh).name + "_Modified";
		Debug.Log((object)("Extracted submesh with " + val.vertexCount + " vertices and " + val.triangles.Length / 3 + " triangles from submesh " + num));
		Bounds bounds2 = default(Bounds);
		if (useBounds)
		{
			Transform transform = objectToModify.transform;
			Bounds bounds = boundsCollider.bounds;
			Vector3 val2 = transform.InverseTransformPoint(((Bounds)(ref bounds)).center);
			Transform transform2 = objectToModify.transform;
			bounds = boundsCollider.bounds;
			((Bounds)(ref bounds2))..ctor(val2, transform2.InverseTransformVector(((Bounds)(ref bounds)).size));
			((Bounds)(ref bounds2)).size = new Vector3(Mathf.Abs(((Bounds)(ref bounds2)).size.x), Mathf.Abs(((Bounds)(ref bounds2)).size.y), Mathf.Abs(((Bounds)(ref bounds2)).size.z));
		}
		else
		{
			bounds2 = sharedMesh.bounds;
		}
		Vector3 val3 = ((Bounds)(ref bounds2)).center;
		string? text = ((object)(Vector3)(ref val3)).ToString();
		val3 = ((Bounds)(ref bounds2)).size;
		Debug.Log((object)("Bounds for triangulation: " + text + " " + ((object)(Vector3)(ref val3)).ToString()));
		Vector3[] vertices = val.vertices;
		int[] triangles = val.triangles;
		int num2 = 0;
		Vector3 val4 = objectToModify.transform.InverseTransformDirection(Vector3.up);
		val4.x *= Mathf.Sign(objectToModify.transform.lossyScale.x);
		val4.y *= Mathf.Sign(objectToModify.transform.lossyScale.y);
		val4.z *= Mathf.Sign(objectToModify.transform.lossyScale.z);
		if (Mathf.Abs(Vector3.Dot(val4, Vector3.right)) > 0.5f)
		{
			num2 = 0;
		}
		else if (Mathf.Abs(Vector3.Dot(val4, Vector3.up)) > 0.5f)
		{
			num2 = 1;
		}
		else if (Mathf.Abs(Vector3.Dot(val4, Vector3.forward)) > 0.5f)
		{
			num2 = 2;
		}
		Debug.Log((object)("Object's up axis: " + num2));
		val3 = val4;
		Debug.Log((object)("Object's up direction: " + ((object)(Vector3)(ref val3)).ToString()));
		val3 = objectToModify.transform.lossyScale;
		float num3 = Mathf.Abs(((Vector3)(ref val3))[(num2 + 1) % 3]);
		val3 = objectToModify.transform.lossyScale;
		float num4 = Mathf.Max(num3, Mathf.Abs(((Vector3)(ref val3))[(num2 + 2) % 3]));
		float num5 = baseEdgeLength / num4;
		Debug.Log((object)("Max scale: " + num4 + " Max edge length: " + num5 + "m"));
		vertexIndicesInBounds = new HashSet<int>();
		Queue<(int, int, int)> queue = new Queue<(int, int, int)>();
		uniqueVertices = new Dictionary<Vector3, int>();
		List<int> list = new List<int>();
		edgeCounts = new Dictionary<EdgePair, int>();
		Dictionary<int, int> dictionary = new Dictionary<int, int>();
		Dictionary<int, int> dictionary2 = new Dictionary<int, int>();
		stopwatch.Start();
		for (int i = 0; i < triangles.Length; i += 3)
		{
			int p = triangles[i];
			int p2 = triangles[i + 1];
			int p3 = triangles[i + 2];
			(p, p2, p3) = CheckForDuplicateVertices(vertices, p, p2, p3);
			if (((Bounds)(ref bounds2)).Contains(vertices[p]) && ((Bounds)(ref bounds2)).Contains(vertices[p2]) && ((Bounds)(ref bounds2)).Contains(vertices[p3]))
			{
				vertexIndicesInBounds.Add(p);
				vertexIndicesInBounds.Add(p2);
				vertexIndicesInBounds.Add(p3);
				if (refineMesh)
				{
					queue.Enqueue((p, p2, p3));
				}
				UpdateEdgeCounts(p, p2);
				UpdateEdgeCounts(p2, p3);
				UpdateEdgeCounts(p3, p);
			}
			else
			{
				list.Add(p);
				list.Add(p2);
				list.Add(p3);
			}
		}
		stopwatch.Stop();
		Debug.Log((object)("Vertex and triangle filtering/deduplication time: " + stopwatch.ElapsedMilliseconds + "ms"));
		List<Vector3> list2 = new List<Vector3>(vertices);
		List<Vector2> list3 = new List<Vector2>(val.uv);
		if (refineMesh)
		{
			stopwatch.Restart();
			Dictionary<Vector3, int> dictionary3 = new Dictionary<Vector3, int>();
			while (queue.Count > 0)
			{
				(int, int, int) tuple3 = queue.Dequeue();
				int item = tuple3.Item1;
				int item2 = tuple3.Item2;
				int item3 = tuple3.Item3;
				Vector3 val5 = list2[item];
				Vector3 val6 = list2[item2];
				Vector3 val7 = list2[item3];
				val3 = val5 - val6;
				float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
				val3 = val6 - val7;
				float sqrMagnitude2 = ((Vector3)(ref val3)).sqrMagnitude;
				val3 = val7 - val5;
				float sqrMagnitude3 = ((Vector3)(ref val3)).sqrMagnitude;
				EdgePair key = new EdgePair(item, item2);
				EdgePair key2 = new EdgePair(item2, item3);
				EdgePair key3 = new EdgePair(item3, item);
				float num6 = num5 * num5;
				bool flag = sqrMagnitude > num6 && sqrMagnitude2 > num6 && sqrMagnitude3 > num6;
				bool flag2 = (edgeCounts.ContainsKey(key) && edgeCounts[key] == 1) || (edgeCounts.ContainsKey(key2) && edgeCounts[key2] == 1) || (edgeCounts.ContainsKey(key3) && edgeCounts[key3] == 1);
				if (flag && !flag2)
				{
					Vector3 val8 = (val5 + val6) / 2f;
					Vector3 val9 = (val6 + val7) / 2f;
					Vector3 val10 = (val7 + val5) / 2f;
					Vector2 val11 = list3[item];
					Vector2 val12 = list3[item2];
					Vector2 val13 = list3[item3];
					int num7 = list2.Count;
					if (!dictionary3.ContainsKey(val8))
					{
						dictionary3[val8] = num7;
						vertexIndicesInBounds.Add(num7);
						list2.Add(val8);
						list3.Add((val11 + val12) / 2f);
					}
					else
					{
						num7 = dictionary3[val8];
					}
					int num8 = list2.Count;
					if (!dictionary3.ContainsKey(val9))
					{
						dictionary3[val9] = num8;
						vertexIndicesInBounds.Add(num8);
						list2.Add(val9);
						list3.Add((val12 + val13) / 2f);
					}
					else
					{
						num8 = dictionary3[val9];
					}
					int num9 = list2.Count;
					if (!dictionary3.ContainsKey(val10))
					{
						dictionary3[val10] = num9;
						vertexIndicesInBounds.Add(num9);
						list2.Add(val10);
						list3.Add((val13 + val11) / 2f);
					}
					else
					{
						num9 = dictionary3[val10];
					}
					queue.Enqueue((item, num7, num9));
					queue.Enqueue((num7, item2, num8));
					queue.Enqueue((num8, item3, num9));
					queue.Enqueue((num7, num8, num9));
				}
			}
			stopwatch.Stop();
			Debug.Log((object)("Refinement time: " + stopwatch.ElapsedMilliseconds + "ms"));
		}
		Polygon polygon = new Polygon();
		foreach (int vertexIndicesInBound in vertexIndicesInBounds)
		{
			TriangleNet.Geometry.Vertex vertex = list2[vertexIndicesInBound].ToTriangleNetVertex(list3[vertexIndicesInBound], num2);
			polygon.Add(vertex);
			dictionary[polygon.Points.Count - 1] = vertexIndicesInBound;
			dictionary2[vertexIndicesInBound] = polygon.Points.Count - 1;
		}
		if (constrainEdges)
		{
			foreach (KeyValuePair<EdgePair, int> edgeCount in edgeCounts)
			{
				if (edgeCount.Value == 1)
				{
					polygon.Add(new Segment(polygon.Points[dictionary2[edgeCount.Key.P1]], polygon.Points[dictionary2[edgeCount.Key.P2]]));
				}
			}
		}
		ConstraintOptions options = new ConstraintOptions
		{
			ConformingDelaunay = true,
			SegmentSplitting = 2
		};
		QualityOptions quality = new QualityOptions
		{
			MinimumAngle = 30f,
			SteinerPoints = (refineMesh ? (-1) : 0)
		};
		stopwatch.Restart();
		IMesh mesh = polygon.Triangulate(options, quality);
		stopwatch.Stop();
		Debug.Log((object)("Triangulation time: " + stopwatch.ElapsedMilliseconds + "ms"));
		if (smoothMesh)
		{
			stopwatch.Restart();
			LaplacianSmoother laplacianSmoother = new LaplacianSmoother(1f);
			laplacianSmoother.Smooth(mesh, smoothingIterations);
			stopwatch.Stop();
			Debug.Log((object)("Smoothing time: " + stopwatch.ElapsedMilliseconds + "ms"));
		}
		List<int> list4 = new List<int>(list);
		Debug.Log((object)("Modified triangles: " + mesh.Triangles.Count));
		foreach (Triangle triangle in mesh.Triangles)
		{
			int vertexID = ((ITriangle)triangle).GetVertexID(0);
			int vertexID2 = ((ITriangle)triangle).GetVertexID(1);
			int vertexID3 = ((ITriangle)triangle).GetVertexID(2);
			if (!dictionary.ContainsKey(vertexID))
			{
				dictionary[vertexID] = list2.Count;
				list2.Add(((ITriangle)triangle).GetVertex(0).ToVector3(num2));
				list3.Add(((ITriangle)triangle).GetVertex(0).UV);
			}
			if (!dictionary.ContainsKey(vertexID2))
			{
				dictionary[vertexID2] = list2.Count;
				list2.Add(((ITriangle)triangle).GetVertex(1).ToVector3(num2));
				list3.Add(((ITriangle)triangle).GetVertex(1).UV);
			}
			if (!dictionary.ContainsKey(vertexID3))
			{
				dictionary[vertexID3] = list2.Count;
				list2.Add(((ITriangle)triangle).GetVertex(2).ToVector3(num2));
				list3.Add(((ITriangle)triangle).GetVertex(2).UV);
			}
			int item4 = dictionary[vertexID];
			int item5 = dictionary[vertexID2];
			int item6 = dictionary[vertexID3];
			if (num2 == 1)
			{
				list4.Add(item4);
				list4.Add(item6);
				list4.Add(item5);
			}
			else
			{
				list4.Add(item4);
				list4.Add(item5);
				list4.Add(item6);
			}
		}
		Debug.Log((object)("Original UVs: " + val.uv.Length + " New UVs: " + list3.Count));
		Debug.Log((object)("Original vertices: " + vertices.Length + " New vertices: " + list2.Count));
		val.vertices = list2.ToArray();
		val.triangles = list4.ToArray();
		val.uv2 = UnwrapUVs(val.vertices, num2, normalize: true);
		if (replaceUvs)
		{
			val.uv = val.uv2;
		}
		else
		{
			val.uv = list3.ToArray();
		}
		val.Optimize();
		val.RecalculateNormals();
		val.RecalculateTangents();
		val.RecalculateBounds();
		MeshFilter component = objectModified.GetComponent<MeshFilter>();
		component.sharedMesh = val;
	}

	private Vector2[] UnwrapUVs(Vector3[] vertices, int upAxis, bool normalize)
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: 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_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: 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)
		Vector2[] array = (Vector2[])(object)new Vector2[vertices.Length];
		Vector2 val = default(Vector2);
		((Vector2)(ref val))..ctor(float.MaxValue, float.MaxValue);
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(float.MinValue, float.MinValue);
		for (int i = 0; i < vertices.Length; i++)
		{
			switch (upAxis)
			{
			case 0:
				array[i] = new Vector2(vertices[i].y, vertices[i].z);
				break;
			case 1:
				array[i] = new Vector2(vertices[i].x, vertices[i].z);
				break;
			default:
				array[i] = new Vector2(vertices[i].x, vertices[i].y);
				break;
			}
			val = Vector2.Min(val, array[i]);
			val2 = Vector2.Max(val2, array[i]);
		}
		if (normalize)
		{
			Vector2 val3 = val2 - val;
			for (int j = 0; j < array.Length; j++)
			{
				array[j] = new Vector2((array[j].x - val.x) / val3.x, (array[j].y - val.y) / val3.y);
			}
		}
		return array;
	}

	private void UpdateEdgeCounts(int p1, int p2)
	{
		EdgePair key = new EdgePair(p1, p2);
		if (edgeCounts.ContainsKey(key))
		{
			edgeCounts[key]++;
		}
		else
		{
			edgeCounts[key] = 1;
		}
	}

	private (int, int, int) CheckForDuplicateVertices(Vector3[] vertices, int p1, int p2, int p3)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		if (!uniqueVertices.ContainsKey(vertices[p1]))
		{
			uniqueVertices[vertices[p1]] = p1;
		}
		else
		{
			p1 = uniqueVertices[vertices[p1]];
		}
		if (!uniqueVertices.ContainsKey(vertices[p2]))
		{
			uniqueVertices[vertices[p2]] = p2;
		}
		else
		{
			p2 = uniqueVertices[vertices[p2]];
		}
		if (!uniqueVertices.ContainsKey(vertices[p3]))
		{
			uniqueVertices[vertices[p3]] = p3;
		}
		else
		{
			p3 = uniqueVertices[vertices[p3]];
		}
		return (p1, p2, p3);
	}

	public (Mesh submesh, int submeshIndex) ExtractLargestSubmesh(GameObject meshObject)
	{
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Expected O, but got Unknown
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		Mesh mesh = meshObject.GetComponent<MeshFilter>().sharedMesh;
		Transform transform = meshObject.transform;
		int subMeshCount = mesh.subMeshCount;
		if (subMeshCount <= 1)
		{
			return (Object.Instantiate<Mesh>(mesh), 0);
		}
		int num = Enumerable.Range(0, subMeshCount).OrderByDescending(delegate(int i)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			SubMeshDescriptor subMesh = mesh.GetSubMesh(i);
			return ((SubMeshDescriptor)(ref subMesh)).vertexCount;
		}).First();
		int[] triangles = mesh.GetTriangles(num);
		HashSet<int> hashSet = new HashSet<int>(triangles);
		Dictionary<int, int> oldToNewVertexMap = new Dictionary<int, int>();
		Vector3[] vertices = mesh.vertices;
		Vector2[] uv = mesh.uv;
		Vector3[] normals = mesh.normals;
		Vector4[] tangents = mesh.tangents;
		List<Vector3> list = new List<Vector3>();
		List<Vector3> list2 = ((mesh.normals.Length != 0) ? new List<Vector3>() : null);
		List<Vector2> list3 = ((mesh.uv.Length != 0) ? new List<Vector2>() : null);
		List<Vector4> list4 = ((mesh.tangents.Length != 0) ? new List<Vector4>() : null);
		foreach (int item in hashSet)
		{
			oldToNewVertexMap[item] = list.Count;
			list.Add(transform.InverseTransformPoint(vertices[item]));
			list2?.Add(normals[item]);
			list3?.Add(uv[item]);
			list4?.Add(tangents[item]);
		}
		int[] triangles2 = triangles.Select((int oldIndex) => oldToNewVertexMap[oldIndex]).ToArray();
		Mesh val = new Mesh
		{
			name = ((Object)mesh).name + "_Submesh" + num,
			vertices = list.ToArray(),
			triangles = triangles2,
			indexFormat = mesh.indexFormat
		};
		if (list2 != null)
		{
			val.normals = list2.ToArray();
		}
		if (list3 != null)
		{
			val.uv = list3.ToArray();
		}
		if (list4 != null)
		{
			val.tangents = list4.ToArray();
		}
		val.RecalculateBounds();
		return (val, num);
	}
}
public struct EdgePair : IEquatable<EdgePair>
{
	public readonly int P1;

	public readonly int P2;

	public EdgePair(int p1, int p2)
	{
		P1 = Mathf.Min(p1, p2);
		P2 = Mathf.Max(p1, p2);
	}

	public bool Equals(EdgePair other)
	{
		return P1 == other.P1 && P2 == other.P2;
	}

	public override bool Equals(object obj)
	{
		return obj is EdgePair other && Equals(other);
	}

	public override int GetHashCode()
	{
		return (P1, P2).GetHashCode();
	}
}
namespace TriangleNet
{
	internal class Behavior
	{
		private bool poly = false;

		private bool quality = false;

		private bool varArea = false;

		private bool convex = false;

		private bool jettison = false;

		private bool boundaryMarkers = true;

		private bool noHoles = false;

		private bool conformDel = false;

		private Func<ITriangle, float, bool> usertest;

		private int noBisect = 0;

		private float minAngle = 0f;

		private float maxAngle = 0f;

		private float maxArea = -1f;

		internal bool fixedArea = false;

		internal bool useSegments = true;

		internal bool useRegions = false;

		internal float goodAngle = 0f;

		internal float maxGoodAngle = 0f;

		internal float offconstant = 0f;

		public static bool NoExact { get; set; }

		public bool Quality
		{
			get
			{
				return quality;
			}
			set
			{
				quality = value;
				if (quality)
				{
					Update();
				}
			}
		}

		public float MinAngle
		{
			get
			{
				return minAngle;
			}
			set
			{
				minAngle = value;
				Update();
			}
		}

		public float MaxAngle
		{
			get
			{
				return maxAngle;
			}
			set
			{
				maxAngle = value;
				Update();
			}
		}

		public float MaxArea
		{
			get
			{
				return maxArea;
			}
			set
			{
				maxArea = value;
				fixedArea = value > 0f;
			}
		}

		public bool VarArea
		{
			get
			{
				return varArea;
			}
			set
			{
				varArea = value;
			}
		}

		public bool Poly
		{
			get
			{
				return poly;
			}
			set
			{
				poly = value;
			}
		}

		public Func<ITriangle, float, bool> UserTest
		{
			get
			{
				return usertest;
			}
			set
			{
				usertest = value;
			}
		}

		public bool Convex
		{
			get
			{
				return convex;
			}
			set
			{
				convex = value;
			}
		}

		public bool ConformingDelaunay
		{
			get
			{
				return conformDel;
			}
			set
			{
				conformDel = value;
			}
		}

		public int NoBisect
		{
			get
			{
				return noBisect;
			}
			set
			{
				noBisect = value;
				if (noBisect < 0 || noBisect > 2)
				{
					noBisect = 0;
				}
			}
		}

		public bool UseBoundaryMarkers
		{
			get
			{
				return boundaryMarkers;
			}
			set
			{
				boundaryMarkers = value;
			}
		}

		public bool NoHoles
		{
			get
			{
				return noHoles;
			}
			set
			{
				noHoles = value;
			}
		}

		public bool Jettison
		{
			get
			{
				return jettison;
			}
			set
			{
				jettison = value;
			}
		}

		public Behavior(bool quality = false, float minAngle = 20f)
		{
			if (quality)
			{
				this.quality = true;
				this.minAngle = minAngle;
				Update();
			}
		}

		private void Update()
		{
			quality = true;
			if (minAngle < 0f || minAngle > 60f)
			{
				minAngle = 0f;
				quality = false;
				Log.Instance.Warning("Invalid quality option (minimum angle).", "Mesh.Behavior");
			}
			if ((double)maxAngle != 0.0 && (maxAngle < 60f || maxAngle > 180f))
			{
				maxAngle = 0f;
				quality = false;
				Log.Instance.Warning("Invalid quality option (maximum angle).", "Mesh.Behavior");
			}
			useSegments = Poly || Quality || Convex;
			goodAngle = Mathf.Cos(MinAngle * MathF.PI / 180f);
			maxGoodAngle = Mathf.Cos(MaxAngle * MathF.PI / 180f);
			if (goodAngle == 1f)
			{
				offconstant = 0f;
			}
			else
			{
				offconstant = 0.475f * Mathf.Sqrt((1f + goodAngle) / (1f - goodAngle));
			}
			goodAngle *= goodAngle;
		}
	}
	public class Configuration
	{
		public Func<IPredicates> Predicates { get; set; }

		public Func<TrianglePool> TrianglePool { get; set; }

		public Configuration()
			: this(() => RobustPredicates.Default, () => new TrianglePool())
		{
		}

		public Configuration(Func<IPredicates> predicates)
			: this(predicates, () => new TrianglePool())
		{
		}

		public Configuration(Func<IPredicates> predicates, Func<TrianglePool> trianglePool)
		{
			Predicates = predicates;
			TrianglePool = trianglePool;
		}
	}
	public enum VertexType
	{
		InputVertex,
		SegmentVertex,
		FreeVertex,
		DeadVertex,
		UndeadVertex
	}
	public enum NodeNumbering
	{
		None,
		Linear,
		CuthillMcKee
	}
	public enum LocateResult
	{
		InTriangle,
		OnEdge,
		OnVertex,
		Outside
	}
	internal enum InsertVertexResult
	{
		Successful,
		Encroaching,
		Violating,
		Duplicate
	}
	internal enum FindDirectionResult
	{
		Within,
		Leftcollinear,
		Rightcollinear
	}
	public interface IPredicates
	{
		float CounterClockwise(Point a, Point b, Point c);

		float InCircle(Point a, Point b, Point c, Point p);

		Point FindCircumcenter(Point org, Point dest, Point apex, ref float xi, ref float eta);

		Point FindCircumcenter(Point org, Point dest, Point apex, ref float xi, ref float eta, float offconstant);
	}
	public sealed class Log : ILog<LogItem>
	{
		private List<LogItem> log = new List<LogItem>();

		private LogLevel level = LogLevel.Info;

		private static readonly Log instance;

		public static bool Verbose { get; set; }

		public static ILog<LogItem> Instance => instance;

		public IList<LogItem> Data => log;

		public LogLevel Level => level;

		static Log()
		{
			instance = new Log();
		}

		private Log()
		{
		}

		public void Add(LogItem item)
		{
			log.Add(item);
		}

		public void Clear()
		{
			log.Clear();
		}

		public void Info(string message)
		{
			log.Add(new LogItem(LogLevel.Info, message));
		}

		public void Warning(string message, string location)
		{
			log.Add(new LogItem(LogLevel.Warning, message, location));
		}

		public void Error(string message, string location)
		{
			log.Add(new LogItem(LogLevel.Error, message, location));
		}
	}
	public static class MeshValidator
	{
		private static RobustPredicates predicates = RobustPredicates.Default;

		public static bool IsConsistent(TriangleNetMesh triangleNetMesh)
		{
			Otri otri = default(Otri);
			Otri ot = default(Otri);
			Otri ot2 = default(Otri);
			ILog<LogItem> instance = Log.Instance;
			bool noExact = Behavior.NoExact;
			Behavior.NoExact = false;
			int num = 0;
			foreach (Triangle triangle2 in triangleNetMesh.triangles)
			{
				Triangle triangle = (otri.tri = triangle2);
				otri.orient = 0;
				while (otri.orient < 3)
				{
					TriangleNet.Geometry.Vertex vertex = otri.Org();
					TriangleNet.Geometry.Vertex vertex2 = otri.Dest();
					if (otri.orient == 0)
					{
						TriangleNet.Geometry.Vertex pc = otri.Apex();
						if ((double)predicates.CounterClockwise(vertex, vertex2, pc) <= 0.0)
						{
							if (Log.Verbose)
							{
								instance.Warning($"Triangle is flat or inverted (ID {triangle.id}).", "MeshValidator.IsConsistent()");
							}
							num++;
						}
					}
					otri.Sym(ref ot);
					if (ot.tri.id != -1)
					{
						ot.Sym(ref ot2);
						if (otri.tri != ot2.tri || otri.orient != ot2.orient)
						{
							if (otri.tri == ot2.tri && Log.Verbose)
							{
								instance.Warning("Asymmetric triangle-triangle bond: (Right triangle, wrong orientation)", "MeshValidator.IsConsistent()");
							}
							num++;
						}
						TriangleNet.Geometry.Vertex vertex3 = ot.Org();
						TriangleNet.Geometry.Vertex vertex4 = ot.Dest();
						if (vertex != vertex4 || vertex2 != vertex3)
						{
							if (Log.Verbose)
							{
								instance.Warning("Mismatched edge coordinates between two triangles.", "MeshValidator.IsConsistent()");
							}
							num++;
						}
					}
					otri.orient++;
				}
			}
			triangleNetMesh.MakeVertexMap();
			foreach (TriangleNet.Geometry.Vertex value in triangleNetMesh.vertices.Values)
			{
				if (value.tri.tri == null && Log.Verbose)
				{
					instance.Warning("Vertex (ID " + value.id + ") not connected to mesh (duplicate input vertex?)", "MeshValidator.IsConsistent()");
				}
			}
			Behavior.NoExact = noExact;
			return num == 0;
		}

		public static bool IsDelaunay(TriangleNetMesh triangleNetMesh)
		{
			return IsDelaunay(triangleNetMesh, constrained: false);
		}

		public static bool IsConstrainedDelaunay(TriangleNetMesh triangleNetMesh)
		{
			return IsDelaunay(triangleNetMesh, constrained: true);
		}

		private static bool IsDelaunay(TriangleNetMesh triangleNetMesh, bool constrained)
		{
			Otri otri = default(Otri);
			Otri ot = default(Otri);
			Osub os = default(Osub);
			ILog<LogItem> instance = Log.Instance;
			bool noExact = Behavior.NoExact;
			Behavior.NoExact = false;
			int num = 0;
			TriangleNet.Geometry.Vertex infvertex = triangleNetMesh.infvertex1;
			TriangleNet.Geometry.Vertex infvertex2 = triangleNetMesh.infvertex2;
			TriangleNet.Geometry.Vertex infvertex3 = triangleNetMesh.infvertex3;
			foreach (Triangle triangle in triangleNetMesh.triangles)
			{
				otri.tri = triangle;
				otri.orient = 0;
				while (otri.orient < 3)
				{
					TriangleNet.Geometry.Vertex vertex = otri.Org();
					TriangleNet.Geometry.Vertex vertex2 = otri.Dest();
					TriangleNet.Geometry.Vertex vertex3 = otri.Apex();
					otri.Sym(ref ot);
					TriangleNet.Geometry.Vertex vertex4 = ot.Apex();
					bool flag = otri.tri.id < ot.tri.id && !Otri.IsDead(ot.tri) && ot.tri.id != -1 && vertex != infvertex && vertex != infvertex2 && vertex != infvertex3 && vertex2 != infvertex && vertex2 != infvertex2 && vertex2 != infvertex3 && vertex3 != infvertex && vertex3 != infvertex2 && vertex3 != infvertex3 && vertex4 != infvertex && vertex4 != infvertex2 && vertex4 != infvertex3;
					if (constrained && triangleNetMesh.checksegments && flag)
					{
						otri.Pivot(ref os);
						if (os.seg.hash != -1)
						{
							flag = false;
						}
					}
					if (flag && (double)predicates.NonRegular(vertex, vertex2, vertex3, vertex4) > 0.0)
					{
						if (Log.Verbose)
						{
							instance.Warning($"Non-regular pair of triangles found (IDs {otri.tri.id}/{ot.tri.id}).", "MeshValidator.IsDelaunay()");
						}
						num++;
					}
					otri.orient++;
				}
			}
			Behavior.NoExact = noExact;
			return num == 0;
		}
	}
	internal class NewLocation
	{
		private const float EPS = 0f;

		private IPredicates predicates;

		private TriangleNetMesh _TriangleNetMesh;

		private Behavior behavior;

		private float[] petalx = new float[20];

		private float[] petaly = new float[20];

		private float[] petalr = new float[20];

		private float[] wedges = new float[500];

		private float[] initialConvexPoly = new float[500];

		private float[] points_p = new float[500];

		private float[] points_q = new float[500];

		private float[] points_r = new float[500];

		private float[] poly1 = new float[100];

		private float[] poly2 = new float[100];

		private float[][] polys = new float[3][];

		public NewLocation(TriangleNetMesh triangleNetMesh, IPredicates predicates)
		{
			_TriangleNetMesh = triangleNetMesh;
			this.predicates = predicates;
			behavior = triangleNetMesh.behavior;
		}

		public Point FindLocation(TriangleNet.Geometry.Vertex org, TriangleNet.Geometry.Vertex dest, TriangleNet.Geometry.Vertex apex, ref float xi, ref float eta, bool offcenter, Otri badotri)
		{
			if (behavior.MaxAngle == 0f)
			{
				return FindNewLocationWithoutMaxAngle(org, dest, apex, ref xi, ref eta, offcenter: true, badotri);
			}
			return FindNewLocation(org, dest, apex, ref xi, ref eta, offcenter: true, badotri);
		}

		private Point FindNewLocationWithoutMaxAngle(TriangleNet.Geometry.Vertex torg, TriangleNet.Geometry.Vertex tdest, TriangleNet.Geometry.Vertex tapex, ref float xi, ref float eta, bool offcenter, Otri badotri)
		{
			float offconstant = behavior.offconstant;
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			float num5 = 0f;
			int num6 = 0;
			int num7 = 0;
			Otri neighotri = default(Otri);
			float[] thirdpoint = new float[2];
			float xi2 = 0f;
			float eta2 = 0f;
			float[] p = new float[5];
			float[] p2 = new float[4];
			float num8 = 0.06f;
			float num9 = 1f;
			float num10 = 1f;
			int num11 = 0;
			float[] newloc = new float[2];
			float num12 = 0f;
			float num13 = 0f;
			Statistic.CircumcenterCount++;
			float num14 = tdest.x - torg.x;
			float num15 = tdest.y - torg.y;
			float num16 = tapex.x - torg.x;
			float num17 = tapex.y - torg.y;
			float num18 = tapex.x - tdest.x;
			float num19 = tapex.y - tdest.y;
			float num20 = num14 * num14 + num15 * num15;
			float num21 = num16 * num16 + num17 * num17;
			float num22 = (tdest.x - tapex.x) * (tdest.x - tapex.x) + (tdest.y - tapex.y) * (tdest.y - tapex.y);
			float num23;
			if (Behavior.NoExact)
			{
				num23 = 0.5f / (num14 * num17 - num16 * num15);
			}
			else
			{
				num23 = 0.5f / predicates.CounterClockwise(tdest, tapex, torg);
				Statistic.CounterClockwiseCount--;
			}
			float num24 = (num17 * num20 - num15 * num21) * num23;
			float num25 = (num14 * num21 - num16 * num20) * num23;
			Point point = new Point(torg.x + num24, torg.y + num25);
			Otri deltri = badotri;
			num6 = LongestShortestEdge(num21, num22, num20);
			Point point2;
			Point point3;
			Point point4;
			switch (num6)
			{
			case 123:
				num = num16;
				num2 = num17;
				num3 = num21;
				num4 = num22;
				num5 = num20;
				point2 = tdest;
				point3 = torg;
				point4 = tapex;
				break;
			case 132:
				num = num16;
				num2 = num17;
				num3 = num21;
				num4 = num20;
				num5 = num22;
				point2 = tdest;
				point3 = tapex;
				point4 = torg;
				break;
			case 213:
				num = num18;
				num2 = num19;
				num3 = num22;
				num4 = num21;
				num5 = num20;
				point2 = torg;
				point3 = tdest;
				point4 = tapex;
				break;
			case 231:
				num = num18;
				num2 = num19;
				num3 = num22;
				num4 = num20;
				num5 = num21;
				point2 = torg;
				point3 = tapex;
				point4 = tdest;
				break;
			case 312:
				num = num14;
				num2 = num15;
				num3 = num20;
				num4 = num21;
				num5 = num22;
				point2 = tapex;
				point3 = tdest;
				point4 = torg;
				break;
			default:
				num = num14;
				num2 = num15;
				num3 = num20;
				num4 = num22;
				num5 = num21;
				point2 = tapex;
				point3 = torg;
				point4 = tdest;
				break;
			}
			if (offcenter && offconstant > 0f)
			{
				if (num6 == 213 || num6 == 231)
				{
					float num26 = 0.5f * num - offconstant * num2;
					float num27 = 0.5f * num2 + offconstant * num;
					if (num26 * num26 + num27 * num27 < (num24 - num14) * (num24 - num14) + (num25 - num15) * (num25 - num15))
					{
						num24 = num14 + num26;
						num25 = num15 + num27;
					}
					else
					{
						num7 = 1;
					}
				}
				else if (num6 == 123 || num6 == 132)
				{
					float num26 = 0.5f * num + offconstant * num2;
					float num27 = 0.5f * num2 - offconstant * num;
					if (num26 * num26 + num27 * num27 < num24 * num24 + num25 * num25)
					{
						num24 = num26;
						num25 = num27;
					}
					else
					{
						num7 = 1;
					}
				}
				else
				{
					float num26 = 0.5f * num - offconstant * num2;
					float num27 = 0.5f * num2 + offconstant * num;
					if (num26 * num26 + num27 * num27 < num24 * num24 + num25 * num25)
					{
						num24 = num26;
						num25 = num27;
					}
					else
					{
						num7 = 1;
					}
				}
			}
			if (num7 == 1)
			{
				float num28 = (num4 + num3 - num5) / (2f * Mathf.Sqrt(num4) * Mathf.Sqrt(num3));
				bool flag = num28 < 0f || Mathf.Abs(num28 - 0f) <= 0f;
				num11 = DoSmoothing(deltri, torg, tdest, tapex, ref newloc);
				if (num11 > 0)
				{
					Statistic.RelocationCount++;
					num24 = newloc[0] - torg.x;
					num25 = newloc[1] - torg.y;
					num12 = torg.x;
					num13 = torg.y;
					switch (num11)
					{
					case 1:
						_TriangleNetMesh.DeleteVertex(ref deltri);
						break;
					case 2:
						deltri.Lnext();
						_TriangleNetMesh.DeleteVertex(ref deltri);
						break;
					case 3:
						deltri.Lprev();
						_TriangleNetMesh.DeleteVertex(ref deltri);
						break;
					}
				}
				else
				{
					float num29 = Mathf.Sqrt(num3) / (2f * Mathf.Sin(behavior.MinAngle * MathF.PI / 180f));
					float num30 = (point3.x + point4.x) / 2f;
					float num31 = (point3.y + point4.y) / 2f;
					float num32 = num30 + Mathf.Sqrt(num29 * num29 - num3 / 4f) * (point3.y - point4.y) / Mathf.Sqrt(num3);
					float num33 = num31 + Mathf.Sqrt(num29 * num29 - num3 / 4f) * (point4.x - point3.x) / Mathf.Sqrt(num3);
					float num34 = num30 - Mathf.Sqrt(num29 * num29 - num3 / 4f) * (point3.y - point4.y) / Mathf.Sqrt(num3);
					float num35 = num31 - Mathf.Sqrt(num29 * num29 - num3 / 4f) * (point4.x - point3.x) / Mathf.Sqrt(num3);
					float num36 = (num32 - point2.x) * (num32 - point2.x);
					float num37 = (num33 - point2.y) * (num33 - point2.y);
					float num38 = (num34 - point2.x) * (num34 - point2.x);
					float num39 = (num35 - point2.y) * (num35 - point2.y);
					float x;
					float y;
					if (num36 + num37 <= num38 + num39)
					{
						x = num32;
						y = num33;
					}
					else
					{
						x = num34;
						y = num35;
					}
					bool neighborsVertex = GetNeighborsVertex(badotri, point3.x, point3.y, point2.x, point2.y, ref thirdpoint, ref neighotri);
					float num40 = num24;
					float num41 = num25;
					if (!neighborsVertex)
					{
						TriangleNet.Geometry.Vertex org = neighotri.Org();
						TriangleNet.Geometry.Vertex dest = neighotri.Dest();
						TriangleNet.Geometry.Vertex apex = neighotri.Apex();
						Point point5 = predicates.FindCircumcenter(org, dest, apex, ref xi2, ref eta2);
						float num42 = point3.y - point2.y;
						float num43 = point2.x - point3.x;
						num42 = point.x + num42;
						num43 = point.y + num43;
						CircleLineIntersection(point.x, point.y, num42, num43, x, y, num29, ref p);
						float x2 = (point3.x + point2.x) / 2f;
						float y2 = (point3.y + point2.y) / 2f;
						float num44;
						float num45;
						if (ChooseCorrectPoint(x2, y2, p[3], p[4], point.x, point.y, flag))
						{
							num44 = p[3];
							num45 = p[4];
						}
						else
						{
							num44 = p[1];
							num45 = p[2];
						}
						PointBetweenPoints(num44, num45, point.x, point.y, point5.x, point5.y, ref p2);
						if ((double)p[0] > 0.0)
						{
							if (Mathf.Abs(p2[0] - 1f) <= 0f)
							{
								if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, point5.x, point5.y))
								{
									num40 = num24;
									num41 = num25;
								}
								else
								{
									num40 = p2[2] - torg.x;
									num41 = p2[3] - torg.y;
								}
							}
							else if (IsBadTriangleAngle(point4.x, point4.y, point3.x, point3.y, num44, num45))
							{
								float num46 = Mathf.Sqrt((num44 - point.x) * (num44 - point.x) + (num45 - point.y) * (num45 - point.y));
								float num47 = point.x - num44;
								float num48 = point.y - num45;
								num47 /= num46;
								num48 /= num46;
								num44 += num47 * num8 * Mathf.Sqrt(num3);
								num45 += num48 * num8 * Mathf.Sqrt(num3);
								if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num44, num45))
								{
									num40 = num24;
									num41 = num25;
								}
								else
								{
									num40 = num44 - torg.x;
									num41 = num45 - torg.y;
								}
							}
							else
							{
								num40 = num44 - torg.x;
								num41 = num45 - torg.y;
							}
							if ((point2.x - point.x) * (point2.x - point.x) + (point2.y - point.y) * (point2.y - point.y) > num9 * ((point2.x - (num40 + torg.x)) * (point2.x - (num40 + torg.x)) + (point2.y - (num41 + torg.y)) * (point2.y - (num41 + torg.y))))
							{
								num40 = num24;
								num41 = num25;
							}
						}
					}
					neighborsVertex = GetNeighborsVertex(badotri, point4.x, point4.y, point2.x, point2.y, ref thirdpoint, ref neighotri);
					float num49 = num24;
					float num50 = num25;
					if (!neighborsVertex)
					{
						TriangleNet.Geometry.Vertex org = neighotri.Org();
						TriangleNet.Geometry.Vertex dest = neighotri.Dest();
						TriangleNet.Geometry.Vertex apex = neighotri.Apex();
						Point point5 = predicates.FindCircumcenter(org, dest, apex, ref xi2, ref eta2);
						float num42 = point4.y - point2.y;
						float num43 = point2.x - point4.x;
						num42 = point.x + num42;
						num43 = point.y + num43;
						CircleLineIntersection(point.x, point.y, num42, num43, x, y, num29, ref p);
						float x3 = (point4.x + point2.x) / 2f;
						float y3 = (point4.y + point2.y) / 2f;
						float num44;
						float num45;
						if (ChooseCorrectPoint(x3, y3, p[3], p[4], point.x, point.y, isObtuse: false))
						{
							num44 = p[3];
							num45 = p[4];
						}
						else
						{
							num44 = p[1];
							num45 = p[2];
						}
						PointBetweenPoints(num44, num45, point.x, point.y, point5.x, point5.y, ref p2);
						if (p[0] > 0f)
						{
							if (Mathf.Abs(p2[0] - 1f) <= 0f)
							{
								if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, point5.x, point5.y))
								{
									num49 = num24;
									num50 = num25;
								}
								else
								{
									num49 = p2[2] - torg.x;
									num50 = p2[3] - torg.y;
								}
							}
							else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num44, num45))
							{
								float num46 = Mathf.Sqrt((num44 - point.x) * (num44 - point.x) + (num45 - point.y) * (num45 - point.y));
								float num47 = point.x - num44;
								float num48 = point.y - num45;
								num47 /= num46;
								num48 /= num46;
								num44 += num47 * num8 * Mathf.Sqrt(num3);
								num45 += num48 * num8 * Mathf.Sqrt(num3);
								if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num44, num45))
								{
									num49 = num24;
									num50 = num25;
								}
								else
								{
									num49 = num44 - torg.x;
									num50 = num45 - torg.y;
								}
							}
							else
							{
								num49 = num44 - torg.x;
								num50 = num45 - torg.y;
							}
							if ((point2.x - point.x) * (point2.x - point.x) + (point2.y - point.y) * (point2.y - point.y) > num9 * ((point2.x - (num49 + torg.x)) * (point2.x - (num49 + torg.x)) + (point2.y - (num50 + torg.y)) * (point2.y - (num50 + torg.y))))
							{
								num49 = num24;
								num50 = num25;
							}
						}
					}
					if (flag)
					{
						num24 = num40;
						num25 = num41;
					}
					else if (num10 * ((point2.x - (num49 + torg.x)) * (point2.x - (num49 + torg.x)) + (point2.y - (num50 + torg.y)) * (point2.y - (num50 + torg.y))) > (point2.x - (num40 + torg.x)) * (point2.x - (num40 + torg.x)) + (point2.y - (num41 + torg.y)) * (point2.y - (num41 + torg.y)))
					{
						num24 = num49;
						num25 = num50;
					}
					else
					{
						num24 = num40;
						num25 = num41;
					}
				}
			}
			Point point6 = new Point();
			if (num11 <= 0)
			{
				point6.x = torg.x + num24;
				point6.y = torg.y + num25;
			}
			else
			{
				point6.x = num12 + num24;
				point6.y = num13 + num25;
			}
			xi = (num17 * num24 - num16 * num25) * (2f * num23);
			eta = (num14 * num25 - num15 * num24) * (2f * num23);
			return point6;
		}

		private Point FindNewLocation(TriangleNet.Geometry.Vertex torg, TriangleNet.Geometry.Vertex tdest, TriangleNet.Geometry.Vertex tapex, ref float xi, ref float eta, bool offcenter, Otri badotri)
		{
			float offconstant = behavior.offconstant;
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			float num5 = 0f;
			int num6 = 0;
			int num7 = 0;
			Otri neighotri = default(Otri);
			float[] thirdpoint = new float[2];
			float xi2 = 0f;
			float eta2 = 0f;
			float[] p = new float[5];
			float[] p2 = new float[4];
			float num8 = 0.06f;
			float num9 = 1f;
			float num10 = 1f;
			int num11 = 0;
			float[] newloc = new float[2];
			float num12 = 0f;
			float num13 = 0f;
			float num14 = 0f;
			float num15 = 0f;
			float[] p3 = new float[3];
			float[] p4 = new float[4];
			Statistic.CircumcenterCount++;
			float num16 = tdest.x - torg.x;
			float num17 = tdest.y - torg.y;
			float num18 = tapex.x - torg.x;
			float num19 = tapex.y - torg.y;
			float num20 = tapex.x - tdest.x;
			float num21 = tapex.y - tdest.y;
			float num22 = num16 * num16 + num17 * num17;
			float num23 = num18 * num18 + num19 * num19;
			float num24 = (tdest.x - tapex.x) * (tdest.x - tapex.x) + (tdest.y - tapex.y) * (tdest.y - tapex.y);
			float num25;
			if (Behavior.NoExact)
			{
				num25 = 0.5f / (num16 * num19 - num18 * num17);
			}
			else
			{
				num25 = 0.5f / predicates.CounterClockwise(tdest, tapex, torg);
				Statistic.CounterClockwiseCount--;
			}
			float num26 = (num19 * num22 - num17 * num23) * num25;
			float num27 = (num16 * num23 - num18 * num22) * num25;
			Point point = new Point(torg.x + num26, torg.y + num27);
			Otri deltri = badotri;
			num6 = LongestShortestEdge(num23, num24, num22);
			Point point2;
			Point point3;
			Point point4;
			switch (num6)
			{
			case 123:
				num = num18;
				num2 = num19;
				num3 = num23;
				num4 = num24;
				num5 = num22;
				point2 = tdest;
				point3 = torg;
				point4 = tapex;
				break;
			case 132:
				num = num18;
				num2 = num19;
				num3 = num23;
				num4 = num22;
				num5 = num24;
				point2 = tdest;
				point3 = tapex;
				point4 = torg;
				break;
			case 213:
				num = num20;
				num2 = num21;
				num3 = num24;
				num4 = num23;
				num5 = num22;
				point2 = torg;
				point3 = tdest;
				point4 = tapex;
				break;
			case 231:
				num = num20;
				num2 = num21;
				num3 = num24;
				num4 = num22;
				num5 = num23;
				point2 = torg;
				point3 = tapex;
				point4 = tdest;
				break;
			case 312:
				num = num16;
				num2 = num17;
				num3 = num22;
				num4 = num23;
				num5 = num24;
				point2 = tapex;
				point3 = tdest;
				point4 = torg;
				break;
			default:
				num = num16;
				num2 = num17;
				num3 = num22;
				num4 = num24;
				num5 = num23;
				point2 = tapex;
				point3 = torg;
				point4 = tdest;
				break;
			}
			if (offcenter && offconstant > 0f)
			{
				if (num6 == 213 || num6 == 231)
				{
					float num28 = 0.5f * num - offconstant * num2;
					float num29 = 0.5f * num2 + offconstant * num;
					if (num28 * num28 + num29 * num29 < (num26 - num16) * (num26 - num16) + (num27 - num17) * (num27 - num17))
					{
						num26 = num16 + num28;
						num27 = num17 + num29;
					}
					else
					{
						num7 = 1;
					}
				}
				else if (num6 == 123 || num6 == 132)
				{
					float num28 = 0.5f * num + offconstant * num2;
					float num29 = 0.5f * num2 - offconstant * num;
					if (num28 * num28 + num29 * num29 < num26 * num26 + num27 * num27)
					{
						num26 = num28;
						num27 = num29;
					}
					else
					{
						num7 = 1;
					}
				}
				else
				{
					float num28 = 0.5f * num - offconstant * num2;
					float num29 = 0.5f * num2 + offconstant * num;
					if (num28 * num28 + num29 * num29 < num26 * num26 + num27 * num27)
					{
						num26 = num28;
						num27 = num29;
					}
					else
					{
						num7 = 1;
					}
				}
			}
			if (num7 == 1)
			{
				float num30 = (num4 + num3 - num5) / (2f * Mathf.Sqrt(num4) * Mathf.Sqrt(num3));
				bool flag = num30 < 0f || Mathf.Abs(num30 - 0f) <= 0f;
				num11 = DoSmoothing(deltri, torg, tdest, tapex, ref newloc);
				if (num11 > 0)
				{
					Statistic.RelocationCount++;
					num26 = newloc[0] - torg.x;
					num27 = newloc[1] - torg.y;
					num12 = torg.x;
					num13 = torg.y;
					switch (num11)
					{
					case 1:
						_TriangleNetMesh.DeleteVertex(ref deltri);
						break;
					case 2:
						deltri.Lnext();
						_TriangleNetMesh.DeleteVertex(ref deltri);
						break;
					case 3:
						deltri.Lprev();
						_TriangleNetMesh.DeleteVertex(ref deltri);
						break;
					}
				}
				else
				{
					float num31 = Mathf.Acos((num4 + num5 - num3) / (2f * Mathf.Sqrt(num4) * Mathf.Sqrt(num5))) * 180f / MathF.PI;
					num31 = ((!(behavior.MinAngle > num31)) ? (num31 + 0.5f) : behavior.MinAngle);
					float num32 = Mathf.Sqrt(num3) / (2f * Mathf.Sin(num31 * MathF.PI / 180f));
					float num33 = (point3.x + point4.x) / 2f;
					float num34 = (point3.y + point4.y) / 2f;
					float num35 = num33 + Mathf.Sqrt(num32 * num32 - num3 / 4f) * (point3.y - point4.y) / Mathf.Sqrt(num3);
					float num36 = num34 + Mathf.Sqrt(num32 * num32 - num3 / 4f) * (point4.x - point3.x) / Mathf.Sqrt(num3);
					float num37 = num33 - Mathf.Sqrt(num32 * num32 - num3 / 4f) * (point3.y - point4.y) / Mathf.Sqrt(num3);
					float num38 = num34 - Mathf.Sqrt(num32 * num32 - num3 / 4f) * (point4.x - point3.x) / Mathf.Sqrt(num3);
					float num39 = (num35 - point2.x) * (num35 - point2.x);
					float num40 = (num36 - point2.y) * (num36 - point2.y);
					float num41 = (num37 - point2.x) * (num37 - point2.x);
					float num42 = (num38 - point2.y) * (num38 - point2.y);
					float num43;
					float num44;
					if (num39 + num40 <= num41 + num42)
					{
						num43 = num35;
						num44 = num36;
					}
					else
					{
						num43 = num37;
						num44 = num38;
					}
					bool neighborsVertex = GetNeighborsVertex(badotri, point3.x, point3.y, point2.x, point2.y, ref thirdpoint, ref neighotri);
					float num45 = num26;
					float num46 = num27;
					float num47 = Mathf.Sqrt((num43 - num33) * (num43 - num33) + (num44 - num34) * (num44 - num34));
					float num48 = (num43 - num33) / num47;
					float num49 = (num44 - num34) / num47;
					float num50 = num43 + num48 * num32;
					float num51 = num44 + num49 * num32;
					float num52 = (2f * behavior.MaxAngle + num31 - 180f) * MathF.PI / 180f;
					float num53 = num50 * Mathf.Cos(num52) + num51 * Mathf.Sin(num52) + num43 - num43 * Mathf.Cos(num52) - num44 * Mathf.Sin(num52);
					float num54 = (0f - num50) * Mathf.Sin(num52) + num51 * Mathf.Cos(num52) + num44 + num43 * Mathf.Sin(num52) - num44 * Mathf.Cos(num52);
					float num55 = num50 * Mathf.Cos(num52) - num51 * Mathf.Sin(num52) + num43 - num43 * Mathf.Cos(num52) + num44 * Mathf.Sin(num52);
					float num56 = num50 * Mathf.Sin(num52) + num51 * Mathf.Cos(num52) + num44 - num43 * Mathf.Sin(num52) - num44 * Mathf.Cos(num52);
					float num57;
					float num58;
					float num59;
					float num60;
					if (ChooseCorrectPoint(num55, num56, point3.x, point3.y, num53, num54, isObtuse: true))
					{
						num57 = num53;
						num58 = num54;
						num59 = num55;
						num60 = num56;
					}
					else
					{
						num57 = num55;
						num58 = num56;
						num59 = num53;
						num60 = num54;
					}
					float num61 = (point3.x + point2.x) / 2f;
					float num62 = (point3.y + point2.y) / 2f;
					if (!neighborsVertex)
					{
						TriangleNet.Geometry.Vertex org = neighotri.Org();
						TriangleNet.Geometry.Vertex dest = neighotri.Dest();
						TriangleNet.Geometry.Vertex apex = neighotri.Apex();
						Point point5 = predicates.FindCircumcenter(org, dest, apex, ref xi2, ref eta2);
						float num63 = point3.y - point2.y;
						float num64 = point2.x - point3.x;
						num63 = point.x + num63;
						num64 = point.y + num64;
						CircleLineIntersection(point.x, point.y, num63, num64, num43, num44, num32, ref p);
						float num65;
						float num66;
						if (ChooseCorrectPoint(num61, num62, p[3], p[4], point.x, point.y, flag))
						{
							num65 = p[3];
							num66 = p[4];
						}
						else
						{
							num65 = p[1];
							num66 = p[2];
						}
						float x = point3.x;
						float y = point3.y;
						num48 = point4.x - point3.x;
						num49 = point4.y - point3.y;
						float x2 = num57;
						float y2 = num58;
						LineLineIntersection(point.x, point.y, num63, num64, x, y, x2, y2, ref p3);
						if (p3[0] > 0f)
						{
							num14 = p3[1];
							num15 = p3[2];
						}
						PointBetweenPoints(num65, num66, point.x, point.y, point5.x, point5.y, ref p2);
						if (p[0] > 0f)
						{
							if (Mathf.Abs(p2[0] - 1f) <= 0f)
							{
								PointBetweenPoints(p2[2], p2[3], point.x, point.y, num14, num15, ref p4);
								if (Mathf.Abs(p4[0] - 1f) <= 0f && (double)p3[0] > 0.0)
								{
									if ((point2.x - num57) * (point2.x - num57) + (point2.y - num58) * (point2.y - num58) > num9 * ((point2.x - num14) * (point2.x - num14) + (point2.y - num15) * (point2.y - num15)) && IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num57, num58) && MinDistanceToNeighbor(num57, num58, ref neighotri) > MinDistanceToNeighbor(num14, num15, ref neighotri))
									{
										num45 = num57 - torg.x;
										num46 = num58 - torg.y;
									}
									else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15))
									{
										float num67 = Mathf.Sqrt((num14 - point.x) * (num14 - point.x) + (num15 - point.y) * (num15 - point.y));
										float num68 = point.x - num14;
										float num69 = point.y - num15;
										num68 /= num67;
										num69 /= num67;
										num14 += num68 * num8 * Mathf.Sqrt(num3);
										num15 += num69 * num8 * Mathf.Sqrt(num3);
										if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15))
										{
											num45 = num26;
											num46 = num27;
										}
										else
										{
											num45 = num14 - torg.x;
											num46 = num15 - torg.y;
										}
									}
									else
									{
										num45 = p4[2] - torg.x;
										num46 = p4[3] - torg.y;
									}
								}
								else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, point5.x, point5.y))
								{
									num45 = num26;
									num46 = num27;
								}
								else
								{
									num45 = p2[2] - torg.x;
									num46 = p2[3] - torg.y;
								}
							}
							else
							{
								PointBetweenPoints(num65, num66, point.x, point.y, num14, num15, ref p4);
								if (Mathf.Abs(p4[0] - 1f) <= 0f && (double)p3[0] > 0.0)
								{
									if ((point2.x - num57) * (point2.x - num57) + (point2.y - num58) * (point2.y - num58) > num9 * ((point2.x - num14) * (point2.x - num14) + (point2.y - num15) * (point2.y - num15)) && IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num57, num58) && MinDistanceToNeighbor(num57, num58, ref neighotri) > MinDistanceToNeighbor(num14, num15, ref neighotri))
									{
										num45 = num57 - torg.x;
										num46 = num58 - torg.y;
									}
									else if (IsBadTriangleAngle(point4.x, point4.y, point3.x, point3.y, num14, num15))
									{
										float num67 = Mathf.Sqrt((num14 - point.x) * (num14 - point.x) + (num15 - point.y) * (num15 - point.y));
										float num68 = point.x - num14;
										float num69 = point.y - num15;
										num68 /= num67;
										num69 /= num67;
										num14 += num68 * num8 * Mathf.Sqrt(num3);
										num15 += num69 * num8 * Mathf.Sqrt(num3);
										if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15))
										{
											num45 = num26;
											num46 = num27;
										}
										else
										{
											num45 = num14 - torg.x;
											num46 = num15 - torg.y;
										}
									}
									else
									{
										num45 = p4[2] - torg.x;
										num46 = p4[3] - torg.y;
									}
								}
								else if (IsBadTriangleAngle(point4.x, point4.y, point3.x, point3.y, num65, num66))
								{
									float num67 = Mathf.Sqrt((num65 - point.x) * (num65 - point.x) + (num66 - point.y) * (num66 - point.y));
									float num68 = point.x - num65;
									float num69 = point.y - num66;
									num68 /= num67;
									num69 /= num67;
									num65 += num68 * num8 * Mathf.Sqrt(num3);
									num66 += num69 * num8 * Mathf.Sqrt(num3);
									if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num65, num66))
									{
										num45 = num26;
										num46 = num27;
									}
									else
									{
										num45 = num65 - torg.x;
										num46 = num66 - torg.y;
									}
								}
								else
								{
									num45 = num65 - torg.x;
									num46 = num66 - torg.y;
								}
							}
							if ((point2.x - point.x) * (point2.x - point.x) + (point2.y - point.y) * (point2.y - point.y) > num9 * ((point2.x - (num45 + torg.x)) * (point2.x - (num45 + torg.x)) + (point2.y - (num46 + torg.y)) * (point2.y - (num46 + torg.y))))
							{
								num45 = num26;
								num46 = num27;
							}
						}
					}
					bool neighborsVertex2 = GetNeighborsVertex(badotri, point4.x, point4.y, point2.x, point2.y, ref thirdpoint, ref neighotri);
					float num70 = num26;
					float num71 = num27;
					float num72 = (point4.x + point2.x) / 2f;
					float num73 = (point4.y + point2.y) / 2f;
					if (!neighborsVertex2)
					{
						TriangleNet.Geometry.Vertex org = neighotri.Org();
						TriangleNet.Geometry.Vertex dest = neighotri.Dest();
						TriangleNet.Geometry.Vertex apex = neighotri.Apex();
						Point point5 = predicates.FindCircumcenter(org, dest, apex, ref xi2, ref eta2);
						float num63 = point4.y - point2.y;
						float num64 = point2.x - point4.x;
						num63 = point.x + num63;
						num64 = point.y + num64;
						CircleLineIntersection(point.x, point.y, num63, num64, num43, num44, num32, ref p);
						float num65;
						float num66;
						if (ChooseCorrectPoint(num72, num73, p[3], p[4], point.x, point.y, isObtuse: false))
						{
							num65 = p[3];
							num66 = p[4];
						}
						else
						{
							num65 = p[1];
							num66 = p[2];
						}
						float x = point4.x;
						float y = point4.y;
						num48 = point3.x - point4.x;
						num49 = point3.y - point4.y;
						float x2 = num59;
						float y2 = num60;
						LineLineIntersection(point.x, point.y, num63, num64, x, y, x2, y2, ref p3);
						if (p3[0] > 0f)
						{
							num14 = p3[1];
							num15 = p3[2];
						}
						PointBetweenPoints(num65, num66, point.x, point.y, point5.x, point5.y, ref p2);
						if (p[0] > 0f)
						{
							if (Mathf.Abs(p2[0] - 1f) <= 0f)
							{
								PointBetweenPoints(p2[2], p2[3], point.x, point.y, num14, num15, ref p4);
								if (Mathf.Abs(p4[0] - 1f) <= 0f && (double)p3[0] > 0.0)
								{
									if ((point2.x - num59) * (point2.x - num59) + (point2.y - num60) * (point2.y - num60) > num9 * ((point2.x - num14) * (point2.x - num14) + (point2.y - num15) * (point2.y - num15)) && IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num59, num60) && MinDistanceToNeighbor(num59, num60, ref neighotri) > MinDistanceToNeighbor(num14, num15, ref neighotri))
									{
										num70 = num59 - torg.x;
										num71 = num60 - torg.y;
									}
									else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15))
									{
										float num67 = Mathf.Sqrt((num14 - point.x) * (num14 - point.x) + (num15 - point.y) * (num15 - point.y));
										float num68 = point.x - num14;
										float num69 = point.y - num15;
										num68 /= num67;
										num69 /= num67;
										num14 += num68 * num8 * Mathf.Sqrt(num3);
										num15 += num69 * num8 * Mathf.Sqrt(num3);
										if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15))
										{
											num70 = num26;
											num71 = num27;
										}
										else
										{
											num70 = num14 - torg.x;
											num71 = num15 - torg.y;
										}
									}
									else
									{
										num70 = p4[2] - torg.x;
										num71 = p4[3] - torg.y;
									}
								}
								else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, point5.x, point5.y))
								{
									num70 = num26;
									num71 = num27;
								}
								else
								{
									num70 = p2[2] - torg.x;
									num71 = p2[3] - torg.y;
								}
							}
							else
							{
								PointBetweenPoints(num65, num66, point.x, point.y, num14, num15, ref p4);
								if (Mathf.Abs(p4[0] - 1f) <= 0f && (double)p3[0] > 0.0)
								{
									if ((point2.x - num59) * (point2.x - num59) + (point2.y - num60) * (point2.y - num60) > num9 * ((point2.x - num14) * (point2.x - num14) + (point2.y - num15) * (point2.y - num15)) && IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num59, num60) && MinDistanceToNeighbor(num59, num60, ref neighotri) > MinDistanceToNeighbor(num14, num15, ref neighotri))
									{
										num70 = num59 - torg.x;
										num71 = num60 - torg.y;
									}
									else if (IsBadTriangleAngle(point4.x, point4.y, point3.x, point3.y, num14, num15))
									{
										float num67 = Mathf.Sqrt((num14 - point.x) * (num14 - point.x) + (num15 - point.y) * (num15 - point.y));
										float num68 = point.x - num14;
										float num69 = point.y - num15;
										num68 /= num67;
										num69 /= num67;
										num14 += num68 * num8 * Mathf.Sqrt(num3);
										num15 += num69 * num8 * Mathf.Sqrt(num3);
										if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num14, num15))
										{
											num70 = num26;
											num71 = num27;
										}
										else
										{
											num70 = num14 - torg.x;
											num71 = num15 - torg.y;
										}
									}
									else
									{
										num70 = p4[2] - torg.x;
										num71 = p4[3] - torg.y;
									}
								}
								else if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num65, num66))
								{
									float num67 = Mathf.Sqrt((num65 - point.x) * (num65 - point.x) + (num66 - point.y) * (num66 - point.y));
									float num68 = point.x - num65;
									float num69 = point.y - num66;
									num68 /= num67;
									num69 /= num67;
									num65 += num68 * num8 * Mathf.Sqrt(num3);
									num66 += num69 * num8 * Mathf.Sqrt(num3);
									if (IsBadTriangleAngle(point3.x, point3.y, point4.x, point4.y, num65, num66))
									{
										num70 = num26;
										num71 = num27;
									}
									else
									{
										num70 = num65 - torg.x;
										num71 = num66 - torg.y;
									}
								}
								else
								{
									num70 = num65 - torg.x;
									num71 = num66 - torg.y;
								}
							}
							if ((point2.x - point.x) * (point2.x - point.x) + (point2.y - point.y) * (point2.y - point.y) > num9 * ((point2.x - (num70 + torg.x)) * (point2.x - (num70 + torg.x)) + (point2.y - (num71 + torg.y)) * (point2.y - (num71 + torg.y))))
							{
								num70 = num26;
								num71 = num27;
							}
						}
					}
					if (flag)
					{
						if (neighborsVertex && neighborsVertex2)
						{
							if (num10 * ((point2.x - num72) * (point2.x - num72) + (point2.y - num73) * (point2.y - num73)) > (point2.x - num61) * (point2.x - num61) + (point2.y - num62) * (point2.y - num62))
							{
								num26 = num70;
								num27 = num71;
							}
							else
							{
								num26 = num45;
								num27 = num46;
							}
						}
						else if (neighborsVertex)
						{
							if (num10 * ((point2.x - (num70 + torg.x)) * (point2.x - (num70 + torg.x)) + (point2.y - (num71 + torg.y)) * (point2.y - (num71 + torg.y))) > (point2.x - num61) * (point2.x - num61) + (point2.y - num62) * (point2.y - num62))
							{
								num26 = num70;
								num27 = num71;
							}
							else
							{
								num26 = num45;
								num27 = num46;
							}
						}
						else if (neighborsVertex2)
						{
							if (num10 * ((point2.x - num72) * (point2.x - num72) + (point2.y - num73) * (point2.y - num73)) > (point2.x - (num45 + torg.x)) * (point2.x - (num45 + torg.x)) + (point2.y - (num46 + torg.y)) * (point2.y - (num46 + torg.y)))
							{
								num26 = num70;
								num27 = num71;
							}
							else
							{
								num26 = num45;
								num27 = num46;
							}
						}
						else if (num10 * ((point2.x - (num70 + torg.x)) * (point2.x - (num70 + torg.x)) + (point2.y - (num71 + torg.y)) * (point2.y - (num71 + torg.y))) > (point2.x - (num45 + torg.x)) * (point2.x - (num45 + torg.x)) + (point2.y - (num46 + torg.y)) * (point2.y - (num46 + torg.y)))
						{
							num26 = num70;
							num27 = num71;
						}
						else
						{
							num26 = num45;
							num27 = num46;
						}
					}
					else if (neighborsVertex && neighborsVertex2)
					{
						if (num10 * ((point2.x - num72) * (point2.x - num72) + (point2.y - num73) * (point2.y - num73)) > (point2.x - num61) * (point2.x - num61) + (point2.y - num62) * (point2.y - num62))
						{
							num26 = num70;
							num27 = num71;
						}
						else
						{
							num26 = num45;
							num27 = num46;
						}
					}
					else if (neighborsVertex)
					{
						if (num10 * ((point2.x - (num70 + torg.x)) * (point2.x - (num70 + torg.x)) + (point2.y - (num71 + torg.y)) * (point2.y - (num71 + torg.y))) > (point2.x - num61) * (point2.x - num61) + (point2.y - num62) * (point2.y - num62))
						{
							num26 = num70;
							num27 = num71;
						}
						else
						{
							num26 = num45;
							num27 = num46;
						}
					}
					else if (neighborsVertex2)
					{
						if (num10 * ((point2.x - num72) * (point2.x - num72) + (point2.y - num73) * (point2.y - num73)) > (point2.x - (num45 + torg.x)) * (point2.x - (num45 + torg.x)) + (point2.y - (num46 + torg.y)) * (point2.y - (num46 + torg.y)))
						{
							num26 = num70;
							num27 = num71;
						}
						else
						{
							num26 = num45;
							num27 = num46;
						}
					}
					else if (num10 * ((point2.x - (num70 + torg.x)) * (point2.x - (num70 + torg.x)) + (point2.y - (num71 + torg.y)) * (point2.y - (num71 + torg.y))) > (point2.x - (num45 + torg.x)) * (point2.x - (num45 + torg.x)) + (point2.y - (num46 + torg.y)) * (point2.y - (num46 + torg.y)))
					{
						num26 = num70;
						num27 = num71;
					}
					else
					{
						num26 = num45;
						num27 = num46;
					}
				}
			}
			Point point6 = new Point();
			if (num11 <= 0)
			{
				point6.x = torg.x + num26;
				point6.y = torg.y + num27;
			}
			else
			{
				point6.x = num12 + num26;
				point6.y = num13 + num27;
			}
			xi = (num19 * num26 - num18 * num27) * (2f * num25);
			eta = (num16 * num27 - num17 * num26) * (2f * num25);
			return point6;
		}

		private int LongestShortestEdge(float aodist, float dadist, float dodist)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			if (dodist < aodist && dodist < dadist)
			{
				num2 = 3;
				if (aodist < dadist)
				{
					num = 2;
					num3 = 1;
				}
				else
				{
					num = 1;
					num3 = 2;
				}
			}
			else if (aodist < dadist)
			{
				num2 = 1;
				if (dodist < dadist)
				{
					num = 2;
					num3 = 3;
				}
				else
				{
					num = 3;
					num3 = 2;
				}
			}
			else
			{
				num2 = 2;
				if (aodist < dodist)
				{
					num = 3;
					num3 = 1;
				}
				else
				{
					num = 1;
					num3 = 3;
				}
			}
			return num2 * 100 + num3 * 10 + num;
		}

		private int DoSmoothing(Otri badotri, TriangleNet.Geometry.Vertex torg, TriangleNet.Geometry.Vertex tdest, TriangleNet.Geometry.Vertex tapex, ref float[] newloc)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			float[] array = new float[6];
			int num4 = 0;
			int num5 = 0;
			int num6 = 0;
			int num7 = 0;
			bool flag = false;
			num = GetStarPoints(badotri, torg, tdest, tapex, 1, ref points_p);
			if (torg.type == VertexType.FreeVertex && num != 0 && ValidPolygonAngles(num, points_p) && ((behavior.MaxAngle != 0f) ? GetWedgeIntersection(num, points_p, ref newloc) : GetWedgeIntersectionWithoutMaxAngle(num, points_p, ref newloc)))
			{
				array[0] = newloc[0];
				array[1] = newloc[1];
				num4++;
				num5 = 1;
			}
			num2 = GetStarPoints(badotri, torg, tdest, tapex, 2, ref points_q);
			if (tdest.type == VertexType.FreeVertex && num2 != 0 && ValidPolygonAngles(num2, points_q) && ((behavior.MaxAngle != 0f) ? GetWedgeIntersection(num2, points_q, ref newloc) : GetWedgeIntersectionWithoutMaxAngle(num2, points_q, ref newloc)))
			{
				array[2] = newloc[0];
				array[3] = newloc[1];
				num4++;
				num6 = 2;
			}
			num3 = GetStarPoints(badotri, torg, tdest, tapex, 3, ref points_r);
			if (tapex.type == VertexType.FreeVertex && num3 != 0 && ValidPolygonAngles(num3, points_r) && ((behavior.MaxAngle != 0f) ? GetWedgeIntersection(num3, points_r, ref newloc) : GetWedgeIntersectionWithoutMaxAngle(num3, points_r, ref newloc)))
			{
				array[4] = newloc[0];
				array[5] = newloc[1];
				num4++;
				num7 = 3;
			}
			if (num4 > 0)
			{
				if (num5 > 0)
				{
					newloc[0] = array[0];
					newloc[1] = array[1];
					return num5;
				}
				if (num6 > 0)
				{
					newloc[0] = array[2];
					newloc[1] = array[3];
					return num6;
				}
				if (num7 > 0)
				{
					newloc[0] = array[4];
					newloc[1] = array[5];
					return num7;
				}
			}
			return 0;
		}

		private int GetStarPoints(Otri badotri, TriangleNet.Geometry.Vertex p, TriangleNet.Geometry.Vertex q, TriangleNet.Geometry.Vertex r, int whichPoint, ref float[] points)
		{
			Otri neighotri = default(Otri);
			float first_x = 0f;
			float first_y = 0f;
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			float[] thirdpoint = new float[2];
			int num5 = 0;
			switch (whichPoint)
			{
			case 1:
				first_x = p.x;
				first_y = p.y;
				num = r.x;
				num2 = r.y;
				num3 = q.x;
				num4 = q.y;
				break;
			case 2:
				first_x = q.x;
				first_y = q.y;
				num = p.x;
				num2 = p.y;
				num3 = r.x;
				num4 = r.y;
				break;
			case 3:
				first_x = r.x;
				first_y = r.y;
				num = q.x;
				num2 = q.y;
				num3 = p.x;
				num4 = p.y;
				break;
			}
			Otri badotri2 = badotri;
			points[num5] = num;
			num5++;
			points[num5] = num2;
			num5++;
			thirdpoint[0] = num;
			thirdpoint[1] = num2;
			do
			{
				if (!GetNeighborsVertex(badotri2, first_x, first_y, num, num2, ref thirdpoint, ref neighotri))
				{
					badotri2 = neighotri;
					num = thirdpoint[0];
					num2 = thirdpoint[1];
					points[num5] = thirdpoint[0];
					num5++;
					points[num5] = thirdpoint[1];
					num5++;
					continue;
				}
				num5 = 0;
				break;
			}
			while (!(Mathf.Abs(thirdpoint[0] - num3) <= 0f) || !(Mathf.Abs(thirdpoint[1] - num4) <= 0f));
			return num5 / 2;
		}

		private bool GetNeighborsVertex(Otri badotri, float first_x, float first_y, float second_x, float second_y, ref float[] thirdpoint, ref Otri neighotri)
		{
			Otri ot = default(Otri);
			bool result = false;
			TriangleNet.Geometry.Vertex vertex = null;
			TriangleNet.Geometry.Vertex vertex2 = null;
			TriangleNet.Geometry.Vertex vertex3 = null;
			int num = 0;
			int num2 = 0;
			badotri.orient = 0;
			while (badotri.orient < 3)
			{
				badotri.Sym(ref ot);
				if (ot.tri.id != -1)
				{
					vertex = ot.Org();
					vertex2 = ot.Dest();
					vertex3 = ot.Apex();
					if ((vertex.x != vertex2.x || vertex.y != vertex2.y) && (vertex2.x != vertex3.x || vertex2.y != vertex3.y) && (vertex.x != vertex3.x || vertex.y != vertex3.y))
					{
						num = 0;
						if (Mathf.Abs(first_x - vertex.x) < 0f && Mathf.Abs(first_y - vertex.y) < 0f)
						{
							num = 11;
						}
						else if (Mathf.Abs(first_x - vertex2.x) < 0f && Mathf.Abs(first_y - vertex2.y) < 0f)
						{
							num = 12;
						}
						else if (Mathf.Abs(first_x - vertex3.x) < 0f && Mathf.Abs(first_y - vertex3.y) < 0f)
						{
							num = 13;
						}
						num2 = 0;
						if (Mathf.Abs(second_x - vertex.x) < 0f && Mathf.Abs(second_y - vertex.y) < 0f)
						{
							num2 = 21;
						}
						else if (Mathf.Abs(second_x - vertex2.x) < 0f && Mathf.Abs(second_y - vertex2.y) < 0f)
						{
							num2 = 22;
						}
						else if (Mathf.Abs(second_x - vertex3.x) < 0f && Mathf.Abs(second_y - vertex3.y) < 0f)
						{
							num2 = 23;
						}
					}
				}
				if ((num == 11 && (num2 == 22 || num2 == 23)) || (num == 12 && (num2 == 21 || num2 == 23)) || (num == 13 && (num2 == 21 || num2 == 22)))
				{
					break;
				}
				badotri.orient++;
			}
			switch (num)
			{
			case 0:
				result = true;
				break;
			case 11:
				switch (num2)
				{
				case 22:
					thirdpoint[0] = vertex3.x;
					thirdpoint[1] = vertex3.y;
					break;
				case 23:
					thirdpoint[0] = vertex2.x;
					thirdpoint[1] = vertex2.y;
					break;
				default:
					result = true;
					break;
				}
				break;
			case 12:
				switch (num2)
				{
				case 21:
					thirdpoint[0] = vertex3.x;
					thirdpoint[1] = vertex3.y;
					break;
				case 23:
					thirdpoint[0] = vertex.x;
					thirdpoint[1] = vertex.y;
					break;
				default:
					result = true;
					break;
				}
				break;
			case 13:
				switch (num2)
				{
				case 21:
					thirdpoint[0] = vertex2.x;
					thirdpoint[1] = vertex2.y;
					break;
				case 22:
					thirdpoint[0] = vertex.x;
					thirdpoint[1] = vertex.y;
					break;
				default:
					result = true;
					break;
				}
				break;
			default:
				if (num2 == 0)
				{
					result = true;
				}
				break;
			}
			neighotri = ot;
			return result;
		}

		private bool GetWedgeIntersectionWithoutMaxAngle(int numpoints, float[] points, ref float[] newloc)
		{
			if (2 * numpoints > petalx.Length)
			{
				petalx = new float[2 * numpoints];
				petaly = new float[2 * numpoints];
				petalr = new float[2 * numpoints];
				wedges = new float[2 * numpoints * 16 + 36];
			}
			float[] p = new float[3];
			int num = 0;
			float num2 = points[2 * numpoints - 4];
			float num3 = points[2 * numpoints - 3];
			float num4 = points[2 * numpoints - 2];
			float num5 = points[2 * numpoints - 1];
			float num6 = behavior.MinAngle * MathF.PI / 180f;
			float num7;
			float num8;
			if (behavior.goodAngle == 1f)
			{
				num7 = 0f;
				num8 = 0f;
			}
			else
			{
				num7 = 0.5f / Mathf.Tan(num6);
				num8 = 0.5f / Mathf.Sin(num6);
			}
			for (int i = 0; i < numpoints * 2; i += 2)
			{
				float num9 = points[i];
				float num10 = points[i + 1];
				float num11 = num4 - num2;
				float num12 = num5 - num3;
				float num13 = Mathf.Sqrt(num11 * num11 + num12 * num12);
				petalx[i / 2] = num2 + 0.5f * num11 - num7 * num12;
				petaly[i / 2] = num3 + 0.5f * num12 + num7 * num11;
				petalr[i / 2] = num8 * num13;
				petalx[numpoints + i / 2] = petalx[i / 2];
				petaly[numpoints + i / 2] = petaly[i / 2];
				petalr[numpoints + i / 2] = petalr[i / 2];
				float num14 = (num2 + num4) / 2f;
				float num15 = (num3 + num5) / 2f;
				float num16 = Mathf.Sqrt((petalx[i / 2] - num14) * (petalx[i / 2] - num14) + (petaly[i / 2] - num15) * (petaly[i / 2] - num15));
				float num17 = (petalx[i / 2] - num14) / num16;
				float num18 = (petaly[i / 2] - num15) / num16;
				float num19 = petalx[i / 2] + num17 * petalr[i / 2];
				float num20 = petaly[i / 2] + num18 * petalr[i / 2];
				num17 = num4 - num2;
				num18 = num5 - num3;
				float num21 = num4 * Mathf.Cos(num6) - num5 * Mathf.Sin(num6) + num2 - num2 * Mathf.Cos(num6) + num3 * Mathf.Sin(num6);
				float num22 = num4 * Mathf.Sin(num6) + num5 * Mathf.Cos(num6) + num3 - num2 * Mathf.Sin(num6) - num3 * Mathf.Cos(num6);
				wedges[i * 16] = num2;
				wedges[i * 16 + 1] = num3;
				wedges[i * 16 + 2] = num21;
				wedges[i * 16 + 3] = num22;
				num17 = num2 - num4;
				num18 = num3 - num5;
				float num23 = num2 * Mathf.Cos(num6) + num3 * Mathf.Sin(num6) + num4 - num4 * Mathf.Cos(num6) - num5 * Mathf.Sin(num6);
				float num24 = (0f - num2) * Mathf.Sin(num6) + num3 * Mathf.Cos(num6) + num5 + num4 * Mathf.Sin(num6) - num5 * Mathf.Cos(num6);
				wedges[i * 16 + 4] = num23;
				wedges[i * 16 + 5] = num24;
				wedges[i * 16 + 6] = num4;
				wedges[i * 16 + 7] = num5;
				num17 = num19 - petalx[i / 2];
				num18 = num20 - petaly[i / 2];
				float num25 = num19;
				float num26 = num20;
				for (int j = 1; j < 4; j++)
				{
					float num27 = num19 * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) + num20 * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) + petalx[i / 2] - petalx[i / 2] * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) - petaly[i / 2] * Mathf.Sin((MathF.PI / 3f - num6) * (float)j);
					float num28 = (0f - num19) * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) + num20 * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) + petaly[i / 2] + petalx[i / 2] * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) - petaly[i / 2] * Mathf.Cos((MathF.PI / 3f - num6) * (float)j);
					wedges[i * 16 + 8 + 4 * (j - 1)] = num27;
					wedges[i * 16 + 9 + 4 * (j - 1)] = num28;
					wedges[i * 16 + 10 + 4 * (j - 1)] = num25;
					wedges[i * 16 + 11 + 4 * (j - 1)] = num26;
					num25 = num27;
					num26 = num28;
				}
				num25 = num19;
				num26 = num20;
				for (int j = 1; j < 4; j++)
				{
					float num29 = num19 * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) - num20 * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) + petalx[i / 2] - petalx[i / 2] * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) + petaly[i / 2] * Mathf.Sin((MathF.PI / 3f - num6) * (float)j);
					float num30 = num19 * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) + num20 * Mathf.Cos((MathF.PI / 3f - num6) * (float)j) + petaly[i / 2] - petalx[i / 2] * Mathf.Sin((MathF.PI / 3f - num6) * (float)j) - petaly[i / 2] * Mathf.Cos((MathF.PI / 3f - num6) * (float)j);
					wedges[i * 16 + 20 + 4 * (j - 1)] = num25;
					wedges[i * 16 + 21 + 4 * (j - 1)] = num26;
					wedges[i * 16 + 22 + 4 * (j - 1)] = num29;
					wedges[i * 16 + 23 + 4 * (j - 1)] = num30;
					num25 = num29;
					num26 = num30;
				}
				if (i == 0)
				{
					LineLineIntersection(num2, num3, num21, num22, num4, num5, num23, num24, ref p);
					if (p[0] == 1f)
					{
						initialConvexPoly[0] = p[1];
						initialConvexPoly[1] = p[2];
						initialConvexPoly[2] = wedges[i * 16 + 16];
						initialConvexPoly[3] = wedges[i * 16 + 17];
						initialConvexPoly[4] = wedges[i * 16 + 12];
						initialConvexPoly[5] = wedges[i * 16 + 13];
						initialConvexPoly[6] = wedges[i * 16 + 8];
						initialConvexPoly[7] = wedges[i * 16 + 9];
						initialConvexPoly[8] = num19;
						initialConvexPoly[9] = num20;
						initialConvexPoly[10] = wedges[i * 16 + 22];
						initialConvexPoly[11] = wedges[i * 16 + 23];
						initialConvexPoly[12] = wedges[i * 16 + 26];
						initialConvexPoly[13] = wedges[i * 16 + 27];
						initialConvexPoly[14] = wedges[i * 16 + 30];
						initialConvexPoly[15] = wedges[i * 16 + 31];
					}
				}
				num2 = num4;
				num3 = num5;
				num4 = num9;
				num5 = num10;
			}
			if (numpoints != 0)
			{
				int num31 = (numpoints - 1) / 2 + 1;
				int num32 = 0;
				int num33 = 0;
				int i = 1;
				int numvertices = 8;
				for (int j = 0; j < 32; j += 4)
				{
					num = HalfPlaneIntersection(numvertices, ref initialConvexPoly, wedges[32 * num31 + j], wedges[32 * num31 + 1 + j], wedges[32 * num31 + 2 + j], wedges[32 * num31 + 3 + j]);
					if (num == 0)
					{
						return false;
					}
					numvertices = num;
				}
				for (num33++; num33 < numpoints - 1; num33++)
				{
					for (int j = 0; j < 32; j += 4)
					{
						num = HalfPlaneIntersection(numvertices, ref initialConvexPoly, wedges[32 * (i + num31 * num32) + j], wedges[32 * (i + num31 * num32) + 1 + j], wedges[32 * (i + num31 * num32) + 2 + j], wedges[32 * (i + num31 * num32) + 3 + j]);
						if (num == 0)
						{
							return false;
						}
						numvertices = num;
					}
					i += num32;
					num32 = (num32 + 1) % 2;
				}
				FindPolyCentroid(num, initialConvexPoly, ref newloc);
				if (!behavior.fixedArea)
				{
					return true;
				}
			}
			return false;
		}

		private bool GetWedgeIntersection(int numpoints, float[] points, ref float[] newloc)
		{
			if (2 * numpoints > petalx.Length)
			{
				petalx = new float[2 * numpoints];
				petaly = new float[2 * numpoints];
				petalr = new float[2 * numpoints];
				wedges = new float[2 * numpoints * 20 + 40];
			}
			float[] p = new float[3];
			float[] p2 = new float[3];
			float[] p3 = new float[3];
			float[] p4 = new float[3];
			int num = 0;
			int num2 = 0;
			float num3 = 4f;
			float num4 = 4f;
			float num5 = points[2 * numpoints - 4];
			float num6 = points[2 * numpoints - 3];
			float num7 = points[2 * numpoints - 2];
			float num8 = points[2 * numpoints - 1];
			float num9 = behavior.MinAngle * MathF.PI / 180f;
			float num10 = Mathf.Sin(num9);
			float num11 = Mathf.Cos(num9);
			float num12 = behavior.MaxAngle * MathF.PI / 180f;
			float num13 = Mathf.Sin(num12);
			float num14 = Mathf.Cos(num12);
			float num15;
			float num16;
			if ((double)behavior.goodAngle == 1.0)
			{
				num15 = 0f;
				num16 = 0f;
			}
			else
			{
				num15 = 0.5f / Mathf.Tan(num9);
				num16 = 0.5f / Mathf.Sin(num9);
			}
			for (int i = 0; i < numpoints * 2; i += 2)
			{
				float num17 = points[i];
				float num18 = points[i + 1];
				float num19 = num7 - num5;
				float num20 = num8 - num6;
				float num21 = Mathf.Sqrt(num19 * num19 + num20 * num20);
				petalx[i / 2] = num5 + 0.5f * num19 - num15 * num20;
				petaly[i / 2] = num6 + 0.5f * num20 + num15 * num19;
				petalr[i / 2] = num16 * num21;
				petalx[numpoints + i / 2] = petalx[i / 2];
				petaly[numpoints + i / 2] = petaly[i / 2];
				petalr[numpoints + i / 2] = petalr[i / 2];
				float num22 = (num5 + num7) / 2f;
				float num23 = (num6 + num8) / 2f;
				float num24 = Mathf.Sqrt((petalx[i / 2] - num22) * (petalx[i / 2] - num22) + (petaly[i / 2] - num23) * (petaly[i / 2] - num23));
				float num25 = (petalx[i / 2] - num22) / num24;
				float num26 = (petaly[i / 2] - num23) / num24;
				float num27 = petalx[i / 2] + num25 * petalr[i / 2];
				float num28 = petaly[i / 2] + num26 * petalr[i / 2];
				num25 = num7 - num5;
				num26 = num8 - num6;
				float num29 = num7 * num11 - num8 * num10 + num5 - num5 * num11 + num6 * num10;
				float num30 = num7 * num10 + num8 * num11 + num6 - num5 * num10 - num6 * num11;
				wedges[i * 20] = num5;
				wedges[i * 20 + 1] = num6;
				wedges[i * 20 + 2] = num29;
				wedges[i * 20 + 3] = num30;
				num25 = num5 - num7;
				num26 = num6 - num8;
				float num31 = num5 * num11 + num6 * num10 + num7 - num7 * num11 - num8 * num10;
				float num32 = (0f - num5) * num10 + num6 * num11 + num8 + num7 * num10 - num8 * num11;
				wedges[i * 20 + 4] = num31;
				wedges[i * 20 + 5] = num32;
				wedges[i * 20 + 6] = num7;
				wedges[i * 20 + 7] = num8;
				num25 = num27 - petalx[i / 2];
				num26 = num28 - petaly[i / 2];
				float num33 = num27;
				float num34 = num28;
				num9 = 2f * behavior.MaxAngle + behavior.MinAngle - 180f;
				if (num9 <= 0f)
				{
					num2 = 4;
					num3 = 1f;
					num4 = 1f;
				}
				else if (num9 <= 5f)
				{
					num2 = 6;
					num3 = 2f;
					num4 = 2f;
				}
				else if (num9 <= 10f)
				{
					num2 = 8;
					num3 = 3f;
					num4 = 3f;
				}
				else
				{
					num2 = 10;
					num3 = 4f;
					num4 = 4f;
				}
				num9 = num9 * MathF.PI / 180f;
				for (int j = 1; (float)j < num3; j++)
				{
					if (num3 != 1f)
					{
						float num35 = num27 * Mathf.Cos(num9 / (num3 - 1f) * (float)j) + num28 * Mathf.Sin(num9 / (num3 - 1f) * (float)j) + petalx[i / 2] - petalx[i / 2] * Mathf.Cos(num9 / (num3 - 1f) * (float)j) - petaly[i / 2] * Mathf.Sin(num9 / (num3 - 1f) * (float)j);
						float num36 = (0f - num27) * Mathf.Sin(num9 / (num3 - 1f) * (float)j) + num28 * Mathf.Cos(num9 / (num3 - 1f) * (float)j) + petaly[i / 2] + petalx[i / 2] * Mathf.Sin(num9 / (num3 - 1f) * (float)j) - petaly[i / 2] * Mathf.Cos(num9 / (num3 - 1f) * (float)j);
						wedges[i * 20 + 8 + 4 * (j - 1)] = num35;
						wedges[i * 20 + 9 + 4 * (j - 1)] = num36;
						wedges[i * 20 + 10 + 4 * (j - 1)] = num33;
						wedges[i * 20 + 11 + 4 * (j - 1)] = num34;
						num33 = num35;
						num34 = num36;
					}
				}
				num25 = num5 - num7;
				num26 = num6 - num8;
				float num37 = num5 * num14 + num6 * num13 + num7 - num7 * num14 - num8 * num13;
				float num38 = (0f - num5) * num13 + num6 * num14 + num8 + num7 * num13 - num8 * num14;
				wedges[i * 20 + 20] = num7;
				wedges[i * 20 + 21] = num8;
				wedges[i * 20 + 22] = num37;
				wedges[i * 20 + 23] = num38;
				num33 = num27;
				num34 = num28;
				for (int j = 1; (float)j < num4; j++)
				{
					if (num4 != 1f)
					{
						float num39 = num27 * Mathf.Cos(num9 / (num4 - 1f) * (float)j) - num28 * Mathf.Sin(num9 / (num4 - 1f) * (float)j) + petalx[i / 2] - petalx[i / 2] * Mathf.Cos(num9 / (num4 - 1f) * (float)j) + petaly[i / 2] * Mathf.Sin(num9 / (num4 - 1f) * (float)j);
						float num40 = num27 * Mathf.Sin(num9 / (num4 - 1f) * (float)j) + num28 * Mathf.Cos(num9 / (num4 - 1f) * (float)j) + petaly[i / 2] - petalx[i / 2] * Mathf.Sin(num9 / (num4 - 1f) * (float)j) - petaly[i / 2] * Mathf.Cos(num9 / (num4 - 1f) * (float)j);
						wedges[i * 20 + 24 + 4 * (j - 1)] = num33;
						wedges[i * 20 + 25 + 4 * (j - 1)] = num34;
						wedges[i * 20 + 26 + 4 * (j - 1)] = num39;
						wedges[i * 20 + 27 + 4 * (j - 1)] = num40;
						num33 = num39;
						num34 = num40;
					}
				}
				num25 = num7 - num5;
				num26 = num8 - num6;
				float num41 = num7 * num14 - num8 * num13 + num5 - num5 * num14 + num6 * num13;
				float num42 = num7 * num13 + num8 * num14 + num6 - num5 * num13 - num6 * num14;
				wedges[i * 20 + 36] = num41;
				wedges[i * 20 + 37] = num42;
				wedges[i * 20 + 38] = num5;
				wedges[i * 20 + 39] = num6;
				if (i == 0)
				{
					switch (num2)
					{
					case 4:
						LineLineIntersection(num5, num6, num29, num30, num7, num8, num31, num32, ref p);
						LineLineIntersection(num5, num6, num29, num30, num7, num8, num37, num38, ref p2);
						LineLineIntersection(num5, num6, num41, num42, num7, num8, num37, num38, ref p3);
						LineLineIntersection(num5, num6, num41, num42, num7, num8, num31, num32, ref p4);
						if (p[0] == 1f && p2[0] == 1f && p3[0] == 1f && p4[0] == 1f)
						{
							initialConvexPoly[0] = p[1];
							initialConvexPoly[1] = p[2];
							initialConvexPoly[2] = p2[1];
							initialConvexPoly[3] = p2[2];
							initialConvexPoly[4] = p3[1];
							initialConvexPoly[5] = p3[2];
							initialConvexPoly[6] = p4[1];
							initialConvexPoly[7] = p4[2];
						}
						break;
					case 6:
						LineLineIntersection(num5, num6, num29, num30, num7, num8, num31, num32, ref p);
						LineLineIntersection(num5, num6, num29, num30, num7, num8, num37, num38, ref p2);
						LineLineIntersection(num5, num6, num41, num42, num7, num8, num31, num32, ref p3);
						if (p[0] == 1f && p2[0] == 1f && p3[0] == 1f)
						{
							initialConvexPoly[0] = p[1];
							initialConvexPoly[1] = p[2];
							initialConvexPoly[2] = p2[1];
							initialConvexPoly[3] = p2[2];
							initialConvexPoly[4] = wedges[i * 20 + 8];
							initialConvexPoly[5] = wedges[i * 20 + 9];
							initialConvexPoly[6] = num27;
							initialConvexPoly[7] = num28;
							initialConvexPoly[8] = wedges[i * 20 + 26];
							initialConvexPoly[9] = wedges[i * 20 + 27];
							initialConvexPoly[10] = p3[1];
							initialConvexPoly[11] = p3[2];
						}
						break;
					case 8:
						LineLineIntersection(num5, num6, num29, num30, num7, num8, num31, num32, ref p);
						LineLineIntersection(num5, num6, num29, num30, num7, num8, num37, num38, ref p2);
						LineLineIntersection(num5, num6, num41, num42, num7, num8, num31, num32, ref p3);
						if (p[0] == 1f && p2[0] == 1f && p3[0] == 1f)
						{
							initialConvexPoly[0] = p[1];
							initialConvexPoly[1] = p[2];
							initialConvexPoly[2] = p2[1];
							initialConvexPoly[3] = p2[2];
							initialConvexPoly[4] = wedges[i * 20 + 12];
							initialConvexPoly[5] = wedges[i * 20 + 13];
							initialConvexPoly[6] = wedges[i * 20 + 8];
							initialConvexPoly[7] = wedges[i * 20 + 9];
							initialConvexPoly[8] = num27;
							initialConvexPoly[9] = num28;
							initialConvexPoly[10] = wedges[i * 20 + 26];
							initialConvexPoly[11] = wedges[i * 20 + 27];
							initialConvexPoly[12] = wedges[i * 20 + 30];
							initialConvexPoly[13] = wedges[i * 20 + 31];
							initialConvexPoly[14] = p3[1];
							initialConvexPoly[15] = p3[2];
						}
						break;
					case 10:
						LineLineIntersection(num5, num6, num29, num30, num7, num8, num31, num32, ref p);
						LineLineIntersection(num5, num6, num29, num30, num7, num8, num37, num38, ref p2);
						LineLineIntersection(num5, num6, num41, num42, num7, num8, num31, num32, ref p3);
						if (p[0] == 1f && p2[0] == 1f && p3[0] == 1f)
						{
							initialConvexPoly[0] = p[1];
							initialConvexPoly[1] = p[2];
							initialConvexPoly[2] = p2[1];
							initialConvexPoly[3] = p2[2];
							initialConvexPoly[4] = wedges[i * 20 + 16];
							initialConvexPoly[5] = wedges[i * 20 + 17];
							initialConvexPoly[6] = wedges[i * 20 + 12];
							initialConvexPoly[7] = wedges[i * 20 + 13];
							initialConvexPoly[8] = wedges[i * 20 + 8];
							initialConvexPoly[9] = wedges[i * 20 + 9];
							initialConvexPoly[10] = num27;
							initialConvexPoly[11] = num28;
							initialConvexPoly[12] = wedges[i * 20 + 28];
							initialConvexPoly[13] = wedges[i * 20 + 29];
							initialConvexPoly[14] = wedges[i * 20 + 32];
							initialConvexPoly[15] = wedges[i * 20 + 33];
							initialConvexPoly[16] = wedges[i * 20 + 34];
							initialConvexPoly[17] = wedges[i * 20 + 35];
							initialConvexPoly[18] = p3[1];
							initialConvexPoly[19] = p3[2];
						}
						break;
					}
				}
				num5 = num7;
				num6 = num8;
				num7 = num17;
				num8 = num18;
			}
			if (numpoints != 0)
			{
				int num43 = (numpoints - 1) / 2 + 1;
				int num44 = 0;
				int num45 = 0;
				int i = 1;
				int numvertices = num2;
				for (int j = 0; j < 40; j += 4)
				{
					if ((num2 != 4 || (j != 8 && j != 12 && j != 16 && j != 24 && j != 28 && j != 32)) && (num2 != 6 || (j != 12 && j != 16 && j != 28 && j != 32)) && (num2 != 8 || (j != 16 && j != 32)))
					{
						num = HalfPlaneIntersection(numvertices, ref initialConvexPoly, wedges[40 * num43 + j], wedges[40 * num43 + 1 + j], wedges[40 * num43 + 2 + j], wedges[40 * num43 + 3 + j]);
						if (num == 0)
						{
							return false;
						}
						numvertices = num;
					}
				}
				for (num45++; num45 < numpoints - 1; num45++)
				{
					for (int j = 0; j < 40; j += 4)
					{
						if ((num2 != 4 || (j != 8 && j != 12 && j != 16 && j != 24 && j != 28 && j != 32)) && (num2 != 6 || (j != 12 && j != 16 && j != 28 && j != 32)) && (num2 != 8 || (j != 16 && j != 32)))
						{
							num = HalfPlaneIntersection(numvertices, ref initialConvexPoly, wedges[40 * (i + num43 * num44) + j], wedges[40 * (i + num43 * num44) + 1 + j], wedges[40 * (i + num43 * num44) + 2 + j], wedges[40 * (i + num43 * num44) + 3 + j]);
							if (num == 0)
							{
								return false;
							}
							numvertices = num;
						}
					}
					i += num44;
					num44 = (num44 + 1) % 2;
				}
				FindPolyCentroid(num, initialConvexPoly, ref newloc);
				if ((double)behavior.MaxAngle == 0.0)
				{
					return true;
				}
				int num46 = 0;
				for (int j = 0; j < numpoints * 2 - 2; j += 2)
				{
					if (IsBadTriangleAngle(newloc[0], newloc[1], points[j], points[j + 1], points[j + 2], points[j + 3]))
					{
						num46++;
					}
				}
				if (IsBadTriangleAngle(newloc[0], newloc[1], points[0], points[1], points[numpoints * 2 - 2], points[numpoints * 2 - 1]))
				{
					num46++;
				}
				if (num46 == 0)
				{
					return true;
				}
				int num47 = ((numpoints <= 2) ? 20 : 30);
				for (int k = 0; k < 2 * numpoints; k += 2)
				{
					for (int l = 1; l < num47; l++)
					{
						newloc[0] = 0f;
						newloc[1] = 0f;
						for (i = 0; i < 2 * numpoints; i += 2)
						{
							float num48 = 1f / (float)numpoints;
							if (i == k)
							{
								newloc[0] = newloc[0] + 0.1f * (float)l * num48 * points[i];
								newloc[1] = newloc[1] + 0.1f * (float)l * num48 * points[i + 1];
							}
							else
							{
								num48 = (1f - 0.1f * (float)l * num48) / (float)((double)numpoints - 1.0);
								newloc[0] = newloc[0] + num48 * points[i];
								newloc[1] = newloc[1] + num48 * points[i + 1];
							}
						}
						num46 = 0;
						for (int j = 0; j < numpoints * 2 - 2; j += 2)
						{
							if (IsBadTriangleAngle(newloc[0], newloc[1], points[j], points[j + 1], points[j + 2], points[j + 3]))
							{
								num46++;
							}
						}
						if (IsBadTriangleAngle(newloc[0], newloc[1], points[0], points[1], points[numpoints * 2 - 2], points[numpoints * 2 - 1]))
						{
							num46++;
						}
						if (num46 == 0)
						{
							return true;
						}
					}
				}
			}
			return false;
		}

		private bool ValidPolygonAngles(int numpoints, float[] points)
		{
			for (int i = 0; i < numpoints; i++)
			{
				if (i == numpoints - 1)
				{
					if (IsBadPolygonAngle(points[i * 2], points[i * 2 + 1], points[0], points[1], points[2], points[3]))
					{
						return false;
					}
				}
				else if (i == numpoints - 2)
				{
					if (IsBadPolygonAngle(points[i * 2], points[i * 2 + 1], points[(i + 1) * 2], points[(i + 1) * 2 + 1], points[0], points[1]))
					{
						return false;
					}
				}
				else if (IsBadPolygonAngle(points[i * 2], points[