Files
AutoMorpherDecompiled/Assets/@Eden_Tools/Eden_AutoMorpher/Script/ProfileLoader.cs

245 lines
13 KiB
C#

// 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<string> GetProfileList()
{
string path1 = Path.Combine(Application.dataPath, new ProfileUtils().GetProfileBasePath());
List<string> profileList = new List<string>();
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<ProfileData>(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<Vector3>(capacity),
datas = new profileBVHData[length1],
nodes = new profileBVHNode[length2],
dataIndices = new int[length3]
};
profileBvh.vertices.AddRange((IEnumerable<Vector3>)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);
}
}