Decompiled source of HeavyarmsEW v0.13.29

BepInEx/plugins/HeavyarmsEW/HeavyarmsEW.Stage3Preview.dll

Decompiled 9 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using BepInEx;
using EntityStates;
using HG.BlendableTypes;
using HeavyarmsEW.Stage3Preview;
using KinematicCharacterController;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using Rewired;
using RoR2;
using RoR2.CameraModes;
using RoR2.CharacterAI;
using RoR2.ContentManagement;
using RoR2.Modding;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.UI;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ModAssemblyControllerType(typeof(Entry))]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HeavyarmsEW.Stage3Preview
{
	public static class Entry
	{
		public static void PreLaunch(Mod mod)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			string text = Path.Combine(Path.GetDirectoryName(Application.dataPath), "Mods", mod.identifier);
			GameObject val = new GameObject("HeavyarmsEW Stage3 original asset validation");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<Preview>().Initialize(text);
			Debug.Log((object)("[HeavyarmsEW.Stage3] PreLaunch entered: " + text));
		}
	}
	[Serializable]
	public class Settings
	{
		public string dataPath = "stage3_preview.bin";

		public string nativeMatrixPath;

		public string nativeControlPath;

		public string portablePosePath;

		public string portableClockPath;

		public string portableRelativeClockPath;

		public string portableUnifiedPath;

		public string portableDirectionPath;

		public string portableFullScenePath;

		public bool captureAllClips;

		public bool captureMaskPairOnly;

		public bool replayAllFrames;

		public string outputDirectory;

		public int imageSize = 1024;

		public float startupDelaySeconds = 8f;
	}
	[Serializable]
	public class MeshEvidence
	{
		public string name;

		public int vertices;

		public int indices;

		public int attributes;

		public int joints;

		public bool defaultVisible;
	}
	[Serializable]
	public class CaptureEvidence
	{
		public string animation;

		public float time;

		public float nativeFrame;

		public string file;

		public string vertexDump;

		public string directionDump;

		public bool maskVisible;

		public bool nativeFrameSpecified;

		public int vertices;

		public float[] bounds;
	}
	[Serializable]
	public class RuntimeEvidence
	{
		public string unityVersion;

		public string graphicsDevice;

		public string shader;

		public string payloadSHA256;

		public string previewAssemblySHA256;

		public string error;

		public int nodes;

		public int skins;

		public int skinJoints;

		public int meshes;

		public int vertices;

		public int indices;

		public int animations;

		public int textures;

		public bool entered;

		public bool assetLoaded;

		public bool cpuSkinningFinite;

		public bool renderReadbackCompleted;

		public bool stage3Complete;

		public bool nativeQuaternionExportDifferenceResolved;

		public bool originalShaderFidelityVerified;

		public bool sourceGameComparisonVerified;

		public bool continuousPartsMeshCompleted;

		public string continuousPartsScope;

		public bool portableFullSceneCompleted;

		public int portableFullSceneSteps;

		public int portableFullSceneScenarios;

		public string portableFullSceneInputSHA256;

		public bool portableMscTasksCompleted;

		public int portableMscTaskDriverSteps;

		public bool portableSceneMscCompleted;

		public int portableSceneMscCalls;

		public string portableSceneMscSHA256;

		public bool portableDirectionCompleted;

		public int portableDirectionCases;

		public string portableDirectionInputSHA256;

		public bool portableUnifiedCompleted;

		public int portableUnifiedSteps;

		public int portableUnifiedScenarios;

		public int portableUnifiedClockPoseSamples;

		public string portableUnifiedInputSHA256;

		public bool portableRelativeClockCompleted;

		public int portableRelativeClockSteps;

		public int portableRelativeClockScenarios;

		public string portableRelativeClockInputSHA256;

		public bool portableClockCompleted;

		public int portableClockEasingCases;

		public int portableClockPoolSteps;

		public int portableClockPoseSteps;

		public string portableClockInputSHA256;

		public string portableClockScope;

		public bool portablePoseSamplingCompleted;

		public bool portablePoseFinalConstraintOrMeshAcceptance;

		public int portablePoseCases;

		public int portablePoseClips;

		public string portablePoseInputSHA256;

		public string portablePoseScope;

		public bool nativeBodyMatrixSidecarLoaded;

		public string nativeBodyMatrixSHA256;

		public string nativeBodyMatrixScope = "Optional original body78 root-relative matrices at exact cached times; original root-to-actor schedule and child weapon pose export fidelity remain separate.";

		public string scope = "Existing corrected original GLB transported exactly. Original hierarchy, mesh attributes, skin weights, inverse binds, embedded PNGs and85baked clips are loaded. CPU matrix skinning renders in RoR2 Unity. Native-vs-export near-unit-Q difference, original shader equivalence, original scene scheduling and fullStage3 acceptance remain open.";

		public List<MeshEvidence> meshDetails = new List<MeshEvidence>();

		public List<CaptureEvidence> captures = new List<CaptureEvidence>();

		public string[] shaderProperties;

		public bool metallicRoughnessChannelsAdapted;

		public bool normalAndDataTexturesLinear;

		public bool previewLightingIsolated;

		public bool maskReferenceAdjacent;

		public int maximumOtherSceneLightsExcluded;

		public bool sequentialNativeFrameReplayCompleted;

		public bool meshVertexGetterReadbackUsed;

		public bool extraDirectionMeshGetterReadbackUsed;

		public string extraDirectionScope = "Original BINORMAL0/BINORMAL1/TANGENT1 stored as Vector3 in Unity UV channels4/5/6. Weighted linear CPU skin transform and handedness conversion preserve lengths; original shader consumption is not verified.";

		public int sequentialNativeFrameCount;

		public string sequentialReadbackFile;

		public string sequentialGPUReadbackFile;

		public int sequentialGPUImageSize;

		public bool controlledRootReplayCompleted;

		public int controlledRootTicks;

		public string controlledRootPayloadSHA256;

		public string controlledRootReadbackFile;

		public string controlledRootScope = "Native blended body/root input fixture; runtime root controller computes actor motion. Original gameplay event timing, portable pose blending, full scene/physics and child-local pose fidelity remain open.";

		public string sequentialScope = "Every cached original frame presented in sequence and actual Mesh.vertices read back. Animation-frame stepping is explicit; wall-clock60Hz, original action-trigger/blend/pause policies and full scene scheduling are not proved by sequential playback alone.";
	}
	internal class Node
	{
		public string name;

		public int parent;

		public Vector3 restT;

		public Vector3 restS;

		public Vector3 t;

		public Vector3 s;

		public Quaternion restQ;

		public Quaternion q;

		public Matrix4x4 world;
	}
	internal class Skin
	{
		public string name;

		public int[] joints;

		public Matrix4x4[] inverse;
	}
	internal class Track
	{
		public int node;

		public int path;

		public float[] times;

		public float[] values;

		public int width;
	}
	internal class Clip
	{
		public string name;

		public Track[] tracks;

		public float duration;
	}
	internal class MatrixSample
	{
		public float frame;

		public Matrix4x4[] body;
	}
	internal class ControlSample
	{
		public int tick;

		public bool paused;

		public bool hasBinding;

		public uint boundModel;

		public uint currentPrimaryModel;

		public int scriptTag;

		public int rootSelector;

		public float animationDelta;

		public Matrix4x4 root;

		public Matrix4x4[] body;
	}
	public sealed class OriginalRootMotion
	{
		public Matrix4x4 World = Matrix4x4.identity;

		public Matrix4x4 Previous = Matrix4x4.identity;

		public Matrix4x4 Delta = Matrix4x4.identity;

		public bool OnSourcePoseBound(uint boundModel, uint currentPrimaryModel, int scriptTag, int rootSelector)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			int num = scriptTag switch
			{
				3 => 1, 
				2 => 0, 
				_ => -1, 
			};
			int num2;
			if (boundModel == currentPrimaryModel)
			{
				num2 = ((num == rootSelector) ? 1 : 0);
				if (num2 != 0)
				{
					Previous = Matrix4x4.identity;
				}
			}
			else
			{
				num2 = 0;
			}
			return (byte)num2 != 0;
		}

		public void Advance(Matrix4x4 current, bool paused)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00bd: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			double num = Math.Atan2(((Matrix4x4)(ref current))[0, 2], ((Matrix4x4)(ref current))[2, 2]);
			float num2 = (float)Math.Cos(num);
			float num3 = (float)Math.Sin(num);
			Matrix4x4 identity = Matrix4x4.identity;
			((Matrix4x4)(ref identity))[0, 0] = num2;
			((Matrix4x4)(ref identity))[0, 2] = num3;
			((Matrix4x4)(ref identity))[2, 0] = 0f - num3;
			((Matrix4x4)(ref identity))[2, 2] = num2;
			((Matrix4x4)(ref identity))[0, 3] = ((Matrix4x4)(ref current))[0, 3];
			((Matrix4x4)(ref identity))[1, 3] = ((Matrix4x4)(ref current))[1, 3];
			((Matrix4x4)(ref identity))[2, 3] = ((Matrix4x4)(ref current))[2, 3];
			Delta = (paused ? Matrix4x4.identity : (((Matrix4x4)(ref Previous)).inverse * identity));
			Previous = identity;
			World *= Delta;
		}
	}
	internal class AttributeData
	{
		public int width;

		public int count;

		public float[] values;
	}
	internal class Part
	{
		public string name;

		public int node;

		public int skin;

		public bool visible;

		public Mesh mesh;

		public GameObject go;

		public Dictionary<string, AttributeData> attributes = new Dictionary<string, AttributeData>();

		public int[][] indices;

		public int[] materials;

		public Vector3[] output;

		public Vector3[] normals;

		public Vector4[] tangents;

		public AttributeData[] extraDirections;

		public List<Vector3>[] directionOutput;
	}
	public sealed class Preview : MonoBehaviour
	{
		private sealed class SceneAnimationChannel
		{
			public OriginalRelativeClockController Controller;

			public OriginalClockRoots Roots;

			public int[] Families = new int[2] { -1, -1 };

			public float[][] Factors = new float[2][]
			{
				new float[2],
				new float[2]
			};

			public float[][] Poses = new float[2][];

			public float[] Aggregate;
		}

		[Serializable]
		private class PilotVisualDiagnostics
		{
			public Vector3 worldCenter;

			public Vector3 worldSize;

			public Vector3 lossyScale;

			public Vector3 anchor;

			public Vector3 cameraPosition;

			public Vector3 sourceCenter;

			public float sourceHeight;

			public float sourceBottom;

			public string clip;

			public bool noPod;
		}

		private string root;

		private Settings settings;

		private RuntimeEvidence evidence = new RuntimeEvidence();

		private Node[] nodes;

		private Skin[] skins;

		private Clip[] clips;

		private Part[] parts;

		private Texture2D[] images;

		private byte[][] imageBytes;

		private Material[] materials;

		private Dictionary<int, Texture2D> linearImages = new Dictionary<int, Texture2D>();

		private Dictionary<string, MatrixSample[]> nativeMatrixClips = new Dictionary<string, MatrixSample[]>();

		private int[] nativeBodyNodes;

		private int nativeRootParent;

		private Transform displayRoot;

		private Camera camera;

		private Light keyLight;

		private bool initialized;

		private const int PreviewLayer = 30;

		private static readonly string[] DirectionAttributes = new string[3] { "_SOURCE_USAGE_2_0", "_SOURCE_USAGE_2_1", "_SOURCE_USAGE_3_1" };

		private static readonly int[] DirectionChannels = new int[3] { 4, 5, 6 };

		private Matrix4x4[] continuousBodyInverse;

		private float[] continuousBodyVertices;

		private float[] continuousBodyWeights;

		private int[] continuousBodyJoints;

		private ContinuousPartRig[] continuousParts;

		private float[] continuousPartConstants;

		private BinaryWriter taskBodyMeshOutput;

		private int taskBodyMeshFrames;

		private CharacterBody pilotBody;

		private Transform pilotDisplay;

		public bool PilotReady;

		private float pilotBaselineHeight;

		private float pilotBottom;

		private Vector3 pilotCenter;

		private Vector3 pilotOriginalRoot;

		private int pilotClip = -1;

		private float pilotTime;

		private float pilotPoseTime;

		private bool pilotWasFiring;

		private Vector3 cachedFoot;

		private Vector3 cachedHeading;

		private float cachedSourceTime;

		private float cachedRootTime;

		private bool cachedMask;

		private bool cachedFiring;

		private bool cachedLocomotionBlocked;

		private Vector3 cachedMoveInput;

		private string cachedPilotAction;

		private int cachedAimSerial;

		private int pilotIdle;

		private int pilotPublishedFrame = -1;

		private int pilotRevision;

		private int pilotPublishedRevision = -1;

		public bool CachePilotPose = true;

		public int PoseEvaluations;

		public int PoseCacheHits;

		public double PoseMilliseconds;

		private Clip[] deathClips;

		public bool DeathPlaybackActive;

		public HeavyarmsDeathRecord DeathRecord;

		private float deathStarted;

		private Vector3 deathOrigin;

		private Vector3 deathRootFirst;

		private Quaternion deathRotation;

		private bool deathMask;

		private int deathScene;

		private CharacterMaster deathMaster;

		private Vector3 deathLastOffset;

		private bool assistMode;

		private HeavyarmsDeathscytheActor assistActor;

		private float assistHeight;

		private float assistBottom;

		private float assistScale;

		private Vector3 assistCenter;

		private Vector3 assistRestRoot;

		public int AssistVisibleFrames;

		public int AssistPoseFrames;

		public bool FastPilotSkinning = true;

		private Matrix4x4[][] pilotSkinMatrices;

		private HeavyarmsAimResources aimResources;

		private OriginalWorldAim liveAim;

		private int aimSerial = -1;

		private int aimFrame = -1;

		private bool aimLocalsApplied;

		public float AimSideFactor;

		public float AimVerticalFactor;

		public int AimFamily = -1;

		public bool LocomotionMainOverlay;

		public int LocomotionMainPoseFrames;

		public float MainUpperLocalChange;

		private Vector3[] cancelFromT;

		private Vector3[] cancelFromS;

		private Quaternion[] cancelFromQ;

		private float cancelBlendAt;

		private float cancelSourceTime;

		private Clip cancelSourceClip;

		private readonly OriginalEaseState cancelEase = new OriginalEaseState();

		public int MainCancelTransitions;

		public float MainCancelBlendWeight = 1f;

		public float MainCancelOutgoingFrame;

		public float MainCancelOutgoingAngle;

		private readonly Dictionary<uint, Transform> weaponMuzzleTransforms = new Dictionary<uint, Transform>();

		private Dictionary<uint, Dictionary<uint, int>> weaponBoneIndices;

		public string PublishedPilotClip
		{
			get
			{
				if (pilotClip >= 0)
				{
					return clips[pilotClip].name;
				}
				return "";
			}
		}

		public int PublishedPilotFrame => pilotPublishedFrame;

		public bool DeathSourceRenderersHidden
		{
			get
			{
				if (parts == null)
				{
					return false;
				}
				Part[] array = parts;
				foreach (Part part in array)
				{
					if ((Object)(object)part.go != (Object)null && !part.go.GetComponent<Renderer>().forceRenderingOff)
					{
						return false;
					}
				}
				return true;
			}
		}

		public bool AssistLoaded
		{
			get
			{
				if (assistMode)
				{
					return PilotReady;
				}
				return false;
			}
		}

		public int AssistVertexCount => evidence.vertices;

		public bool MainCancelBlendActive => cancelFromQ != null;

		public string PilotBaseClip
		{
			get
			{
				if (pilotClip >= 0)
				{
					return clips[pilotClip].name;
				}
				return null;
			}
		}

		public Bounds PilotWorldBounds => parts[0].go.GetComponent<Renderer>().bounds;

		public void Initialize(string path)
		{
			root = path;
			Application.runInBackground = true;
			initialized = true;
		}

		private IEnumerator Start()
		{
			while (!initialized)
			{
				yield return null;
			}
			try
			{
				settings = (assistMode ? new Settings
				{
					dataPath = "original_assist.bin",
					outputDirectory = Path.Combine(root, "playable_evidence"),
					startupDelaySeconds = 0f
				} : JsonUtility.FromJson<Settings>(File.ReadAllText(Path.Combine(root, "stage3-preview.json"))));
				if (settings == null || string.IsNullOrEmpty(settings.outputDirectory))
				{
					throw new InvalidDataException("Missing preview output directory");
				}
				Directory.CreateDirectory(settings.outputDirectory);
				evidence.entered = true;
				evidence.unityVersion = Application.unityVersion;
				evidence.graphicsDevice = SystemInfo.graphicsDeviceName;
				using (SHA256 sHA = SHA256.Create())
				{
					evidence.previewAssemblySHA256 = BitConverter.ToString(sHA.ComputeHash(File.ReadAllBytes(Assembly.GetExecutingAssembly().Location))).Replace("-", "").ToLowerInvariant();
				}
				SaveEvidence();
			}
			catch (Exception ex)
			{
				Fail(ex);
				yield break;
			}
			yield return (object)new WaitForSecondsRealtime(((Object)(object)pilotBody != (Object)null || (Object)(object)pilotDisplay != (Object)null) ? 0f : settings.startupDelaySeconds);
			try
			{
				LoadAsset();
				if (!assistMode)
				{
					SetUpCamera();
				}
			}
			catch (Exception ex2)
			{
				Fail(ex2);
				yield break;
			}
			if (assistMode)
			{
				yield return RunAssistVisual();
				yield break;
			}
			if ((Object)(object)pilotBody != (Object)null || (Object)(object)pilotDisplay != (Object)null)
			{
				yield return RunPilotVisual();
				yield break;
			}
			if (!string.IsNullOrEmpty(settings.portableFullScenePath))
			{
				yield return ReplayMscTaskProof();
				yield break;
			}
			if (!string.IsNullOrEmpty(settings.portableDirectionPath))
			{
				yield return ReplayFullDirection();
				yield break;
			}
			if (!string.IsNullOrEmpty(settings.portableUnifiedPath))
			{
				yield return ReplayUnifiedAnimation();
				yield break;
			}
			if (!string.IsNullOrEmpty(settings.portableRelativeClockPath))
			{
				yield return ReplayRelativeClocks();
				yield break;
			}
			if (!string.IsNullOrEmpty(settings.portableClockPath))
			{
				yield return ReplayPortableClocks();
				yield break;
			}
			if (!string.IsNullOrEmpty(settings.portablePosePath))
			{
				yield return ReplayPortablePoseSampling();
				yield break;
			}
			if (!string.IsNullOrEmpty(settings.nativeControlPath))
			{
				yield return ReplayControlledRoot();
				yield break;
			}
			if (settings.replayAllFrames)
			{
				yield return ReplayNativeFrames();
				yield break;
			}
			string[] array = new string[6] { "kamae_sht_gnd_fr", "15bakutyu2kai_sht_air_fr", "15sokutyu_sht_gnd_lf", "45sub11a_sht_air_fr", "50spmovefr11a_sht_air_fr", "acrobat11a_sht_gnd_fr" };
			if (settings.captureAllClips)
			{
				array = new string[clips.Length];
				for (int i = 0; i < clips.Length; i++)
				{
					if (!clips[i].name.StartsWith("001hito_016gundmw_002hvarms_001_", StringComparison.Ordinal))
					{
						throw new InvalidDataException("Unexpected original clip name");
					}
					array[i] = clips[i].name.Substring("001hito_016gundmw_002hvarms_001_".Length);
				}
			}
			if (settings.captureMaskPairOnly)
			{
				array = new string[1] { "kamae_sht_gnd_fr" };
			}
			string[] array2 = array;
			foreach (string suffix in array2)
			{
				Clip clip = Array.Find(clips, (Clip c) => c.name.EndsWith(suffix, StringComparison.Ordinal));
				if (clip == null)
				{
					Fail(new InvalidDataException("Missing original clip " + suffix));
					yield break;
				}
				for (int i2 = 0; i2 < (settings.captureMaskPairOnly ? 1 : 3); i2++)
				{
					try
					{
						Pose(clip, clip.duration * (float)i2 / 2f, mask: false);
					}
					catch (Exception ex3)
					{
						Fail(ex3);
						yield break;
					}
					yield return (object)new WaitForEndOfFrame();
					try
					{
						Capture(clip, clip.duration * (float)i2 / 2f, mask: false, suffix + "_" + i2);
					}
					catch (Exception ex4)
					{
						Fail(ex4);
						yield break;
					}
					yield return null;
				}
			}
			Clip idle = Array.Find(clips, (Clip c) => c.name.EndsWith("kamae_sht_gnd_fr", StringComparison.Ordinal));
			if (!settings.captureMaskPairOnly)
			{
				try
				{
					Pose(idle, 0f, mask: false);
				}
				catch (Exception ex5)
				{
					Fail(ex5);
					yield break;
				}
				yield return (object)new WaitForEndOfFrame();
				try
				{
					Capture(idle, 0f, mask: false, "kamae_mask_reference");
					evidence.maskReferenceAdjacent = true;
				}
				catch (Exception ex6)
				{
					Fail(ex6);
					yield break;
				}
			}
			try
			{
				Pose(idle, 0f, mask: true);
			}
			catch (Exception ex7)
			{
				Fail(ex7);
				yield break;
			}
			yield return (object)new WaitForEndOfFrame();
			try
			{
				Capture(idle, 0f, mask: true, "kamae_mask_enabled");
				evidence.renderReadbackCompleted = true;
				SaveEvidence();
				Debug.Log((object)("[HeavyarmsEW.Stage3] RUNTIME_CAPTURE_COMPLETE " + evidence.captures.Count));
			}
			catch (Exception ex8)
			{
				Fail(ex8);
			}
		}

		private static void JsonString(StringBuilder b, string s)
		{
			b.Append('"');
			foreach (char c in s)
			{
				switch (c)
				{
				case '"':
					b.Append("\\\"");
					continue;
				case '\\':
					b.Append("\\\\");
					continue;
				case '\n':
					b.Append("\\n");
					continue;
				case '\r':
					b.Append("\\r");
					continue;
				case '\t':
					b.Append("\\t");
					continue;
				}
				if (c < ' ')
				{
					int num = c;
					b.Append("\\u" + num.ToString("x4"));
				}
				else
				{
					b.Append(c);
				}
			}
			b.Append('"');
		}

		private static void WriteJson(StringBuilder b, object v)
		{
			if (v == null)
			{
				b.Append("null");
				return;
			}
			if (v is string)
			{
				JsonString(b, (string)v);
				return;
			}
			if (v is bool)
			{
				b.Append(((bool)v) ? "true" : "false");
				return;
			}
			Type type = v.GetType();
			if (type.IsPrimitive || v is decimal)
			{
				b.Append(Convert.ToString(v, CultureInfo.InvariantCulture));
				return;
			}
			if (v is IEnumerable enumerable)
			{
				b.Append('[');
				bool flag = true;
				foreach (object item in enumerable)
				{
					if (!flag)
					{
						b.Append(',');
					}
					flag = false;
					WriteJson(b, item);
				}
				b.Append(']');
				return;
			}
			b.Append('{');
			bool flag2 = true;
			FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!flag2)
				{
					b.Append(',');
				}
				flag2 = false;
				JsonString(b, fieldInfo.Name);
				b.Append(':');
				WriteJson(b, fieldInfo.GetValue(v));
			}
			b.Append('}');
		}

		private void SaveEvidence()
		{
			if (!assistMode && settings != null && !string.IsNullOrEmpty(settings.outputDirectory))
			{
				StringBuilder stringBuilder = new StringBuilder();
				WriteJson(stringBuilder, evidence);
				File.WriteAllText(Path.Combine(settings.outputDirectory, "unity_runtime_evidence.json"), stringBuilder.ToString());
			}
		}

		private void Fail(Exception ex)
		{
			evidence.error = ex.ToString();
			Debug.LogError((object)("[HeavyarmsEW.Stage3] " + ex));
			try
			{
				SaveEvidence();
			}
			catch
			{
			}
		}

		private void WriteMeshReadback(BinaryWriter writer)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_008b: 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)
			writer.Write(parts.Length);
			Part[] array = parts;
			foreach (Part part in array)
			{
				Vector3[] vertices = part.mesh.vertices;
				if (vertices.Length != part.output.Length)
				{
					throw new InvalidDataException("Mesh vertex readback count");
				}
				writer.Write(part.name);
				writer.Write(part.go.activeSelf);
				writer.Write(vertices.Length);
				Vector3[] array2 = vertices;
				foreach (Vector3 val in array2)
				{
					writer.Write(val.x);
					writer.Write(val.y);
					writer.Write(val.z);
				}
			}
			writer.Write(nodes.Length);
			Node[] array3 = nodes;
			foreach (Node node in array3)
			{
				for (int k = 0; k < 4; k++)
				{
					for (int l = 0; l < 4; l++)
					{
						writer.Write(((Matrix4x4)(ref node.world))[l, k]);
					}
				}
			}
			evidence.meshVertexGetterReadbackUsed = true;
		}

		private static void WriteMatrix(BinaryWriter writer, Matrix4x4 matrix)
		{
			for (int i = 0; i < 4; i++)
			{
				for (int j = 0; j < 4; j++)
				{
					writer.Write(((Matrix4x4)(ref matrix))[j, i]);
				}
			}
		}

		private static bool Finite(Vector3 v)
		{
			//IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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)
			if (!float.IsNaN(v.x) && !float.IsInfinity(v.x) && !float.IsNaN(v.y) && !float.IsInfinity(v.y) && !float.IsNaN(v.z))
			{
				return !float.IsInfinity(v.z);
			}
			return false;
		}

		private void WriteDirectionReadback(BinaryWriter writer)
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			writer.Write(Encoding.ASCII.GetBytes("HWEWDIR1"));
			writer.Write(1);
			writer.Write(parts.Length);
			Part[] array = parts;
			foreach (Part part in array)
			{
				writer.Write(part.name);
				writer.Write(DirectionChannels.Length);
				for (int j = 0; j < DirectionChannels.Length; j++)
				{
					List<Vector3> list = new List<Vector3>();
					part.mesh.GetUVs(DirectionChannels[j], list);
					if (list.Count != part.output.Length)
					{
						throw new InvalidDataException("Original direction Mesh readback count");
					}
					writer.Write(DirectionAttributes[j]);
					writer.Write(DirectionChannels[j]);
					writer.Write(list.Count);
					foreach (Vector3 item in list)
					{
						if (!Finite(item))
						{
							throw new InvalidDataException("Nonfinite direction readback");
						}
						writer.Write(item.x);
						writer.Write(item.y);
						writer.Write(item.z);
					}
				}
			}
			evidence.extraDirectionMeshGetterReadbackUsed = true;
		}

		private ControlSample[] LoadControlInputs()
		{
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			byte[] buffer = File.ReadAllBytes(Path.Combine(root, settings.nativeControlPath));
			using (SHA256 sHA = SHA256.Create())
			{
				evidence.controlledRootPayloadSHA256 = BitConverter.ToString(sHA.ComputeHash(buffer)).Replace("-", "").ToLowerInvariant();
			}
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(buffer), Encoding.UTF8);
			if (Encoding.ASCII.GetString(binaryReader.ReadBytes(8)) != "HWEWCTL1")
			{
				throw new InvalidDataException("Control input format");
			}
			int num = binaryReader.ReadInt32();
			if (num != 1 && num != 2)
			{
				throw new InvalidDataException("Control input version");
			}
			ControlSample[] array = new ControlSample[binaryReader.ReadInt32()];
			for (int i = 0; i < array.Length; i++)
			{
				ControlSample controlSample = new ControlSample();
				controlSample.tick = binaryReader.ReadInt32();
				controlSample.paused = binaryReader.ReadBoolean();
				controlSample.animationDelta = binaryReader.ReadSingle();
				if (num == 2)
				{
					controlSample.hasBinding = binaryReader.ReadBoolean();
					controlSample.boundModel = binaryReader.ReadUInt32();
					controlSample.currentPrimaryModel = binaryReader.ReadUInt32();
					controlSample.scriptTag = binaryReader.ReadInt32();
					controlSample.rootSelector = binaryReader.ReadInt32();
				}
				controlSample.root = ReadMatrix(binaryReader);
				controlSample.body = (Matrix4x4[])(object)new Matrix4x4[78];
				for (int j = 0; j < 78; j++)
				{
					controlSample.body[j] = ReadMatrix(binaryReader);
				}
				array[i] = controlSample;
			}
			if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
			{
				throw new InvalidDataException("Unconsumed control input bytes");
			}
			return array;
		}

		private void ApplyControlledPose(Clip idle, ControlSample sample, Matrix4x4 actor)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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)
			Pose(idle, 0f, mask: false);
			nodes[nativeRootParent].world = actor;
			bool[] array = new bool[nodes.Length];
			array[nativeRootParent] = true;
			for (int i = 0; i < 78; i++)
			{
				nodes[nativeBodyNodes[i]].world = actor * sample.body[i];
				array[nativeBodyNodes[i]] = true;
			}
			for (int j = 0; j < nodes.Length; j++)
			{
				if (!array[j])
				{
					Node node = nodes[j];
					Matrix4x4 val = TRS(node.t, node.q, node.s);
					node.world = ((node.parent < 0) ? val : (nodes[node.parent].world * val));
				}
			}
			SkinMeshes(mask: false);
		}

		private IEnumerator ReplayControlledRoot()
		{
			bool failed = false;
			ControlSample[] samples;
			BinaryWriter writer;
			try
			{
				samples = LoadControlInputs();
				evidence.controlledRootReadbackFile = Path.Combine(settings.outputDirectory, "controlled_root_mesh_readback.bin");
				writer = new BinaryWriter(File.Create(evidence.controlledRootReadbackFile), Encoding.UTF8);
				writer.Write(Encoding.ASCII.GetBytes("HWEWCTL2"));
				writer.Write(2);
				writer.Write(samples.Length);
			}
			catch (Exception ex)
			{
				Fail(ex);
				yield break;
			}
			OriginalRootMotion controller = new OriginalRootMotion();
			Clip idle = Array.Find(clips, (Clip c) => c.name.EndsWith("kamae_sht_gnd_fr", StringComparison.Ordinal));
			try
			{
				ControlSample[] array = samples;
				foreach (ControlSample sample in array)
				{
					bool rootReset = false;
					try
					{
						if (sample.hasBinding)
						{
							rootReset = controller.OnSourcePoseBound(sample.boundModel, sample.currentPrimaryModel, sample.scriptTag, sample.rootSelector);
						}
						controller.Advance(sample.root, sample.paused);
						ApplyControlledPose(idle, sample, controller.World);
					}
					catch (Exception ex2)
					{
						Fail(ex2);
						failed = true;
						break;
					}
					yield return (object)new WaitForEndOfFrame();
					try
					{
						writer.Write(sample.tick);
						writer.Write(sample.paused);
						writer.Write(rootReset);
						WriteMatrix(writer, controller.World);
						WriteMatrix(writer, controller.Previous);
						WriteMatrix(writer, controller.Delta);
						WriteMeshReadback(writer);
						Capture(idle, 0f, mask: false, "control_tick_" + sample.tick.ToString("000", CultureInfo.InvariantCulture), 0f);
						evidence.controlledRootTicks++;
					}
					catch (Exception ex3)
					{
						Fail(ex3);
						failed = true;
						break;
					}
					yield return null;
				}
			}
			finally
			{
				writer?.Dispose();
			}
			if (!failed)
			{
				evidence.controlledRootReplayCompleted = evidence.controlledRootTicks == samples.Length;
				evidence.renderReadbackCompleted = true;
				SaveEvidence();
				Debug.Log((object)("[HeavyarmsEW.Stage3] CONTROLLED_ROOT_REPLAY_COMPLETE " + evidence.controlledRootTicks));
			}
		}

		private IEnumerator ReplayNativeFrames()
		{
			bool failed = false;
			int total = 0;
			Clip[] array = clips;
			foreach (Clip clip in array)
			{
				if (nativeMatrixClips.TryGetValue(clip.name, out var value))
				{
					total += value.Length;
				}
			}
			BinaryWriter writer;
			BinaryWriter gpuWriter;
			RenderTexture replayTarget;
			Texture2D replayImage;
			try
			{
				evidence.sequentialReadbackFile = Path.Combine(settings.outputDirectory, "native_sequence_mesh_readback.bin");
				writer = new BinaryWriter(File.Create(evidence.sequentialReadbackFile), Encoding.UTF8);
				writer.Write(Encoding.ASCII.GetBytes("HWEWSEQ1"));
				writer.Write(1);
				writer.Write(total);
				evidence.sequentialGPUImageSize = 128;
				evidence.sequentialGPUReadbackFile = Path.Combine(settings.outputDirectory, "native_sequence_GPU_readback.bin");
				gpuWriter = new BinaryWriter(File.Create(evidence.sequentialGPUReadbackFile), Encoding.UTF8);
				gpuWriter.Write(Encoding.ASCII.GetBytes("HWEWGPU1"));
				gpuWriter.Write(1);
				gpuWriter.Write(total);
				gpuWriter.Write(128);
				replayTarget = new RenderTexture(128, 128, 24, (RenderTextureFormat)0);
				replayTarget.Create();
				replayImage = new Texture2D(128, 128, (TextureFormat)3, false);
			}
			catch (Exception ex)
			{
				Fail(ex);
				yield break;
			}
			try
			{
				Clip[] array2 = clips;
				foreach (Clip clip2 in array2)
				{
					if (!nativeMatrixClips.TryGetValue(clip2.name, out var samples))
					{
						continue;
					}
					for (int index = 0; index < samples.Length; index++)
					{
						float frame = samples[index].frame;
						float time = frame / 60f;
						try
						{
							Pose(clip2, time, mask: false);
						}
						catch (Exception ex2)
						{
							Fail(ex2);
							failed = true;
							break;
						}
						yield return (object)new WaitForEndOfFrame();
						try
						{
							writer.Write(clip2.name);
							writer.Write(frame);
							writer.Write(time);
							writer.Write(Time.frameCount);
							writer.Write((double)Time.realtimeSinceStartup);
							FrameCamera(out var _);
							ReadRenderedImage(replayImage, replayTarget);
							byte[] rawTextureData = replayImage.GetRawTextureData();
							if (rawTextureData.Length != 49152)
							{
								throw new InvalidDataException("Sequential GPU image size");
							}
							gpuWriter.Write(evidence.sequentialNativeFrameCount);
							gpuWriter.Write(rawTextureData.Length);
							gpuWriter.Write(rawTextureData);
							WriteMeshReadback(writer);
							evidence.sequentialNativeFrameCount++;
							if (index == 0 || index == (samples.Length - 1) / 2 || index == samples.Length - 1)
							{
								string text = clip2.name.Substring("001hito_016gundmw_002hvarms_001_".Length);
								Capture(clip2, time, mask: false, text + "_seq_" + frame.ToString("0", CultureInfo.InvariantCulture), frame);
							}
						}
						catch (Exception ex3)
						{
							Fail(ex3);
							failed = true;
							break;
						}
						yield return null;
					}
					if (failed)
					{
						break;
					}
					writer.Flush();
					gpuWriter.Flush();
					SaveEvidence();
					Debug.Log((object)("[HeavyarmsEW.Stage3] SEQUENTIAL_CLIP_COMPLETE " + clip2.name + " frames=" + samples.Length));
					samples = null;
				}
			}
			finally
			{
				writer?.Dispose();
				gpuWriter?.Dispose();
				if ((Object)(object)replayTarget != (Object)null)
				{
					replayTarget.Release();
					Object.Destroy((Object)(object)replayTarget);
				}
				if ((Object)(object)replayImage != (Object)null)
				{
					Object.Destroy((Object)(object)replayImage);
				}
			}
			if (!failed)
			{
				Clip idle = Array.Find(clips, (Clip c) => c.name.EndsWith("kamae_sht_gnd_fr", StringComparison.Ordinal));
				try
				{
					Pose(idle, 0f, mask: false);
				}
				catch (Exception ex4)
				{
					Fail(ex4);
					yield break;
				}
				yield return (object)new WaitForEndOfFrame();
				try
				{
					Capture(idle, 0f, mask: false, "kamae_mask_reference", 0f);
					evidence.maskReferenceAdjacent = true;
					Pose(idle, 0f, mask: true);
				}
				catch (Exception ex5)
				{
					Fail(ex5);
					yield break;
				}
				yield return (object)new WaitForEndOfFrame();
				try
				{
					Capture(idle, 0f, mask: true, "kamae_mask_enabled", 0f);
					evidence.sequentialNativeFrameReplayCompleted = evidence.sequentialNativeFrameCount == total;
					evidence.renderReadbackCompleted = true;
					SaveEvidence();
					Debug.Log((object)("[HeavyarmsEW.Stage3] SEQUENTIAL_REPLAY_COMPLETE " + evidence.sequentialNativeFrameCount));
					Debug.Log((object)("[HeavyarmsEW.Stage3] RUNTIME_CAPTURE_COMPLETE " + evidence.captures.Count));
				}
				catch (Exception ex6)
				{
					Fail(ex6);
				}
			}
		}

		private static Vector3 ReadV3(BinaryReader r)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
		}

		private static Quaternion ReadQ(BinaryReader r)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Quaternion(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
		}

		private static float[] ReadFloats(BinaryReader r, int n)
		{
			if (n < 0 || n > 10000000)
			{
				throw new InvalidDataException("Bad array count");
			}
			float[] array = new float[n];
			for (int i = 0; i < n; i++)
			{
				array[i] = r.ReadSingle();
			}
			return array;
		}

		private static Matrix4x4 ReadMatrix(BinaryReader r)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			Matrix4x4 result = default(Matrix4x4);
			for (int i = 0; i < 4; i++)
			{
				for (int j = 0; j < 4; j++)
				{
					((Matrix4x4)(ref result))[j, i] = r.ReadSingle();
				}
			}
			return result;
		}

		private void LoadAsset()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_010e: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Expected O, but got Unknown
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Expected O, but got Unknown
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ac: 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_0484: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_094e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0958: Expected O, but got Unknown
			//IL_0539: Unknown result type (might be due to invalid IL or missing references)
			//IL_053e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0544: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_056e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0573: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_059e: Expected O, but got Unknown
			//IL_0a8d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a97: Expected O, but got Unknown
			byte[] buffer = File.ReadAllBytes(Path.Combine(root, settings.dataPath));
			using (SHA256 sHA = SHA256.Create())
			{
				evidence.payloadSHA256 = BitConverter.ToString(sHA.ComputeHash(buffer)).Replace("-", "").ToLowerInvariant();
			}
			displayRoot = new GameObject("Original Heavyarms EW").transform;
			displayRoot.SetParent(((Component)this).transform, false);
			using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(buffer), Encoding.UTF8))
			{
				if (Encoding.ASCII.GetString(binaryReader.ReadBytes(8)) != "HWEW3PV1" || binaryReader.ReadInt32() != 1)
				{
					throw new InvalidDataException("Preview format");
				}
				nodes = new Node[binaryReader.ReadInt32()];
				for (int i = 0; i < nodes.Length; i++)
				{
					Node node = new Node();
					node.name = binaryReader.ReadString();
					node.parent = binaryReader.ReadInt32();
					node.restT = ReadV3(binaryReader);
					node.restQ = ReadQ(binaryReader);
					node.restS = ReadV3(binaryReader);
					if (node.parent >= i)
					{
						throw new InvalidDataException("Non-topological original hierarchy");
					}
					nodes[i] = node;
				}
				images = (Texture2D[])(object)new Texture2D[binaryReader.ReadInt32()];
				imageBytes = new byte[images.Length][];
				for (int j = 0; j < images.Length; j++)
				{
					byte[] array = binaryReader.ReadBytes(binaryReader.ReadInt32());
					imageBytes[j] = array;
					Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
					if (!ImageConversion.LoadImage(val, array, false))
					{
						throw new InvalidDataException("Original PNG decode");
					}
					((Object)val).name = "OriginalPNG_" + j;
					((Texture)val).wrapMode = (TextureWrapMode)0;
					images[j] = val;
				}
				Shader val2 = Shader.Find("Hopoo Games/Deferred/Standard");
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = Shader.Find("Standard");
				}
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = Shader.Find("Unlit/Texture");
				}
				if ((Object)(object)val2 == (Object)null)
				{
					throw new InvalidOperationException("No compatible existing shader");
				}
				evidence.shader = ((Object)val2).name;
				evidence.shaderProperties = new string[val2.GetPropertyCount()];
				for (int k = 0; k < evidence.shaderProperties.Length; k++)
				{
					evidence.shaderProperties[k] = val2.GetPropertyName(k);
				}
				materials = (Material[])(object)new Material[binaryReader.ReadInt32()];
				Color val4 = default(Color);
				Color val6 = default(Color);
				for (int l = 0; l < materials.Length; l++)
				{
					Material val3 = new Material(val2);
					((Object)val3).name = binaryReader.ReadString();
					((Color)(ref val4))..ctor(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
					float num = binaryReader.ReadSingle();
					float num2 = binaryReader.ReadSingle();
					Vector3 val5 = ReadV3(binaryReader);
					int num3 = binaryReader.ReadInt32();
					int num4 = binaryReader.ReadInt32();
					int num5 = binaryReader.ReadInt32();
					int num6 = binaryReader.ReadInt32();
					int num7 = binaryReader.ReadInt32();
					bool num8 = binaryReader.ReadBoolean();
					if (val3.HasProperty("_Color"))
					{
						val3.SetColor("_Color", val4);
					}
					if (num3 >= 0)
					{
						val3.mainTexture = (Texture)(object)images[num3];
					}
					if (val3.HasProperty("_Metallic"))
					{
						val3.SetFloat("_Metallic", num);
					}
					if (val3.HasProperty("_Glossiness"))
					{
						val3.SetFloat("_Glossiness", 1f - num2);
					}
					if (val3.HasProperty("_Smoothness"))
					{
						val3.SetFloat("_Smoothness", 1f - num2);
					}
					if (num4 >= 0)
					{
						if (val3.HasProperty("_BumpMap"))
						{
							val3.SetTexture("_BumpMap", (Texture)(object)LinearImage(num4));
						}
						if (val3.HasProperty("_NormalTex"))
						{
							val3.SetTexture("_NormalTex", (Texture)(object)LinearImage(num4));
						}
						val3.EnableKeyword("_NORMALMAP");
					}
					if (num6 >= 0 && val3.HasProperty("_OcclusionMap"))
					{
						val3.SetTexture("_OcclusionMap", (Texture)(object)LinearImage(num6));
					}
					if (num7 >= 0)
					{
						if (val3.HasProperty("_EmissionMap"))
						{
							val3.SetTexture("_EmissionMap", (Texture)(object)images[num7]);
						}
						if (val3.HasProperty("_EmTex"))
						{
							val3.SetTexture("_EmTex", (Texture)(object)images[num7]);
						}
						((Color)(ref val6))..ctor(val5.x, val5.y, val5.z, 1f);
						if (val3.HasProperty("_EmissionColor"))
						{
							val3.SetColor("_EmissionColor", val6);
						}
						if (val3.HasProperty("_EmColor"))
						{
							val3.SetColor("_EmColor", val6);
						}
						val3.EnableKeyword("_EMISSION");
					}
					if (num8 && val3.HasProperty("_Cull"))
					{
						val3.SetInt("_Cull", 0);
					}
					if (num5 >= 0 && val3.HasProperty("_MetallicGlossMap"))
					{
						Texture2D val7 = LinearImage(num5);
						Color32[] pixels = val7.GetPixels32();
						for (int m = 0; m < pixels.Length; m++)
						{
							Color32 val8 = pixels[m];
							pixels[m] = new Color32((byte)Mathf.RoundToInt((float)(int)val8.b * num), (byte)0, (byte)0, (byte)Mathf.RoundToInt(255f - (float)(int)val8.g * num2));
						}
						Texture2D val9 = new Texture2D(((Texture)val7).width, ((Texture)val7).height, (TextureFormat)4, false, true);
						val9.SetPixels32(pixels);
						val9.Apply();
						val3.SetTexture("_MetallicGlossMap", (Texture)(object)val9);
						if (val3.HasProperty("_GlossMapScale"))
						{
							val3.SetFloat("_GlossMapScale", 1f);
						}
						val3.EnableKeyword("_METALLICGLOSSMAP");
					}
					materials[l] = val3;
				}
				skins = new Skin[binaryReader.ReadInt32()];
				foreach (int item in Range(skins.Length))
				{
					Skin skin = new Skin();
					skin.name = binaryReader.ReadString();
					skin.joints = new int[binaryReader.ReadInt32()];
					skin.inverse = (Matrix4x4[])(object)new Matrix4x4[skin.joints.Length];
					for (int n = 0; n < skin.joints.Length; n++)
					{
						skin.joints[n] = binaryReader.ReadInt32();
					}
					for (int num9 = 0; num9 < skin.joints.Length; num9++)
					{
						skin.inverse[num9] = ReadMatrix(binaryReader);
					}
					skins[item] = skin;
					evidence.skinJoints += skin.joints.Length;
				}
				parts = new Part[binaryReader.ReadInt32()];
				for (int num10 = 0; num10 < parts.Length; num10++)
				{
					Part part = new Part();
					part.name = binaryReader.ReadString();
					part.node = binaryReader.ReadInt32();
					part.skin = binaryReader.ReadInt32();
					part.visible = binaryReader.ReadBoolean();
					int num11 = binaryReader.ReadInt32();
					for (int num12 = 0; num12 < num11; num12++)
					{
						string key = binaryReader.ReadString();
						AttributeData attributeData = new AttributeData();
						attributeData.width = binaryReader.ReadInt32();
						attributeData.count = binaryReader.ReadInt32();
						attributeData.values = ReadFloats(binaryReader, attributeData.width * attributeData.count);
						part.attributes.Add(key, attributeData);
					}
					int num13 = binaryReader.ReadInt32();
					part.indices = new int[num13][];
					part.materials = new int[num13];
					int num14 = 0;
					for (int num15 = 0; num15 < num13; num15++)
					{
						part.materials[num15] = binaryReader.ReadInt32();
						part.indices[num15] = new int[binaryReader.ReadInt32()];
						for (int num16 = 0; num16 < part.indices[num15].Length; num16++)
						{
							part.indices[num15][num16] = binaryReader.ReadInt32();
						}
						num14 += part.indices[num15].Length;
					}
					int count = part.attributes["POSITION"].count;
					part.output = (Vector3[])(object)new Vector3[count];
					part.normals = (Vector3[])(object)new Vector3[count];
					part.tangents = (Vector4[])(object)new Vector4[count];
					part.extraDirections = new AttributeData[DirectionAttributes.Length];
					part.directionOutput = new List<Vector3>[DirectionAttributes.Length];
					for (int num17 = 0; num17 < DirectionAttributes.Length; num17++)
					{
						if (!part.attributes.TryGetValue(DirectionAttributes[num17], out var value) || value.width != 3 || value.count != count)
						{
							throw new InvalidDataException("Missing or malformed original direction " + DirectionAttributes[num17]);
						}
						part.extraDirections[num17] = value;
						part.directionOutput[num17] = new List<Vector3>((IEnumerable<Vector3>)(object)new Vector3[count]);
					}
					part.mesh = new Mesh();
					((Object)part.mesh).name = part.name + "_original_geometry";
					part.mesh.indexFormat = (IndexFormat)1;
					part.mesh.MarkDynamic();
					part.mesh.vertices = (Vector3[])(object)new Vector3[count];
					if (part.attributes.ContainsKey("TEXCOORD_0"))
					{
						part.mesh.uv = UV(part.attributes["TEXCOORD_0"]);
					}
					if (part.attributes.ContainsKey("TEXCOORD_1"))
					{
						part.mesh.uv2 = UV(part.attributes["TEXCOORD_1"]);
					}
					part.mesh.subMeshCount = num13;
					for (int num18 = 0; num18 < num13; num18++)
					{
						int[] array2 = (int[])part.indices[num18].Clone();
						for (int num19 = 0; num19 < array2.Length; num19 += 3)
						{
							int num20 = array2[num19 + 1];
							array2[num19 + 1] = array2[num19 + 2];
							array2[num19 + 2] = num20;
						}
						part.mesh.SetTriangles(array2, num18, false);
					}
					part.go = new GameObject(part.name);
					part.go.layer = 30;
					part.go.transform.SetParent(displayRoot, false);
					part.go.AddComponent<MeshFilter>().sharedMesh = part.mesh;
					MeshRenderer val10 = part.go.AddComponent<MeshRenderer>();
					Material[] array3 = (Material[])(object)new Material[num13];
					for (int num21 = 0; num21 < num13; num21++)
					{
						array3[num21] = materials[part.materials[num21]];
					}
					((Renderer)val10).sharedMaterials = array3;
					((Renderer)val10).lightProbeUsage = (LightProbeUsage)0;
					((Renderer)val10).reflectionProbeUsage = (ReflectionProbeUsage)0;
					parts[num10] = part;
					evidence.vertices += count;
					evidence.indices += num14;
					evidence.meshDetails.Add(new MeshEvidence
					{
						name = part.name,
						vertices = count,
						indices = num14,
						attributes = num11,
						joints = skins[part.skin].joints.Length,
						defaultVisible = part.visible
					});
				}
				clips = new Clip[binaryReader.ReadInt32()];
				for (int num22 = 0; num22 < clips.Length; num22++)
				{
					Clip clip = new Clip();
					clip.name = binaryReader.ReadString();
					clip.tracks = new Track[binaryReader.ReadInt32()];
					for (int num23 = 0; num23 < clip.tracks.Length; num23++)
					{
						Track track = new Track();
						track.node = binaryReader.ReadInt32();
						track.path = binaryReader.ReadInt32();
						track.width = ((track.path == 1) ? 4 : 3);
						int num24 = binaryReader.ReadInt32();
						track.times = ReadFloats(binaryReader, num24);
						track.values = ReadFloats(binaryReader, num24 * track.width);
						clip.duration = Mathf.Max(clip.duration, track.times[num24 - 1]);
						clip.tracks[num23] = track;
					}
					clips[num22] = clip;
				}
				if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
				{
					throw new InvalidDataException("Unconsumed original asset bytes");
				}
			}
			if (!string.IsNullOrEmpty(settings.nativeMatrixPath))
			{
				LoadNativeMatrices();
			}
			evidence.nodes = nodes.Length;
			evidence.skins = skins.Length;
			evidence.meshes = parts.Length;
			evidence.animations = clips.Length;
			evidence.textures = images.Length;
			bool num25;
			if (!assistMode)
			{
				if (evidence.vertices == 11636 && evidence.skinJoints == 90)
				{
					num25 = evidence.animations != 85;
					goto IL_0dfe;
				}
			}
			else if (evidence.vertices == 12853 && evidence.skinJoints == 71)
			{
				num25 = evidence.animations != 49;
				goto IL_0dfe;
			}
			goto IL_0e00;
			IL_0dfe:
			if (!num25)
			{
				evidence.metallicRoughnessChannelsAdapted = true;
				evidence.normalAndDataTexturesLinear = true;
				evidence.assetLoaded = true;
				SaveEvidence();
				Debug.Log((object)("[HeavyarmsEW.Stage3] ORIGINAL_ASSET_LOADED vertices=" + evidence.vertices + " joints=" + evidence.skinJoints + " clips=" + clips.Length));
				return;
			}
			goto IL_0e00;
			IL_0e00:
			throw new InvalidDataException("Original asset counts changed");
		}

		private Texture2D LinearImage(int index)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (linearImages.TryGetValue(index, out var value))
			{
				return value;
			}
			value = new Texture2D(2, 2, (TextureFormat)4, false, true);
			if (!ImageConversion.LoadImage(value, imageBytes[index], false))
			{
				throw new InvalidDataException("Original data PNG decode");
			}
			((Object)value).name = "OriginalLinearPNG_" + index;
			((Texture)value).wrapMode = (TextureWrapMode)0;
			linearImages.Add(index, value);
			return value;
		}

		private static IEnumerable<int> Range(int n)
		{
			for (int i = 0; i < n; i++)
			{
				yield return i;
			}
		}

		private static Vector2[] UV(AttributeData a)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			Vector2[] array = (Vector2[])(object)new Vector2[a.count];
			for (int i = 0; i < a.count; i++)
			{
				array[i] = new Vector2(a.values[i * a.width], 1f - a.values[i * a.width + 1]);
			}
			return array;
		}

		private static Vector3 V3(float[] a, int at)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(a[at], a[at + 1], a[at + 2]);
		}

		private static Quaternion Q(float[] a, int at)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Quaternion(a[at], a[at + 1], a[at + 2], a[at + 3]);
		}

		private void LoadNativeMatrices()
		{
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			byte[] buffer = File.ReadAllBytes(Path.Combine(root, settings.nativeMatrixPath));
			using (SHA256 sHA = SHA256.Create())
			{
				evidence.nativeBodyMatrixSHA256 = BitConverter.ToString(sHA.ComputeHash(buffer)).Replace("-", "").ToLowerInvariant();
			}
			using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(buffer), Encoding.UTF8))
			{
				if (Encoding.ASCII.GetString(binaryReader.ReadBytes(8)) != "HWEWMX01" || binaryReader.ReadInt32() != 1)
				{
					throw new InvalidDataException("Native matrix sidecar version");
				}
				nativeRootParent = binaryReader.ReadInt32();
				nativeBodyNodes = new int[binaryReader.ReadInt32()];
				if (nativeBodyNodes.Length != 78 || nativeRootParent < 0 || nativeRootParent >= nodes.Length)
				{
					throw new InvalidDataException("Original body node count/root");
				}
				for (int i = 0; i < nativeBodyNodes.Length; i++)
				{
					nativeBodyNodes[i] = binaryReader.ReadInt32();
					if (nativeBodyNodes[i] < 0 || nativeBodyNodes[i] >= nodes.Length)
					{
						throw new InvalidDataException("Original body node index");
					}
				}
				int num = binaryReader.ReadInt32();
				for (int j = 0; j < num; j++)
				{
					string key = binaryReader.ReadString();
					MatrixSample[] array = new MatrixSample[binaryReader.ReadInt32()];
					for (int k = 0; k < array.Length; k++)
					{
						MatrixSample matrixSample = new MatrixSample();
						matrixSample.frame = binaryReader.ReadSingle();
						matrixSample.body = (Matrix4x4[])(object)new Matrix4x4[78];
						for (int l = 0; l < 78; l++)
						{
							matrixSample.body[l] = ReadMatrix(binaryReader);
						}
						array[k] = matrixSample;
					}
					nativeMatrixClips.Add(key, array);
				}
				if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
				{
					throw new InvalidDataException("Unconsumed native matrix sidecar bytes");
				}
			}
			evidence.nativeBodyMatrixSidecarLoaded = true;
		}

		private void ApplyNativeBodyMatrices(Clip clip, float time)
		{
			//IL_0074: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			if (!nativeMatrixClips.TryGetValue(clip.name, out var value))
			{
				throw new InvalidDataException("Missing native matrix clip " + clip.name);
			}
			MatrixSample matrixSample = Array.Find(value, (MatrixSample s) => Mathf.Abs(s.frame - time * 60f) < 0.0001f);
			if (matrixSample == null)
			{
				throw new InvalidDataException("No exact native matrix time; matrix interpolation is not an accepted source animation substitute");
			}
			bool[] array = new bool[nodes.Length];
			Matrix4x4 world = nodes[nativeRootParent].world;
			for (int num = 0; num < 78; num++)
			{
				int num2 = nativeBodyNodes[num];
				nodes[num2].world = world * matrixSample.body[num];
				array[num2] = true;
			}
			for (int num3 = 0; num3 < nodes.Length; num3++)
			{
				if (!array[num3])
				{
					Node node = nodes[num3];
					Matrix4x4 val = TRS(node.t, node.q, node.s);
					node.world = ((node.parent < 0) ? val : (nodes[node.parent].world * val));
				}
			}
		}

		private static Matrix4x4 TRS(Vector3 t, Quaternion q, Vector3 s)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			float x = q.x;
			float y = q.y;
			float z = q.z;
			float w = q.w;
			Matrix4x4 identity = Matrix4x4.identity;
			((Matrix4x4)(ref identity))[0, 0] = (1f - 2f * y * y - 2f * z * z) * s.x;
			((Matrix4x4)(ref identity))[1, 0] = (2f * x * y + 2f * z * w) * s.x;
			((Matrix4x4)(ref identity))[2, 0] = (2f * x * z - 2f * y * w) * s.x;
			((Matrix4x4)(ref identity))[0, 1] = (2f * x * y - 2f * z * w) * s.y;
			((Matrix4x4)(ref identity))[1, 1] = (1f - 2f * x * x - 2f * z * z) * s.y;
			((Matrix4x4)(ref identity))[2, 1] = (2f * y * z + 2f * x * w) * s.y;
			((Matrix4x4)(ref identity))[0, 2] = (2f * x * z + 2f * y * w) * s.z;
			((Matrix4x4)(ref identity))[1, 2] = (2f * y * z - 2f * x * w) * s.z;
			((Matrix4x4)(ref identity))[2, 2] = (1f - 2f * x * x - 2f * y * y) * s.z;
			((Matrix4x4)(ref identity))[0, 3] = t.x;
			((Matrix4x4)(ref identity))[1, 3] = t.y;
			((Matrix4x4)(ref identity))[2, 3] = t.z;
			return identity;
		}

		private void Pose(Clip clip, float time, bool mask)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: 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_01e3: 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_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: 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_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			Node[] array = nodes;
			foreach (Node obj in array)
			{
				obj.t = obj.restT;
				obj.q = obj.restQ;
				obj.s = obj.restS;
			}
			Track[] tracks = clip.tracks;
			foreach (Track track in tracks)
			{
				int num = Array.BinarySearch(track.times, time);
				int num2;
				int num3;
				if (num >= 0)
				{
					num2 = (num3 = num);
				}
				else
				{
					num3 = Math.Min(~num, track.times.Length - 1);
					num2 = Math.Max(0, num3 - 1);
					if (Mathf.Abs(track.times[num3] - time) < 1E-06f)
					{
						num2 = num3;
					}
				}
				float num4 = ((num3 == num2) ? 0f : Mathf.Clamp01((time - track.times[num2]) / (track.times[num3] - track.times[num2])));
				Node node = nodes[track.node];
				int at = num2 * track.width;
				int at2 = num3 * track.width;
				if (track.path == 0)
				{
					node.t = Vector3.LerpUnclamped(V3(track.values, at), V3(track.values, at2), num4);
				}
				else if (track.path == 2)
				{
					node.s = Vector3.LerpUnclamped(V3(track.values, at), V3(track.values, at2), num4);
				}
				else
				{
					node.q = ((num2 == num3) ? Q(track.values, at) : Quaternion.SlerpUnclamped(Q(track.values, at), Q(track.values, at2), num4));
				}
			}
			ApplyPilotAimLocals();
			BlendMainCancelLocals();
			ApplySourceWeaponParts();
			ApplyAssistAttachmentLocals();
			for (int j = 0; j < nodes.Length; j++)
			{
				Node node2 = nodes[j];
				Matrix4x4 val = TRS(node2.t, node2.q, node2.s);
				node2.world = ((node2.parent < 0) ? val : (nodes[node2.parent].world * val));
			}
			if (!ApplyDeathConstraints() && !ApplyPilotAimConstraints() && evidence.nativeBodyMatrixSidecarLoaded)
			{
				ApplyNativeBodyMatrices(clip, time);
			}
			SkinMeshes(mask);
		}

		private void SkinMeshes(bool mask)
		{
			//IL_0073: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_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)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: 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_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: 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_01f2: 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_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: 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_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			if (PilotReady && FastPilotSkinning)
			{
				SkinPilotMeshes(mask);
				return;
			}
			Part[] array = parts;
			foreach (Part part in array)
			{
				part.go.SetActive(part.visible || mask);
				Skin skin = skins[part.skin];
				Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[skin.joints.Length];
				for (int j = 0; j < array2.Length; j++)
				{
					array2[j] = nodes[skin.joints[j]].world * skin.inverse[j];
				}
				AttributeData attributeData = part.attributes["POSITION"];
				AttributeData attributeData2 = part.attributes["NORMAL"];
				AttributeData attributeData3 = part.attributes["JOINTS_0"];
				AttributeData attributeData4 = part.attributes["WEIGHTS_0"];
				AttributeData value = null;
				part.attributes.TryGetValue("TANGENT", out value);
				for (int k = 0; k < attributeData.count; k++)
				{
					Vector3 val = V3(attributeData.values, k * attributeData.width);
					Vector3 val2 = V3(attributeData2.values, k * attributeData2.width);
					Vector3 val3 = Vector3.zero;
					Vector3 val4 = Vector3.zero;
					Vector3 val5 = Vector3.zero;
					for (int l = 0; l < 4; l++)
					{
						float num = attributeData4.values[k * attributeData4.width + l];
						if (num != 0f)
						{
							int num2 = (int)attributeData3.values[k * attributeData3.width + l];
							Matrix4x4 val6 = array2[num2];
							val3 += ((Matrix4x4)(ref val6)).MultiplyPoint3x4(val) * num;
							val4 += ((Matrix4x4)(ref val6)).MultiplyVector(val2) * num;
							if (value != null)
							{
								val5 += ((Matrix4x4)(ref val6)).MultiplyVector(V3(value.values, k * value.width)) * num;
							}
						}
					}
					if (float.IsNaN(val3.x) || float.IsInfinity(val3.x) || float.IsNaN(val3.y) || float.IsInfinity(val3.y) || float.IsNaN(val3.z) || float.IsInfinity(val3.z))
					{
						throw new InvalidDataException("Nonfinite original skin output");
					}
					part.output[k] = new Vector3(val3.x, val3.y, 0f - val3.z);
					((Vector3)(ref val4)).Normalize();
					part.normals[k] = new Vector3(val4.x, val4.y, 0f - val4.z);
					((Vector3)(ref val5)).Normalize();
					part.tangents[k] = new Vector4(val5.x, val5.y, 0f - val5.z, (value == null) ? 1f : (0f - value.values[k * value.width + 3]));
					for (int m = 0; m < DirectionAttributes.Length; m++)
					{
						Vector3 val7 = V3(part.extraDirections[m].values, k * 3);
						Vector3 val8 = Vector3.zero;
						for (int n = 0; n < 4; n++)
						{
							float num3 = attributeData4.values[k * attributeData4.width + n];
							if (num3 != 0f)
							{
								int num4 = (int)attributeData3.values[k * attributeData3.width + n];
								val8 += ((Matrix4x4)(ref array2[num4])).MultiplyVector(val7) * num3;
							}
						}
						if (!Finite(val8))
						{
							throw new InvalidDataException("Nonfinite original extra direction");
						}
						part.directionOutput[m][k] = new Vector3(val8.x, val8.y, 0f - val8.z);
					}
				}
				part.mesh.vertices = part.output;
				part.mesh.normals = part.normals;
				if (value != null)
				{
					part.mesh.tangents = part.tangents;
				}
				part.mesh.RecalculateBounds();
				for (int num5 = 0; num5 < DirectionChannels.Length; num5++)
				{
					part.mesh.SetUVs(DirectionChannels[num5], part.directionOutput[num5]);
				}
			}
			evidence.cpuSkinningFinite = true;
		}

		private void SetUpCamera()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0067: 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_00b8: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Stage3 isolated render camera");
			val.transform.SetParent(((Component)this).transform, false);
			camera = val.AddComponent<Camera>();
			((Behaviour)camera).enabled = false;
			camera.renderingPath = (RenderingPath)1;
			camera.clearFlags = (CameraClearFlags)2;
			camera.backgroundColor = new Color(0.12f, 0.14f, 0.17f, 1f);
			camera.cullingMask = 1073741824;
			camera.nearClipPlane = 0.01f;
			camera.farClipPlane = 1000f;
			camera.orthographic = true;
			GameObject val2 = new GameObject("Stage3 preview light");
			val2.transform.SetParent(((Component)this).transform, false);
			keyLight = val2.AddComponent<Light>();
			keyLight.type = (LightType)1;
			keyLight.intensity = 1.4f;
			keyLight.cullingMask = 1073741824;
			((Component)keyLight).transform.rotation = Quaternion.Euler(35f, 145f, 0f);
		}

		private Bounds FrameCamera(out int vertices)
		{
			//IL_0002: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			bool flag = true;
			vertices = 0;
			Part[] array = parts;
			foreach (Part part in array)
			{
				if (part.go.activeSelf)
				{
					if (flag)
					{
						result = part.mesh.bounds;
						flag = false;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(part.mesh.bounds);
					}
					vertices += part.output.Length;
				}
			}
			float num = Mathf.Max(((Bounds)(ref result)).size.y, Mathf.Max(((Bounds)(ref result)).size.x, ((Bounds)(ref result)).size.z));
			camera.orthographicSize = num * 0.67f;
			Transform transform = ((Component)camera).transform;
			Vector3 center = ((Bounds)(ref result)).center;
			Vector3 val = new Vector3(1.1f, 0.35f, -2f);
			transform.position = center + ((Vector3)(ref val)).normalized * num * 3f;
			((Component)camera).transform.LookAt(((Bounds)(ref result)).center);
			camera.farClipPlane = num * 10f + 10f;
			return result;
		}

		private void ReadRenderedImage(Texture2D image, RenderTexture target)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: 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)
			RenderTexture active = RenderTexture.active;
			RenderTexture targetTexture = camera.targetTexture;
			camera.targetTexture = target;
			AmbientMode ambientMode = RenderSettings.ambientMode;
			Color ambientLight = RenderSettings.ambientLight;
			SphericalHarmonicsL2 ambientProbe = RenderSettings.ambientProbe;
			float reflectionIntensity = RenderSettings.reflectionIntensity;
			bool fog = RenderSettings.fog;
			Light sun = RenderSettings.sun;
			List<Light> list = new List<Light>();
			List<int> list2 = new List<int>();
			try
			{
				Light[] array = Object.FindObjectsOfType<Light>();
				foreach (Light val in array)
				{
					if ((Object)(object)val != (Object)(object)keyLight && (val.cullingMask & 0x40000000) != 0)
					{
						list.Add(val);
						list2.Add(val.cullingMask);
						val.cullingMask &= -1073741825;
					}
				}
				evidence.maximumOtherSceneLightsExcluded = Math.Max(evidence.maximumOtherSceneLightsExcluded, list.Count);
				RenderSettings.fog = false;
				RenderSettings.sun = keyLight;
				RenderSettings.ambientMode = (AmbientMode)3;
				RenderSettings.ambientLight = new Color(0.4f, 0.4f, 0.4f, 1f);
				SphericalHarmonicsL2 ambientProbe2 = default(SphericalHarmonicsL2);
				((SphericalHarmonicsL2)(ref ambientProbe2)).AddAmbientLight(new Color(0.4f, 0.4f, 0.4f, 1f));
				RenderSettings.ambientProbe = ambientProbe2;
				RenderSettings.reflectionIntensity = 0f;
				((Behaviour)keyLight).enabled = true;
				keyLight.color = Color.white;
				keyLight.intensity = 1.4f;
				((Component)keyLight).transform.rotation = Quaternion.Euler(35f, -35f, 0f);
				camera.Render();
				evidence.previewLightingIsolated = true;
				RenderTexture.active = target;
				image.ReadPixels(new Rect(0f, 0f, (float)((Texture)image).width, (float)((Texture)image).height), 0, 0);
				image.Apply();
			}
			finally
			{
				for (int j = 0; j < list.Count; j++)
				{
					if ((Object)(object)list[j] != (Object)null)
					{
						list[j].cullingMask = list2[j];
					}
				}
				RenderSettings.fog = fog;
				RenderSettings.sun = sun;
				RenderSettings.ambientMode = ambientMode;
				RenderSettings.ambientLight = ambientLight;
				RenderSettings.ambientProbe = ambientProbe;
				RenderSettings.reflectionIntensity = reflectionIntensity;
				RenderTexture.active = active;
				camera.targetTexture = targetTexture;
			}
		}

		private void Capture(Clip clip, float time, bool mask, string name, float nativeFrame = -1f)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_019e: 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_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: 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_01e9: Unknown result type (might be due to invalid IL or missing references)
			int vertices;
			Bounds val = FrameCamera(out vertices);
			RenderTexture val2 = new RenderTexture(settings.imageSize, settings.imageSize, 24, (RenderTextureFormat)0);
			val2.Create();
			Texture2D val3 = new Texture2D(settings.imageSize, settings.imageSize, (TextureFormat)3, false);
			try
			{
				ReadRenderedImage(val3, val2);
				string text = Path.Combine(settings.outputDirectory, name + ".png");
				File.WriteAllBytes(text, ImageConversion.EncodeToPNG(val3));
				string text2 = Path.Combine(settings.outputDirectory, name + ".vertices.bin");
				using (BinaryWriter binaryWriter = new BinaryWriter(File.Create(text2), Encoding.UTF8))
				{
					binaryWriter.Write(Encoding.ASCII.GetBytes("HWEWVTX1"));
					WriteMeshReadback(binaryWriter);
				}
				string text3 = Path.Combine(settings.outputDirectory, name + ".directions.bin");
				using (BinaryWriter writer = new BinaryWriter(File.Create(text3), Encoding.UTF8))
				{
					WriteDirectionReadback(writer);
				}
				evidence.captures.Add(new CaptureEvidence
				{
					animation = clip.name,
					time = time,
					nativeFrame = nativeFrame,
					nativeFrameSpecified = (nativeFrame >= 0f),
					file = text,
					vertexDump = text2,
					directionDump = text3,
					maskVisible = mask,
					vertices = vertices,
					bounds = new float[6]
					{
						((Bounds)(ref val)).min.x,
						((Bounds)(ref val)).min.y,
						((Bounds)(ref val)).min.z,
						((Bounds)(ref val)).max.x,
						((Bounds)(ref val)).max.y,
						((Bounds)(ref val)).max.z
					}
				});
				SaveEvidence();
				Debug.Log((object)("[HeavyarmsEW.Stage3] CAPTURE " + text));
			}
			finally
			{
				val2.Release();
				Object.Destroy((Object)(object)val2);
				Object.Destroy((Object)(object)val3);
			}
		}

		private IEnumerator ReplayPortablePoseSampling()
		{
			OriginalPoseSampler sampler = null;
			OriginalPoseKeys[] originalClips = null;
			PortablePoseCase[] requests = null;
			int[] parents = null;
			int sampleCount = 0;
			try
			{
				byte[] buffer = File.ReadAllBytes(Path.Combine(root, settings.portablePosePath));
				using (SHA256 sHA = SHA256.Create())
				{
					evidence.portablePoseInputSHA256 = BitConverter.ToString(sHA.ComputeHash(buffer)).Replace("-", "").ToLowerInvariant();
				}
				using BinaryReader binaryReader = new BinaryReader(new MemoryStream(buffer), Encoding.UTF8);
				if (Encoding.ASCII.GetString(binaryReader.ReadBytes(8)) != "HWEWPSE1" || binaryReader.ReadInt32() != 1 || binaryReader.ReadInt32() != 78)
				{
					throw new InvalidDataException("Original pose input version");
				}
				float[] array = ReadFloats(binaryReader, 4);
				sampler = new OriginalPoseSampler(78, array[0], array[1], array[2], array[3]);
				parents = new int[78];
				for (int i = 0; i < 78; i++)
				{
					parents[i] = binaryReader.ReadInt32();
					if (parents[i] >= i)
					{
						throw new InvalidDataException("Original pose hierarchy");
					}
				}
				int num = binaryReader.ReadInt32();
				if (num < 1 || num > 256)
				{
					throw new InvalidDataException("Original pose clip count");
				}
				originalClips = new OriginalPoseKeys[num];
				for (int j = 0; j < num; j++)
				{
					OriginalPoseKeys originalPoseKeys = new OriginalPoseKeys();
					originalPoseKeys.name = binaryReader.ReadString();
					originalPoseKeys.frames = binaryReader.ReadInt32();
					if (originalPoseKeys.frames < 1 || originalPoseKeys.frames > 10000)
					{
						throw new InvalidDataException("Original frame count");
					}
					originalPoseKeys.keys = ReadFloats(binaryReader, originalPoseKeys.frames * 78 * 10);
					originalClips[j] = originalPoseKeys;
				}
				sampleCount = binaryReader.ReadInt32();
				int num2 = binaryReader.ReadInt32();
				if (sampleCount < 1 || sampleCount + num2 > 20000)
				{
					throw new InvalidDataException("Pose request count");
				}
				requests = new PortablePoseCase[sampleCount + num2];
				for (int k = 0; k < requests.Length; k++)
				{
					int num3 = binaryReader.ReadInt32();
					if (num3 < 1 || num3 > 4)
					{
						throw new InvalidDataException("Pose layers");
					}
					PortablePoseCase portablePoseCase = new PortablePoseCase();
					portablePoseCase.clips = new int[num3];
					portablePoseCase.frames = new float[num3];
					portablePoseCase.weights = new float[num3 - 1];
					for (int l = 0; l < num3; l++)
					{
						portablePoseCase.clips[l] = binaryReader.ReadInt32();
						portablePoseCase.frames[l] = binaryReader.ReadSingle();
						if (portablePoseCase.clips[l] < 0 || portablePoseCase.clips[l] >= num)
						{
							throw new InvalidDataException("Pose clip index");
						}
					}
					for (int m = 0; m < num3 - 1; m++)
					{
						portablePoseCase.weights[m] = binaryReader.ReadSingle();
					}
					requests[k] = portablePoseCase;
				}
				if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
				{
					throw new InvalidDataException("Unconsumed original pose input");
				}
				evidence.portablePoseClips = num;
			}
			catch (Exception ex)
			{
				Fail(ex);
				yield break;
			}
			BinaryWriter writer = null;
			try
			{
				writer = new BinaryWriter(File.Create(Path.Combine(settings.outputDirectory, "portable_pose_readback.bin")), Encoding.UTF8);
				writer.Write(Encoding.ASCII.GetBytes("HWEWPSR1"));
				writer.Write(1);
				writer.Write(requests.Length);
				for (int n = 0; n < requests.Length; n++)
				{
					try
					{
						PortablePoseCase portablePoseCase2 = requests[n];
						float[] array2 = sampler.Sample(originalClips[portablePoseCase2.clips[0]], portablePoseCase2.frames[0]);
						for (int num4 = 1; num4 < portablePoseCase2.clips.Length; num4++)
						{
							array2 = sampler.Blend(array2, sampler.Sample(originalClips[portablePoseCase2.clips[num4]], portablePoseCase2.frames[num4]), portablePoseCase2.weights[num4 - 1]);
						}
						writer.Write(n);
						writer.Write(n >= sampleCount);
						writer.Write(78);
						float[] array3 = array2;
						foreach (float num6 in array3)
						{
							if (float.IsNaN(num6) || float.IsInfinity(num6))
							{
								throw new InvalidDataException("Nonfinite portable pose");
							}
							writer.Write(num6);
						}
						Matrix4x4[] array4 = (Matrix4x4[])(object)new Matrix4x4[78];
						for (int num7 = 0; num7 < 78; num7++)
						{
							Matrix4x4 val = TRS(V3(array2, num7 * 10), Q(array2, num7 * 10 + 3), V3(array2, num7 * 10 + 7));
							array4[num7] = ((parents[num7] < 0) ? val : (array4[parents[num7]] * val));
							WriteMatrix(writer, array4[num7]);
						}
						evidence.portablePoseCases++;
					}
					catch (Exception ex2)
					{
						Fail(ex2);
						yield break;
					}
					yield return null;
				}
			}
			finally
			{
				writer?.Dispose();
			}
			evidence.portablePoseSamplingCompleted = true;
			evidence.portablePoseFinalConstraintOrMeshAcceptance = false;
			evidence.portablePoseScope = "Original raw integer component keys, raw quaternion endpoint retention and source fractional NLERP, source layer SLERP and hierarchy computed in RoR2. Leaf decoding remains offline original code; layer weights explicit original-manager reference. Constraints/aim/parts/root/physics and final model frame integration remain separate.";
			SaveEvidence();
			Debug.Log((object)("[HeavyarmsEW.Stage3] PORTABLE_POSE_SAMPLING_COMPLETE " + evidence.portablePoseCases));
		}

		private static void WriteEase(BinaryWriter w, OriginalEaseState s)
		{
			w.Write(s.Start);
			w.Write(s.End);
			w.Write(s.Value);
			w.Write(s.Elapsed);
			w.Write(s.Duration);
			w.Write(s.Progress);
			w.Write(s.Kind);
		}

		private static void WritePool(BinaryWriter w, OriginalBlendPool pool)
		{
			w.Write(pool.Active.Count);
			foreach (int item in pool.Active)
			{
				w.Write(item);
			}
			w.Write(pool.Free.Count);
			foreach (int item2 in pool.Free)
			{
				w.Write(item2);
			}
			w.Write(pool.States.Length);
			OriginalEaseState[] states = pool.States;
			foreach (OriginalEaseState s in states)
			{
				WriteEase(w, s);
			}
			float[] array = pool.Weights();
			w.Write(array.Length);
			float[] array2 = array;
			foreach (float value in array2)
			{
				w.Write(value);
			}
		}

		private static ClockEvent ReadClockEvent(BinaryReader r)
		{
			ClockEvent clockEvent = new ClockEvent();
			clockEvent.op = r.ReadInt32();
			switch (clockEvent.op)
			{
			case 0:
				clockEvent.clip = r.ReadInt32();
				clockEvent.frame = r.ReadSingle();
				clockEvent.blend = r.ReadSingle();
				clockEvent.kind = r.ReadInt32();
				clockEvent.loop = r.ReadBoolean();
				break;
			case 1:
				clockEvent.delta = r.ReadSingle();
				break;
			case 2:
				clockEvent.rate = r.ReadSingle();
				clockEvent.blendRate = r.ReadSingle();
				break;
			default:
				throw new InvalidDataException("Clock event");
			}
			return clockEvent;
		}

		private IEnumerator ReplayPortableClocks()
		{
			try
			{
				byte[] buffer = File.ReadAllBytes(Path.Combine(root, settings.portableClockPath));
				using (SHA256 sHA = SHA256.Create())
				{
					evidence.portableClockInputSHA256 = BitConverter.ToString(sHA.ComputeHash(buffer)).Replace("-", "").ToLowerInvariant();
				}
				using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(buffer), Encoding.UTF8))
				{
					using BinaryWriter binaryWriter = new BinaryWriter(File.Create(Path.Combine(settings.outputDirectory, "portable_clock_readback.bin")), Encoding.UTF8);
					if (Encoding.ASCII.GetString(binaryReader.ReadBytes(8)) != "HWEWCLK1" || binaryReader.ReadInt32() != 1 || binaryReader.ReadInt32() != 78)
					{
						throw new InvalidDataException("Clock input version");
					}
					float[] array = ReadFloats(binaryReader, 4);
					float[] array2 = ReadFloats(binaryReader, 5);
					int[] array3 = new int[78];
					for (int i = 0; i < 78; i++)
					{
						array3[i] = binaryReader.ReadInt32();
					}
					int num = binaryReader.ReadInt32();
					if (num < 1 || num > 256)
					{
						throw new InvalidDataException("Clock clips");
					}
					OriginalPoseKeys[] array4 = new OriginalPoseKeys[num];
					for (int j = 0; j < num; j++)
					{
						OriginalPoseKeys originalPoseKeys = new OriginalPoseKeys();
						originalPoseKeys.name = binaryReader.ReadString();
						originalPoseKeys.frames = binaryReader.ReadInt32();
						originalPoseKeys.keys = ReadFloats(binaryReader, originalPoseKeys.frames * 78 * 10);
						array4[j] = originalPoseKeys;
					}
					binaryWriter.Write(Encoding.ASCII.GetBytes("HWEWCLR1"));
					binaryWriter.Write(1);
					int num2 = binaryReader.ReadInt32();
					binaryWriter.Write(num2);
					for (int k = 0; k < num2; k++)
					{
						OriginalEaseState originalEaseState = new OriginalEaseState
						{
							Kind = binaryReader.ReadInt32(),
							Elapsed = binaryReader.ReadSingle(),
							Duration = binaryReader.ReadSingle(),
							Start = binaryReader.ReadSingle(),
							End = binaryReader.ReadSingle()
						};
						originalEaseState.Evaluate(array2[0]);
						WriteEase(binaryWriter, originalEaseState);
						evidence.portableClockEasingCases++;
					}
					int num3 = binaryReader.ReadInt32();
					binaryWriter.Write(num3);
					for (int l = 0; l < num3; l++)
					{
						int num4 = binaryReader.ReadInt32();
						int num5 = binaryReader.ReadInt32();
						OriginalBlendPool originalBlendPool = new OriginalBlendPool(num4, array2[0]);
						binaryWriter.Write(num4);
						binaryWriter.Write(num5);
						for (int m = 0; m < num5; m++)
						{
							int num6 = binaryReader.ReadInt32();
							int value = -1;
							switch (num6)
							{
							case 1:
							{
								float duration = binaryReader.ReadSingle();
								int kind = binaryReader.ReadInt32();
								value = originalBlendPool.Select(duration, kind);
								break;
							}
							case 2:
								originalBlendPool.Advance(binaryReader.ReadSingle());
								break;
							default:
								throw new InvalidDataException("Pool operation");
							case 0:
								break;
							}
							binaryWriter.Write(value);
							WritePool(binaryWriter, originalBlendPool);
							evidence.portableClockPoolSteps++;
						}
					}
					int num7 = binaryReader.ReadInt32();
					binaryWriter.Write(num7);
					OriginalClockController originalClockController = new OriginalClockController(4, array2);
					OriginalPoseSampler originalPoseSampler = new OriginalPoseSampler(78, array[0], array[1], array[2], array[3]);
					for (int n = 0; n < num7; n++)
					{
						ClockEvent clockEvent = ReadClockEvent(binaryReader);
						int value2 = -1;
						if (clockEvent.op == 0)
						{
							value2 = originalClockController.Bind(clockEvent.clip, (float)(array4[clockEvent.clip].frames - 1) / 60f, clockEvent.frame, clockEvent.blend, clockEvent.kind, clockEvent.loop);
						}
						else if (clockEvent.op == 1)
						{
							originalClockController.Advance(clockEvent.delta);
						}
						else
						{
							originalClockController.Rate = clockEvent.rate;
							originalClockController.BlendRate = clockEvent.blendRate;
						}
						binaryWriter.Write(n);
						binaryWriter.Write(value2);
						WritePool(binaryWriter, originalClockController.Pool);
						binaryWriter.Write(originalClockController.Rate);
						binaryWriter.Write(originalClockController.BlendRate);
						binaryWriter.Write(originalClockController.LastDelta);
						binaryWriter.Write(originalClockController.PreviousFrame);
						binaryWriter.Write(originalClockController.BindingFlag);
						OriginalAnimationClock[] clocks = originalClockController.Clocks;
						foreach (OriginalAnimationClock originalAnimationClock in clocks)
						{
							binaryWriter.Write(originalAnimationClock.Clip);
							binaryWriter.Write(originalAnimationClock.Time);
							binaryWriter.Write(originalAnimationClock.Duration);
							binaryWriter.Write(originalAnimationClock.Loop);
						}
						float[] array5 = null;
						float[] array6 = originalClockController.Pool.Weights();
						for (int num9 = 0; num9 < originalClockController.Pool.Active.Count; num9++)
						{
							OriginalAnimationClock originalAnimationClock2 = originalClockController.Clocks[originalClockController.Pool.Active[num9]];
							float[] array7 = originalPoseSampler.SampleTime(array4[originalAnimationClock2.Clip], originalAnimationClock2.Time);
							array5 = ((array5 == null) ? array7 : originalPoseSampler.Blend(array5, array7, array6[num9 - 1]));
						}
						if (array5 == null)
						{
							throw new InvalidDataException("Empty controller pose");
						}
						float[] array8 = array5;
						foreach (float num10 in array8)
						{
							if (float.IsInfinity(num10) || float.IsNaN(num10))
							{
								throw new InvalidDataException("Nonfinite controller pose");
							}
							binaryWriter.Write(num10);
						}
						Matrix4x4[] array9 = (Matrix4x4[])(object)new Matrix4x4[78];
						for (int num11 = 0; num11 < 78; num11++)
						{
							Matrix4x4 val = TRS(V3(array5, num11 * 10), Q(array5, num11 * 10 + 3), V3(array5, num11 * 10 + 7));
							array9[num11] = ((array3[num11] < 0) ? val : (array9[array3[num11]] * val));
							WriteMatrix(binaryWriter, array9[num11]);
						}
						evidence.portableClockPoseSteps++;
					}
					if (binaryRe