Re: Mirror's Edge Catalyst Beta
Posted: Sat Oct 01, 2016 9:41 pm
@OriginOfWaves thank you! I was really hoping to get the models from this game but I didn't know if it was already possible or not.
Code: Select all
private void Skeleton(string fpebx) {
MemoryStream siSkel = new MemoryStream(File.ReadAllBytes(fpebx));
BinaryReader brSkel = new BinaryReader(siSkel);
SkelFileHeader fileHeader = new SkelFileHeader {
Data64 = brSkel.ReadBytes(64),
};
siSkel.Position = fileHeader.OffsetStrBlock1 + fileHeader.LengthStrBlock1;
brSkel.ReadBytes(16 * fileHeader.EntryCount1);
brSkel.ReadBytes(16 * fileHeader.EntryCount2);
SkelHeader header = new SkelHeader {
Data160 = brSkel.ReadBytes(160),
};
var strBlk2 = Encoding.ASCII.GetString(brSkel.ReadBytes(fileHeader.LengthStrBlock2));
brSkel.ReadBytes(16); //GUID?
brSkel.ReadBytes(0x30); //?
List<Bone> bones = new List<Bone>();
{
int countBones = brSkel.ReadInt32();
Debug.Assert(countBones == header.CountBones);
for (int x = 0; x < countBones; x++) {
int relativeOffsetName = brSkel.ReadInt32();
bones.Add(new Bone {
index = x,
name = strBlk2.Substring(relativeOffsetName).Split('\0')[0],
});
}
}
{
int countBones = brSkel.ReadInt32();
Debug.Assert(countBones == header.CountBones);
for (int x = 0; x < countBones; x++) {
brSkel.ReadInt32();//?
}
}
{
int countBones = brSkel.ReadInt32();
Debug.Assert(countBones == header.CountBones);
for (int x = 0; x < countBones; x++) {
bones[x].parentIndex = brSkel.ReadInt32();
}
}
{
siSkel.Position += 12 - (int)(siSkel.Position & 15);
int countBones = brSkel.ReadInt32();
Debug.Assert(countBones == header.CountBones);
for (int x = 0; x < countBones; x++) {
bones[x].matrix1 = new float[9];
bones[x].matrix1[0] = brSkel.ReadSingle();
bones[x].matrix1[1] = brSkel.ReadSingle();
bones[x].matrix1[2] = brSkel.ReadSingle();
brSkel.ReadSingle();
bones[x].matrix1[3] = brSkel.ReadSingle();
bones[x].matrix1[4] = brSkel.ReadSingle();
bones[x].matrix1[5] = brSkel.ReadSingle();
brSkel.ReadSingle();
bones[x].matrix1[6] = brSkel.ReadSingle();
bones[x].matrix1[7] = brSkel.ReadSingle();
bones[x].matrix1[8] = brSkel.ReadSingle();
brSkel.ReadSingle();
bones[x].vector1 = new float[3];
bones[x].vector1[0] = brSkel.ReadSingle();
bones[x].vector1[1] = brSkel.ReadSingle();
bones[x].vector1[2] = brSkel.ReadSingle();
brSkel.ReadSingle();
}
}
{
siSkel.Position += 12 - (int)(siSkel.Position & 15);
int countBones = brSkel.ReadInt32();
Debug.Assert(countBones == header.CountBones);
for (int x = 0; x < countBones; x++) {
bones[x].matrix2 = new float[9];
bones[x].matrix2[0] = brSkel.ReadSingle();
bones[x].matrix2[1] = brSkel.ReadSingle();
bones[x].matrix2[2] = brSkel.ReadSingle();
brSkel.ReadSingle();
bones[x].matrix2[3] = brSkel.ReadSingle();
bones[x].matrix2[4] = brSkel.ReadSingle();
bones[x].matrix2[5] = brSkel.ReadSingle();
brSkel.ReadSingle();
bones[x].matrix2[6] = brSkel.ReadSingle();
bones[x].matrix2[7] = brSkel.ReadSingle();
bones[x].matrix2[8] = brSkel.ReadSingle();
brSkel.ReadSingle();
bones[x].vector2 = new float[3];
bones[x].vector2[0] = brSkel.ReadSingle();
bones[x].vector2[1] = brSkel.ReadSingle();
bones[x].vector2[2] = brSkel.ReadSingle();
brSkel.ReadSingle();
}
}
siSkel.Position = fileHeader.OffsetStrBlock2;
String fullName = Util.ReadStr(brSkel);
String fpJson = Path.ChangeExtension(fpebx, ".json");
using (StreamWriter writer = new StreamWriter(fpJson, false, Encoding.ASCII)) {
JsonSerializer.CreateDefault(new JsonSerializerSettings { Formatting = Formatting.Indented }).Serialize(writer, new SkelJson {
fullName = fullName,
name = Path.GetFileNameWithoutExtension(fullName),
bones = bones.ToArray(),
});
}
String fpTxt = Path.ChangeExtension(fpebx, ".skel.txt");
using (StreamWriter writer = new StreamWriter(fpTxt, false, Encoding.ASCII)) {
for (int y = 0; y < bones.Count; y++) {
writer.WriteLine("0x{0:X2},{0,4},{1,4}, {2}", y, bones[y].parentIndex, bones[y].name);
}
}
}
public class SkelFileHeader {
public byte[] Data64;
public int OffsetStrBlock2 { get { return BitConverter.ToInt32(Data64, 0x04); } }
public int EntryCount2 { get { return BitConverter.ToUInt16(Data64, 0x16); } }
public int EntryCount1 { get { return BitConverter.ToUInt16(Data64, 0x18); } }
public int LengthStrBlock1 { get { return BitConverter.ToUInt16(Data64, 0x1A); } }
public int LengthStrBlock2 { get { return BitConverter.ToInt32(Data64, 0x1C); } }
public int OffsetStrBlock1 { get { return BitConverter.ToInt32(Data64, 0x24); } }
}
public class SkelHeader {
public byte[] Data160;
public int CountBones { get { return BitConverter.ToInt32(Data160, 0x20); } }
}
Code: Select all
Failure: System.IO.EndOfStreamException: Unable to read beyond the end of the stream.
at System.IO.BinaryReader.FillBuffer(Int32 numBytes)
at System.IO.BinaryReader.ReadInt32()
at DecMECMesh.Program.Conv(String fpMesh, String dirConvTo, String dirChunks, Boolean ExportPy, Boolean ExportH2O, Boolean ExportOnlyFirstLOD)
at DecMECMesh.ConvMeshForm.bwConv_DoWork(Object sender, DoWorkEventArgs e)
So how is it going. In my experience, binding model to skeleton may be the hardest part because of so many ways devs are doing this. Bone remaps, submeshes, groups, all of that stuff.kkdf2 wrote:MEC's skeleton data is partially decoded. Export will be available in near future...
sorry, currently I don't have much time to work on other game...It'd be really nice if it could work with PvZGW2, just saying.
Skeleton exporter is ready on 0.2, pass MEC:daemon1 wrote:So how is it going. In my experience, binding model to skeleton may be the hardest part because of so many ways devs are doing this. Bone remaps, submeshes, groups, all of that stuff.kkdf2 wrote:MEC's skeleton data is partially decoded. Export will be available in near future...
Code: Select all
bundlesDirectory = r"H:\MEC\bundles";
Code: Select all
importTables = [
{
"jsonMeshFile": r"res\characters\faith\armgear\magrope\magrope_skin_mesh\magrope_skin-lod1.json",
"diffuseMap": r"res\characters\faith\armgear\magrope\t_magrope_d ec6cb90b09fef721 0b000000010000000000000000000000.PNG"
},
{
"jsonMeshFile": r"res\characters\faith\arms\faith_arms_mesh\faith_arms-lod1.json"
},
{
"jsonMeshFile": r"res\characters\faith\gridlink\faith_gridlink_mesh\faith_gridlink-lod1.json"
},
{
"jsonMeshFile": r"res\characters\faith\hair\faith_hair_3pcloth_ingame_mesh ba25d653909762f1 3005000070a404006800000090003001-lod1.json",
"diffuseMap": r"res\characters\faith\hair\t_alphahair_a 98be69afce0ddd0b 0b000000010000000000000000000000.PNG"
},
{
"jsonMeshFile": r"res\characters\faith\head\faith_head_mesh 9bd03e0f689c56d9 002c190020050800f800000090003001-lod1.json",
"diffuseMap": r"res\characters\faith\head\t_faithhead_dao b99b387e03207ab7 0b000000010000000000000000000000.PNG"
},
{
"jsonMeshFile": r"res\characters\faith\headparts\faith_headparts_mesh\faith_headparts-lod1.json"
},
{
"jsonMeshFile": r"res\characters\faith\lowerbody\faith_lowerbody_mesh\faith_lowerbody-lod1.json",
"diffuseMap": r"res\characters\faith\lowerbody\t_lowerbody_dao fc8450880b45f12b 0b000000010000000000000000000000.PNG"
},
{
"jsonMeshFile": r"res\characters\faith\toolbag\faith_toolbag_mesh\faith_toolbag-lod1.json",
"diffuseMap": r"res\characters\faith\toolbag\faith_pickupbag_dao 6206caa6286b3edb 0b000000010000000000000000000000.PNG"
},
{
"jsonMeshFile": r"res\characters\faith\upperbody\faith_upperbody_mesh\faith_upperbody-lod1.json",
"diffuseMap": r"res\characters\faith\upperbody\t_arms_dao a97c9a442565aba7 0b000000010000000000000000000000.PNG"
}
]
Code: Select all
#!BPY
# Runs great on Blender 2.77a
# How to:
# - Launch Blender 2.77a
# - Press Shift+[F11] to open Text Editor
# - Press Alt+O to open this script
# - Press Alt+P to run this script
# - Press Shift+[F5] to get back initial perspective view