|aka Character Animation Bank Data|
|Main Memory only|
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[edit | edit source]
Header[edit | edit source]
|0x8||0x8||Resource ID||?||Animation table raw resource ID|
|0x20||0x8||Resource ID||?||LUA Code resource ID|
|0x28||0x4||uint32_t||?||Number of entries|
Entry[edit | edit source]
|0x0||0x8||uint64_t||?||Name hash?||Unknown source/algorithm|
|0x8||0x8||Resource ID||?||Animation data resource ID|
Animation table[edit | edit source]
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[edit | edit source]
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.
|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[edit | edit source]
Like the animation info, this raw resource is read sequentially. The header structure is below.
|0x0||0x8||char||?||Magic||NMMORPH followed by null terminator|
|0xC||0x4||?*||?||Data start offset||All other pointers are relative to this value|
|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|
|0x24||0x4||uint32_t||?||Data subsection size|
NMMORPH data[edit | edit source]
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:
This is follows by a different structure:
|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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
|0x0||0x4||uint32_t||?||Version? Number of takes?|
|0x4||0xC||char||?||Animation name||Always Take_001|
|0x18||0x4||uint32_t||?||Number of bones|
Initial bone data[edit | edit source]
|0x0||0x8||uint64_t||?||Animation ID 1?|
|0x8||0x8||uint64_t||?||Animation ID 2?|
Bone animation[edit | edit source]
16 characters for the bone name immediately followed by the raw animation data.