Menu

ACT file format

BDB

ACT file format

ACT files are animations for models.

First comes the header:

  • uint32 - Magic - Should be 0x41435448
  • uint32 - Version
  • uint32 - Number of frames
  • uint32 - Number of meshes
  • uint32 - Data size
  • char[32] - Name of the model to which this animation corresponds

Next comes an array of offsets to frame data
* uint32[number of frames] - Offset relative to start of the file

Frame data

Next it's time to read frame data. The number of these data chunks is the number of meshes from the header.

  • uint16 - Mesh index
  • uint32 - Size of the data section that follows in bytes

Immediately after these fields is another chunk of data that contains the actual transformation data. Remember that "size" in the previous field might be 0, which means the mesh has no keyframes at this particular frame. Each chunk contains some number of these:

  • byte - Type of keyframe data (0 = absolutely positioned vertices (as in, morph targets), 1 = relatively positioned vertices, 2 = 4x3 transformation matrix, 3 = absolutely positioned bounding box)
  • uint32 - Size of this chunk

What comes next depends on the type of keyframe data.

Keyframes

Absolute vertices

If the type is absolutely positioned vertices, then this comes next:

  • uint16 - Group index
  • uint16 - Number of vertices

Then comes a stream of X, Y, Z coordinates, each one a 32-bit float.

Relative vertices

If the type is relative vertices, then this comes next:

  • uint16 - Group index
  • uint16 - Number of vertices

Relative vertices may be compressed, and the compression can vary per vertex (in other words, one vertex may be compressed, and the next uncompressed). So before you can read the vertices you'll have to read the compression info:

Next comes the vertex data itself. Before you can read the vertices you'll need to decode the compression bitfield. Basically, each vertex is 2 bits within the bitfield. Vertex 0's compression info would live at bitfield & 0x3, Vertex 1's compression info would live at bitfield & 0xC, Vertex 2's compression info would live at bitfield & 0x30, etc. Here's how to interpret the compression info:

  • 0 = No vertices (therefore, no position change)
  • 1 = Each vertex component is stored as a byte (so 3 bytes for X, Y, Z)
  • 2 = Each vertex component is stored as a 16-bit unsigned int
  • 3 = Each vertex component is stored as a 32-bit float (uncompressed)

If the vertex data is compressed a byte or a uint16, you'll have to uncompress it.

Decompressing a byte:

  • Sign = most significant bit (value & 0x80)
  • Fraction = value & 0x1f / 32
  • Whole part = value & 0x7f >> 5

Decompressing a uint16:

  • Sign = most significant bit (value & 0x8000)
  • Fraction = value & 0x1ff / 256
  • Whole part = value & 0x7fff >> 8

Transform matrix

If the type is a transformation matrix, just read it in as 12 32-bit floats and turn it into a 4x3 matrix. Done!

Bounding box

The bounding box is made of 6 32-bit floats. Just read them in.