Import into Blender

Documentation of the relation of RTM transform matrices, to the Blender transformation data, and the necessary calculations to apply them to an armature

This page is meant to supplement and clarify certain informations written on the community wiki about the transformation data stored in RTM files, prior knowledge of that article is required.

Introduction

The community wiki notes, that the 3D transformation matrices stored in the RTM file format are DirectX matrices, but it does not clarify what transformation they actually describe.

According to the specifications, each matrix represents a transposed 4x4 transformation matrix, with the last column being omitted, and implicitly defined to be (0, 0, 0, 1) , therefore the data is actually stored as a 3x4 matrix. The values are stored row by row continuously, 12 32-bit floating point values.

Transformation

The nature of the transformation can be deduced from two clues:

  1. There are no file formats for Arma 3 that would support the storage and use of an armature structure (either FK or IK) as we know them in animation software, any such structure is notably absent from character models. The only hint at an apparent bone structure is the model.cfg file.

  2. Animations from RTM files can be imported into Object Builder, and displayed on the mesh data present in the file, without the need to define any skeleton structure.

From the above characteristics we can conclude, that the transformation matrices must represent the direct transformation from the resting place of mesh vertices, to the animated position in the selected animation phase. A simple coordinate transformation, with the matrices of each bone being completely disconnected from each other, and only dependent on the rest pose positions.

Relation to Blender

Before any actual calculations, the 4x4 matrix needs to be reconstructed, and transformed to the format, that Blender accepts.

Matrix reconstruction

Since Arma 3 uses a left-handed, Y-up coordinate system, and Blender uses a right handed, Z-up coordinate system, the matrix data has to be reordered for use in Blender.

Assuming the 12 significant values of the matrix are stored in a list called data, a Blender-compatible matrix can be reconstructed as the following conceptual Python code shows:

matrix = [
    [data[0], data[6], data[3], data[9]],
    [data[2], data[8], data[5], data[11]],
    [data[1], data[7], data[4], data[10]],
    [0, 0, 0, 1]
]

Applying the transformations

Since the RTM file stores absolute transformations of each bone, if we want to apply the animation to an FK armature, we need to take into account the bone parent-child relations and calculate relative transforms where necessary.

Blender operates with a handful of different transformations for each bone, with the following being important in our case:

  • rest:rest: rest position of a bone, accessed through the edit mode bone connected to the posing bone we are modifying, in object space (pose_bone.bone.matrix_local)

  • mat:mat: absolute animated position of a bone, in object space (pose_bone.matrix)

  • channel:channel: absolute transformation of a posing bone, this is essentially what the RTM stores (pose_bone.matrix_channel)

  • basis:basis: transformation relative to a parent bone when present, in local space relative to rest pose, this is what we need to calculate

Let us see an example:

b1 is an orphan bone with no parent, and b2 is parented to b1.

With some thinking and testing in Blender, we can derive the following equations:

mat=channelā‹…restmat = channel \cdot rest

mat=channelparentā‹…restā‹…basisā†’basis=restāˆ’1ā‹…channelparentāˆ’1ā‹…matmat=channel_{parent} \cdot rest \cdot basis \to basis=rest^{-1}\cdot channel_{parent}^{-1}\cdot mat

After substituting:

basis=restāˆ’1ā‹…channelparentāˆ’1ā‹…channelā‹…restbasis=rest^{-1} \cdot channel_{parent}^{-1} \cdot channel \cdot rest

(If the bone is orphan, channelparentchannel_{parent} is a 4x4 identity matrix.)

Conclusion

Once we calculate the relative transformations with the deduced formula, we can decompose them into location, rotation and scale components. We can use these components to set individual poses, or even decode the entire RTM, and create keyframe animation data from it.

Last updated