Tertius Media Resource File format specifications


The Tertius Media Resource File format is designed to enable the storage of various types of media in a common container format.  The primary goals of the format are:
Suggested extensions for TMRF files are:
.tmdl  - Single skeleton, single skeletal model, any number of animations
.tani  - Single animation
.tapk  - Multiple animations
.tskl  - Single skeleton
.tskm  - Single skeletal model
.tmsh  - Single static mesh
.tpak  - Multiple entries of various types

The following types are defined in this document:
uint32  - Unsigned 32-bit integer
sint16  - Signed 16-bit integer
uint16  - Unsigned 16-bit integer
float32 - Signed 32-bit floating point value
packed  - Variable-sized data block packed as 8-bit data
string  - 32-bit index into the string definition list.  0 indicates no value, 1 indicates the first string.
char    - ASCII text characters
ident   - 32-bit index into the string definition list.  0 indicates the first strong.

Data is stored with the most-significant bytes first (big-endian).  Indices use 0 for the first value, unless indicated otherwise.

The format of a media file is as follows:
struct terMediaFile
char[8]             - Always "TDPMedia"
uint32              - Version number.  This document describes version 1
uint32              - Size of the string pool
uint32              - Number of strings
char[]              - String pool data
terMediaStringDef[] - String definition list
packed[]            - Resources

struct terMediaStringDef
uint32 - Length of the string
uint32 - Offset of the in the string pool.

Strings do not have to be NULL-terminated.

Resources are are defined as:
struct terMediaResource
ident    - Resource type identifier
uint32   - Size of the resource data in bytes
uint32   - Offset within the resource of the first subresources (0 for no subresources)
packed[] - Resource data
packed[] - Subresources

Resource formats

TableOfContents - Table of contents

The table of contents is used to quickly reference other resources within the media file.  The table of contents is the first resource in any TMRF file.  The TMedia tool will create a TOC entry for every resource.

struct terMediaTOC
uint32             - Number of entries
terMediaTOCEntry[] - Table of contents entries

struct terMediaTOCEntry
string  - Resource name
string  - Name of the DTL the resource is bound to
ident   - Resource type identifier
uint32  - Byte offset of the resource header from the start of the file

Hints - Dynamic total list (DTL)

The DTL is an index of totals for data in other resources that are stored in dynamically-sized arrays.  It is designed to allow loaders to allocate large arrays once for numerous resources.  All entries in the DTL correspond to a type of data, identified by the type of resource it is stored in, and another 8-character identifier to distinguish it from other data arrays in that resource.  DTLs correspond to all resources that are linked to the DTL in the table of contents.

struct terMediaHintList
uint32         - Number of dynamic total hints
terMediaHint[] - Dynamic total hints

struct terMediaHint
ident   - Resource type identifier
ident   - Data type identifier
uint32  - Data count

AX3Skeleton - Skeleton

Skeletons are 3-dimensional heirarchial point and orientation lists.

struct terModelSkeleton
uint32         - Number of bones. Adds to Bone hint
terModelBone[] - Bones

struct terModelBone
uint32     - Index of parent bone.  1 is the first listed bone, 0 indicates no parent.  Parent bones must be defined before their children.
string     - This bone's name.
float32[3] - Base position of this bone, relative to its parent.
float32[4] - Base orientation quaternion of this bone, relative to its parent.

3DPoints - Point list

Point lists contain a list of points in 3-dimensional space.

struct terModelPointList
uint32          - Number of points.  Adds to Point hint
terModelPoint[] - Points for this point list

struct terModelPoint
float[3] - Position of this point

AX3SkeletalDeform - Skeletal deformation subresource

Points lists may be linked to a skeleton, which allows them to be used for mesh deformation.

struct terModelSkelDeformation
string                - Name of the skeleton to bind the points list to
uint32                - Number of bone bindings.  Adds to BoneBinding hint
uint32                - Number of weight blends.  Adds to WeightBlend hint
string[]              - Names of bone bindings
terModelWeightBlend[] - Weight blends
uint32[]              - Indices of the weight blends for each point

struct terModelWeightBlend
uint32           - Number of weights.  Adds to Weight hint
terModelWeight[] - Weights

struct terModelWeight
uint32  - Index of the bone binding to use for this weight
float32 - Weighting factor


AX3FrameAnimation - Frame-based skeletal animation

Frame-based skeletal animations update every relevant bone every frame with a fixed time interval between updates.

struct terModelFrameAnimation
string                 - Skeleton to bind this animation to
uint32                 - Number of frames.  Adds to Frame hint
uint32                 - Number of bone bindings.  Adds to BoneBinding hint
float32                - Number of frames per second.
terModelAnimBoneData[] - Bindings and frame lists for each bone

struct terModelAnimBoneData
string   - Bone to bind this animation track to
float[3] - Base position for this bone
float[4] - Base orientation for this bone
uint32   - Compression flags (See below)
packed[] - Compressed bone frame data (See below)

float32 values packed in the model data are hinted as Float32.  sint16 values are hinted as SInt16

Frame lists may be compressed against the initial bone pose information.  The frame data may contain up to 7 values per frame, but some may be omitted based
on the compression flags.  If a position element or the X, Y or Z elements of the orientation are compressed, then they will be copied from the base pose.  If the W element of the orientation is compressed, it will be regenerated from the X, Y and Z.

Orientations may optionally use sint16 values instead of float32.  If stored as sint16, the values are multiplied by 32767.

Positions and orientations are relative to the parent bone.

Values are stored in the order: (Pos X) (Pos Y) (Pos Z) (Orient X) (Orient Y) (Orient Z) (Orient W)

Compression flags are stored as a binary mask with the following values:
1   - Copy Pos X from base
2   - Copy Pos Y from base
4   - Copy Pos Z from base
8   - Copy Orient X from base
16  - Copy Orient Y from base
32  - Copy Orient Z from base
64  - Calculate Orient W from X, Y and Z
128 - Store orientation values as sint16


AX3TrackAnimation - Track-based animation

Track-based animations are marked by time and are interpolated between each other based on the current time on the animation track.  For times earlier than the first key or later than the last, the value may be determined by the implementation.

struct terModelTrackedAnimation
string              - Name of this animation
string              - Skeleton to bind this animation to
float32             - Length of this animation in seconds
uint32              - Number of bone bindings.  Adds to BoneBinding hint
string[]            - Names of bone bindings
terModelAnimTrack[] - Animation tracks for each bone binding

struct terModelAnimTrack
uint32            - Number of keys in this track.  Adds to Key hint
terModelAnimKey[] - Keys for this track

struct terModelAnimKey
float32    - Time of this key on the track.  Must be after the previous key.
float32[3] - Base position of this bone, relative to its parent.
float32[4] - Base orientation quaternion of this bone, relative to its parent.

TriangleMesh - Triangle mesh

Triangle meshes contain vertices with positions derived from a point list and a list of triangles connecting them.

struct terModelMesh
string             - Name of the point list to use for this mesh
uint32             - Number of vertices.  Adds to Vertex hint
uint32             - Number of triangles.  Adds to Triangle hint
uint32[]           - Indicies of the points to use as the location for each vertex
terModelTriangle[] - Triangles

struct terModelTriangle
uint32[3]  - Indices of the vertices that compose this triangle

Normals - Vertex normal subresource

Normal subresources are used to manually assign normals to each vertex in a triangle mesh.

struct terModelNormalList
terModelNormal[] - Normals for each vertex

struct terModelNormal
float32[3] - Vertex normal

CompressedNormals - Compressed normal subresource

Compressed normal subresources manually assign normals to each vertex in a triangle mesh, but uses a simplified, less-accurate normal representation.

struct terModelCompressedNormalList
terModelCompressedNormal[] - Normals for each vertex

struct terModelCompressedNormal
uint16 - Coefficient A
uint16 - Coefficient B

Normals can be regenerated from compressed data using the following formulae:

cAR = Coefficient A * pi / 32768
cBR = Coefficient B * pi / 65535

Normal X = sin(cAR) * sin(cBR)
Normal Y = cos(cAR) * sin(cBR)
Normal Z = cos(cBR)

Texture - Texture map subresource

Texture maps allow textures to be assigned to a model and contain other subresources pertaining to how to apply them.

struct terModelTextureSection
string - Texture to use for this mesh

TextureCoordinates - Texture coordinate subresource

Texture coordinate subresources assign one 2-dimensional texture-space coordinate to each vertex in a mesh.

struct terModelTCList
terModelTextureCoord[] - Texture coordinates for each mesh vertex

struct terModelTextureCoord
float32[2] - Texture coordinates for this vertex

TangentVectors - Tangent vector subresource

Tangent vectors are used to define the directions in three-dimensional space corresponding to axes on the texture map.

struct terModelTVecSection
terModelTangentVectors[] - Tangent vectors for each mesh vertex

struct terModelTangentVectors
float32[3] - Vector pointing down the horizontal axis of the texture for this vertex
float32[3] - Vector pointing down the vertical axis of the texture for this vertex.

CompressedTangentVectors - Compressed tangent vector subresource


Compressed tangent vectors have the same function as tangent vectors, but the vertical vector is calculated from the cross-product of the normal and the horizontal vector, multiplied by a scalar, rather than being explicity defined.

struct terModelCTVecSection
terModelCompressedTangentVectors[] - Compressed tangent vectors for each mesh vertex

struct terModelCompressedTangentVectors
float32[3] - Vector pointing down the horizontal axis of the texture for this vertex
float32    - Cross-product multiplier for this vertex

HighCompressedTangentVectors - High-compression tangent vector subresource

High-compression tangent vectors store tangent vectors as a rotation around the normal.  TangentVectorsCompressedHigh resources use coefficients from CompressedNormals subresources.

struct terModelRCTVecSection
terModelRCVectorData[] - Compressed tangent vector coefficient for each mesh vertex

struct terModelRCVectorData
uint16 - Coefficient C

The tangent vectors are calculated as follows:

cAR = Coefficient A * pi / 32768
cBR = Coefficient B * pi / 65535
cCR = Coefficient C * pi / 16384

Horizontal Vector X = -cos(cAR)*sin(cCR) + cos(cBR)*sin(cAR)*cos(cCR)
Horizontal Vector Y = sin(cAR)*sin(cCR) + cos(cBR)*cos(cAR)*cos(cCR)
Horizontal Vector Z = -sin(cBR)*cos(cCR)

Vertical Vector X = -cos(cAR)*cos(cCR) - cos(cBR)*sin(cAR)*sin(cCR)
Vertical Vector Y = sin(cAR)*cos(cCR) - cos(cBR)*cos(cAR)*sin(cCR)
Vertical Vector Z = sin(cBR)*sin(cCR)

If Coefficient C is greater than 32767, then the T vector is negated


TMatVariants - Tertius Material Variants Index

Material variants indexes are used to look up compiled shaders by their original preprocessor settings.

struct terMaterialVariants
uint32             - Number of varying preprocessor definitions
uint32             - Number of compiled variants
terShaderDef[]     - Preprocessor definition information
terShaderVariant[] - Declarations of each variant

struct terShaderDef
string   - Preprocessor definition key
uint32   - Number of possible values for this definition.  0 indicates a boolean.
string[] - If non-boolean, each possible value of this definition.

TMatCompiledShader - Tertius Material compiled shader

Tertius Material compiled shaders are used to store a compiled version of a shader.  They are indexed to the string table to reduce the memory footprint.

struct terCompiledShader
uint32              - Number of uniforms accessable in this shader
uint32              - Number of non-uniform bindings in this shader
uint32              - Number of strings to concatenate to construct this shader
uint32              - Size of the decompressed shader result in bytes
terShaderConstant[] - Constant table lookups
terShaderBinding[]  - Named binding lookups
string[]            - List of strings to concatenate to create this shader


struct terShaderConstant
ident   - Name of this constant
ident   - Type description of this constant
uint32  - Index of this constant in the constant table
uint32  - Number of consecutive constants that this uniform takes up


struct terShaderBinding
ident   - Name of this uniform
ident   - Type description of this uniform
ident   - Binding semantic of this uniform
uint32  - Number of consecutive values that this binding takes up