BMTR to plain RTM
Documentation of the steps needed to restore a plain RTM file
Introduction
Differences
Conversion
Conceptual code
import struct
import numpy as np
# Following function reads a BMTR quaternion and a location vector from
# a file-like object, and returns the right-handed matrix representation
def transform_to_matrix(file):
qx, qz, qy, qw = struct.unpack('<4h', file.read(8))
x, y, z = struct.unpack('<3e', file.read(6))
r00 = 1 - 2*qy**2 - 2*qz**2
r01 = 2*qx*qy - 2*qz*qw
r02 = 2*qx*qz + 2*qy*qw
r10 = 2*qx*qy + 2*qz*qw
r11 = 1 - 2*qx**2 - 2*qz**2
r12 = 2*qy*qz - 2*qx*qw
r20 = 2*qx*qz - 2*qy*qw
r21 = 2*qy*qz + 2*qx*qw
r22 = 1 - 2*qx**2 - 2*qy**2
matrix = [
[r00, r01, -r02, x],
[r10, r11, -r12, y],
[-r20, -r21, r22, z],
[0, 0, 0, 1]
]
return output
# We can collect the transformation matrices in a dictionary, where the key
# is the bone the transformation belongs to, and the value is the matrix
# With a second dictionary having the bone-parent pairs in hierarchical
# order, the RTM-like absolute matrices can be calculated
def calculate_absolute_matrices():
matrices = {
"base_bone": ..., # matrix
"bone2": ..., # matrix
"bone1": ... # matrix
}
bone_hierarchy = {
"base_bone": "",
"bone1": "base_bone",
"bone2": "base_bone"
}
default = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
for bone in bone_hierarchy:
mat_bone = np.matrix(matrices[bone])
mat_parent = np.matrix(matrices.get(bone_hierarchy[bone], default))
matrices[bone] = (mat_parent @ mat_bone).tolist()
return matricesLast updated