Rtm Binarised File Format: Difference between revisions
m (→Structure) |
|||
(13 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
{{ | {{Feature|UnsupportedDoc}} | ||
= UnBinarised Format = | |||
For unbinarised see [[Rtm (Animation) File Format]] | |||
==Structure== | = Binarised format = | ||
Binarised rtm was introduced for the Arma2 engine. | |||
There are currently three versions. | |||
version 3: Arma2 family, some found in Arma3 files too | |||
version 4: Arma3 | |||
version 5: Arma3 (1024 byte compression rule changed to prefixed flag) | |||
== Structure == | |||
RTMB | RTMB | ||
{ | { | ||
Line 17: | Line 27: | ||
ulong NoOfBones; // 128 eg | ulong NoOfBones; // 128 eg | ||
Asciiz BoneNames[NoOfBones]; // "weapon\0\rightarm\leftarm\etc..." | Asciiz BoneNames[NoOfBones]; // "weapon\0\rightarm\leftarm\etc..." | ||
if (Version >= 4) | |||
{ | |||
ulong Zero; // probably count and structure | |||
ulong nFrameProperties; | |||
FrameProperty FrameProperties[nFrameProperties]; | |||
} | |||
FrameTimes FrameTimes; // CompressedFloats | |||
FramePosition FramePositions[nFrames];// CompressedFrames | |||
} | } | ||
BoneNames are the traditional Bis catenated | 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 == | ||
RTMBHeader | RTMBHeader | ||
{ | { | ||
char[4] Type; //"BMTR" | char[4] Type; //"BMTR" | ||
ulong Version; // = | ulong Version; // 3==A2, 4,5==A3 | ||
} | } | ||
== | == FrameTimes (compressed) == | ||
FrameTimes | |||
{ | { | ||
ulong nFrameTimes; // should always be same as nFrames | ulong nFrameTimes; // should always be same as nFrames | ||
Line 37: | Line 53: | ||
} | } | ||
This is the traditional Bis potentially compressed structure, where, if, the total bytes stored >=1024, the array is compressed (in lzo format) | 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. | ||
Version 5 files use the same new compression rule as Version 64 ODOL .P3D files; each compressed array is prefixed by: | |||
ulong elementCount; | |||
byte compressed; // 0 for not compressed, 2 for compressed | |||
== FramePosition (compressed) == | |||
FramePosition | |||
{ | { | ||
ulong ThisFrameNoOfBones; // Should always be same as nBones | 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'. | |||
Version 5 FramePosition's are optionally compressed with the same compression flag as FrameTimes. | |||
=== 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 ); } | |||
} | |||
=== Frame Properties === | |||
FrameProperty// eg "var"="thing"; | |||
{ | |||
ulong default; // generally 0 sometimes -1 | |||
asciiz name; // "StepSound" in all current A3 files. | |||
float frame_time; | |||
asciiz value; // "" in all current A3 files. | |||
}; | |||
{{GameCategory|ofp|Modelling}} | |||
[[Category:BIS_File_Formats]] | [[Category:BIS_File_Formats]] |
Latest revision as of 06:07, 20 January 2024
UnBinarised Format
For unbinarised see Rtm (Animation) File Format
Binarised format
Binarised rtm was introduced for the Arma2 engine.
There are currently three versions.
version 3: Arma2 family, some found in Arma3 files too version 4: Arma3 version 5: Arma3 (1024 byte compression rule changed to prefixed flag)
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 (Version >= 4) { ulong Zero; // probably count and structure ulong nFrameProperties; FrameProperty FrameProperties[nFrameProperties]; } 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,5==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.
Version 5 files use the same new compression rule as Version 64 ODOL .P3D files; each compressed array is prefixed by:
ulong elementCount; byte compressed; // 0 for not compressed, 2 for compressed
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'.
Version 5 FramePosition's are optionally compressed with the same compression flag as FrameTimes.
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 ); } }
Frame Properties
FrameProperty// eg "var"="thing"; { ulong default; // generally 0 sometimes -1 asciiz name; // "StepSound" in all current A3 files. float frame_time; asciiz value; // "" in all current A3 files. };