245 lines
13 KiB
C#
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);
|
|
}
|
|
}
|