BTK
BTK stores texture matrix animation data.
Contents
JSYSTEM header
The file starts with a standard JSYSTEM header, using a magic of J3D1btk1. BTK files have one chunk, the TTK1 chunk.
TTK1 Chunk
Offset | Type | Name | Description |
---|---|---|---|
|
Chunk Header | Standard JSYSTEM chunk header | |
|
Loop Mode | Loop Mode | |
|
int | 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 | Remap Table Offset | Not used at runtime |
|
int | Name Table Offset | Contains the material names to bind against |
|
int | Texture Coordinate Index Table Offset | |
|
int | Center Coordinate Table Offset | |
|
int | Scale Table Offset | |
|
int | Rotation Table Offset | |
|
int | Translation Table Offset | |
|
byte[0x28] | Post Matrix Data | A similar set of tables, for Post Matrices. Has never been observed to exist in the wild. |
|
MatrixMode | Matrix Mode | Determines whether texture coordinates should be calculated with the Basic or Maya algorithm. This field is not read in Sunshine's copy of JSYSTEM, hardcoding the Basic mode, and their tooling seems to have output uninitialized data instead of a valid enum value. It is explicitly checked to equal exactly 0x01 in Wind Waker onwards, likely for this reason. |
MatrixMode
MatrixMode is an enum as follows:
Value | Name | Meaning |
---|---|---|
0x00000000 | Basic Mode | |
0x00000001 | Maya Mode |
The table data is packed in Struct-of-Arrays fashion, meaning that to read the Nth animation, one should read the Nth item in the material name, texture coordinate index, material center, and animation data tables.
Material Name and Texture Coordinate Index
The material name and texture coordinate index tell you how to bind the animation to a model. Animations are always bound by material name and texture coordinate index. The material name table is a JUTNameTab table. The table entries are laid out as follows:
Offset | Type | Name | Description |
---|---|---|---|
|
GXTexCoordID (byte) | Texture Coordinate Index |
Center Coordinate Table
The center coordinate is used by the Basic Matrix Mode algorithm. The table entries are laid out as follows:
Offset | Type | Name | Description |
---|---|---|---|
|
float | S | |
|
float | T | |
|
float | Q |
Animation Data
The animation data itself is stored in an identical form to BCK, so see the BCK page for details. Note that as this is acting on texture coordinates rather than world positions, the coordinates S, T, Q are used instead of X, Y, Z.
Calculating the SRT Texture Matrix
The SRT texture matrix can be calculated by either the Basic or Maya matrix modes.
Basic Mode
The Center S, Center T, Scale S, Scale T, Rotation Q, Translation S and Translation T inputs are used. The final matrix is a 3x2 matrix, which is as follows:
00 = Scale S * cos(Rotation Q) 01 = Scale S * -sin(Rotation Q) 02 = Translation S + Center S + (Scale S * (sin(Rotation Q) * Center T - cos(Rotation Q) * Center S))
10 = Scale T * sin(Rotation Q) 11 = Scale T * cos(Rotation R) 12 = Translation T + Center T + (Scale T * (-sin(Rotation Q) * Center S + cos(Rotation Q) * Center T))
Maya Mode
The Scale S, Scale T, Rotation Q, Translation S and Translation T inputs are used. The final matrix is a 3x2 matrix, which is as follows:
00 = Scale S * cos(Rotation Q) 01 = Scale T * -sin(Rotation Q) 02 = Scale S * ((0.5 * -cos(Rotation Q)) - (0.5 * sin(Rotation Q) - 0.5) - Translation S)
10 = Scale S * sin(rotation) 11 = Scale T * cos(rotation) 12 = Scale T * ((0.5 * -cos(Rotation Q)) + (0.5 * sin(Rotation Q) - 0.5) + Translation T) + 1