// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts, // for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies. // EdenAutoMorpherScript, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null // Eden.AutoMorpher.profile.ProfileLoader using System; using System.Collections.Generic; using System.IO; using System.Text; using Eden.AutoMorpher; using Eden.AutoMorpher.profile; using UnityEngine; public class ProfileLoader { private ProfileData loadedProfileData; private const int HEX32_W = 8; public List GetProfileList() { ProfileUtils profileUtils = new ProfileUtils(); string text = Path.Combine(Application.dataPath, profileUtils.GetProfileBasePath()); List list = new List(); if (!Directory.Exists(text)) { Debug.LogWarning("[ProfileUtils] Profile base path does not exist: " + text); return list; } string[] directories = Directory.GetDirectories(text); foreach (string text2 in directories) { string fileName = Path.GetFileName(text2); if (!string.IsNullOrEmpty(fileName)) { string path = Path.Combine(text2, fileName + ".json"); string path2 = Path.Combine(text2, fileName + ".eb"); if (File.Exists(path) && File.Exists(path2)) { list.Add(fileName); } } } return list; } public ProfileData LoadProfileData(string profileName) { ProfileUtils profileUtils = new ProfileUtils(); string path = Path.Combine(Application.dataPath, profileUtils.GetProfileBasePath()); path = Path.Combine(path, profileName); path = Path.Combine(path, profileName + ".json"); if (string.IsNullOrWhiteSpace(path)) { throw new AutoMorpherException("Profile File Path is Invalid", "[ProfileLoader] LoadProfileData\n - Profile Path is null, empty, or whitespace"); } if (!File.Exists(path)) { throw new AutoMorpherException("Profile File Does Not Exist", "[ProfileLoader] LoadProfileData\n - profile file does not exist\n - path : " + path); } string json = File.ReadAllText(path); loadedProfileData = JsonUtility.FromJson(json); if (loadedProfileData == null) { throw new AutoMorpherException("Failed to Load Profile Data", "[ProfileLoader] LoadProfileData\n - Can't Load Profile Data\n - Please place a valid profile data file at " + path); } return loadedProfileData; } public BvhTriangleMesh LoadBvhWithRootTransform(Transform rootTransform, string profileName) { ProfileUtils profileUtils = new ProfileUtils(); string path = Path.Combine(Application.dataPath, profileUtils.GetProfileBasePath()); path = Path.Combine(path, profileName); path = Path.Combine(path, profileName + ".eb"); if (rootTransform == null) { throw new AutoMorpherException("Root Transform is Null", "[ProfileLoader] LoadBvhWithRootTransform\n - rootTransform is null"); } if (string.IsNullOrEmpty(path)) { throw new AutoMorpherException("Profile BVH Path is Invalid", "[ProfileLoader] LoadBvhWithRootTransform\n - profileBvhPath is null or empty"); } int version; ProfileBVH profileBVH = LoadProfileBVHData(path, out version); if (profileBVH == null || profileBVH.vertices == null || profileBVH.datas == null || profileBVH.nodes == null || profileBVH.dataIndices == null) { throw new AutoMorpherException("Profile BVH Data is Invalid", "[ProfileLoader] LoadBvhWithRootTransform\n - profile or one of its internal data fields is null"); } Matrix4x4 localToWorldMatrix = rootTransform.localToWorldMatrix; int num = profileBVH.datas.Length; BvhTriangleMesh bvhTriangleMesh = new BvhTriangleMesh { triangles = new BvhTriangle[num], triIndices = new int[profileBVH.dataIndices.Length], nodes = new BvhNode[profileBVH.nodes.Length] }; for (int i = 0; i < num; i++) { profileBVHData profileBVHData2 = profileBVH.datas[i]; Vector3 point = profileBVH.vertices[profileBVHData2.verA]; Vector3 point2 = profileBVH.vertices[profileBVHData2.verB]; Vector3 point3 = profileBVH.vertices[profileBVHData2.verC]; Vector3 a = localToWorldMatrix.MultiplyPoint3x4(point); Vector3 b = localToWorldMatrix.MultiplyPoint3x4(point2); Vector3 c = localToWorldMatrix.MultiplyPoint3x4(point3); Vector3 normal = ComputeTriangleNormal(a, b, c); bvhTriangleMesh.triangles[i] = new BvhTriangle { a = a, b = b, c = c, normal = normal, mainHumanBone = HumanBodyBones.LastBone }; } Array.Copy(profileBVH.dataIndices, bvhTriangleMesh.triIndices, profileBVH.dataIndices.Length); for (int j = 0; j < profileBVH.nodes.Length; j++) { profileBVHNode profileBVHNode2 = profileBVH.nodes[j]; bvhTriangleMesh.nodes[j] = new BvhNode { isLeaf = profileBVHNode2.isLeaf, leftChild = profileBVHNode2.leftChild, rightChild = profileBVHNode2.rightChild, start = profileBVHNode2.start, count = profileBVHNode2.count, bounds = TransformBoundsToWorldAABB(localToWorldMatrix, profileBVHNode2.bounds) }; } return bvhTriangleMesh; } private ProfileBVH LoadProfileBVHData(string path, out int version) { version = 0; int num = 0; if (!File.Exists(path)) { throw new AutoMorpherException("Profile BVH File Not Found", "[ProfileLoader] LoadProfileBVHData\n - file not found\n - path : " + path); } string text = File.ReadAllText(path, Encoding.UTF8); int num2 = 0; ProfileUtils profileUtils = new ProfileUtils(); string profileMagic = profileUtils.GetProfileMagic(); if (text.Length < profileMagic.Length || text.Substring(0, profileMagic.Length) != profileMagic) { throw new AutoMorpherException("Profile BVH Magic Mismatch", "[ProfileLoader] LoadProfileBVHData\n - magic string mismatch\n - invalid or corrupted BVH file"); } num2 += profileMagic.Length; version = ReadHexIntSafe(text, ref num2); num = ReadHexIntSafe(text, ref num2); int num3 = ReadHexIntSafe(text, ref num2); int num4 = ReadHexIntSafe(text, ref num2); int num5 = ReadHexIntSafe(text, ref num2); int num6 = ReadHexIntSafe(text, ref num2); if (num3 < 0 || num4 < 0 || num5 < 0 || num6 < 0) { throw new AutoMorpherException("Profile BVH Count Data is Invalid", "[ProfileLoader] LoadProfileBVHData\n - one or more count values are negative"); } Vector3[] array = new Vector3[num3]; for (int i = 0; i < num3; i++) { array[i] = ReadHexVec3Safe(text, ref num2); } int version2; int countInFile; BaseKey3[] array2 = new ProfileUtils_VertexUtil().LoadTable(profileUtils.GetBaseDataPath(), out version2, out countInFile); if (array2 == null || array2.Length == 0) { throw new AutoMorpherException("Profile BVH Base Vertex Table is Invalid", "[ProfileLoader] LoadProfileBVHData\n - base vertex table is null or empty"); } ProfileUtil_IndexUtil profileUtil_IndexUtil = new ProfileUtil_IndexUtil(); profileUtil_IndexUtil.Build(num); Vector3[] array3 = new Vector3[num3]; profileUtil_IndexUtil.DecodeInto(array, array3); Vector3[] array4 = new Vector3[num3]; for (int j = 0; j < num3; j++) { array4[j] = TransformVec3(array3[j], array2[j % array2.Length]); } ProfileBVH profileBVH = new ProfileBVH { vertices = new List(num3), datas = new profileBVHData[num4], nodes = new profileBVHNode[num5], dataIndices = new int[num6] }; profileBVH.vertices.AddRange(array4); for (int k = 0; k < num4; k++) { profileBVH.datas[k] = new profileBVHData { verA = ReadHexIntSafe(text, ref num2), verB = ReadHexIntSafe(text, ref num2), verC = ReadHexIntSafe(text, ref num2) }; } for (int l = 0; l < num5; l++) { Vector3 center = ReadHexVec3Safe(text, ref num2); Vector3 vector = ReadHexVec3Safe(text, ref num2); profileBVH.nodes[l] = new profileBVHNode { bounds = new Bounds(center, vector * 2f), leftChild = ReadHexIntSafe(text, ref num2), rightChild = ReadHexIntSafe(text, ref num2), start = ReadHexIntSafe(text, ref num2), count = ReadHexIntSafe(text, ref num2), isLeaf = (num2 < text.Length && text[num2++] == '1') }; } for (int m = 0; m < num6; m++) { profileBVH.dataIndices[m] = ReadHexIntSafe(text, ref num2); } return profileBVH; } private int ReadHexIntSafe(string s, ref int p) { if (p + 8 > s.Length) { p = s.Length; throw new AutoMorpherException("Profile BVH ReadHexInt Out of Range", "[ProfileBVH] ReadHexIntSafe\n - read position exceeds string length"); } uint result = Convert.ToUInt32(s.Substring(p, 8), 16); p += 8; return (int)result; } private Vector3 ReadHexVec3Safe(string s, ref int p) { return new Vector3(ReadHexFloatSafe(s, ref p), ReadHexFloatSafe(s, ref p), ReadHexFloatSafe(s, ref p)); } private float ReadHexFloatSafe(string s, ref int p) { if (p + 8 > s.Length) { p = s.Length; throw new AutoMorpherException("Profile BVH ReadHexFloat Out of Range", "[ProfileBVH] ReadHexFloat\n - read position exceeds string length"); } uint value = Convert.ToUInt32(s.Substring(p, 8), 16); p += 8; return BitConverter.Int32BitsToSingle((int)value); } private Vector3 TransformVec3(Vector3 v, BaseKey3 k) { return new Vector3(TransformFloatBits(v.x, k.x), TransformFloatBits(v.y, k.y), TransformFloatBits(v.z, k.z)); } private float TransformFloatBits(float a, uint keyBits) { return BitConverter.Int32BitsToSingle(BitConverter.SingleToInt32Bits(a) ^ (int)keyBits); } private Vector3 ComputeTriangleNormal(Vector3 a, Vector3 b, Vector3 c) { Vector3 vector = Vector3.Cross(b - a, c - a); float magnitude = vector.magnitude; if (magnitude > 1E-08f) { return vector / magnitude; } return Vector3.up; } private Bounds TransformBoundsToWorldAABB(Matrix4x4 l2w, Bounds localBounds) { Vector3 center = localBounds.center; Vector3 extents = localBounds.extents; Vector3 vector = l2w.MultiplyPoint3x4(center + new Vector3(0f - extents.x, 0f - extents.y, 0f - extents.z)); Vector3 p = l2w.MultiplyPoint3x4(center + new Vector3(0f - extents.x, 0f - extents.y, extents.z)); Vector3 p2 = l2w.MultiplyPoint3x4(center + new Vector3(0f - extents.x, extents.y, 0f - extents.z)); Vector3 p3 = l2w.MultiplyPoint3x4(center + new Vector3(0f - extents.x, extents.y, extents.z)); Vector3 p4 = l2w.MultiplyPoint3x4(center + new Vector3(extents.x, 0f - extents.y, 0f - extents.z)); Vector3 p5 = l2w.MultiplyPoint3x4(center + new Vector3(extents.x, 0f - extents.y, extents.z)); Vector3 p6 = l2w.MultiplyPoint3x4(center + new Vector3(extents.x, extents.y, 0f - extents.z)); Vector3 p7 = l2w.MultiplyPoint3x4(center + new Vector3(extents.x, extents.y, extents.z)); Vector3 min = vector; Vector3 max = vector; Encapsulate(ref min, ref max, p); Encapsulate(ref min, ref max, p2); Encapsulate(ref min, ref max, p3); Encapsulate(ref min, ref max, p4); Encapsulate(ref min, ref max, p5); Encapsulate(ref min, ref max, p6); Encapsulate(ref min, ref max, p7); return new Bounds((min + max) * 0.5f, max - min); } private void Encapsulate(ref Vector3 min, ref Vector3 max, Vector3 p) { min = Vector3.Min(min, p); max = Vector3.Max(max, p); } }