Files
AutoMorpherDecompiled/Assets/@Eden_Tools/Eden_AutoMorpher/Script/ProfileLoader.cs
2026-02-01 19:30:24 +09:00

297 lines
13 KiB
C#

// 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 UnityEngine;
public class ProfileLoader
{
private ProfileData loadedProfileData;
private const int HEX32_W = 8;
public List<string> GetProfileList()
{
ProfileUtils profileUtils = new ProfileUtils();
string text = Path.Combine(Application.dataPath, profileUtils.GetProfileBasePath());
List<string> list = new List<string>();
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);
this.loadedProfileData = JsonUtility.FromJson<ProfileData>(json);
if (this.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 this.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 = this.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 = this.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 = this.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 = this.ReadHexIntSafe(text, ref num2);
num = this.ReadHexIntSafe(text, ref num2);
int num3 = this.ReadHexIntSafe(text, ref num2);
int num4 = this.ReadHexIntSafe(text, ref num2);
int num5 = this.ReadHexIntSafe(text, ref num2);
int num6 = this.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] = this.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] = this.TransformVec3(array3[j], array2[j % array2.Length]);
}
ProfileBVH profileBVH = new ProfileBVH
{
vertices = new List<Vector3>(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 = this.ReadHexIntSafe(text, ref num2),
verB = this.ReadHexIntSafe(text, ref num2),
verC = this.ReadHexIntSafe(text, ref num2)
};
}
for (int l = 0; l < num5; l++)
{
Vector3 center = this.ReadHexVec3Safe(text, ref num2);
Vector3 vector = this.ReadHexVec3Safe(text, ref num2);
profileBVH.nodes[l] = new profileBVHNode
{
bounds = new Bounds(center, vector * 2f),
leftChild = this.ReadHexIntSafe(text, ref num2),
rightChild = this.ReadHexIntSafe(text, ref num2),
start = this.ReadHexIntSafe(text, ref num2),
count = this.ReadHexIntSafe(text, ref num2),
isLeaf = (num2 < text.Length && text[num2++] == '1')
};
}
for (int m = 0; m < num6; m++)
{
profileBVH.dataIndices[m] = this.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(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");
}
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(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 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;
this.Encapsulate(ref min, ref max, p);
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((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);
}
}