From CloudModding TWW Wiki

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.

JSYSTEM Header

The file starts with a standard JSYSTEM header, using a magic of J3D1bck1. BCK files have one chunk, the ANK1 chunk.

Header

Offset Type Name Description
0x00
Chunk Header Standard JSYSTEM chunk header
0x08
Loop Mode Loop Mode
0x09
byte Rotation Frac Multiplier for fixed-point decimal
0x0A
short Duration The number of frames in the animation
0x0C
short Keyframe Count The total number of keyframes, times 3
0x0E
short Scale Table Count The number of entries in the scale table
0x10
short Rotation Table Count The number of entries in the rotation table
0x12
short Translation Table Count The number of entries in the rotation table
0x14
int Animation Data Table Offset Offset to the start of the animation data table
0x18
int Scale Table Offset
0x1C
int Rotation Table Offset
0x20
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
0x00
TrackData Scale X Scale of the X coordinate
0x06
TrackData Rotation X Rotation of the X coordinate
0x0C
TrackData Translation X Translation of the X coordinate
0x12
TrackData Scale Y Scale of the Y coordinate
0x18
TrackData Rotation Y Rotation of the Y coordinate
0x1E
TrackData Translation Y Translation of the Y coordinate
0x24
TrackData Scale Z Scale of the Z coordinate
0x2A
TrackData Rotation Z Rotation of the Z coordinate
0x30
TrackData Translation Z Translation of the Z coordinate

TrackData

Each TrackData is 0x06 bytes long, with the following layout:

Offset Type Name Description
0x00
short Count Number of keyframes in the track
0x02
short Index The index of the first piece of keyframe data
0x04
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:

  1. If the Count field is 1, then there is no curve, and instead, a single value is stored in the table at Index.
  2. 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).
  3. 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.
  4. 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.