Rtm Binarised File Format

From Bohemia Interactive Community
Revision as of 22:00, 6 July 2013 by Mikero (talk | contribs) (version4 a3)
Jump to navigation Jump to search

Template:unsupported-doc


UnBinarised Format

For unbinarised see Rtm (Animation) File Format

Binarised format

Binarised rtm was introduced for the Arma2 engine.

There are currently two versions.

version 3: Arma2 family
version 4: Arma3 (alpha/beta)

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..."
  if (v4)
  {
     ulong         Zeroes[2];            // probably 2x count and structure
  }
  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==A2, 4==A3
}

FrameTimes (compressed)

FrameTimes
{
 ulong nFrameTimes;          // should always be same as nFrames
 float Array[nFrameTimes];
}

This is the traditional Bis potentially-compressed lzo 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
 Transform  Transforms[ThisFrameNoOfBones];
}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'.


Transform

following information supplied by 'Voyager' to whom all honor and glory

transform
{
  short  Qnion[4]; //compressed xyzw Rotation
  short  XYZ[3];// Compressed triplet
};
Quarternion(qX=Qnion[0]/16384,qY=Qnion[1]/16384,qZ=Qnion[2]/16384,qW=Qnion[3]/16384);

Triplet(X=Convert(XYZ[0],Y=Convert(XYZ[1],Z=Convert(XYZ[2]);
double Convert(ushort value)
{
 double sign = ((value & 0x8000) != 0) ? -1 : 1;
 // S eeeee xxxxxxxxxx
 ushort exponent = (value & 0x7FFF) >> 10;//5bits
 double significand = (double)(value & 0x03FF) / (1 << 10);
 if (exponent == 0) {
   return (sign / 0x4000) * (0.0 + significand );
 }
 return sign * Pow(2, exponent - 15) * (1 + significand ); }
}