// Decompiled with JetBrains decompiler // Type: Eden.AutoMorpher.profile.ProfileLoader // Assembly: EdenAutoMorpherScript, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null // MVID: D39968B3-E151-4276-BDB4-E82752BBAFF0 // Assembly location: D:\dev\AutoMorpher\Assets\@Eden_Tools\Eden_AutoMorpher\Script\EdenAutoMorpherScript.dll using System; using System.Collections.Generic; using System.IO; using System.Text; using UnityEngine; namespace Eden.AutoMorpher.profile; public class ProfileLoader { private ProfileData loadedProfileData; private const int HEX32_W = 8; public List GetProfileList() { string path1 = Path.Combine(Application.dataPath, new ProfileUtils().GetProfileBasePath()); List profileList = new List(); if (!Directory.Exists(path1)) { Debug.LogWarning((object)("[ProfileUtils] Profile base path does not exist: " + path1)); return profileList; } foreach (string directory in Directory.GetDirectories(path1)) { string fileName = Path.GetFileName(directory); if (!string.IsNullOrEmpty(fileName)) { string path2 = Path.Combine(directory, fileName + ".json"); string path3 = Path.Combine(directory, fileName + ".eb"); if (File.Exists(path2) && File.Exists(path3)) profileList.Add(fileName); } } return profileList; } public ProfileData LoadProfileData(string profileName) { string path = Path.Combine(Path.Combine(Path.Combine(Application.dataPath, new ProfileUtils().GetProfileBasePath()), profileName), profileName + ".json"); if (string.IsNullOrWhiteSpace(path)) throw new AutoMorpherException("Profile File Path is Invalid", "[ProfileLoader] LoadProfileData\n - Profile Path is null, empty, or whitespace"); this.loadedProfileData = File.Exists(path) ? JsonUtility.FromJson(File.ReadAllText(path)) : throw new AutoMorpherException("Profile File Does Not Exist", "[ProfileLoader] LoadProfileData\n - profile file does not exist\n - path : " + path); return this.loadedProfileData != null ? this.loadedProfileData : 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); } public BvhTriangleMesh LoadBvhWithRootTransform(Transform rootTransform, string profileName) { string path = Path.Combine(Path.Combine(Path.Combine(Application.dataPath, new ProfileUtils().GetProfileBasePath()), profileName), profileName + ".eb"); if (Object.op_Equality((Object)rootTransform, (Object)null)) throw new AutoMorpherException("Root Transform is Null", "[ProfileLoader] LoadBvhWithRootTransform\n - rootTransform is null"); ProfileBVH profileBvh = !string.IsNullOrEmpty(path) ? this.LoadProfileBVHData(path, out int _) : throw new AutoMorpherException("Profile BVH Path is Invalid", "[ProfileLoader] LoadBvhWithRootTransform\n - profileBvhPath is null or empty"); 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 length = profileBvh.datas.Length; BvhTriangleMesh bvhTriangleMesh = new BvhTriangleMesh() { triangles = new BvhTriangle[length], triIndices = new int[profileBvh.dataIndices.Length], nodes = new BvhNode[profileBvh.nodes.Length] }; for (int index = 0; index < length; ++index) { profileBVHData data = profileBvh.datas[index]; Vector3 vertex1 = profileBvh.vertices[data.verA]; Vector3 vertex2 = profileBvh.vertices[data.verB]; Vector3 vertex3 = profileBvh.vertices[data.verC]; Vector3 a = ((Matrix4x4)ref localToWorldMatrix).MultiplyPoint3x4(vertex1); Vector3 b = ((Matrix4x4)ref localToWorldMatrix).MultiplyPoint3x4(vertex2); Vector3 c = ((Matrix4x4)ref localToWorldMatrix).MultiplyPoint3x4(vertex3); Vector3 triangleNormal = this.ComputeTriangleNormal(a, b, c); bvhTriangleMesh.triangles[index] = new BvhTriangle() { a = a, b = b, c = c, normal = triangleNormal, mainHumanBone = (HumanBodyBones)55 }; } Array.Copy((Array)profileBvh.dataIndices, (Array)bvhTriangleMesh.triIndices, profileBvh.dataIndices.Length); for (int index = 0; index < profileBvh.nodes.Length; ++index) { profileBVHNode node = profileBvh.nodes[index]; bvhTriangleMesh.nodes[index] = new BvhNode() { isLeaf = node.isLeaf, leftChild = node.leftChild, rightChild = node.rightChild, start = node.start, count = node.count, bounds = this.TransformBoundsToWorldAABB(localToWorldMatrix, node.bounds) }; } return bvhTriangleMesh; } private ProfileBVH LoadProfileBVHData(string path, out int version) { version = 0; string s = File.Exists(path) ? File.ReadAllText(path, Encoding.UTF8) : throw new AutoMorpherException("Profile BVH File Not Found", "[ProfileLoader] LoadProfileBVHData\n - file not found\n - path : " + path); int num = 0; ProfileUtils profileUtils = new ProfileUtils(); string profileMagic = profileUtils.GetProfileMagic(); if (s.Length < profileMagic.Length || s.Substring(0, profileMagic.Length) != profileMagic) throw new AutoMorpherException("Profile BVH Magic Mismatch", "[ProfileLoader] LoadProfileBVHData\n - magic string mismatch\n - invalid or corrupted BVH file"); int p = num + profileMagic.Length; version = this.ReadHexIntSafe(s, ref p); int seed = this.ReadHexIntSafe(s, ref p); int capacity = this.ReadHexIntSafe(s, ref p); int length1 = this.ReadHexIntSafe(s, ref p); int length2 = this.ReadHexIntSafe(s, ref p); int length3 = this.ReadHexIntSafe(s, ref p); if (capacity < 0 || length1 < 0 || length2 < 0 || length3 < 0) throw new AutoMorpherException("Profile BVH Count Data is Invalid", "[ProfileLoader] LoadProfileBVHData\n - one or more count values are negative"); Vector3[] encoded = new Vector3[capacity]; for (int index = 0; index < capacity; ++index) encoded[index] = this.ReadHexVec3Safe(s, ref p); BaseKey3[] baseKey3Array = new ProfileUtils_VertexUtil().LoadTable(profileUtils.GetBaseDataPath(), out int _, out int _); if (baseKey3Array == null || baseKey3Array.Length == 0) throw new AutoMorpherException("Profile BVH Base Vertex Table is Invalid", "[ProfileLoader] LoadProfileBVHData\n - base vertex table is null or empty"); ProfileUtil_IndexUtil profileUtilIndexUtil = new ProfileUtil_IndexUtil(); profileUtilIndexUtil.Build(seed); Vector3[] output = new Vector3[capacity]; profileUtilIndexUtil.DecodeInto(encoded, output); Vector3[] collection = new Vector3[capacity]; for (int index = 0; index < capacity; ++index) collection[index] = this.TransformVec3(output[index], baseKey3Array[index % baseKey3Array.Length]); ProfileBVH profileBvh = new ProfileBVH() { vertices = new List(capacity), datas = new profileBVHData[length1], nodes = new profileBVHNode[length2], dataIndices = new int[length3] }; profileBvh.vertices.AddRange((IEnumerable)collection); for (int index = 0; index < length1; ++index) profileBvh.datas[index] = new profileBVHData() { verA = this.ReadHexIntSafe(s, ref p), verB = this.ReadHexIntSafe(s, ref p), verC = this.ReadHexIntSafe(s, ref p) }; for (int index = 0; index < length2; ++index) { Vector3 vector3_1 = this.ReadHexVec3Safe(s, ref p); Vector3 vector3_2 = this.ReadHexVec3Safe(s, ref p); profileBvh.nodes[index] = new profileBVHNode() { bounds = new Bounds(vector3_1, Vector3.op_Multiply(vector3_2, 2f)), leftChild = this.ReadHexIntSafe(s, ref p), rightChild = this.ReadHexIntSafe(s, ref p), start = this.ReadHexIntSafe(s, ref p), count = this.ReadHexIntSafe(s, ref p), isLeaf = p < s.Length && s[p++] == '1' }; } for (int index = 0; index < length3; ++index) profileBvh.dataIndices[index] = this.ReadHexIntSafe(s, ref p); 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"); } int uint32 = (int)Convert.ToUInt32(s.Substring(p, 8), 16 /*0x10*/); p += 8; return uint32; } private Vector3 ReadHexVec3Safe(string s, ref int p) { return new Vector3(this.ReadHexFloatSafe(s, ref p), this.ReadHexFloatSafe(s, ref p), this.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"); } int uint32 = (int)Convert.ToUInt32(s.Substring(p, 8), 16 /*0x10*/); p += 8; return BitConverter.Int32BitsToSingle(uint32); } private Vector3 TransformVec3(Vector3 v, BaseKey3 k) { return new Vector3(this.TransformFloatBits(v.x, k.x), this.TransformFloatBits(v.y, k.y), this.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 vector3 = Vector3.Cross(Vector3.op_Subtraction(b, a), Vector3.op_Subtraction(c, a)); float magnitude = ((Vector3)ref vector3).magnitude; return (double)magnitude > 9.99999993922529E-09 ? Vector3.op_Division(vector3, magnitude) : Vector3.up; } private Bounds TransformBoundsToWorldAABB(Matrix4x4 l2w, Bounds localBounds) { Vector3 center = ((Bounds)ref localBounds).center; Vector3 extents = ((Bounds)ref localBounds).extents; Vector3 vector3 = ((Matrix4x4)ref l2w).MultiplyPoint3x4(Vector3.op_Addition(center, new Vector3(-extents.x, -extents.y, -extents.z))); Vector3 p1 = ((Matrix4x4)ref l2w).MultiplyPoint3x4(Vector3.op_Addition(center, new Vector3(-extents.x, -extents.y, extents.z))); Vector3 p2 = ((Matrix4x4)ref l2w).MultiplyPoint3x4(Vector3.op_Addition(center, new Vector3(-extents.x, extents.y, -extents.z))); Vector3 p3 = ((Matrix4x4)ref l2w).MultiplyPoint3x4(Vector3.op_Addition(center, new Vector3(-extents.x, extents.y, extents.z))); Vector3 p4 = ((Matrix4x4)ref l2w).MultiplyPoint3x4(Vector3.op_Addition(center, new Vector3(extents.x, -extents.y, -extents.z))); Vector3 p5 = ((Matrix4x4)ref l2w).MultiplyPoint3x4(Vector3.op_Addition(center, new Vector3(extents.x, -extents.y, extents.z))); Vector3 p6 = ((Matrix4x4)ref l2w).MultiplyPoint3x4(Vector3.op_Addition(center, new Vector3(extents.x, extents.y, -extents.z))); Vector3 p7 = ((Matrix4x4)ref l2w).MultiplyPoint3x4(Vector3.op_Addition(center, new Vector3(extents.x, extents.y, extents.z))); Vector3 min = vector3; Vector3 max = vector3; this.Encapsulate(ref min, ref max, p1); this.Encapsulate(ref min, ref max, p2); this.Encapsulate(ref min, ref max, p3); this.Encapsulate(ref min, ref max, p4); this.Encapsulate(ref min, ref max, p5); this.Encapsulate(ref min, ref max, p6); this.Encapsulate(ref min, ref max, p7); return new Bounds(Vector3.op_Multiply(Vector3.op_Addition(min, max), 0.5f), Vector3.op_Subtraction(max, min)); } private void Encapsulate(ref Vector3 min, ref Vector3 max, Vector3 p) { min = Vector3.Min(min, p); max = Vector3.Max(max, p); } }