MOTN

From Wulinshu
Jump to: navigation, search

The MOTN file format contains the animations for models based on their node structure.
This format can be found in various PKS files and in the motion.bin file.

Structure

Section Description
Header File description
Sequence Data Table Pointers to sequence data blocks
Unknown Extra Data Extra data for sequence data
Sequence Name Table Sequence names
Sequence Data Animation data

Header

Position Length Type Description
0x00 0x04 uint Sequence data table offset
0x04 0x04 uint Sequence names offset
0x08 0x04 uint Sequence data offset
0x0C 0x04 Attributes Attributes
0x10 0x04 uint File size

Attributes

Mask Type Description
0x00000FFF uint12_t Sequence count

Sequence Data Table

The sequence data table consists out of two offsets (each unsigned 32bit) per sequence.
Both offsets point inside the sequence data segment.
The first offset points to the main sequence data containing the key frames.
The second offset points to some unknown data array.

Sequence Name Table

The sequence name table consists out of the offsets (unsigned 32bit) to the strings and the strings themself.
The amount of names is given by the sequence count inside the header.
The strings are zero terminated/seperated.

Sequence Data

Header

Position Length Type Description
0x00 0x04 uint Flag (decides the byte size for the block 2 and block 3 entries)
0x04 0x02 ushort Block 1 end offset/Block 2 start offset
0x06 0x02 ushort Block 2 end offset/Block 3 start offset
0x08 0x02 ushort Block 3 end offset/Block 4 start offset
0x08 0x02 ushort Block 4 end offset/Block 5 start offset

Block 1

The first block contains the descriptions for the structure of the keyframes.
Each entry in the block is 2 bytes in size.

Bit-Mask Description
ins >> 9 Node ID/Bone ID
0x0100 Translation X channel available
0x0080 Translation Y channel available
0x0040 Translation Z channel available
0x0020 Rotation X channel available
0x0010 Rotation Y channel available
0x0008 Rotation Z channel available
0x0007 Reserved

Block 2

The second block contains for each channel the amount of data points (key frames?).
Each entry in the block is 2 bytes or 1 bytes in size depending on the flag.

Block 3

The third block contains frame index data.
Each entry in the block is 2 bytes or 1 bytes in size depending on the flag.
Each frame is 0.0333333 milliseconds (30 FPS)

Block 4

The fourth block contains the same amount of data as the second block.
Each entry in the block is 1 bytes in size.

Block 5

The fifth and last block contains the actual data for the keyframes.
Each entry in the block is 2 bytes in size and could be interpreted as degrees.

Sequences are expressed using a minimal skeleton hierarchy designed for use with a full-body IK solver which is somewhat custom to the original games (more info here: https://www.shenmuedojo.com/forum/index.php?threads/development-log-3.3595/)

Keyframes are described using the instructions as detailed above, which also pack the bones they are associated with. Function curves are used for interpolation and as such, keyframe data may store a left and right slope/tangent if necessary. Values stored within keyframes are half-precision floats, which are then expanded to 32-bit full-precision floats at runtime.

Keyframes are parsed and a structure such as the following is constructed:

struct struct_FCVKey {
    fp32 fp32_time;
    fp16 fp16_left_slope;
    fp16 fp16_right_slope;
    fp16 fp16_value;
    
    uint16_t reserved[3];
};