Torchlight file specs

All questions and discussions about file format analysis are welcome in this forum.

Moderators: Alhexx, mirex

Torchlight file specs

Postby OmegaThree » Mon Jan 11, 2010 18:14

Still working on my converter, off and on. I deciphered most of Torchlight's model and animation formats last week. Here are the details:

NOTE: I realized only after the fact that Torchlight probably uses OGRE's internal mesh format, so if you look up docs on that, you'll likely have what you need.
____________________

Strings terminate with "\xA" ((char)10) rather than the usual zero.

The size specified in each block isn't always accurate and can generally be ignored.
____________________

BLOCK STRUCTURE

The general block structure is as follows:

ushort Signature;
int SizeInBytes;
byte[] Data;

Size includes the six-byte header itself, so a block without data (e.g., 0xA000) will have a size of six (6) bytes.

The exception to this is the file burn info block (0x1000), which does not contain the size field.
____________________

BLOCK TYPES

*.MESH files:

0x1000 - File burn info

0x3000 - Model/scene (master block)

0x4000 - Mesh
0x4010 - ???
0x4100 - Bone-weight info

0x5000 - Geometry
0x5100 - ??? (contains exactly three 0x5110 blocks)
0x5110 - ???

0x5200 - Vertex data header
0x5210 - Vertex data

0x6000 - Skeleton reference

0x9000 - Bounding volume

0xA000 - End-of-file marker

Code: Select all
struct 0x1000    // File burn info
{
    ushort Id;
    string ToolName;
}

struct 0x3000    // Unknown
{
    ushort Id;
    int Size;
    byte Unknown;

    Mesh[] Meshes;    // 0x4000
    SkeletonRefChunk SkeletonRef;    // 0x6000
    BoundingVolumeChunk BoundingVolume;    // 0x9000
    EOFChunk EOF;    // 0xA000
}

struct 0x4000    // Mesh
{
    ushort Id;
    int Size;
    string MeshName;
    byte Unknown = 0;
    int IndexCount;
    byte Unknown = 0;
    ushort[IndexCount] Indices;

    GeometryChunk Geometry;    // 0x5000

    0x4010 Unknown;

    BoneWeightChunk[] BoneWeights;    // 0x4110
}

struct 0x4010    // Unknown
{
    ushort Id;
    int Size;
    ushort Unknown;
}

struct 0x4110    // Bone-weight info
{
    ushort Id;
    int Size;
    int VertexId;
    ushort BoneId;
    float Influence;
}

struct 0x5000    // Geometry
{
    ushort Id;
    int Size;
    int VertexCount;

    0x5100 Unknown;

    VertexChunk[2] Vertices;    // 0x5200
}

struct 0x5100    // Unknown
{
    ushort Id;
    int Size;

    0x5110[3] Unknown;
}

struct 0x5110    // Unknown
{
    ushort Id;
    int Size;
    ushort[3] Unknown;    // These types could be incorrect
    int Unknown;
}

struct 0x5200    // Vertices
{
    ushort Id;
    int Size;
    int DataType;    // 0 = position & normal, 1 = uv coords
    int DataSize;    // size of each item

    VertexDataChunk VertexData;    // 0x5210
}

struct 0x5210    // Vertex data
{
    ushort Id;
    int Size;
    byte[] Data;    // length = VertexCount * DataSize
}

struct 0x6000    // Skeleton reference
{
    ushort Id;
    int Size;
    string SkeletonFileName;
}

struct 0x9000    // Bounding volume
{
    ushort Id;
    int Size;
    vec3 Minimum;
    vec3 Maximum;
    float Radius;    // Centered on mesh
}

struct 0xA000    // EOF marker
{
    ushort Id;
    int Size;    // Always six (6)
}

____________________

*.SKELETON files:

0x1000 - File burn info

0x2000 - Node (bone)

0x3000 - Link (node hierarchy)

0x4000 - Animation
0x4100 - Sequence
0x4110 - Key

Code: Select all
struct 0x1000    // File burn info
{
    ushort Id;
    string ToolName;
}

struct 0x2000    // Skeletal node (i.e., bone)
{
    ushort Id;
    int Size;    // Excludes the name field!
    string Name;
    ushort BoneId;
    vec3 Position;
    quat Rotation;
}

struct 0x3000    // Hierarchical link
{
    ushort Id;
    int Size;
    ushort BoneId;
    ushort ParentId;
}

struct 0x4000    // Animation info
{
    ushort Id;
    int Size;
    string Name;
    float Duration;
}

struct 0x4100    // Sequence of keys
{
    ushort Id;
    int Size;
    ushort NodeId;    // Applies to this node
}

struct 0x4110    // Key frame
{
    ushort Id;
    int Size;
    float Time;
    vec3 Position;
    quat Rotation;
}

____________________

Note that the geometry block (0x5000) will contains TWO vertex blocks (0x5200), one for position & normal, and another for UV coordinates.

Note that *.SKELETON files do not have EOF blocks (0xA000). Skeletons may contain both node and animation data. If the skeleton contains only the initial (default) pose, it will have exactly one keyframe for each node.

There are probably many other block types I've not yet encountered, as I've only examined a handful of files, but this should get you started. I intend to support Torchlight in Proteus (my converter) when it's done.
OmegaThree
 
Posts: 18
Joined: Mon Oct 30, 2006 2:25

Postby mirex » Tue Jan 12, 2010 7:23

Thanks for the info on the format OmegaThree.
User avatar
mirex
Administrator
Administrator
 
Posts: 119
Joined: Sat Oct 15, 2005 11:20
Location: SVK


Return to File Format Analysis

Who is online

Users browsing this forum: No registered users and 2 guests

cron