Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TetoAndPearto v0.3.0
BepInEx/plugins/RepoTeto/TetoAddon.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using BepInEx.Bootstrap; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyVersion("0.0.0.0")] namespace RepoTeto; [BepInPlugin("local.repo.tetoaddon", "R.E.P.O. Teto Addon", "0.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class TetoAddon : BaseUnityPlugin { private const string ExpectedBaseHash = "C5C0DAF063A670313CA7DAD45DF7257DF916F7AA0E2B7D9AE8129E53244F68B5"; private const string ModelName = "KasaneTeto"; private const string CacheKey = "repo-teto/kasaneteto.prefab"; private const int SpeedGrowth = 30; private const int PowerGrowth = 30; private AssetBundle bundle; private RuntimeModelAssets runtimeAssets; private static readonly List<Action> pendingRegistrations = new List<Action>(); private static TetoAddon activeInstance; private static int registeredModelId = -1; private static int registeredSlotId = -1; public static int RegisteredModelId => registeredModelId; public static int RegisteredSlotId => registeredSlotId; public static void AfterTetoRegistered(Action registerCharacter) { if (registerCharacter == null) { throw new ArgumentNullException("registerCharacter"); } if (RegisteredModelId < 0) { pendingRegistrations.Add(registerCharacter); } else { RunRegistration(registerCharacter); } } private static void RunRegistration(Action callback) { try { callback(); } catch (Exception ex) { if ((Object)(object)activeInstance != (Object)null) { ((BaseUnityPlugin)activeInstance).Logger.LogError((object)("Dependent character registration failed: " + ex)); } else { Debug.LogError((object)("[TetoAddon] Dependent character registration failed: " + ex)); } } } private void Awake() { activeInstance = this; SceneManager.sceneLoaded += RegisterAfterSceneLoad; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Teto initialization queued for the first loaded scene."); } private void RegisterAfterSceneLoad(Scene scene, LoadSceneMode mode) { SceneManager.sceneLoaded -= RegisterAfterSceneLoad; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Preparing Teto after scene load: " + ((Scene)(ref scene)).name)); try { RegisterModel(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Teto was not registered: " + ex.ToString())); } if (Array.IndexOf(Environment.GetCommandLineArgs(), "--teto-self-test") >= 0) { Application.Quit(); } } private void OnDestroy() { SceneManager.sceneLoaded -= RegisterAfterSceneLoad; } private void RegisterModel() { if (!Chainloader.PluginInfos.TryGetValue("UmamusumeSemiBots", out var value)) { throw new InvalidOperationException("UmamusumeSemibots is required."); } Type type = ((object)value.Instance).GetType(); using (SHA256 sHA = SHA256.Create()) { using FileStream inputStream = File.OpenRead(type.Assembly.Location); string a = BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", ""); if (!string.Equals(a, "C5C0DAF063A670313CA7DAD45DF7257DF916F7AA0E2B7D9AE8129E53244F68B5", StringComparison.Ordinal)) { throw new InvalidOperationException("This addon supports the inspected UmamusumeSemibots 2.1.0 DLL only."); } } string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); string text = Path.Combine(directoryName, "tetoassets"); List<string> list = ReadField<List<string>>(type, "ModelNames"); List<string> list2 = ReadField<List<string>>(type, "ModelAssetPaths"); List<Texture2D> list3 = ReadField<List<Texture2D>>(type, "Thumbnails"); List<Texture2D> list4 = ReadField<List<Texture2D>>(type, "Chibis"); List<Texture2D> list5 = ReadField<List<Texture2D>>(type, "ChibisTalking"); List<List<int>> list6 = ReadField<List<List<int>>>(type, "ModelOutfitGroups"); Dictionary<int, int> dictionary = ReadField<Dictionary<int, int>>(type, "SlotOutfitSelection"); Dictionary<int, int> dictionary2 = ReadField<Dictionary<int, int>>(type, "ColorToModel"); Dictionary<string, GameObject> dictionary3 = ReadField<Dictionary<string, GameObject>>(type, "_loadedPrefabs"); if (list.Contains("KasaneTeto")) { throw new InvalidOperationException("KasaneTeto is already registered."); } int count = list.Count; if (list2.Count != count || list3.Count != count || list4.Count != count || list5.Count != count) { throw new InvalidOperationException("Base model lists are not aligned; refusing registration."); } int count2 = list6.Count; if (dictionary.ContainsKey(count2) || dictionary2.ContainsKey(count2) || dictionary3.ContainsKey("repo-teto/kasaneteto.prefab")) { throw new InvalidOperationException("Model slot/cache collision; refusing registration."); } Type type2 = type.Assembly.GetType("UmamusumeSemiBots.UmaGrowthRateData", throwOnError: true); Type type3 = type.Assembly.GetType("UmamusumeSemiBots.UmaGrowthRates", throwOnError: true); IDictionary dictionary4 = ReadField<IDictionary>(type2, "UmaGrowthRateTable"); if (dictionary4.Contains("KasaneTeto")) { throw new InvalidOperationException("Teto growth rates already exist; refusing registration."); } object value2 = Activator.CreateInstance(type3, 30, 0, 30, 0, 0); MethodInfo method = type.GetMethod("GetPrefabFlat", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method == null || count == 0) { throw new InvalidOperationException("Reference prefab loader is unavailable."); } object? obj = method.Invoke(null, new object[1] { 0 }); GameObject val = (GameObject)((obj is GameObject) ? obj : null); Animator val2 = (((Object)(object)val == (Object)null) ? null : val.GetComponent<Animator>()); if ((Object)(object)val2 == (Object)null || (Object)(object)val2.runtimeAnimatorController == (Object)null) { throw new InvalidOperationException("Reference animation controller is unavailable."); } GameObject val3; Texture2D val4; Texture2D val5; Texture2D val6; if (File.Exists(text)) { bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)bundle == (Object)null) { throw new InvalidOperationException("Could not read tetoassets."); } val3 = bundle.LoadAsset<GameObject>("KasaneTeto"); val4 = bundle.LoadAsset<Texture2D>("KasaneTetoThumbnail"); val5 = bundle.LoadAsset<Texture2D>("KasaneTetoChibi"); val6 = bundle.LoadAsset<Texture2D>("KasaneTetoChibiTalk"); } else { string text2 = Path.Combine(directoryName, "assets"); if (!File.Exists(Path.Combine(text2, "teto.rpm")) || !File.Exists(Path.Combine(text2, "pearto.rpm"))) { throw new FileNotFoundException("Prepared Teto and Pearto data is missing."); } runtimeAssets = RuntimeModelFactory.Create(text2, val); val3 = runtimeAssets.Prefab; val4 = runtimeAssets.Thumbnail; val5 = runtimeAssets.Chibi; val6 = runtimeAssets.ChibiTalk; } if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null) { throw new InvalidOperationException("The prefab and portrait textures are required."); } ValidatePrefab(val3); val3.GetComponent<Animator>().runtimeAnimatorController = val2.runtimeAnimatorController; ((Object)val3).name = "KasaneTeto"; Type type4 = type.Assembly.GetType("UmamusumeSemiBots.UmaModelCrouchData"); Dictionary<string, float> dictionary5 = ReadField<Dictionary<string, float>>(type4, "CrouchOffsets"); if (!dictionary5.TryGetValue(Path.GetFileNameWithoutExtension(list[0]), out var value3)) { throw new InvalidOperationException("Reference model has no calibrated crouch camera distance."); } dictionary5["KasaneTeto"] = value3; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Teto crouch camera uses reference " + list[0] + ": " + value3)); dictionary4.Add("KasaneTeto", value2); dictionary3.Add("repo-teto/kasaneteto.prefab", val3); list.Add("KasaneTeto"); list2.Add("repo-teto/kasaneteto.prefab"); list3.Add(val4); list4.Add(val5); list5.Add(val6); list6.Add(new List<int> { count }); dictionary.Add(count2, 0); dictionary2.Add(count2, count); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Kasane Teto registered: slot=" + count2 + ", model=" + count + ". Both players need identical base mod and addon assets.")); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Teto growth rates: Speed=+30%, Power=+30%; Stamina/Guts/Wit=0%. Uses the base mod's upgrade multipliers and EnableGrowthRates setting."); if (Array.IndexOf(Environment.GetCommandLineArgs(), "--teto-self-test") >= 0) { ValidateGrowthMultipliers(type); } registeredModelId = count; registeredSlotId = count2; Action[] array = pendingRegistrations.ToArray(); pendingRegistrations.Clear(); Action[] array2 = array; foreach (Action callback in array2) { RunRegistration(callback); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Character registration callback ready; pending callbacks processed=" + array.Length)); MethodInfo method2 = type.GetMethod("LoadSavedModel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method2 != null) { try { method2.Invoke(value.Instance, null); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not restore saved selection: " + ex.Message)); } } } private static T ReadField<T>(Type type, string name) where T : class { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); T val = ((field == null) ? null : (field.GetValue(null) as T)); if (val == null) { throw new InvalidOperationException("Missing/incompatible base mod field: " + name); } return val; } private static void ValidateGrowthMultipliers(Type modType) { Type nestedType = modType.GetNestedType("PunManagerUpgradePatch", BindingFlags.Public | BindingFlags.NonPublic); MethodInfo methodInfo = ((nestedType == null) ? null : nestedType.GetMethod("GetGrowthMultiplier", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); if (methodInfo == null) { throw new InvalidOperationException("Original growth multiplier method is unavailable."); } string[] array = new string[5] { "speed", "strength", "stamina", "health", "range" }; foreach (string text in array) { float num = (float)methodInfo.Invoke(null, new object[2] { "KasaneTeto", text }); float num2 = ((text == "speed" || text == "strength") ? 1.3f : 1f); if (!Mathf.Approximately(num, num2)) { throw new InvalidOperationException("Original growth multiplier differs for " + text + ": " + num); } Debug.Log((object)("[TetoAddon] Original upgrade multiplier verified: " + text + "=" + num)); } } private static void ValidatePrefab(GameObject prefab) { Animator component = prefab.GetComponent<Animator>(); Transform val = prefab.transform.Find("Body"); Transform val2 = prefab.transform.Find("Smol"); if ((Object)(object)component == (Object)null || (Object)(object)component.avatar == (Object)null || !component.avatar.isValid || !component.avatar.isHuman) { throw new InvalidOperationException("KasaneTeto needs a valid Humanoid Animator on its root."); } if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponent<SkinnedMeshRenderer>() == (Object)null) { throw new InvalidOperationException("KasaneTeto needs a direct Body child with a SkinnedMeshRenderer."); } if ((Object)(object)prefab.transform.Find("Armature/Hips/Spine/Chest/Neck") == (Object)null) { throw new InvalidOperationException("Expected Armature/Hips/Spine/Chest/Neck hierarchy is missing."); } Animator val3 = (((Object)(object)val2 == (Object)null) ? null : ((Component)val2).GetComponent<Animator>()); if ((Object)(object)val3 == (Object)null || (Object)(object)val3.avatar == (Object)null || !val3.avatar.isValid || !val3.avatar.isHuman) { throw new InvalidOperationException("Smol needs its own valid Humanoid Animator; a static pear alone does not provide the original chibi IK."); } if ((Object)(object)((Component)val2).GetComponentInChildren<SkinnedMeshRenderer>(true) == (Object)null) { throw new InvalidOperationException("Smol needs a SkinnedMeshRenderer."); } if ((Object)(object)val2.Find("SmolEyePosition") == (Object)null) { throw new InvalidOperationException("Smol/SmolEyePosition anchor is missing."); } } } internal sealed class RuntimeModelAssets { public GameObject Prefab; public Texture2D Thumbnail; public Texture2D Chibi; public Texture2D ChibiTalk; public GameObject Storage; } internal static class RuntimeModelFactory { private static readonly Dictionary<Texture2D, Texture2D> alphaMasks = new Dictionary<Texture2D, Texture2D>(); private static int Count(BinaryReader reader, int max) { int num = reader.ReadInt32(); if (num < 0 || num > max) { throw new InvalidDataException("Invalid prepared asset count."); } return num; } private static string Text(BinaryReader reader) { int num = Count(reader, 4096); byte[] array = reader.ReadBytes(num); if (array.Length != num) { throw new EndOfStreamException(); } return Encoding.UTF8.GetString(array); } private static Vector3 Vec(BinaryReader reader) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } private static Texture2D Texture(string path) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(path), false)) { throw new InvalidDataException("Cannot decode " + Path.GetFileName(path)); } ((Object)val).name = Path.GetFileNameWithoutExtension(path); ((Texture)val).wrapMode = (TextureWrapMode)1; return val; } private static Material Surface(Shader shader, Texture2D texture, Color color, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(shader); ((Object)val).name = name; val.mainTexture = (Texture)(object)texture; if (val.HasProperty("_Color")) { val.SetColor("_Color", color); } if (val.HasProperty("_Glossiness")) { val.SetFloat("_Glossiness", 0.12f); } if (val.HasProperty("_Metallic")) { val.SetFloat("_Metallic", 0f); } if (val.HasProperty("_Cull")) { val.SetInt("_Cull", 0); } if (val.HasProperty("_ShadowTex")) { val.SetTexture("_ShadowTex", (Texture)(object)texture); } if (val.HasProperty("_MinBrightness")) { val.SetFloat("_MinBrightness", 0.25f); } if (val.HasProperty("_AmbientStrength")) { val.SetFloat("_AmbientStrength", 0.35f); } if (val.HasProperty("_ShadowStrength")) { val.SetFloat("_ShadowStrength", 0.35f); } if (val.HasProperty("_BrightnessClamp")) { val.SetFloat("_BrightnessClamp", 1f); } if (val.HasProperty("_RimStrength")) { val.SetFloat("_RimStrength", 0f); } if (val.HasProperty("_SpecularStrength")) { val.SetFloat("_SpecularStrength", 0f); } if (val.HasProperty("_MatcapStrength")) { val.SetFloat("_MatcapStrength", 0f); } if (val.HasProperty("_RflStrength")) { val.SetFloat("_RflStrength", 0f); } if (val.HasProperty("_OutlineWidth")) { val.SetFloat("_OutlineWidth", (((Object)shader).name == "Custom/Chibi Shader") ? 0.003f : 0.5f); } if (val.HasProperty("_MaskTex") && (Object)(object)texture != (Object)null) { val.SetTexture("_MaskTex", (Texture)(object)AlphaMask(texture)); } if (((Object)shader).name == "Standard") { val.SetFloat("_Glossiness", 0f); val.SetFloat("_SpecularHighlights", 0f); val.SetFloat("_GlossyReflections", 0f); val.SetColor("_EmissionColor", Color.black); val.DisableKeyword("_EMISSION"); } if (val.HasProperty("_Cutoff")) { val.SetFloat("_Cutoff", 0.25f); if (val.HasProperty("_Mode")) { val.SetFloat("_Mode", 1f); val.EnableKeyword("_ALPHATEST_ON"); } val.renderQueue = 2450; } return val; } private static Material ReferenceSurface(Material template, Texture2D texture, Color color, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0032: 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) Material val = new Material(template); ((Object)val).name = "Teto_" + name; val.mainTexture = (Texture)(object)texture; if (val.HasProperty("_Color")) { val.SetColor("_Color", color); } if (val.HasProperty("_ShadowTex")) { val.SetTexture("_ShadowTex", (Texture)(object)texture); } if (val.HasProperty("_MaskTex") && (Object)(object)texture != (Object)null) { val.SetTexture("_MaskTex", (Texture)(object)AlphaMask(texture)); } if (val.HasProperty("_EmissionColor")) { val.SetColor("_EmissionColor", Color.black); } if (val.HasProperty("_EmissionStrength")) { val.SetFloat("_EmissionStrength", 0f); } val.DisableKeyword("_EMISSION"); string[] array = new string[4] { "_MatcapStrength", "_SpecularStrength", "_RflStrength", "_RimStrength" }; foreach (string text in array) { if (val.HasProperty(text)) { val.SetFloat(text, 0f); } } if (val.HasProperty("_Cutoff")) { val.SetFloat("_Cutoff", 0.25f); } val.renderQueue = 2450; return val; } private static Texture2D AlphaMask(Texture2D source) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) if (alphaMasks.TryGetValue(source, out var value)) { return value; } Color32[] pixels = source.GetPixels32(); for (int i = 0; i < pixels.Length; i++) { ref Color32 reference = ref pixels[i]; reference = new Color32(byte.MaxValue, (byte)0, pixels[i].a, byte.MaxValue); } value = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)4, true); ((Object)value).name = ((Object)source).name + "_AlphaMask"; ((Texture)value).wrapMode = ((Texture)source).wrapMode; value.SetPixels32(pixels); value.Apply(); alphaMasks.Add(source, value); return value; } public static RuntimeModelAssets Create(string directory, GameObject reference) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_027f: 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_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) Transform val = reference.transform.Find("Body"); SkinnedMeshRenderer val2 = (((Object)(object)val == (Object)null) ? null : ((Component)val).GetComponent<SkinnedMeshRenderer>()); Shader val3 = (((Object)(object)val2 != (Object)null && ((Renderer)val2).sharedMaterials.Length > 0) ? ((Renderer)val2).sharedMaterials[0].shader : Shader.Find("Standard")); if ((Object)(object)val3 == (Object)null) { val3 = Shader.Find("Unlit/Texture"); } if ((Object)(object)val3 == (Object)null) { throw new InvalidOperationException("No supported texture shader in the game."); } Debug.Log((object)("[TetoAddon] Surface shader: " + ((Object)val3).name)); RuntimeModelAssets runtimeModelAssets = new RuntimeModelAssets(); runtimeModelAssets.Storage = new GameObject("TetoAddon_Templates"); Object.DontDestroyOnLoad((Object)(object)runtimeModelAssets.Storage); try { GameObject val4 = CreateTeto(directory, val3, reference); val4.transform.SetParent(runtimeModelAssets.Storage.transform, false); Animator component = val4.GetComponent<Animator>(); component.runtimeAnimatorController = reference.GetComponent<Animator>().runtimeAnimatorController; CreatePear(directory, val3, reference, val4); ((Component)val4.transform.Find("Smol")).gameObject.SetActive(false); ((Behaviour)component).enabled = false; runtimeModelAssets.Thumbnail = Portrait(val4, val4.transform.Find("Armature/Hips/Spine/Chest/Neck/Head").position + Vector3.up * 0.12f, 0.38f); File.WriteAllBytes(Path.Combine(directory, "preview-upperbody.png"), ImageConversion.EncodeToPNG(Portrait(val4, new Vector3(0f, 1.3f, -0.05f), 0.48f))); if (Array.IndexOf(Environment.GetCommandLineArgs(), "--teto-self-test") >= 0) { GameObject val5 = Object.Instantiate<GameObject>(reference); val5.transform.position = Vector3.zero; ((Behaviour)val5.GetComponent<Animator>()).enabled = false; ((Component)val5.transform.Find("Smol")).gameObject.SetActive(false); File.WriteAllBytes(Path.Combine(directory, "test-reference-lighting.png"), ImageConversion.EncodeToPNG(Portrait(val5, new Vector3(0f, 1.3f, -0.05f), 0.48f))); Object.Destroy((Object)(object)val5); } Transform val6 = val4.transform.Find("Smol"); ((Component)val4.transform.Find("Body")).gameObject.SetActive(false); ((Component)val6).gameObject.SetActive(true); SkinnedMeshRenderer componentInChildren = ((Component)val6).GetComponentInChildren<SkinnedMeshRenderer>(true); Bounds val7 = SkinnedWorldBounds(componentInChildren); float size = Mathf.Max(Mathf.Max(((Bounds)(ref val7)).size.y, ((Bounds)(ref val7)).size.x) * 0.58f, 0.2f); Texture2D val8 = Portrait(val4, ((Bounds)(ref val7)).center, size); File.WriteAllBytes(Path.Combine(directory, "preview-teto.png"), ImageConversion.EncodeToPNG(runtimeModelAssets.Thumbnail)); File.WriteAllBytes(Path.Combine(directory, "preview-pearto.png"), ImageConversion.EncodeToPNG(val8)); ((Component)val6).gameObject.SetActive(false); ((Behaviour)((Component)val6).GetComponent<Animator>()).enabled = true; ((Component)val4.transform.Find("Body")).gameObject.SetActive(true); CreateUiPortraits(directory, val4, runtimeModelAssets); ((Behaviour)component).enabled = true; runtimeModelAssets.Storage.SetActive(false); runtimeModelAssets.Prefab = val4; ValidateReferenceAnimation(val4, reference, runtimeModelAssets.Storage); if (Array.IndexOf(Environment.GetCommandLineArgs(), "--teto-self-test") >= 0) { ValidateBodyPoses(val4, reference, runtimeModelAssets.Storage, directory); } Debug.Log((object)("[TetoAddon] Prepared model created; main Avatar valid=" + component.avatar.isValid + ", human=" + component.avatar.isHuman)); return runtimeModelAssets; } catch { Object.Destroy((Object)(object)runtimeModelAssets.Storage); throw; } } private static GameObject CreateTeto(string directory, Shader shader, GameObject reference) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_04da: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_04ed: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_0830: Unknown result type (might be due to invalid IL or missing references) //IL_0778: Unknown result type (might be due to invalid IL or missing references) //IL_077f: Unknown result type (might be due to invalid IL or missing references) //IL_078d: Unknown result type (might be due to invalid IL or missing references) //IL_0792: Unknown result type (might be due to invalid IL or missing references) //IL_0797: Unknown result type (might be due to invalid IL or missing references) //IL_0887: Unknown result type (might be due to invalid IL or missing references) //IL_088e: Unknown result type (might be due to invalid IL or missing references) //IL_0893: Unknown result type (might be due to invalid IL or missing references) //IL_08a2: Unknown result type (might be due to invalid IL or missing references) //IL_08a7: Unknown result type (might be due to invalid IL or missing references) //IL_0a3c: Unknown result type (might be due to invalid IL or missing references) //IL_0a43: Expected O, but got Unknown //IL_08ff: Unknown result type (might be due to invalid IL or missing references) //IL_0904: Unknown result type (might be due to invalid IL or missing references) //IL_090b: Unknown result type (might be due to invalid IL or missing references) //IL_0982: Unknown result type (might be due to invalid IL or missing references) //IL_0984: Unknown result type (might be due to invalid IL or missing references) //IL_0993: Unknown result type (might be due to invalid IL or missing references) //IL_09a6: Unknown result type (might be due to invalid IL or missing references) //IL_09b2: Unknown result type (might be due to invalid IL or missing references) //IL_09c5: Unknown result type (might be due to invalid IL or missing references) //IL_09d1: Unknown result type (might be due to invalid IL or missing references) //IL_09d6: Unknown result type (might be due to invalid IL or missing references) //IL_09e9: Unknown result type (might be due to invalid IL or missing references) //IL_09f5: Unknown result type (might be due to invalid IL or missing references) //IL_09fa: Unknown result type (might be due to invalid IL or missing references) //IL_0a0d: Unknown result type (might be due to invalid IL or missing references) //IL_0a19: Unknown result type (might be due to invalid IL or missing references) //IL_0a1e: Unknown result type (might be due to invalid IL or missing references) //IL_0a23: Unknown result type (might be due to invalid IL or missing references) //IL_0a28: Unknown result type (might be due to invalid IL or missing references) //IL_0a97: Unknown result type (might be due to invalid IL or missing references) //IL_0aa2: Unknown result type (might be due to invalid IL or missing references) //IL_0aa7: Unknown result type (might be due to invalid IL or missing references) //IL_0aac: Unknown result type (might be due to invalid IL or missing references) //IL_05a7: Unknown result type (might be due to invalid IL or missing references) //IL_05ac: Unknown result type (might be due to invalid IL or missing references) //IL_05ba: Unknown result type (might be due to invalid IL or missing references) //IL_05c1: Unknown result type (might be due to invalid IL or missing references) //IL_05c6: Unknown result type (might be due to invalid IL or missing references) //IL_05cb: Unknown result type (might be due to invalid IL or missing references) //IL_0605: Unknown result type (might be due to invalid IL or missing references) //IL_060a: Unknown result type (might be due to invalid IL or missing references) //IL_061f: Unknown result type (might be due to invalid IL or missing references) //IL_0626: Unknown result type (might be due to invalid IL or missing references) //IL_062b: Unknown result type (might be due to invalid IL or missing references) //IL_0630: Unknown result type (might be due to invalid IL or missing references) //IL_0645: Unknown result type (might be due to invalid IL or missing references) //IL_0be9: Unknown result type (might be due to invalid IL or missing references) //IL_0d70: Unknown result type (might be due to invalid IL or missing references) //IL_0d77: Unknown result type (might be due to invalid IL or missing references) //IL_0d7c: Unknown result type (might be due to invalid IL or missing references) //IL_0e3a: Unknown result type (might be due to invalid IL or missing references) //IL_0e46: Unknown result type (might be due to invalid IL or missing references) //IL_0e52: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(File.OpenRead(Path.Combine(directory, "teto.rpm"))); if (Encoding.ASCII.GetString(binaryReader.ReadBytes(8)) != "TETO0001") { throw new InvalidDataException("Unknown Teto model format."); } GameObject val = Object.Instantiate<GameObject>(reference); ((Object)val).name = "KasaneTeto"; val.transform.position = Vector3.zero; val.transform.rotation = Quaternion.identity; Animator component = val.GetComponent<Animator>(); ((Behaviour)component).enabled = false; if ((Object)(object)component.avatar == (Object)null || !component.avatar.isHuman || !component.avatar.isValid) { throw new InvalidDataException("Reference Avatar is not valid."); } MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val2 in componentsInChildren) { if (((object)val2).GetType().FullName == "JigglePhysicsPlugin.JiggleRigBuilder") { ((Behaviour)val2).enabled = false; } } Transform val3 = val.transform.Find("Armature"); if ((Object)(object)val3 == (Object)null) { throw new InvalidDataException("Reference armature is missing."); } int num = Count(binaryReader, 1024); Transform[] array = (Transform[])(object)new Transform[num]; int[] array2 = new int[num]; Vector3[] array3 = (Vector3[])(object)new Vector3[num]; string[] array4 = new string[num]; for (int j = 0; j < num; j++) { array4[j] = Text(binaryReader); array2[j] = binaryReader.ReadInt32(); ref Vector3 reference2 = ref array3[j]; reference2 = Vec(binaryReader); if (array2[j] >= num || array2[j] == j) { throw new InvalidDataException("Invalid bone hierarchy."); } } int num2 = Count(binaryReader, 100); Dictionary<HumanBodyBones, int> dictionary = new Dictionary<HumanBodyBones, int>(); for (int k = 0; k < num2; k++) { HumanBodyBones val4 = (HumanBodyBones)Enum.Parse(typeof(HumanBodyBones), Text(binaryReader)); int num3 = binaryReader.ReadInt32(); if (num3 < 0 || num3 >= num) { throw new InvalidDataException("Invalid human mapping."); } dictionary.Add(val4, num3); array[num3] = component.GetBoneTransform(val4); if ((Object)(object)array[num3] == (Object)null) { throw new InvalidDataException("Reference bone missing: " + val4); } } float num4 = array3[dictionary[(HumanBodyBones)13]].x - array3[dictionary[(HumanBodyBones)14]].x; float num5 = val.transform.InverseTransformPoint(array[dictionary[(HumanBodyBones)13]].position).x - val.transform.InverseTransformPoint(array[dictionary[(HumanBodyBones)14]].position).x; bool flag = Mathf.Sign(num4) != Mathf.Sign(num5); if (flag) { for (int l = 0; l < array3.Length; l++) { array3[l].x = 0f - array3[l].x; } } Debug.Log((object)("[TetoAddon] Source left/right axis corrected=" + flag)); float num6 = (array3[dictionary[(HumanBodyBones)21]].y + array3[dictionary[(HumanBodyBones)22]].y) * 0.5f; float num7 = (val.transform.InverseTransformPoint(array[dictionary[(HumanBodyBones)21]].position).y + val.transform.InverseTransformPoint(array[dictionary[(HumanBodyBones)22]].position).y) * 0.5f; float num8 = num7 / num6; if (num8 < 0.3f || num8 > 3f || float.IsNaN(num8)) { throw new InvalidDataException("Invalid reference scale."); } bool[] array5 = new bool[num]; foreach (int value3 in dictionary.Values) { array5[value3] = true; } float num9 = val.transform.InverseTransformPoint(array[dictionary[(HumanBodyBones)9]].position).y - array3[dictionary[(HumanBodyBones)9]].y * num8; float num10 = val.transform.InverseTransformPoint(array[dictionary[(HumanBodyBones)9]].position).z - array3[dictionary[(HumanBodyBones)9]].z * num8; Vector3[] array6 = (Vector3[])(object)new Vector3[num]; for (int m = 0; m < num; m++) { int num11 = m; int num12 = 0; while (num11 >= 0 && !array5[num11] && ++num12 <= num) { num11 = array2[num11]; } if (num12 > num) { throw new InvalidDataException("Cyclic source hierarchy."); } ref Vector3 reference3 = ref array6[m]; reference3 = ((num11 >= 0) ? (val.transform.InverseTransformPoint(array[num11].position) - array3[num11] * num8) : Vector3.zero); if (num11 == dictionary[(HumanBodyBones)7] || num11 == dictionary[(HumanBodyBones)8]) { array6[m].y = num9; } if (num11 == dictionary[(HumanBodyBones)0] || num11 == dictionary[(HumanBodyBones)7] || num11 == dictionary[(HumanBodyBones)8]) { array6[m].z = num10; } if (num11 == dictionary[(HumanBodyBones)19] || num11 == dictionary[(HumanBodyBones)20]) { int num13 = dictionary[(HumanBodyBones)((num11 == dictionary[(HumanBodyBones)19]) ? 5 : 6)]; ref Vector3 reference4 = ref array6[m]; reference4 = val.transform.InverseTransformPoint(array[num13].position) - array3[num13] * num8; } if (num11 == dictionary[(HumanBodyBones)21] || num11 == dictionary[(HumanBodyBones)22]) { ref Vector3 reference5 = ref array6[m]; reference5 = val.transform.InverseTransformPoint(array[dictionary[(HumanBodyBones)10]].position) - array3[dictionary[(HumanBodyBones)10]] * num8; } if (!array5[m]) { array[m] = new GameObject(array4[m]).transform; } } Debug.Log((object)("[TetoAddon] Torso rest spacing preserved relative to neck: yShift=" + num9 + "; source neck/chest spacing=" + (array3[dictionary[(HumanBodyBones)9]].y - array3[dictionary[(HumanBodyBones)8]].y) * num8)); Debug.Log((object)("[TetoAddon] Pelvis/torso depth aligned together: zShift=" + num10 + "; toe vertices retain ankle offset.")); for (int n = 0; n < num; n++) { if (!array5[n]) { array[n].SetParent((array2[n] < 0) ? val3 : array[array2[n]], false); } } Dictionary<Transform, int> dictionary2 = new Dictionary<Transform, int>(); for (int num14 = 0; num14 < num; num14++) { if (!array5[num14]) { dictionary2.Add(array[num14], num14); } } Transform[] componentsInChildren2 = val.GetComponentsInChildren<Transform>(true); foreach (Transform val5 in componentsInChildren2) { if (dictionary2.TryGetValue(val5, out var value)) { val5.position = val.transform.TransformPoint(array3[value] * num8 + array6[value]); } } Debug.Log((object)("[TetoAddon] Original reference Avatar reused=" + ((Object)(object)component.avatar == (Object)(object)reference.GetComponent<Animator>().avatar) + "; skeleton=" + ((Object)reference).name + "; humanScale=" + component.humanScale + "; eyeHeight=" + num7)); Debug.Log((object)("[TetoAddon] Reference animation visibility preserved: " + component.cullingMode)); int num15 = Count(binaryReader, 100000); Vector3[] array7 = (Vector3[])(object)new Vector3[num15]; Vector3[] array8 = (Vector3[])(object)new Vector3[num15]; Vector2[] array9 = (Vector2[])(object)new Vector2[num15]; BoneWeight[] array10 = (BoneWeight[])(object)new BoneWeight[num15]; for (int num16 = 0; num16 < num15; num16++) { ref Vector3 reference6 = ref array7[num16]; reference6 = Vec(binaryReader) * num8; ref Vector3 reference7 = ref array8[num16]; reference7 = Vec(binaryReader); if (flag) { array7[num16].x = 0f - array7[num16].x; array8[num16].x = 0f - array8[num16].x; } ref Vector2 reference8 = ref array9[num16]; reference8 = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); BoneWeight val6 = default(BoneWeight); ((BoneWeight)(ref val6)).boneIndex0 = binaryReader.ReadInt32(); ((BoneWeight)(ref val6)).boneIndex1 = binaryReader.ReadInt32(); ((BoneWeight)(ref val6)).boneIndex2 = binaryReader.ReadInt32(); ((BoneWeight)(ref val6)).boneIndex3 = binaryReader.ReadInt32(); ((BoneWeight)(ref val6)).weight0 = binaryReader.ReadSingle(); ((BoneWeight)(ref val6)).weight1 = binaryReader.ReadSingle(); ((BoneWeight)(ref val6)).weight2 = binaryReader.ReadSingle(); ((BoneWeight)(ref val6)).weight3 = binaryReader.ReadSingle(); array10[num16] = val6; ref Vector3 reference9 = ref array7[num16]; reference9 += array6[((BoneWeight)(ref val6)).boneIndex0] * ((BoneWeight)(ref val6)).weight0 + array6[((BoneWeight)(ref val6)).boneIndex1] * ((BoneWeight)(ref val6)).weight1 + array6[((BoneWeight)(ref val6)).boneIndex2] * ((BoneWeight)(ref val6)).weight2 + array6[((BoneWeight)(ref val6)).boneIndex3] * ((BoneWeight)(ref val6)).weight3; } Mesh val7 = new Mesh(); ((Object)val7).name = "TdaVkTeto"; val7.indexFormat = (IndexFormat)1; val7.vertices = array7; val7.normals = array8; val7.uv = array9; val7.boneWeights = array10; Matrix4x4[] array11 = (Matrix4x4[])(object)new Matrix4x4[num]; for (int num17 = 0; num17 < num; num17++) { ref Matrix4x4 reference10 = ref array11[num17]; reference10 = array[num17].worldToLocalMatrix * val.transform.localToWorldMatrix; } val7.bindposes = array11; int num18 = (val7.subMeshCount = Count(binaryReader, 128)); Material[] array12 = (Material[])(object)new Material[num18]; Dictionary<string, Texture2D> dictionary3 = new Dictionary<string, Texture2D>(); Color color = default(Color); for (int num20 = 0; num20 < num18; num20++) { string text = Text(binaryReader); string text2 = Text(binaryReader); ((Color)(ref color))..ctor(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); bool flag2 = binaryReader.ReadByte() != 0; Texture2D value2 = null; if (text2.Length > 0) { if (Path.GetFileName(text2) != text2) { throw new InvalidDataException("Invalid texture filename."); } if (!dictionary3.TryGetValue(text2, out value2)) { value2 = Texture(Path.Combine(directory, text2)); dictionary3.Add(text2, value2); } } Material[] sharedMaterials = ((Renderer)((Component)reference.transform.Find("Body")).GetComponent<SkinnedMeshRenderer>()).sharedMaterials; int num21 = ((text.StartsWith("neck", StringComparison.OrdinalIgnoreCase) || text.StartsWith("face", StringComparison.OrdinalIgnoreCase)) ? 2 : ((text.IndexOf("hair", StringComparison.OrdinalIgnoreCase) >= 0) ? 4 : 0)); array12[num20] = ReferenceSurface(sharedMaterials[Mathf.Min(num21, sharedMaterials.Length - 1)], value2, color, text); int num22 = Count(binaryReader, 1000000); if (num22 % 3 != 0) { throw new InvalidDataException("Invalid triangles."); } bool flag3 = flag2 && !array12[num20].HasProperty("_OutlineWidth"); int[] array13 = new int[flag3 ? (num22 * 2) : num22]; for (int num23 = 0; num23 < num22; num23++) { array13[num23] = binaryReader.ReadInt32(); if (array13[num23] < 0 || array13[num23] >= num15) { throw new InvalidDataException("Invalid vertex index."); } } if (flag) { for (int num24 = 0; num24 < num22; num24 += 3) { int num25 = array13[num24 + 1]; array13[num24 + 1] = array13[num24 + 2]; array13[num24 + 2] = num25; } } if (flag3) { for (int num26 = 0; num26 < num22; num26 += 3) { array13[num22 + num26] = array13[num26]; array13[num22 + num26 + 1] = array13[num26 + 2]; array13[num22 + num26 + 2] = array13[num26 + 1]; } } val7.SetTriangles(array13, num20); } int num27 = Count(binaryReader, 256); Vector3[] array14 = (Vector3[])(object)new Vector3[num15]; for (int num28 = 0; num28 < num27; num28++) { string text3 = Text(binaryReader); int num29 = Count(binaryReader, num15); Vector3[] array15 = (Vector3[])(object)new Vector3[num15]; for (int num30 = 0; num30 < num29; num30++) { int num31 = binaryReader.ReadInt32(); if (num31 < 0 || num31 >= num15) { throw new InvalidDataException("Invalid shape vertex."); } ref Vector3 reference11 = ref array15[num31]; reference11 = Vec(binaryReader) * num8; if (flag) { array15[num31].x = 0f - array15[num31].x; } } val7.AddBlendShapeFrame(text3, 100f, array15, array14, array14); } if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length) { throw new InvalidDataException("Trailing model data."); } val7.RecalculateBounds(); Transform val8 = val.transform.Find("Body"); SkinnedMeshRenderer val9 = (((Object)(object)val8 == (Object)null) ? null : ((Component)val8).GetComponent<SkinnedMeshRenderer>()); if ((Object)(object)val9 == (Object)null) { throw new InvalidDataException("Reference Body renderer is missing."); } val8.localPosition = Vector3.zero; val8.localRotation = Quaternion.identity; val8.localScale = Vector3.one; val9.sharedMesh = val7; ((Renderer)val9).sharedMaterials = array12; val9.bones = array; val9.rootBone = array[4]; val9.quality = (SkinQuality)4; SetMeshBounds(val9, val7); TetoHairMotion tetoHairMotion = val.AddComponent<TetoHairMotion>(); tetoHairMotion.Head = array[9]; tetoHairMotion.Roots = (Transform[])(object)new Transform[7] { array[154], array[160], array[19], array[21], array[23], array[15], array[17] }; Debug.Log((object)("[TetoAddon] Teto geometry: vertices=" + num15 + ", materials=" + num18 + ", shapes=" + num27)); return val; } private static void ValidateReferenceAnimation(GameObject root, GameObject reference, GameObject storage) { //IL_003b: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: 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_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(root, storage.transform); GameObject val2 = Object.Instantiate<GameObject>(reference, storage.transform); try { val.SetActive(true); val2.SetActive(true); storage.SetActive(true); Transform transform = val.transform; Vector3 localPosition = (val2.transform.localPosition = Vector3.zero); transform.localPosition = localPosition; Transform transform2 = val.transform; Quaternion localRotation = (val2.transform.localRotation = Quaternion.identity); transform2.localRotation = localRotation; Animator component = val.GetComponent<Animator>(); Animator component2 = val2.GetComponent<Animator>(); ((Component)val.transform.Find("Body")).gameObject.SetActive(false); ((Component)val2.transform.Find("Body")).gameObject.SetActive(false); ((Component)val.transform.Find("Smol")).gameObject.SetActive(false); ((Component)val2.transform.Find("Smol")).gameObject.SetActive(false); bool enabled = (((Behaviour)component2).enabled = true); ((Behaviour)component).enabled = enabled; component.Rebind(); component2.Rebind(); component.Update(0f); component2.Update(0f); float num = (val.transform.InverseTransformPoint(component.GetBoneTransform((HumanBodyBones)21).position).y + val.transform.InverseTransformPoint(component.GetBoneTransform((HumanBodyBones)22).position).y) * 0.5f; float num2 = (val2.transform.InverseTransformPoint(component2.GetBoneTransform((HumanBodyBones)21).position).y + val2.transform.InverseTransformPoint(component2.GetBoneTransform((HumanBodyBones)22).position).y) * 0.5f; Debug.Log((object)("[TetoAddon] Hidden-renderer camera sample: modelEye=" + num + ", referenceEye=" + num2 + ", error=" + Mathf.Abs(num - num2))); if (Mathf.Abs(num - num2) > 0.001f || num < 1f) { throw new InvalidDataException("Standing camera sample differs from the reference."); } ((Component)val.transform.Find("Body")).gameObject.SetActive(true); ((Component)val2.transform.Find("Body")).gameObject.SetActive(true); AnimatorCullingMode cullingMode = (AnimatorCullingMode)0; component2.cullingMode = (AnimatorCullingMode)0; component.cullingMode = cullingMode; bool enabled2 = (((Behaviour)component2).enabled = true); ((Behaviour)component).enabled = enabled2; component.Rebind(); component2.Rebind(); component.Update(0f); component2.Update(0f); object[] array = new object[12] { "[TetoAddon] Idle controllers identical=", (Object)(object)component.runtimeAnimatorController == (Object)(object)component2.runtimeAnimatorController, ", avatars identical=", (Object)(object)component.avatar == (Object)(object)component2.avatar, ", states=", null, null, null, null, null, null, null }; AnimatorStateInfo currentAnimatorStateInfo = component.GetCurrentAnimatorStateInfo(0); array[5] = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash; array[6] = "/"; AnimatorStateInfo currentAnimatorStateInfo2 = component2.GetCurrentAnimatorStateInfo(0); array[7] = ((AnimatorStateInfo)(ref currentAnimatorStateInfo2)).fullPathHash; array[8] = ", root scales="; array[9] = val.transform.localScale; array[10] = "/"; array[11] = val2.transform.localScale; Debug.Log((object)string.Concat(array)); float num3 = 0f; float num4 = 0f; int num5 = 0; for (int i = 0; i < 55; i++) { Transform boneTransform = component.GetBoneTransform((HumanBodyBones)i); Transform boneTransform2 = component2.GetBoneTransform((HumanBodyBones)i); if (!((Object)(object)boneTransform == (Object)null) && !((Object)(object)boneTransform2 == (Object)null)) { if (i < 23) { Debug.Log((object)string.Concat("[TetoAddon] Idle bone ", (object)(HumanBodyBones)i, ": model=", ((Object)boneTransform).name, "@", val.transform.InverseTransformPoint(boneTransform.position), ", reference=", ((Object)boneTransform2).name, "@", val2.transform.InverseTransformPoint(boneTransform2.position))); } num3 = Mathf.Max(num3, Vector3.Distance(val.transform.InverseTransformPoint(boneTransform.position), val2.transform.InverseTransformPoint(boneTransform2.position))); num4 = Mathf.Max(num4, Quaternion.Angle(Quaternion.Inverse(val.transform.rotation) * boneTransform.rotation, Quaternion.Inverse(val2.transform.rotation) * boneTransform2.rotation)); num5++; } } Debug.Log((object)("[TetoAddon] Reference idle animation comparison: bones=" + num5 + ", maxPositionError=" + num3 + ", maxAngleError=" + num4)); if (num5 < 20 || num3 > 0.001f || num4 > 0.1f) { throw new InvalidDataException("Original-rig idle comparison failed."); } } finally { Object.Destroy((Object)(object)val); Object.Destroy((Object)(object)val2); storage.SetActive(false); } } private static void ValidateBodyPoses(GameObject root, GameObject reference, GameObject storage, string directory) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0149: 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_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Expected O, but got Unknown //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_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Expected O, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022d: 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_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0363: 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_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) storage.SetActive(true); try { GameObject[] array = (GameObject[])(object)new GameObject[2] { root, reference }; foreach (GameObject val in array) { GameObject val2 = Object.Instantiate<GameObject>(val, storage.transform); try { val2.SetActive(true); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; ((Component)val2.transform.Find("Smol")).gameObject.SetActive(false); Animator component = val2.GetComponent<Animator>(); component.cullingMode = (AnimatorCullingMode)0; SkinnedMeshRenderer component2 = ((Component)val2.transform.Find("Body")).GetComponent<SkinnedMeshRenderer>(); string[] array2 = new string[4] { "Bind", "Stand", "SpecialIdle", "Crouch" }; foreach (string text in array2) { ((Behaviour)component).enabled = true; component.Rebind(); if (text != "Bind") { int num = Animator.StringToHash("Base Layer." + text); if (!component.HasState(0, num)) { throw new InvalidDataException("Body state missing: " + text); } component.Play(num, 0, 0f); component.Update(0f); } ((Behaviour)component).enabled = false; Bounds val3 = SkinnedWorldBounds(component2); string text2 = (((Object)(object)val == (Object)(object)root) ? "teto" : "reference"); string text3 = "test-body-" + text2 + "-" + text; File.WriteAllBytes(Path.Combine(directory, text3 + "-side.png"), ImageConversion.EncodeToPNG(Portrait(val2, ((Bounds)(ref val3)).center, ((Bounds)(ref val3)).size.y * 0.56f, transparent: false, mirrored: false, side: true))); if (text == "Bind" || text == "Stand") { Mesh val4 = new Mesh(); component2.BakeMesh(val4); Vector3 val5 = Vector3.zero; int num2 = 0; Vector3[] vertices = val4.vertices; foreach (Vector3 val6 in vertices) { Vector3 val7 = ((Component)component2).transform.TransformPoint(val6); if (val7.y < ((Bounds)(ref val3)).min.y + 0.2f) { val5 += val7; num2++; } } Object.Destroy((Object)(object)val4); if (num2 == 0) { throw new InvalidDataException("Feet sample is empty."); } val5 /= (float)num2; Debug.Log((object)string.Concat("[TetoAddon] Feet framing: ", text2, " ", text, ", centre=", val5, ", samples=", num2)); File.WriteAllBytes(Path.Combine(directory, text3 + "-feet.png"), ImageConversion.EncodeToPNG(Portrait(val2, val5, 0.19f, transparent: false, mirrored: false, side: true, 0.8f))); } Mesh val8 = new Mesh(); component2.BakeMesh(val8); try { Vector3[] vertices2 = val8.vertices; using BinaryWriter binaryWriter = new BinaryWriter(File.Create(Path.Combine(directory, text3 + ".vertices"))); binaryWriter.Write(vertices2.Length); Vector3[] array3 = vertices2; foreach (Vector3 val9 in array3) { Vector3 val10 = val2.transform.InverseTransformPoint(((Component)component2).transform.TransformPoint(val9)); binaryWriter.Write(val10.x); binaryWriter.Write(val10.y); binaryWriter.Write(val10.z); } } finally { Object.Destroy((Object)(object)val8); } Debug.Log((object)("[TetoAddon] Body surface sampled: " + text2 + " " + text + ", bounds=" + val3)); } } finally { Object.Destroy((Object)(object)val2); } } } finally { storage.SetActive(false); } } private static void CreatePear(string directory, Shader shader, GameObject reference, GameObject root) { //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_011c: 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_012d: 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_015a: 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_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Expected O, but got Unknown //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_036d: 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_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: 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_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) //IL_058d: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Unknown result type (might be due to invalid IL or missing references) Transform val = reference.transform.Find("Smol"); if ((Object)(object)val == (Object)null) { throw new InvalidDataException("Base model has no Smol form."); } Transform val2 = root.transform.Find("Smol"); GameObject val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : Object.Instantiate<GameObject>(((Component)val).gameObject, root.transform)); ((Object)val3).name = "Smol"; val3.SetActive(true); Animator component = val3.GetComponent<Animator>(); if ((Object)(object)component == (Object)null || (Object)(object)component.avatar == (Object)null || !component.avatar.isHuman) { throw new InvalidDataException("Base small rig is unavailable."); } SkinnedMeshRenderer componentInChildren = val3.GetComponentInChildren<SkinnedMeshRenderer>(true); if ((Object)(object)componentInChildren == (Object)null) { throw new InvalidDataException("Base small mesh is unavailable."); } Transform[] bones = componentInChildren.bones; Transform boneTransform = component.GetBoneTransform((HumanBodyBones)0); Transform boneTransform2 = component.GetBoneTransform((HumanBodyBones)10); int num = Array.IndexOf(bones, boneTransform); int num2 = Array.IndexOf(bones, boneTransform2); if (num < 0 || num2 < 0) { throw new InvalidDataException("Base small weighted bones do not match its Avatar."); } Mesh val4 = new Mesh(); componentInChildren.BakeMesh(val4); Matrix4x4 val5 = val3.transform.worldToLocalMatrix * ((Component)componentInChildren).transform.localToWorldMatrix; Vector3[] vertices = val4.vertices; if (vertices.Length == 0) { throw new InvalidDataException("Small reference pose is empty."); } Bounds val6 = default(Bounds); ((Bounds)(ref val6))..ctor(((Matrix4x4)(ref val5)).MultiplyPoint3x4(vertices[0]), Vector3.zero); for (int i = 1; i < vertices.Length; i++) { ((Bounds)(ref val6)).Encapsulate(((Matrix4x4)(ref val5)).MultiplyPoint3x4(vertices[i])); } Object.Destroy((Object)(object)val4); Matrix4x4 val7 = ((Component)componentInChildren).transform.worldToLocalMatrix * val3.transform.localToWorldMatrix; float num3 = Mathf.Max(((Bounds)(ref val6)).size.y * 0.92f, 0.5f); Debug.Log((object)string.Concat("[TetoAddon] Small renderer frame=", ((Component)componentInChildren).transform.localEulerAngles, "; root-space bounds=", val6, "; pear height=", num3)); Mesh val8 = new Mesh(); ((Object)val8).name = "Pearto"; using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(Path.Combine(directory, "pearto.rpm")))) { if (Encoding.ASCII.GetString(binaryReader.ReadBytes(8)) != "PEAR0001") { throw new InvalidDataException("Unknown pear format."); } int num4 = Count(binaryReader, 10000); Vector3[] array = (Vector3[])(object)new Vector3[num4]; Vector3[] array2 = (Vector3[])(object)new Vector3[num4]; Vector2[] array3 = (Vector2[])(object)new Vector2[num4]; BoneWeight[] array4 = (BoneWeight[])(object)new BoneWeight[num4]; Vector3 val10 = default(Vector3); for (int j = 0; j < num4; j++) { Vector3 val9 = Vec(binaryReader); ((Vector3)(ref val10))..ctor(0f - val9.z, val9.y, val9.x); ref Vector3 reference2 = ref array[j]; reference2 = ((Matrix4x4)(ref val7)).MultiplyPoint3x4(val10 * num3 + new Vector3(((Bounds)(ref val6)).center.x, ((Bounds)(ref val6)).min.y, ((Bounds)(ref val6)).center.z)); val9 = Vec(binaryReader); ref Vector3 reference3 = ref array2[j]; Vector3 val11 = ((Matrix4x4)(ref val7)).MultiplyVector(new Vector3(0f - val9.z, val9.y, val9.x)); reference3 = ((Vector3)(ref val11)).normalized; ref Vector2 reference4 = ref array3[j]; reference4 = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); ref BoneWeight reference5 = ref array4[j]; BoneWeight val12 = default(BoneWeight); ((BoneWeight)(ref val12)).boneIndex0 = num; ((BoneWeight)(ref val12)).weight0 = 1f; reference5 = val12; } int num5 = Count(binaryReader, 100000); int[] array5 = new int[num5]; for (int k = 0; k < num5; k++) { array5[k] = binaryReader.ReadInt32(); if (array5[k] < 0 || array5[k] >= num4) { throw new InvalidDataException("Invalid pear indices."); } } val8.vertices = array; val8.normals = array2; val8.uv = array3; val8.boneWeights = array4; Matrix4x4[] array6 = (Matrix4x4[])(object)new Matrix4x4[bones.Length]; for (int l = 0; l < bones.Length; l++) { ref Matrix4x4 reference6 = ref array6[l]; reference6 = bones[l].worldToLocalMatrix * ((Component)componentInChildren).transform.localToWorldMatrix; } val8.bindposes = array6; Material[] sharedMaterials = ((Renderer)componentInChildren).sharedMaterials; val8.subMeshCount = sharedMaterials.Length; val8.SetTriangles(array5, 0); for (int m = 1; m < sharedMaterials.Length; m++) { val8.SetTriangles(new int[0], m); } Shader shader2 = sharedMaterials[0].shader; sharedMaterials[0] = Surface(((Object)(object)shader2 != (Object)null) ? shader2 : shader, Texture(Path.Combine(directory, "pearto.png")), Color.white, "Pearto"); ((Renderer)componentInChildren).sharedMaterials = sharedMaterials; val8.RecalculateBounds(); componentInChildren.sharedMesh = val8; SetMeshBounds(componentInChildren, val8); Debug.Log((object)("[TetoAddon] Pearto geometry: triangles=" + num5 / 3 + "; existing small Avatar and ragdoll bones retained.")); } ((Behaviour)component).enabled = false; if (Array.IndexOf(Environment.GetCommandLineArgs(), "--teto-self-test") >= 0) { ValidatePear(val3, root.GetComponent<Animator>().runtimeAnimatorController, ((Matrix4x4)(ref val7)).MultiplyVector(Vector3.up), directory); } } private static void SetMeshBounds(SkinnedMeshRenderer renderer, Mesh mesh) { //IL_001e: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)renderer.rootBone != (Object)null) ? renderer.rootBone : ((Component)renderer).transform); Matrix4x4 val2 = val.worldToLocalMatrix * ((Component)renderer).transform.localToWorldMatrix; Bounds localBounds = ((Renderer)renderer).localBounds; Vector3[] vertices = mesh.vertices; foreach (Vector3 val3 in vertices) { ((Bounds)(ref localBounds)).Encapsulate(((Matrix4x4)(ref val2)).MultiplyPoint3x4(val3)); } ((Bounds)(ref localBounds)).Expand(0.3f); ((Renderer)renderer).localBounds = localBounds; Debug.Log((object)("[TetoAddon] Mesh visibility bounds preserve reference and use root frame: " + ((Object)val).name + ", bounds=" + localBounds)); } private static Bounds SkinnedWorldBounds(SkinnedMeshRenderer renderer) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh(); renderer.BakeMesh(val); try { Vector3[] vertices = val.vertices; if (vertices.Length == 0) { throw new InvalidDataException("Skinned pose is empty."); } Bounds result = default(Bounds); ((Bounds)(ref result))..ctor(((Component)renderer).transform.TransformPoint(vertices[0]), Vector3.zero); for (int i = 1; i < vertices.Length; i++) { ((Bounds)(ref result)).Encapsulate(((Component)renderer).transform.TransformPoint(vertices[i])); } return result; } finally { Object.Destroy((Object)(object)val); } } private static void ValidatePear(GameObject small, RuntimeAnimatorController controller, Vector3 meshUp, string directory) { //IL_0014: 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_012d: 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_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_0170: 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_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(small); try { val.SetActive(true); val.transform.position = Vector3.zero; val.transform.rotation = Quaternion.identity; Animator component = val.GetComponent<Animator>(); SkinnedMeshRenderer componentInChildren = val.GetComponentInChildren<SkinnedMeshRenderer>(true); component.runtimeAnimatorController = controller; Debug.Log((object)("[TetoAddon] Pear validation controller=" + (((Object)(object)controller == (Object)null) ? "null" : ((Object)controller).name))); component.cullingMode = (AnimatorCullingMode)0; ((Behaviour)component).enabled = true; string[] array = new string[5] { "Bind", "Stand", "SpecialIdle", "Stand to Crouch", "Crouch" }; foreach (string text in array) { component.Rebind(); if (text != "Bind") { int num = Animator.StringToHash("Base Layer." + text); if (!component.HasState(0, num)) { Debug.Log((object)("[TetoAddon] Pear state unavailable: " + text)); continue; } component.Play(num, 0, 0f); component.Update(0f); } else { ((Behaviour)component).enabled = false; } ((Behaviour)component).enabled = false; Bounds val2 = SkinnedWorldBounds(componentInChildren); int boneIndex = ((BoneWeight)(ref componentInChildren.sharedMesh.boneWeights[0])).boneIndex0; Matrix4x4 localToWorldMatrix = componentInChildren.bones[boneIndex].localToWorldMatrix; Vector3 val3 = ((Matrix4x4)(ref localToWorldMatrix)).MultiplyVector(((Matrix4x4)(ref componentInChildren.sharedMesh.bindposes[boneIndex])).MultiplyVector(meshUp)); Vector3 normalized = ((Vector3)(ref val3)).normalized; float num2 = Vector3.Dot(normalized, val.transform.up); Debug.Log((object)string.Concat("[TetoAddon] Pear pose ", text, ": world bounds=", val2, ", uprightDot=", num2, ", hips=", component.GetBoneTransform((HumanBodyBones)0).eulerAngles)); if ((text == "Stand" || text == "SpecialIdle") && num2 < 0.9f) { throw new InvalidDataException("Pear is not upright in " + text); } float num3 = Mathf.Max(((Bounds)(ref val2)).size.y, Mathf.Max(((Bounds)(ref val2)).size.x, ((Bounds)(ref val2)).size.z)) * 0.58f; File.WriteAllBytes(Path.Combine(directory, "test-pear-" + text + ".png"), ImageConversion.EncodeToPNG(Portrait(val, ((Bounds)(ref val2)).center, Mathf.Max(num3, 0.2f)))); ((Behaviour)component).enabled = true; } } finally { Object.Destroy((Object)(object)val); } } private static void CreateUiPortraits(string directory, GameObject root, RuntimeModelAssets result) { //IL_0014: 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) GameObject val = Object.Instantiate<GameObject>(root); try { val.SetActive(true); val.transform.position = Vector3.zero; val.transform.rotation = Quaternion.identity; ((Component)val.transform.Find("Body")).gameObject.SetActive(true); ((Component)val.transform.Find("Smol")).gameObject.SetActive(false); Animator component = val.GetComponent<Animator>(); component.cullingMode = (AnimatorCullingMode)0; ((Behaviour)component).enabled = true; component.Rebind(); int num = Animator.StringToHash("Base Layer.SpecialIdle"); if (component.HasState(0, num)) { component.Play(num, 0, 0f); component.Update(0f); } ((Behaviour)component).enabled = false; result.Thumbnail = Texture(Path.Combine(directory, "teto-thumbnail.png")); ((Component)val.transform.Find("Body")).gameObject.SetActive(false); GameObject gameObject = ((Component)val.transform.Find("Smol")).gameObject; gameObject.SetActive(true); Animator component2 = gameObject.GetComponent<Animator>(); component2.runtimeAnimatorController = component.runtimeAnimatorController; component2.cullingMode = (AnimatorCullingMode)0; ((Behaviour)component2).enabled = true; component2.Rebind(); if (component2.HasState(0, num)) { component2.Play(num, 0, 0f); component2.Update(0f); } ((Behaviour)component2).enabled = false; result.Chibi = LoadOrRenderSkinPortrait(directory, "teto-lobby.png", val, gameObject.GetComponentInChildren<SkinnedMeshRenderer>(true), 0.58f); string path = Path.Combine(directory, "teto-lobby-talk.png"); if (File.Exists(path) && Array.IndexOf(Environment.GetCommandLineArgs(), "--teto-rebuild-icons") < 0) { result.ChibiTalk = Texture(path); } else { result.ChibiTalk = MirrorPortrait(result.Chibi); File.WriteAllBytes(path, ImageConversion.EncodeToPNG(result.ChibiTalk)); } Debug.Log((object)("[TetoAddon] UI PNGs loaded/generated: provided Teto selection illustration (" + ((Texture)result.Thumbnail).width + "x" + ((Texture)result.Thumbnail).height + ") + Pearto lobby + exact mirrored speaking Pearto.")); } finally { Object.Destroy((Object)(object)val); } } private static Texture2D MirrorPortrait(Texture2D source) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)4, false); Color32[] pixels = source.GetPixels32(); Color32[] array = (Color32[])(object)new Color32[pixels.Length]; for (int i = 0; i < ((Texture)source).height; i++) { for (int j = 0; j < ((Texture)source).width; j++) { ref Color32 reference = ref array[i * ((Texture)source).width + j]; reference = pixels[i * ((Texture)source).width + ((Texture)source).width - 1 - j]; } } val.SetPixels32(array); val.Apply(); return val; } private static Texture2D LoadOrRenderSkinPortrait(string directory, string filename, GameObject root, SkinnedMeshRenderer skin, float padding) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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) string path = Path.Combine(directory, filename); if (File.Exists(path) && Array.IndexOf(Environment.GetCommandLineArgs(), "--teto-rebuild-icons") < 0) { return Texture(path); } Mesh val = new Mesh(); skin.BakeMesh(val); val.RecalculateBounds(); GameObject val2 = new GameObject("TetoPortraitSnapshot"); val2.transform.SetParent(((Component)skin).transform, false); val2.AddComponent<MeshFilter>().sharedMesh = val; ((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterials = ((Renderer)skin).sharedMaterials; bool enabled = ((Renderer)skin).enabled; try { ((Renderer)skin).enabled = false; Vector3[] vertices = val.vertices; Bounds val3 = default(Bounds); ((Bounds)(ref val3))..ctor(((Component)skin).transform.TransformPoint(vertices[0]), Vector3.zero); Vector3[] array = vertices; foreach (Vector3 val4 in array) { ((Bounds)(ref val3)).Encapsulate(((Component)skin).transform.TransformPoint(val4)); } float num = Mathf.Max(((Bounds)(ref val3)).size.y, ((Bounds)(ref val3)).size.x) * padding; Texture2D val5 = Portrait(root, ((Bounds)(ref val3)).center, num, transparent: true); File.WriteAllBytes(path, ImageConversion.EncodeToPNG(val5)); Debug.Log((object)string.Concat("[TetoAddon] Baked portrait framing: ", filename, ", bounds=", val3, ", size=", num)); return val5; } finally { ((Renderer)skin).enabled = enabled; val2.SetActive(false); Object.Destroy((Object)(object)val2); Object.Destroy((Object)(object)val); } } private static Texture2D Portrait(GameObject root, Vector3 centre, float size, bool transparent = false, bool mirrored = false, bool side = false, float elevation = 0f) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0091: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown //IL_01ec: 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_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true); int[] array = new int[componentsInChildren.Length]; for (int i = 0; i < componentsInChildren.Length; i++) { array[i] = ((Component)componentsInChildren[i]).gameObject.layer; ((Component)componentsInChildren[i]).gameObject.layer = 31; } GameObject val = new GameObject("TetoPortraitCamera"); Camera val2 = val.AddComponent<Camera>(); ((Behaviour)val2).enabled = false; val2.orthographic = true; val2.orthographicSize = size; val2.clearFlags = (CameraClearFlags)2; val2.backgroundColor = (Color)(transparent ? Color.clear : new Color(0.06f, 0.09f, 0.13f, 1f)); val2.cullingMask = int.MinValue; val2.nearClipPlane = 0.01f; val2.farClipPlane = 10f; val2.useOcclusionCulling = false; ((Component)val2).transform.position = centre + (side ? new Vector3(-3f, 0f, 0f) : new Vector3(0f, 0f, 3f)) + Vector3.up * elevation; ((Component)val2).transform.LookAt(centre); GameObject val3 = new GameObject("TetoPortraitLight"); Light val4 = val3.AddComponent<Light>(); val4.type = (LightType)1; val4.intensity = 0.8f; val4.color = Color.white; val4.cullingMask = int.MinValue; ((Component)val4).transform.rotation = Quaternion.Euler(25f, side ? 250f : 170f, 0f); RenderTexture val5 = (val2.targetTexture = new RenderTexture(256, 256, 24, (RenderTextureFormat)0)); RenderTexture active = RenderTexture.active; try { val2.Render(); RenderTexture.active = val5; Texture2D val7 = new Texture2D(256, 256, (TextureFormat)4, false); val7.ReadPixels(new Rect(0f, 0f, 256f, 256f), 0, 0); val7.Apply(); if (mirrored) { Color32[] pixels = val7.GetPixels32(); for (int j = 0; j < ((Texture)val7).height; j++) { for (int k = 0; k < ((Texture)val7).width / 2; k++) { int num = j * ((Texture)val7).width + k; int num2 = j * ((Texture)val7).width + ((Texture)val7).width - 1 - k; Color32 val8 = pixels[num]; ref Color32 reference = ref pixels[num]; reference = pixels[num2]; pixels[num2] = val8; } } val7.SetPixels32(pixels); val7.Apply(); } return val7; } finally { RenderTexture.active = active; val2.targetTexture = null; val5.Release(); Object.Destroy((Object)(object)val5); Object.Destroy((Object)(object)val); Object.Destroy((Object)(object)val3); for (int l = 0; l < componentsInChildren.Length; l++) { ((Component)componentsInChildren[l]).gameObject.layer = array[l]; } } } } public sealed class TetoHairMotion : MonoBehaviour { public Transform Head; public Transform[] Roots; private Quaternion[] rest; private Vector3 previous; private Vector3 angle; private Vector3 velocity; private void OnEnable() { //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_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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Head == (Object)null) && Roots != null) { previous = Head.position; angle = (velocity = Vector3.zero); rest = (Quaternion[])(object)new Quaternion[Roots.Length]; for (int i = 0; i < Roots.Length; i++) { ref Quaternion reference = ref rest[i]; reference = Roots[i].localRotation; } } } private void LateUpdate() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00a5: 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_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_014b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Head == (Object)null || Roots == null) { return; } if (rest == null || rest.Length != Roots.Length) { OnEnable(); return; } float num = Mathf.Clamp(Time.deltaTime, 0.001f, 0.05f); Vector3 val = Head.InverseTransformDirection((Head.position - previous) / num); previous = Head.position; if (((Vector3)(ref val)).sqrMagnitude > 400f) { angle = (velocity = Vector3.zero); return; } Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(Mathf.Clamp((0f - val.z) * 4f, -12f, 12f), 0f, Mathf.Clamp(val.x * 4f, -12f, 12f)); angle = Vector3.SmoothDamp(angle, val2, ref velocity, 0.12f, 250f, num); for (int i = 0; i < Roots.Length; i++) { if ((Object)(object)Roots[i] != (Object)null) { Roots[i].localRotation = rest[i] * Quaternion.Euler(angle); } } } }