Rtm Binarised File Format
UnBinarised Format
For unbinarised see Rtm (Animation) File Format
Binarised format
Binarised rtm was introduced for the Arma2 engine.
Structure
RTMB { RTMBHeader Header; byte Always1; // ?? XYZTriplet Displacement; ulong nFrames; // 55 eg ulong Generally0; // ?? ulong nBones; // same value as NoOfBones ulong NoOfBones; // 128 eg Asciiz BoneNames[NoOfBones]; // "weapon\0\rightarm\leftarm\etc..." FrameTimes FrameTimes; // CompressedFloats FramePosition FramePositions[nFrames];// CompressedFrames }
BoneNames are the traditional Bis catenated strings. One after the other separated by '\0'. Unlike most others encountered in Bis file architecture, there is no final terminating double null because the count is already known.
RTMBHeader
RTMBHeader { char[4] Type; //"BMTR" ulong Version; // =3 }
FrameTimes (compressed)
FrameTimes { ulong nFrameTimes; // should always be same as nFrames float Array[nFrameTimes]; }
This is the traditional Bis potentially compressed structure, where, if, the total bytes stored >=1024, the array is compressed (in lzo format). All bones are 'held' in a position and orientation (specified by FramePosition) for the duration of that frametime period.
FramePosition (compressed)
FramePosition { ulong ThisFrameNoOfBones; // Should always be same as nBones short Transforms[ThisFrameNoOfBones][7]; }FramePositions[nFrames];
Each bone is held in this position and orientation for this frametime. ThisFrameNoOfBones is irrelevant to the engine and always must be the nBones value. It is present however because of efficiencies in using the standard bis lzo compression methods which rely on this 'count'.
The short values are compressed floats (7 in total) for each 'frame'. conversion to float is
float ShortToFloat(short value) {return ((float)1.0 / (65534)) * (value + 32767);}
this is suspiciously similar to ofp compressed floats
float = short * 0.045
4 floats probably are used to describe a quaternion that describes the rotation. the other 3 floats are then for the translation