mirror of
https://github.com/Scobalula/Tyrant
synced 2024-11-10 06:24:14 +00:00
Resident Evil 3 Support
This commit is contained in:
parent
38dae7b9f2
commit
493e5da2e6
4 changed files with 515 additions and 38 deletions
|
@ -81,6 +81,19 @@ namespace Tyrant.Logic
|
||||||
public long TextureNamePointer;
|
public long TextureNamePointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resident Evil 7 Material Texture Entry
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
internal struct MaterialTextureEntryRE3
|
||||||
|
{
|
||||||
|
public long TypePointer;
|
||||||
|
public uint TypeHash;
|
||||||
|
public uint UnkHash;
|
||||||
|
public long TextureNamePointer;
|
||||||
|
public long Padding;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resident Evil 7 Material Texture Entry
|
/// Resident Evil 7 Material Texture Entry
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -153,32 +166,59 @@ namespace Tyrant.Logic
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the given material file
|
/// Converts the given material file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Dictionary<string, Model.Material> Convert(byte[] buffer)
|
public static Dictionary<string, Model.Material> ConvertRE3(BinaryReader reader)
|
||||||
|
{
|
||||||
|
var results = new Dictionary<string, Model.Material>();
|
||||||
|
|
||||||
|
{
|
||||||
|
reader.BaseStream.Position = 0;
|
||||||
|
var header = reader.ReadStruct<MaterialHeaderRE7>();
|
||||||
|
var materials = reader.ReadArray<MaterialEntryRE2>(header.MaterialCount);
|
||||||
|
|
||||||
|
Console.WriteLine(Marshal.SizeOf<MaterialEntryRE2>());
|
||||||
|
|
||||||
|
foreach (var material in materials)
|
||||||
|
{
|
||||||
|
var result = new Model.Material(reader.ReadUTF16NullTerminatedString(material.NamePointer));
|
||||||
|
|
||||||
|
foreach (var texture in reader.ReadArray<MaterialTextureEntryRE3>(material.TexturesPointer, material.TextureCount))
|
||||||
|
result.Images[reader.ReadUTF16NullTerminatedString(texture.TypePointer)] = reader.ReadUTF16NullTerminatedString(texture.TextureNamePointer).ToLower();
|
||||||
|
//foreach (var setting in reader.ReadArray<MaterialSettingsInfoRE7>(material.SettingsInfoPointer, material.SettingsInfoCount))
|
||||||
|
// result.Settings[reader.ReadUTF16NullTerminatedString(setting.NamePointer)] = reader.ReadArray<float>(material.SettingsBufferPointer + setting.DataOffset, setting.DataCount);
|
||||||
|
|
||||||
|
results[result.Name] = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the given material file
|
||||||
|
/// </summary>
|
||||||
|
public static Dictionary<string, Model.Material> Convert(byte[] buffer, string gameName = "13")
|
||||||
{
|
{
|
||||||
using (var stream = new MemoryStream(buffer))
|
using (var stream = new MemoryStream(buffer))
|
||||||
{
|
{
|
||||||
return Convert(stream);
|
return Convert(stream, gameName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the given material file
|
/// Converts the given material file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Dictionary<string, Model.Material> Convert(Stream stream)
|
public static Dictionary<string, Model.Material> Convert(Stream stream, string gameName = "13")
|
||||||
{
|
{
|
||||||
using (var reader = new BinaryReader(stream))
|
using (var reader = new BinaryReader(stream))
|
||||||
{
|
{
|
||||||
reader.BaseStream.Position = 28;
|
switch(gameName)
|
||||||
|
{
|
||||||
|
case "6": return ConvertRE7(reader);
|
||||||
|
case "10": return ConvertRE2(reader);
|
||||||
|
case "13": return ConvertRE3(reader);
|
||||||
|
}
|
||||||
|
|
||||||
// Check size of buffer
|
throw new Exception();
|
||||||
if(reader.ReadUInt32() != 0)
|
|
||||||
{
|
|
||||||
return ConvertRE2(reader);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ConvertRE7(reader);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,18 @@ namespace Tyrant.Logic
|
||||||
public long KeysPointer;
|
public long KeysPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resident Evil 3 Bone Data
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
internal struct BoneDataRE3
|
||||||
|
{
|
||||||
|
public ushort BoneIndex;
|
||||||
|
public DataPrecenseFlags Flags;
|
||||||
|
public uint BoneHash; // MurMur3;
|
||||||
|
public int KeysPointer;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resident Evil 7 Key Data (per channel per bone)
|
/// Resident Evil 7 Key Data (per channel per bone)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -165,6 +177,19 @@ namespace Tyrant.Logic
|
||||||
public long UnpackDataPointer;
|
public long UnpackDataPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resident Evil 3 Key Data (per channel per bone)
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
internal struct KeyDataRE3
|
||||||
|
{
|
||||||
|
public uint Flags;
|
||||||
|
public int KeyCount;
|
||||||
|
public int FramesPointer;
|
||||||
|
public int DataPointer;
|
||||||
|
public int UnpackDataPointer;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Packed 16-Bit Vector 3
|
/// Packed 16-Bit Vector 3
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -182,9 +207,10 @@ namespace Tyrant.Logic
|
||||||
private static DataDecompressorList Vector3Decompressors = new DataDecompressorList()
|
private static DataDecompressorList Vector3Decompressors = new DataDecompressorList()
|
||||||
{
|
{
|
||||||
{ 0x00000, LoadVector3sFull },
|
{ 0x00000, LoadVector3sFull },
|
||||||
{ 0x20000, LoadVector3s5Bit },
|
{ 0x20000, LoadVector3s5BitA },
|
||||||
{ 0x30000, LoadVector3s10Bit },
|
{ 0x30000, LoadVector3s10BitA },
|
||||||
{ 0x70000, LoadVector3s21Bit },
|
{ 0x40000, LoadVector3s10BitA },
|
||||||
|
{ 0x70000, LoadVector3s21BitA },
|
||||||
{ 0x31000, LoadVector3sXAxis },
|
{ 0x31000, LoadVector3sXAxis },
|
||||||
{ 0x32000, LoadVector3sYAxis },
|
{ 0x32000, LoadVector3sYAxis },
|
||||||
{ 0x33000, LoadVector3sZAxis },
|
{ 0x33000, LoadVector3sZAxis },
|
||||||
|
@ -193,6 +219,26 @@ namespace Tyrant.Logic
|
||||||
{ 0x23000, LoadVector3sZAxis16Bit },
|
{ 0x23000, LoadVector3sZAxis16Bit },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Vector 3 Decompressors, used by Translations and Scales for RE3
|
||||||
|
/// </summary>
|
||||||
|
private static DataDecompressorList Vector3DecompressorsRE3 = new DataDecompressorList()
|
||||||
|
{
|
||||||
|
{ 0x00000, LoadVector3sFull },
|
||||||
|
{ 0x20000, LoadVector3s5BitB },
|
||||||
|
{ 0x30000, LoadVector3s5BitB },
|
||||||
|
{ 0x40000, LoadVector3s10BitB },
|
||||||
|
{ 0x80000, LoadVector3s21BitB },
|
||||||
|
{ 0x21000, LoadVector3sXAxis16Bit },
|
||||||
|
{ 0x22000, LoadVector3sYAxis16Bit },
|
||||||
|
{ 0x23000, LoadVector3sZAxis16Bit },
|
||||||
|
{ 0x24000, LoadVector3sXYZAxis16Bit },
|
||||||
|
{ 0x41000, LoadVector3sXAxis },
|
||||||
|
{ 0x42000, LoadVector3sYAxis },
|
||||||
|
{ 0x43000, LoadVector3sZAxis },
|
||||||
|
{ 0x44000, LoadVector3sXYZAxis },
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Quaternion Decompressors, used by Rotations
|
/// Quaternion Decompressors, used by Rotations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -200,15 +246,46 @@ namespace Tyrant.Logic
|
||||||
{
|
{
|
||||||
{ 0x00000, LoadQuaternionsFull },
|
{ 0x00000, LoadQuaternionsFull },
|
||||||
{ 0xB0000, LoadQuaternions3Component },
|
{ 0xB0000, LoadQuaternions3Component },
|
||||||
|
{ 0xC0000, LoadQuaternions3Component },
|
||||||
{ 0x30000, LoadQuaternions10Bit },
|
{ 0x30000, LoadQuaternions10Bit },
|
||||||
|
{ 0x40000, LoadQuaternions10Bit },
|
||||||
{ 0x50000, LoadQuaternions16Bit },
|
{ 0x50000, LoadQuaternions16Bit },
|
||||||
{ 0x70000, LoadQuaternions21Bit },
|
{ 0x70000, LoadQuaternions21Bit },
|
||||||
{ 0x21000, LoadQuaternionsXAxis16Bit },
|
{ 0x21000, LoadQuaternionsXAxis16Bit },
|
||||||
{ 0x22000, LoadQuaternionsYAxis16Bit },
|
{ 0x22000, LoadQuaternionsYAxis16Bit },
|
||||||
{ 0x23000, LoadQuaternionsZAxis16Bit },
|
{ 0x23000, LoadQuaternionsZAxis16Bit },
|
||||||
{ 0x31000, LoadQuaternionsXAxis },
|
{ 0x31000, LoadQuaternionsXAxis },
|
||||||
|
{ 0x41000, LoadQuaternionsXAxis },
|
||||||
{ 0x32000, LoadQuaternionsYAxis },
|
{ 0x32000, LoadQuaternionsYAxis },
|
||||||
|
{ 0x42000, LoadQuaternionsYAxis },
|
||||||
{ 0x33000, LoadQuaternionsZAxis },
|
{ 0x33000, LoadQuaternionsZAxis },
|
||||||
|
{ 0x43000, LoadQuaternionsZAxis },
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Quaternion Decompressors, used by Rotations
|
||||||
|
/// </summary>
|
||||||
|
private static DataDecompressorList QuaternionDecompressorsRE3 = new DataDecompressorList()
|
||||||
|
{
|
||||||
|
{ 0x00000, LoadQuaternionsFull },
|
||||||
|
{ 0xB0000, LoadQuaternions3Component },
|
||||||
|
{ 0xC0000, LoadQuaternions3Component },
|
||||||
|
{ 0x20000, LoadQuaternions5Bit },
|
||||||
|
{ 0x30000, LoadQuaternions8Bit },
|
||||||
|
{ 0x40000, LoadQuaternions10Bit },
|
||||||
|
{ 0x50000, LoadQuaternions13Bit },
|
||||||
|
{ 0x60000, LoadQuaternions16Bit },
|
||||||
|
{ 0x70000, LoadQuaternions18Bit },
|
||||||
|
{ 0x80000, LoadQuaternions21Bit },
|
||||||
|
{ 0x21000, LoadQuaternionsXAxis16Bit },
|
||||||
|
{ 0x22000, LoadQuaternionsYAxis16Bit },
|
||||||
|
{ 0x23000, LoadQuaternionsZAxis16Bit },
|
||||||
|
{ 0x31000, LoadQuaternionsXAxis },
|
||||||
|
{ 0x41000, LoadQuaternionsXAxis },
|
||||||
|
{ 0x32000, LoadQuaternionsYAxis },
|
||||||
|
{ 0x42000, LoadQuaternionsYAxis },
|
||||||
|
{ 0x33000, LoadQuaternionsZAxis },
|
||||||
|
{ 0x43000, LoadQuaternionsZAxis },
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -231,7 +308,7 @@ namespace Tyrant.Logic
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads 5Bit Vector3s
|
/// Loads 5Bit Vector3s
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void LoadVector3s5Bit(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
private static void LoadVector3s5BitA(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
{
|
{
|
||||||
var data = reader.ReadArray<ushort>(dataPointer, frames.Length);
|
var data = reader.ReadArray<ushort>(dataPointer, frames.Length);
|
||||||
|
|
||||||
|
@ -245,18 +322,52 @@ namespace Tyrant.Logic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads 5Bit Vector3s
|
||||||
|
/// </summary>
|
||||||
|
private static void LoadVector3s5BitB(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
|
{
|
||||||
|
var data = reader.ReadArray<ushort>(dataPointer, frames.Length);
|
||||||
|
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
var x = (unpackData[0] * ((data[i] >> 00) & 0x1F) / 31.0f) + unpackData[3];
|
||||||
|
var y = (unpackData[1] * ((data[i] >> 05) & 0x1F) / 31.0f) + unpackData[4];
|
||||||
|
var z = (unpackData[2] * ((data[i] >> 10) & 0x1F) / 31.0f) + unpackData[5];
|
||||||
|
|
||||||
|
bone.Translations[frames[i]] = new Vector3(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads 10Bit Vector3s
|
/// Loads 10Bit Vector3s
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void LoadVector3s10Bit(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
private static void LoadVector3s10BitA(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
{
|
{
|
||||||
var data = reader.ReadArray<uint>(dataPointer, frames.Length);
|
var data = reader.ReadArray<uint>(dataPointer, frames.Length);
|
||||||
|
|
||||||
for (int i = 0; i < data.Length; i++)
|
for (int i = 0; i < data.Length; i++)
|
||||||
{
|
{
|
||||||
var x = (unpackData[0] * ((data[i] >> 00) & 0x3FF) / 1023.0f) + unpackData[4];
|
var x = unpackData[0] * (((data[i] >> 00) & 0x3FF) * (1.0f / 0x3FF)) + unpackData[4];
|
||||||
var y = (unpackData[1] * ((data[i] >> 10) & 0x3FF) / 1023.0f) + unpackData[5];
|
var y = unpackData[1] * (((data[i] >> 10) & 0x3FF) * (1.0f / 0x3FF)) + unpackData[5];
|
||||||
var z = (unpackData[2] * ((data[i] >> 20) & 0x3FF) / 1023.0f) + unpackData[6];
|
var z = unpackData[2] * (((data[i] >> 20) & 0x3FF) * (1.0f / 0x3FF)) + unpackData[6];
|
||||||
|
|
||||||
|
bone.Translations[frames[i]] = new Vector3(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads 10Bit Vector3s
|
||||||
|
/// </summary>
|
||||||
|
private static void LoadVector3s10BitB(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
|
{
|
||||||
|
var data = reader.ReadArray<uint>(dataPointer, frames.Length);
|
||||||
|
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
var x = unpackData[0] * (((data[i] >> 00) & 0x3FF) * (1.0f / 0x3FF)) + unpackData[3];
|
||||||
|
var y = unpackData[1] * (((data[i] >> 10) & 0x3FF) * (1.0f / 0x3FF)) + unpackData[4];
|
||||||
|
var z = unpackData[2] * (((data[i] >> 20) & 0x3FF) * (1.0f / 0x3FF)) + unpackData[5];
|
||||||
|
|
||||||
bone.Translations[frames[i]] = new Vector3(x, y, z);
|
bone.Translations[frames[i]] = new Vector3(x, y, z);
|
||||||
}
|
}
|
||||||
|
@ -265,7 +376,7 @@ namespace Tyrant.Logic
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads 21Bit Vector3s
|
/// Loads 21Bit Vector3s
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void LoadVector3s21Bit(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
private static void LoadVector3s21BitA(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
{
|
{
|
||||||
var data = reader.ReadArray<ulong>(dataPointer, frames.Length);
|
var data = reader.ReadArray<ulong>(dataPointer, frames.Length);
|
||||||
|
|
||||||
|
@ -279,6 +390,23 @@ namespace Tyrant.Logic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads 21Bit Vector3s
|
||||||
|
/// </summary>
|
||||||
|
private static void LoadVector3s21BitB(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
|
{
|
||||||
|
var data = reader.ReadArray<ulong>(dataPointer, frames.Length);
|
||||||
|
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
var x = (unpackData[0] * ((data[i] >> 00) & 0x1FFFFF) / 2097151.0f) + unpackData[3];
|
||||||
|
var y = (unpackData[1] * ((data[i] >> 21) & 0x1FFFFF) / 2097151.0f) + unpackData[4];
|
||||||
|
var z = (unpackData[2] * ((data[i] >> 42) & 0x1FFFFF) / 2097151.0f) + unpackData[5];
|
||||||
|
|
||||||
|
bone.Translations[frames[i]] = new Vector3(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads Vector3s with 1 Component on X Axis
|
/// Loads Vector3s with 1 Component on X Axis
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -330,6 +458,23 @@ namespace Tyrant.Logic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads Vector3s with 1 Component on Z Axis
|
||||||
|
/// </summary>
|
||||||
|
private static void LoadVector3sXYZAxis(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
|
{
|
||||||
|
var data = reader.ReadArray<float>(dataPointer, frames.Length);
|
||||||
|
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
var x = data[i];
|
||||||
|
var y = data[i];
|
||||||
|
var z = data[i];
|
||||||
|
|
||||||
|
bone.Translations[frames[i]] = new Vector3(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads Vector3s with 1 Component on X Axis
|
/// Loads Vector3s with 1 Component on X Axis
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -381,6 +526,25 @@ namespace Tyrant.Logic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads Vector3s with 1 Component on Y Axis
|
||||||
|
/// </summary>
|
||||||
|
private static void LoadVector3sXYZAxis16Bit(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
|
{
|
||||||
|
var data = reader.ReadArray<ushort>(dataPointer, frames.Length);
|
||||||
|
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
var val = unpackData[0] * (data[i] / 65535.0f) + unpackData[3];
|
||||||
|
|
||||||
|
var x = val;
|
||||||
|
var y = val;
|
||||||
|
var z = val;
|
||||||
|
|
||||||
|
bone.Translations[frames[i]] = new Vector3(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads Quaternions with all components
|
/// Loads Quaternions with all components
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -412,13 +576,64 @@ namespace Tyrant.Logic
|
||||||
var x = data[i].X;
|
var x = data[i].X;
|
||||||
var y = data[i].Y;
|
var y = data[i].Y;
|
||||||
var z = data[i].Z;
|
var z = data[i].Z;
|
||||||
var w = (float)Math.Sqrt(1 - x * x - y * y - z * z);
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads 10Bit Quaternions
|
||||||
|
/// </summary>
|
||||||
|
private static void LoadQuaternions5Bit(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
|
{
|
||||||
|
var data = reader.ReadArray<ushort>(dataPointer, frames.Length);
|
||||||
|
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
var x = (unpackData[0] * ((data[i] >> 00) & 0x1F) * (1.0f / 0x1F)) + unpackData[4];
|
||||||
|
var y = (unpackData[1] * ((data[i] >> 05) & 0x1F) * (1.0f / 0x1F)) + unpackData[5];
|
||||||
|
var z = (unpackData[2] * ((data[i] >> 10) & 0x1F) * (1.0f / 0x1F)) + unpackData[6];
|
||||||
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads 10Bit Quaternions
|
||||||
|
/// </summary>
|
||||||
|
private static void LoadQuaternions8Bit(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
|
{
|
||||||
|
reader.BaseStream.Position = dataPointer;
|
||||||
|
|
||||||
|
for (int i = 0; i < frames.Length; i++)
|
||||||
|
{
|
||||||
|
var x = (unpackData[0] * (reader.ReadByte() * 0.000015259022f)) + unpackData[4];
|
||||||
|
var y = (unpackData[1] * (reader.ReadByte() * 0.000015259022f)) + unpackData[5];
|
||||||
|
var z = (unpackData[2] * (reader.ReadByte() * 0.000015259022f)) + unpackData[6];
|
||||||
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads 10Bit Quaternions
|
/// Loads 10Bit Quaternions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -431,7 +646,12 @@ namespace Tyrant.Logic
|
||||||
var x = (unpackData[0] * ((data[i] >> 00) & 0x3FF) / 1023.0f) + unpackData[4];
|
var x = (unpackData[0] * ((data[i] >> 00) & 0x3FF) / 1023.0f) + unpackData[4];
|
||||||
var y = (unpackData[1] * ((data[i] >> 10) & 0x3FF) / 1023.0f) + unpackData[5];
|
var y = (unpackData[1] * ((data[i] >> 10) & 0x3FF) / 1023.0f) + unpackData[5];
|
||||||
var z = (unpackData[2] * ((data[i] >> 20) & 0x3FF) / 1023.0f) + unpackData[6];
|
var z = (unpackData[2] * ((data[i] >> 20) & 0x3FF) / 1023.0f) + unpackData[6];
|
||||||
var w = (float)Math.Sqrt(1 - x * x - y * y - z * z);
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
}
|
}
|
||||||
|
@ -449,7 +669,61 @@ namespace Tyrant.Logic
|
||||||
var x = (unpackData[0] * (data[i].X / 65535.0f)) + unpackData[4];
|
var x = (unpackData[0] * (data[i].X / 65535.0f)) + unpackData[4];
|
||||||
var y = (unpackData[1] * (data[i].Y / 65535.0f)) + unpackData[5];
|
var y = (unpackData[1] * (data[i].Y / 65535.0f)) + unpackData[5];
|
||||||
var z = (unpackData[2] * (data[i].Z / 65535.0f)) + unpackData[6];
|
var z = (unpackData[2] * (data[i].Z / 65535.0f)) + unpackData[6];
|
||||||
var w = (float)Math.Sqrt(1 - x * x - y * y - z * z);
|
var w = (float)Math.Sqrt(Math.Abs(1 - x * x - y * y - z * z));
|
||||||
|
|
||||||
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads 10Bit Quaternions
|
||||||
|
/// </summary>
|
||||||
|
private static void LoadQuaternions13Bit(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
|
{
|
||||||
|
reader.BaseStream.Position = dataPointer;
|
||||||
|
|
||||||
|
for (int i = 0; i < frames.Length; i++)
|
||||||
|
{
|
||||||
|
var data = reader.ReadBytes(5);
|
||||||
|
ulong val = 0;
|
||||||
|
for(int j = 0; j < 5; j++)
|
||||||
|
val = data[j] | (val << 8);
|
||||||
|
|
||||||
|
var x = (unpackData[0] * ((val >> 00) & 0x1FFF) * 0.00012208521f) + unpackData[4];
|
||||||
|
var y = (unpackData[1] * ((val >> 13) & 0x1FFF) * 0.00012208521f) + unpackData[5];
|
||||||
|
var z = (unpackData[2] * ((val >> 26) & 0x1FFF) * 0.00012208521f) + unpackData[6];
|
||||||
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads 18Bit Quaternions
|
||||||
|
/// </summary>
|
||||||
|
private static void LoadQuaternions18Bit(BinaryReader reader, Animation.Bone bone, int[] frames, float[] unpackData, long dataPointer)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < frames.Length; i++)
|
||||||
|
{
|
||||||
|
var data = reader.ReadBytes(7);
|
||||||
|
ulong val = 0;
|
||||||
|
for (int j = 0; j < 7; j++)
|
||||||
|
val = data[j] | (val << 8);
|
||||||
|
|
||||||
|
var x = (unpackData[0] * ((val >> 00) & 0x1FFF) * 0.00012208521f) + unpackData[4];
|
||||||
|
var y = (unpackData[1] * ((val >> 13) & 0x1FFF) * 0.00012208521f) + unpackData[5];
|
||||||
|
var z = (unpackData[2] * ((val >> 26) & 0x1FFF) * 0.00012208521f) + unpackData[6];
|
||||||
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
}
|
}
|
||||||
|
@ -467,7 +741,12 @@ namespace Tyrant.Logic
|
||||||
var x = (unpackData[0] * ((data[i] >> 00) & 0x1FFFFF) / 2097151.0f) + unpackData[4];
|
var x = (unpackData[0] * ((data[i] >> 00) & 0x1FFFFF) / 2097151.0f) + unpackData[4];
|
||||||
var y = (unpackData[1] * ((data[i] >> 21) & 0x1FFFFF) / 2097151.0f) + unpackData[5];
|
var y = (unpackData[1] * ((data[i] >> 21) & 0x1FFFFF) / 2097151.0f) + unpackData[5];
|
||||||
var z = (unpackData[2] * ((data[i] >> 42) & 0x1FFFFF) / 2097151.0f) + unpackData[6];
|
var z = (unpackData[2] * ((data[i] >> 42) & 0x1FFFFF) / 2097151.0f) + unpackData[6];
|
||||||
var w = (float)Math.Sqrt(1 - x * x - y * y - z * z);
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
}
|
}
|
||||||
|
@ -485,7 +764,12 @@ namespace Tyrant.Logic
|
||||||
var x = data[i];
|
var x = data[i];
|
||||||
var y = 0.0f;
|
var y = 0.0f;
|
||||||
var z = 0.0f;
|
var z = 0.0f;
|
||||||
var w = (float)Math.Sqrt(1 - x * x - y * y - z * z);
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
}
|
}
|
||||||
|
@ -503,7 +787,12 @@ namespace Tyrant.Logic
|
||||||
var x = 0.0f;
|
var x = 0.0f;
|
||||||
var y = data[i];
|
var y = data[i];
|
||||||
var z = 0.0f;
|
var z = 0.0f;
|
||||||
var w = (float)Math.Sqrt(1 - x * x - y * y - z * z);
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
}
|
}
|
||||||
|
@ -521,7 +810,12 @@ namespace Tyrant.Logic
|
||||||
var x = 0.0f;
|
var x = 0.0f;
|
||||||
var y = 0.0f;
|
var y = 0.0f;
|
||||||
var z = data[i];
|
var z = data[i];
|
||||||
var w = (float)Math.Sqrt(1 - x * x - y * y - z * z);
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
}
|
}
|
||||||
|
@ -540,7 +834,12 @@ namespace Tyrant.Logic
|
||||||
var x = unpackData[0] * (data[i] / 65535.0f) + unpackData[1];
|
var x = unpackData[0] * (data[i] / 65535.0f) + unpackData[1];
|
||||||
var y = 0.0f;
|
var y = 0.0f;
|
||||||
var z = 0.0f;
|
var z = 0.0f;
|
||||||
var w = (float)Math.Sqrt(1 - x * x - y * y - z * z);
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
}
|
}
|
||||||
|
@ -558,7 +857,12 @@ namespace Tyrant.Logic
|
||||||
var x = 0.0f;
|
var x = 0.0f;
|
||||||
var y = unpackData[0] * (data[i] / 65535.0f) + unpackData[1];
|
var y = unpackData[0] * (data[i] / 65535.0f) + unpackData[1];
|
||||||
var z = 0.0f;
|
var z = 0.0f;
|
||||||
var w = (float)Math.Sqrt(1 - x * x - y * y - z * z);
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
}
|
}
|
||||||
|
@ -576,7 +880,12 @@ namespace Tyrant.Logic
|
||||||
var x = 0.0f;
|
var x = 0.0f;
|
||||||
var y = 0.0f;
|
var y = 0.0f;
|
||||||
var z = unpackData[0] * (data[i] / 65535.0f) + unpackData[1];
|
var z = unpackData[0] * (data[i] / 65535.0f) + unpackData[1];
|
||||||
var w = (float)Math.Sqrt(1 - x * x - y * y - z * z);
|
var w = 1.0f - (x * x + y * y + z * z);
|
||||||
|
|
||||||
|
if (w > 0.0f)
|
||||||
|
w = (float)Math.Sqrt(w);
|
||||||
|
else
|
||||||
|
w = 0.0f;
|
||||||
|
|
||||||
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
bone.Rotations[frames[i]] = new Quaternion(x, y, z, w);
|
||||||
}
|
}
|
||||||
|
@ -587,6 +896,15 @@ namespace Tyrant.Logic
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static int[] LoadFrames(BinaryReader reader, long framesPointer, int frameCount, uint frameDataType)
|
private static int[] LoadFrames(BinaryReader reader, long framesPointer, int frameCount, uint frameDataType)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if(frameCount < 2)
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var results = new int[frameCount];
|
var results = new int[frameCount];
|
||||||
|
|
||||||
reader.BaseStream.Position = framesPointer;
|
reader.BaseStream.Position = framesPointer;
|
||||||
|
@ -698,6 +1016,7 @@ namespace Tyrant.Logic
|
||||||
|
|
||||||
var keyFrames = LoadFrames(reader, keyData.FramesPointer, keyData.KeyCount, keyFrameDataType);
|
var keyFrames = LoadFrames(reader, keyData.FramesPointer, keyData.KeyCount, keyFrameDataType);
|
||||||
|
|
||||||
|
|
||||||
if (QuaternionDecompressors.TryGetValue(compression, out var decompressionMethod))
|
if (QuaternionDecompressors.TryGetValue(compression, out var decompressionMethod))
|
||||||
decompressionMethod(reader, bones[bone.BoneHash], keyFrames, unpackData, keyData.DataPointer);
|
decompressionMethod(reader, bones[bone.BoneHash], keyFrames, unpackData, keyData.DataPointer);
|
||||||
else
|
else
|
||||||
|
@ -808,10 +1127,116 @@ namespace Tyrant.Logic
|
||||||
return new Tuple<string, Animation>(reader.ReadUTF16NullTerminatedString(header.NamePointer), animation);
|
return new Tuple<string, Animation>(reader.ReadUTF16NullTerminatedString(header.NamePointer), animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts an RE3 Motion File to a SEAnim
|
||||||
|
/// </summary>
|
||||||
|
private static Tuple<string, Animation> ConvertRE3(BinaryReader reader, Dictionary<uint, Animation.Bone> bones)
|
||||||
|
{
|
||||||
|
var animation = new Animation(Animation.DataType.Absolute);
|
||||||
|
|
||||||
|
var header = reader.ReadStruct<MotionHeaderRE2>();
|
||||||
|
|
||||||
|
var name = reader.ReadUTF16NullTerminatedString(header.NamePointer);
|
||||||
|
|
||||||
|
var localBones = new Dictionary<uint, Animation.Bone>();
|
||||||
|
|
||||||
|
{
|
||||||
|
if(bones.Count <= 0)
|
||||||
|
{
|
||||||
|
reader.BaseStream.Position = header.BoneBaseDataPointer;
|
||||||
|
|
||||||
|
var baseDataOffset = reader.ReadInt64();
|
||||||
|
var baseDataCount = reader.ReadInt32();
|
||||||
|
|
||||||
|
var boneBaseData = reader.ReadArray<BoneBaseDataRE7>(baseDataOffset, baseDataCount);
|
||||||
|
|
||||||
|
foreach (var boneBase in boneBaseData)
|
||||||
|
{
|
||||||
|
var bone = new Animation.Bone(reader.ReadUTF16NullTerminatedString(boneBase.NamePointer));
|
||||||
|
|
||||||
|
bone.Translations[0] = boneBase.Translation.ToVector3();
|
||||||
|
bone.Rotations[0] = boneBase.Rotation;
|
||||||
|
bones[boneBase.Hash] = bone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add base data
|
||||||
|
foreach(var bone in bones)
|
||||||
|
{
|
||||||
|
var nbone = new Animation.Bone(bone.Value.Name);
|
||||||
|
|
||||||
|
nbone.Translations[0] = bone.Value.Translations[0];
|
||||||
|
nbone.Rotations[0] = bone.Value.Rotations[0];
|
||||||
|
|
||||||
|
localBones[bone.Key] = nbone;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.BoneDataPointer > 0)
|
||||||
|
{
|
||||||
|
var boneData = reader.ReadArray<BoneDataRE3>(header.BoneDataPointer, header.BoneDataCount);
|
||||||
|
|
||||||
|
foreach (var bone in boneData)
|
||||||
|
{
|
||||||
|
var keyDataOffset = bone.KeysPointer;
|
||||||
|
|
||||||
|
if (bone.Flags.HasFlag(DataPrecenseFlags.Translations))
|
||||||
|
{
|
||||||
|
var keyData = reader.ReadStruct<KeyDataRE3>(keyDataOffset);
|
||||||
|
|
||||||
|
float[] unpackData = null;
|
||||||
|
uint keyFrameDataType = keyData.Flags & 0xF00000;
|
||||||
|
uint compression = keyData.Flags & 0xFF000;
|
||||||
|
uint unkFlag = keyData.Flags & 0xFFF;
|
||||||
|
|
||||||
|
if (keyData.UnpackDataPointer > 0)
|
||||||
|
unpackData = reader.ReadArray<float>(keyData.UnpackDataPointer, 16);
|
||||||
|
|
||||||
|
var keyFrames = LoadFrames(reader, keyData.FramesPointer, keyData.KeyCount, keyFrameDataType);
|
||||||
|
|
||||||
|
if (Vector3DecompressorsRE3.TryGetValue(compression, out var decompressionMethod))
|
||||||
|
decompressionMethod(reader, localBones[bone.BoneHash], keyFrames, unpackData, keyData.DataPointer);
|
||||||
|
else
|
||||||
|
throw new Exception(string.Format("Unknown Vector3 compression type: 0x{0:X}", compression));
|
||||||
|
|
||||||
|
keyDataOffset += Marshal.SizeOf<KeyDataRE3>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bone.Flags.HasFlag(DataPrecenseFlags.Rotations))
|
||||||
|
{
|
||||||
|
var keyData = reader.ReadStruct<KeyDataRE3>(keyDataOffset);
|
||||||
|
|
||||||
|
float[] unpackData = null;
|
||||||
|
uint keyFrameDataType = keyData.Flags & 0xF00000;
|
||||||
|
uint compression = keyData.Flags & 0xFF000;
|
||||||
|
uint unkFlag = keyData.Flags & 0xFFF;
|
||||||
|
|
||||||
|
if (keyData.UnpackDataPointer > 0)
|
||||||
|
unpackData = reader.ReadArray<float>(keyData.UnpackDataPointer, 16);
|
||||||
|
|
||||||
|
var keyFrames = LoadFrames(reader, keyData.FramesPointer, keyData.KeyCount, keyFrameDataType);
|
||||||
|
|
||||||
|
|
||||||
|
if (QuaternionDecompressorsRE3.TryGetValue(compression, out var decompressionMethod))
|
||||||
|
decompressionMethod(reader, localBones[bone.BoneHash], keyFrames, unpackData, keyData.DataPointer);
|
||||||
|
else
|
||||||
|
throw new Exception(string.Format("Unknown Quaternion compression type: 0x{0:X}", compression));
|
||||||
|
|
||||||
|
keyDataOffset += Marshal.SizeOf<KeyDataRE3>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var bone in localBones)
|
||||||
|
animation.Bones.Add(bone.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Tuple<string, Animation>(reader.ReadUTF16NullTerminatedString(header.NamePointer), animation);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the given Motion
|
/// Converts the given Motion
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Tuple<string, Animation> Convert(Stream stream)
|
public static Tuple<string, Animation> Convert(Stream stream, Dictionary<uint, Animation.Bone> bones)
|
||||||
{
|
{
|
||||||
using (var reader = new BinaryReader(stream))
|
using (var reader = new BinaryReader(stream))
|
||||||
{
|
{
|
||||||
|
@ -822,6 +1247,7 @@ namespace Tyrant.Logic
|
||||||
{
|
{
|
||||||
case 0x2B: return ConvertRE7(reader);
|
case 0x2B: return ConvertRE7(reader);
|
||||||
case 0x41: return ConvertRE2(reader);
|
case 0x41: return ConvertRE2(reader);
|
||||||
|
case 0x4E: return ConvertRE3(reader, bones);
|
||||||
default: throw new Exception("Invalid Motion Version");
|
default: throw new Exception("Invalid Motion Version");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ namespace Tyrant.Logic
|
||||||
|
|
||||||
using (var stream = new MemoryStream(reader.ReadBytes((int)(endOffset - offsets[i]))))
|
using (var stream = new MemoryStream(reader.ReadBytes((int)(endOffset - offsets[i]))))
|
||||||
{
|
{
|
||||||
results.Add(Motion.Convert(stream));
|
results.Add(Motion.Convert(stream, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +103,7 @@ namespace Tyrant.Logic
|
||||||
{
|
{
|
||||||
var header = reader.ReadStruct<MotionListHeaderRE2>();
|
var header = reader.ReadStruct<MotionListHeaderRE2>();
|
||||||
var results = new List<Tuple<string, Animation>>();
|
var results = new List<Tuple<string, Animation>>();
|
||||||
|
var bones = new Dictionary<uint, Animation.Bone>();
|
||||||
|
|
||||||
// Sort by offsets since they don't store sizes, we also need to remove dupes as some entries point to another
|
// Sort by offsets since they don't store sizes, we also need to remove dupes as some entries point to another
|
||||||
var offsets = reader.ReadArray<long>(header.AssetsPointer, header.AssetCount).Distinct().OrderBy(x => x).ToArray();
|
var offsets = reader.ReadArray<long>(header.AssetsPointer, header.AssetCount).Distinct().OrderBy(x => x).ToArray();
|
||||||
|
@ -122,9 +123,11 @@ namespace Tyrant.Logic
|
||||||
|
|
||||||
reader.BaseStream.Position = offsets[i];
|
reader.BaseStream.Position = offsets[i];
|
||||||
|
|
||||||
using (var stream = new MemoryStream(reader.ReadBytes((int)(endOffset - offsets[i]))))
|
var buffer = reader.ReadBytes((int)(endOffset - offsets[i]));
|
||||||
|
|
||||||
|
using (var stream = new MemoryStream(buffer))
|
||||||
{
|
{
|
||||||
results.Add(Motion.Convert(stream));
|
results.Add(Motion.Convert(stream, bones));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +157,7 @@ namespace Tyrant.Logic
|
||||||
{
|
{
|
||||||
case 0x3C: return ConvertRE7(reader);
|
case 0x3C: return ConvertRE7(reader);
|
||||||
case 0x55: return ConvertRE2(reader);
|
case 0x55: return ConvertRE2(reader);
|
||||||
|
case 0x63: return ConvertRE2(reader);
|
||||||
default: throw new Exception("Invalid Motion List Version");
|
default: throw new Exception("Invalid Motion List Version");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,8 @@ namespace Tyrant
|
||||||
{
|
{
|
||||||
"natives/x64/streaming/",
|
"natives/x64/streaming/",
|
||||||
"natives/x64/",
|
"natives/x64/",
|
||||||
|
"natives/stm/streaming/",
|
||||||
|
"natives/stm/",
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -81,9 +83,12 @@ namespace Tyrant
|
||||||
"_mat.mdf2.10",
|
"_mat.mdf2.10",
|
||||||
".mdf2.6",
|
".mdf2.6",
|
||||||
"_mat.mdf2.6",
|
"_mat.mdf2.6",
|
||||||
|
".mdf2.13",
|
||||||
|
"_mat.mdf2.13",
|
||||||
".10",
|
".10",
|
||||||
".11",
|
".11",
|
||||||
".8",
|
".8",
|
||||||
|
".190820018"
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -278,7 +283,6 @@ namespace Tyrant
|
||||||
var folder = Path.Combine(path, motions.Item1);
|
var folder = Path.Combine(path, motions.Item1);
|
||||||
|
|
||||||
var result = path;
|
var result = path;
|
||||||
|
|
||||||
Directory.CreateDirectory(folder);
|
Directory.CreateDirectory(folder);
|
||||||
|
|
||||||
foreach(var motion in motions.Item2)
|
foreach(var motion in motions.Item2)
|
||||||
|
@ -390,7 +394,7 @@ namespace Tyrant
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
materials = MaterialDefs.Convert(ActivePackage.LoadEntry(result));
|
materials = MaterialDefs.Convert(ActivePackage.LoadEntry(result), prefix.Split('.').Last());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@ -487,6 +491,9 @@ namespace Tyrant
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
File.WriteAllBytes("BAD_BUFFER.dat", ActivePackage.LoadEntry(asset.PackageEntry));
|
||||||
|
#endif
|
||||||
Log(string.Format("Error has occured while exporting {0}: {1}", Path.GetFileNameWithoutExtension(asset.Name), e), "ERROR");
|
Log(string.Format("Error has occured while exporting {0}: {1}", Path.GetFileNameWithoutExtension(asset.Name), e), "ERROR");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue