ANM - Model Animation
The ANM format stores keyframes for a TMD model animation. Longer animation sequences may be split into multiple .ANM files.
File Layout
- .ANM
- 1
Header - 0-n
Frame- 0-n
Keyframe(per object)
- 0-n
- 1
Header
| Offset | Type | Name | Notes |
|---|---|---|---|
| 0x00 | int16 | unk | Always 0x8000 |
| 0x02 | int16 | unk | Unused? Possible values: 1, 15, 20, 30, or 60 |
| 0x04 | uint16 | frameCount | |
| 0x06 | uint16[] | frameOffsetTable |
The frameOffsetTable array contains (frameCount + 1) elements. To find the start offset of frame n, multiply the value at index n by 2. The last entry marks the end offset of the file.
Frame
| Offset | Type | Name | Notes |
|---|---|---|---|
| 0x00 | Keyframe[] |
Contains keyframes for all keyed objects in the TMD for one animation frame.
If an object index does not have a keyframe, it is not drawn for the current frame.
There is no explicit count for the number of elements in the Keyframe array. To determine this count for frame n, continue processing the next Keyframe until reaching the end offset given by frameOffsetTable[n + 1] * 2.
Keyframe
| Offset | Type | Name | Notes |
|---|---|---|---|
| 0x00 | uint8 | objectIndex | |
| 0x01 | uint8 | flags | |
| int16 | rotationX | Present if (flags & 0b001) > 0. Radians = value * 2π / 4096 |
|
| int16 | rotationY | Present if (flags & 0b001) > 0. Radians = value * 2π / 4096 |
|
| int16 | rotationZ | Present if (flags & 0b001) > 0. Radians = value * 2π / 4096 |
|
| int16 | scaleX | Present if (flags & 0b010) > 0. Scale = value / 4096 |
|
| int16 | scaleY | Present if (flags & 0b010) > 0. Scale = value / 4096 |
|
| int16 | scaleZ | Present if (flags & 0b010) > 0. Scale = value / 4096 |
|
| int16 | positionX | Present if (flags & 0b100) > 0. |
|
| int16 | positionY | Present if (flags & 0b100) > 0. |
|
| int16 | positionZ | Present if (flags & 0b100) > 0. |
Each keyframe animates an individual object in the TMD indicated by objectIndex. Rotation, scale and position keys are optional depending on the bits set in flags, and will always appear in that order.