Character Animation Bank Data

From Burnout Wiki
CharAnimBankFile
aka Character Animation Bank Data
No Example
Resource names Unknown
Type ID 0x2710
Category Unknown
(decimal 10000)
Memory
distribution
Main Memory only
Imports Unknown
Imported by Unknown
Editor
available?
No

Character animation banks are used in Black 2 (2007-02-13 build). As the name suggests, they store character animations details. Though they are not imported, raw resources are used to store the animation data itself; banks only contain a list of animations.

This type is loosely related to animation collections and the raw animation data format appears to be the same or similar.

Structures

Header

Offset Length Type Name Description Comments
0x0 0x4 uint32_t ? Resource size
0x4 0x4 Padding
0x8 0x8 Resource ID ? Animation table raw resource ID
0x10 0x8 Resource ID ?
0x18 0x8 Resource ID ?
0x20 0x8 Resource ID ? LUA Code resource ID
0x28 0x4 uint32_t ? Number of entries
0x2C 0x4 Entry* ? Entries

Entry

Offset Length Type Name Description Comments
0x0 0x8 uint64_t ? Name hash? Unknown source/algorithm
0x8 0x8 Resource ID ? Animation data resource ID

Animation table

This raw resource is a text file rather than a data structure. It begins with the number of entries and a line break. Each entry that follows is in the format "row,name,column". Entries are separated by line breaks.

CRLF is used for line breaks in the animation table.

Animation info

It is unclear what this raw resource is for, but each entry contains a single float for each bone. Entries are named things like RightArm and Trajectory.

This resource is read sequentially. The header structure is below.

Offset Length Type Name Description Comments
0x0 0x4 uint32_t ? Number of bones
0x4 0x4 uint32_t ? 0x5B or 2
0x8 0x4 uint32_t ? 2 or 3

This is immediately followed by an array of indices of an amount corresponding to the number of bones.

After the array of indices is a 4-byte integer defining the number of entries, followed by the entries themselves, which are:

  • A 4-byte integer defining the length of the name string that follows,
  • The name of the entry,
  • An array of floats of an amount corresponding to the number of bones.

Note that entries (and their contents) are completely unaligned, which is unique among resources.

NMMORPH header

Like the animation info, this raw resource is read sequentially. The header structure is below.

Offset Length Type Name Description Comments
0x0 0x8 char[8] ? Magic NMMORPH followed by null terminator
0x8 0x1 uint8_t ? Version? Always 1
0x9 0x3 ? ? Padding?
0xC 0x4 ?* ? Data start offset All other pointers are relative to this value
See data
0x10 0x4 ? ? Always null
0x14 0x4 ?* ? String table See string table
0x18 0x4 uint32_t ? Data size Not including this header
0x1C 0x4 uint32_t ? Number of data subsection/string entries
0x20 0x4 uint32_t ? Always 0x1C
0x24 0x4 uint32_t ? Data subsection size

NMMORPH data

Hmmm...
Hmmm...
To do:
Data is convoluted and not understood, and this section needs to be cleaned up.

Data is generally sorted into a bunch of arrays with the array length prepended to each array.

  • First is an array of indices, then
  • An array of 12-byte entries, where the array length is 6 in both samples, then
  • Another array of 12-byte entries (seemingly the same structure as previously), where the array length is 7 in both samples.

The 12-byte structure is described below:

Offset Length Type Name Description Comments
0x0 0x4 uint32_t ?
0x4 0x4 uint32_t ?
0x8 0x4 uint32_t ?

This is follows by a different structure:

Offset Length Type Name Description Comments
0x0 0x4 uint32_t ? Always 1
0x4 0x4 uint32_t ? Always 0x190
0x8 0x4 uint32_t ?
0xC 0x4 uint32_t ?
0x10 0x4 uint32_t ? Always null
0x14 0x4 uint32_t ? Data subsection size

The data subsection size always equals the size given in the header. It immediately follows the end of the primary data section.

NMMORPH data subsection

Data in this section is unclear. The number of entries is determined by the count in the header and each entry begins with its index, but beyond that it is difficult to decipher.

Like other parts of the resource, much of the entries in the subsection are comprised of arrays with their length prepended. However, determining exactly where these are can be challenging. The minimum size of an entry appears to be 24 bytes, so it is possible the presence of the arrays are determined through values within that range.

NMMORPH string table

String table info is made of indices and offsets to the string:

  • Starts with the end index, which is the same as the number of strings in the header, then
  • An array of indices of an amount corresponding to the number of strings, then
  • An array of offsets starting from 0, where 0 is relative to the start of the string table, then
  • A single offset indicating the end of the string table, relative to the start of the string table, then
  • The strings themselves.

Animation data

Animation data raw resources contain the actual animation. They are made up of a small header and initial entries for each bone, followed by the animations for each bone in sequence.

Animation data header

Offset Length Type Name Description Comments
0x0 0x4 uint32_t ? Version? Number of takes?
0x4 0xC char[12] ? Animation name Always Take_001
0x10 0x4 float ?
0x14 0x4 float ? Animation rate?
0x18 0x4 uint32_t ? Number of bones

Initial bone data

Offset Length Type Name Description Comments
0x0 0x8 uint64_t ? Animation ID 1?
0x8 0x8 uint64_t ? Animation ID 2?
0x10 0x10 uint32_t ? Animation data?
0x20 0xC float[3] ? Position?

Bone animation

16 characters for the bone name immediately followed by the raw animation data.