BCK
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.
Contents
JSYSTEM Header
The file starts with a standard JSYSTEM header, using a magic of J3D1bck1. BCK files have one chunk, the ANK1 chunk.
ANK1 Chunk
Offset | Type | Name | Description |
---|---|---|---|
|
Chunk Header | Standard JSYSTEM chunk header | |
|
Loop Mode | Loop Mode | |
|
byte | Rotation Frac | Multiplier for fixed-point decimal |
|
short | Duration | The number of frames in the animation |
|
short | Keyframe Count | The total number of keyframes, times 3 |
|
short | Scale Table Count | The number of entries in the scale table |
|
short | Rotation Table Count | The number of entries in the rotation table |
|
short | Translation Table Count | The number of entries in the translation table |
|
int | Animation Data Table Offset | Offset to the start of the animation data table |
|
int | Scale Table Offset | |
|
int | Rotation Table Offset | |
|
int | Translation Table Offset |
LoopMode
LoopMode is an enum as follows:
Value | Name | Meaning |
---|---|---|
0x00 | Once | The animation plays once and stops on the final frame. |
0x01 | Once and Reset | The animation plays once and stops on the first frame. |
0x02 | Loop | The animation loops indefinitely. |
0x03 | Mirrored Once | The animation plays once, then plays in reverse, then stops on the first frame. |
0x04 | Mirrored Loop | The animation plays once, then plays in reverse, then the process repeats. |
Animation Data
There are 9 animation tracks stored in each animation table.
Offset | Type | Name | Description |
---|---|---|---|
|
TrackData | Scale X | Scale of the X coordinate |
|
TrackData | Rotation X | Rotation of the X coordinate |
|
TrackData | Translation X | Translation of the X coordinate |
|
TrackData | Scale Y | Scale of the Y coordinate |
|
TrackData | Rotation Y | Rotation of the Y coordinate |
|
TrackData | Translation Y | Translation of the Y coordinate |
|
TrackData | Scale Z | Scale of the Z coordinate |
|
TrackData | Rotation Z | Rotation of the Z coordinate |
|
TrackData | Translation Z | Translation of the Z coordinate |
TrackData
Each TrackData is 0x06 bytes long, with the following layout:
Offset | Type | Name | Description |
---|---|---|---|
|
short | Count | Number of keyframes in the track |
|
short | Index | The index of the first piece of keyframe data |
|
TangentMode | Tangent Mode | The mode of storing animation curve tangents |
TangentMode
TangentMode is an enum as follows:
Value | Name | Meaning |
---|---|---|
0x00 | Symmetric | One tangent value is stored, used for both the incoming and outgoing tangents |
0x01 | Piece-wise | Two tangent values are stored, the incoming and outgoing tangents, respectively |
Animation Curve Data
The tables for the individual component types store the component data. That is, the Scale Table stores the values for the Scale X, Scale Y, and Scale Z tracks, the Rotation Table stores the values for the Rotation X, Rotation Y, and Rotation Z tracks, and the Translation Table stores the values for the Translation X, Translation Y and Translation Z tracks.
Using the Index, Count, and Tangent Mode values for the curves, the decoding is as follows:
- If the Count field is 1, then there is no curve, and instead, a single value is stored in the table at Index.
- Otherwise, then if Tangent Mode is Symmetric: Read 3 values per keyframe, with Count keyframes, starting from the table at Index. The three values, are, in order: Time (the frame index), Value, and Tangent (both incoming and outgoing).
- Otherwise, then Tangent Mode should be Piece-wise. Read 4 values per keyframe, with Count keyframes, starting from the table at Index. The four values, are, in order: Time (the frame index), Value, Incoming Tangent, and Outgoing Tangent.
- If this is a Rotation table, then left-shift the Values and Tangents by the Rotation Frac field in the header. Time is unaffected.
The Scale and Translation tables are stored as consecutive floats, and the Rotation table is stored as consecutive signed shorts. Rotation is stored in signed units that range from -0x7FFF to 0x7FFF, corresponding to -180 degrees and 180 degrees, respectively.
Calculating the value for an animation track
To calculate a single value for a single animation track, a Hermite spline interpolation should be used. Specifically, choose the two keyframes on either side of the current time, and interpolate using the left's outgoing tangent and value, and the right's incoming tangent and value to build the four control points on a 1D Cubic Hermite spline.