BCK is the format that stores bone animation data for BMD and BDL models. It consists of the standard animation header, followed by BCK-specific data in the ANK1 chunk, with data stored in banks at the end separated by component type - scale, rotation, and translation.
This header is found at the start of all the animation formats. Below is what it looks like for the BCK format.
//0x20/32 bytes long /*0x00*/ char Magic; // "J3D1" /*0x04*/ char StudioType; // "bck1" /*0x08*/ int fileSize; /*0x0C*/ int numChunks; // From 0x10 to 0x20 is an array of padding bytes with the value 0xFF/255.
This follows the standard header and contains data specific to the BCK format.
The layout of the header is as follows:
//0x24/36 bytes long, padded out to 0x40/64 bytes /*0x00*/ string "ANK1"; /*0x04*/ int ank1Size; /*0x08*/ byte flag; /*0x09*/ byte angleMultiplier; /*0x0A*/ short animLength; /*0x0C*/ short jointAnimationEntryCount; //One for each bone in the model /*0x0E*/ short scaleFloatBankEntryCount; /*0x10*/ short rotationShortBankEntryCount; /*0x12*/ short translateFloatBankEntryCount; /*0x14*/ int jointAnimationEntriesOffset; /*0x18*/ int scaleFloatBankOffset; /*0x1C*/ int rotationShortBankOffset; /*0x20*/ int translateFloatBankOffset; //From 0x24 to 0x40 is the standard padding string: "This is padding data to alig".
After this header is the keyframe data.
There are 9 keyframes for each bone - 1 each for the X, Y, and Z components of scaling, rotation, and translation. The layout of these keyframes is shown below.
//0x36/54 bytes long // X components /*0x00*/ Keyframe ScaleX; /*0x06*/ Keyframe RotationX; /*0x0C*/ Keyframe TranslationX; // Y components /*0x12*/ Keyframe ScaleY; /*0x18*/ Keyframe RotationY; /*0x1E*/ Keyframe TranslationY; // Z components /*0x24*/ Keyframe ScaleZ; /*0x2A*/ Keyframe RotationZ; /*0x30*/ Keyframe TranslationZ;
The keyframes are grouped according to their components, and are always in the order of scale/rotation/translation.
Each keyframe is 6 bytes long, with the following layout:
//0x6/6 bytes long /*0x00*/ short keyCount; //Number of keys in this keyframe /*0x02*/ short startingIndex; //Starting index of data in relevant bank /*0x04*/ short unknownShort; //Either 0 or 1
Thus, a keyframe contains the number of keys that will be interpolated over the course of the animation, the index of the first key in the relevant data bank, and a short with an unknown purpose.
This section is padded to the nearest 32 bytes with the standard padding string.
There are 3 data banks after the keyframe data that store the keys for scaling, rotation, and translation. The scale and translation values are stored as floats, but the rotation values are stored as shorts.
Each bank begins with one "default" value that the keyframes can reference when they don't need to sample any keys. For scale, this is 1.0f; for rotation, this is 0; and for translation, this is 0.0f. This default is just the value, but every key after it follows this format:
var Timestamp; var Value; var Tangent;
The timestamp and the tangent are stored in the same datatype as the value - float for the scale and translation banks, and short for the rotation bank.