This is related to this question. In that question, with the help of the answer of Mr shakotay2, I was able to extract the 3D object and exported it to a .obj and .mtl file. Now, I am working on getting the bones and animation.
DISCLOSURE
I have not done this before so I do not know much. I also haven't done any 3D programming before. And lastly, animation math breaks my brain.
WHAT I KNOW
In my efforts to complete this task, I have:
- Read the book `3D Game Programming with Directx 11` by Mr Luna.
- Read the book `Game Coding Complete` by Mike & Rez.
- Read a lot of articles online related to `Vertex Skinning`, `Skeletal Animation`.
I know the original format I used; .obj doesn't support bones and animation. So, now I'm considering using FBX.
THE GAME FORMAT
The models in the game are stored in 3 files:
- def.t16 - Texture archive, when extracted shows all the related textures of def.
- def.obj - Mesh archive, contains an array of meshes for def. Each mesh has `Faces, Vertex Indices, Vertex Normals, UV`.
- def.ani - Animation archive, all related animation for def.t16.
THE PET
From here on, I will be talking about a specific file: pet.obj and pet.ani. There are only 3 kinds of pets, and they are all birds that fly above the character:
In-game Animation (All 3 pets):

Notice that all 3 pets have the exact same animation. They also animate-in and animate-out when equipped and unequipped. So I'm thinking there are 3 animation for each pet. In, Out and Fly. (although In and Out could simply be a spiral rotate on the mesh)
Model & Texture (For 1st Pet or index 0):

You can download the pet files here. (I included export scripts in .py)
PET.OBJ
I have mapped most of the structures on pet.obj but there is a few more data that I'm guessing is the bind pose bone structure.
The structure for pet.obj that I have mapped so far:
Code: Select all
struct PetFace {
uint16 x
uint16 y
uint16 z
}
struct PetVertex {
float x
float y
float z
float unknown // bone weight??
uint32 unknown // face/vertex index??
float normal_x
float normal_y
float normal_z
float u
float v
}
struct PetModel {
byte[14] header??
byte[9124] unknown // bind pose bones??
uint32 face_count
uint32 face_count
uint32 vertex_count
uint32 vertex_count
byte[12] unknown // ??
uint16 texture_index
byte[320] unknown // ?? some floats
PetFace[face_count] faces
PetVertex[vertex_count] vertices
}
struct PetObjArchive {
uint32 number_of_models
uint16 unknown
PetModel[length] models
}
- Is there any type of data I should expect for the unknown bytes? vertex weights or bind pose bones maybe?
- What kind of structure does bones generally have?
I don't really know what this file contains but I think it contains Animation data. Here is my understanding of the file:
Code: Select all
struct AniMatrix {
float unknown1
float unknown2
float unknown3
float unknown4
float unknown5
float unknown6
float unknown7
float unknown8
float unknown9
float unknown10
float unknown11
float unknown12
}
struct AniData {
uint16 unknown // always 4, only shows every 4 entry
uint16 unknownX
uint16 unknownY
AniMatrix[unknownX*unknownY] animation_matrices (?)
}
struct PetAniArchive {
uint32 number_of_animations? (not sure)
AniData[number_of_animations*4] animation_data
}Code: Select all
09 00 00 00 // uint32 - number of indexes? 9/3... 3 per pet
// AniData
04 00 // uint16 - unknown = 4 dec.. 36/9 = 4 (only shows every 4 entries)
1A 00 // uint16 - unknown = 26 dec.. 26*85=2210.. 2210*48=106080 (total bytes for this animation matrix?)
55 00 // uint16 - unknown = 85 dec.. 26*85=2210.. 2210*48=106080 (total bytes for this animation matrix?)
// AniMatrix (4x3??)
00 00 80 3F // float 1.0
E6 7F 98 37 // float? 1.8179369e-005
24 07 67 38 // float? 5.5081342e-005
D9 AE 98 37 // float? 1.8201232e-005
C2 B1 51 3F // float 0.81911862
08 D9 12 BF // float -0.57362413
24 07 67 B8 // float? -5.5081342e-005
F4 D8 12 3F // float 0.57362294
D1 B1 51 3F // float 0.81911951
BE F8 8A B8 // float? -6.6266846e-005
E8 80 D8 3F // float 1.6914339
FF 94 C9 3F // float 1.5748595
...repeat 2210 times?
Again, I'm guessing that the animation is a 4x3 matrix... Note: Unknown1 only shows up for every 4 entries.
I parse the file like this:
Code: Select all
binary_file.seek(0)
total_entries = struct.unpack("<I", binary_file.read(4))[0]
unk1r = 0
for i in range(total_entries * 4):
if unk1r == 0:
unknown1 = struct.unpack("<H", binary_file.read(2))[0]
unk1r = unk1r + 1
if unk1r == unknown1:
unk1r = 0
unknownX = struct.unpack("<H", binary_file.read(2))[0]
unknownY = struct.unpack("<H", binary_file.read(2))[0]
for ii in range(unknownX * unknownY):
matrix = struct.unpack("<ffffffffffff", binary_file.read(48))[0]
- How do I move forward?
- What could the `unknown*` data possibly be? (I know some unknown could only be game data, but some could actually be used for the bones and animation right?)
- How do I export to FBX? (Should I manually create the ASCII file or is there a library I could use?)



