TPM File Format

Last updated August 7, 2007.

Introduction

TPM stands for "Trespasser Models". This file format was created as an alternative for the .3ds format. The main reason for this was that .3ds files do not store texture coordinates and normals correctly on all geometry.
TPM files are ASCII text files which define the elements that make up a scene. The formatting is somewhat based on the Alias/Wavefront OBJ file format. Elements are defined in blocks, marked by curly brackets to indicate the start and end of a block, much like the C/C++ and Java programming languages do. Like these languages, lines of text can also be 'commented out' by using double slashes.

Conventions

Coordinate System
All positions are in world space, and consist of three floating point values: X,Y,Z. These are contained in parenthesis to indicate they make up a triplet.
The format sticks to the Trespasser (and 3dsmax) scene orientation, where X is left/right, Y is front/back and Z is up/down direction.

Floating Point Numbers
Floating point numbers may be rounded, or unnecessary leading and/or trailing zeros removed to compress files. Note that rounding may have an impact on quality of the content.

Strings
Strings are contained by double quotation marks ("). Note that these must be character 34 defined in the ASCII standard. Other quotation marks, or those in extended character sets are not valid.
There are no escape characters, nor are line breaks or cariage returns supported as of now.

Name Strings
Strings that are used as identifiers should conform to what Trespasser supports. If it does not, it may lead to undefined behavior in other implementations.

Elements

The TPM format defines a number of different elements (also called 'data blocks' or just 'blocks'). All blocks start by a keyword, defining the type of the block. It is followed by a string that is used as identifier, essentially the 'name' of the block. Note that the "fileinfo" block does not have this identifier as there can be only one instance of that block in a TPM file. The block properties are containted in parentheses, curly brackets mark the start and end of each block.

The blocks types are:
Blocks
fileinfo instance material mesh skin bone

Fileinfo

The fileinfo element provides information about the TPM file itself for the application that is processing it. Not all properties are required, only the file format version is needed to properly parse the file.

Example
fileinfo
{
 formatversion = 1.0.1
 name = "NewRaptor.max"
 version = 0.1.3
 source = "NewRaptor.max"
 date = 7/2/2007 6:03:23 PM
 comments = "unfinished yet"
}
Properties
PropertyFormatDescription
formatversionmajor.minor.revisionDefines the version of the file format.
namestringOptional. Contains the name of the content.
versionmajor.minor.revisionOptional. Can be used to store the version of the content.
sourcestringOptional. Contains a reference to the source of the content, for example a file name.
datem/d/y h:m:s XXOptional. Time stamp at which the file was created or last changed. Implementations are free to use file system information instead, which is more reliable.
commentsstringOptional. May be used to store arbitrary information.

Instance

In Trespasser worlds, instances are the nodes that contain the transform of a single entity, as well as references to other elements. The transform defines the position and rotation of the node. A reference to a mesh element may be included in order to render visible geometry to the screen.

Example
instance "RaptorB"
{
 mesh = "RaptorB"
 position = (0.00585938,-0.51088,0.0339626)
 rotation = (0,0,0)
 scale = 3.05637
}
Properties
PropertyFormatDescription
meshstringName of the mesh that is rendered in place of the node.
position(x,y,z)World space position of the node.
rotation(x,y,z)World space rotation of the node in Euler Angles.
scalenumberScale of the node. This number is a multiplier, so a value of 0.5 means the node will be half the normal size.

Material

The material element defines the surface properties that are used on meshes, such as the texture maps.

Example
material "RaptorGreen2"
{
 colormap = "RaptorGreen2color.bmp"
 bumpmap = "RaptorGreen2bump.bmp"
}
Properties
PropertyFormatDescription
colormapfile pathOptional. File path to color texture map.
bumpmapfile pathOptional. File path to the bump texture map.

Mesh

Mesh elements contain all the data that is required to construct a three dimensional model. This includes vertices, which are points in 3d space, and faces, which contain indices to these vertices to make up a three dimensional triangle. Other data is used to define the appearance of these polygons.

Example
mesh "Plane01"
{
 m = "wood04"
 m = "stone03"
 v = (-1.0,-0.5,0.0)
 v = (1.0,-0.5,0.0)
 v = (-1.0,0.5,0.0)
 v = (1.0,0.5,0.0)
 t = (0.0,0.0)
 t = (1.0,0.0)
 t = (0.0,1.0)
 t = (1.0,1.0)
 n = (0.0,0.0,1.0)
 f = (3,1,4),(3,1,4),(1,1,1),2
 f = (2,4,1),(2,4,1),(1,1,1),1
}
Materials
A mesh may use one or more materials. These are stored per mesh in a 'material table'. Each material can be added to this table by the "m = ..." construct. These must be in proper order; the first material will have index 1, the second will have index 2, etc. Each face has an index that points to this material table.

Vertices
Vertices are defined as a triplet of three floating point numbers. Faces are constructed by using three vertices to make up a three-dimensional triangle.

Texture Coordinates
Texture coordinates are two dimensional coordinates that define the placement of texture maps on the surface of a face (polygon). These are sometimes referred to as "UVs". These coordinates consist of two floating point numbers which typically range from 0.0 to 1.0, however larger values may be used to 'tile' textures on surfaces, and negative values to 'mirror' textures.

It should be noted that textures maps are usually stored vertically flipped, and displayed normally. That is, the coordinate [0,0] is the bottom left pixel. Texture coordinates however are not flipped, where [0,0] is the upper left corner. Virtually all software use these same conventions, so it should not lead to problems.

Normals
Normals are normalized vectors that provide infomation to the renderer to approximate the curvature of a polygon (face). This is used for Gouraud shading. Each face has three normals, one for every vertex.

Normals should be normalized, that is, the square length of the vector is equal to one. This is not a requirement however, but should be seen as good practice.

Faces
Faces are the structures that make up a triangle (a polygon). They consist solely of indices. The first triplet indexes three vertices. The second triplet indexes three texture coordinates. The third triplet indexes three normals. The last index points to the material table.

The vertex, texture coordinate and normal arrays are all one based, that is, the index of the first element is one. Faces that do not have a material, may point to zero. Implementations are encouraged to check for indices that lay outside the array ranges to prevent data corruption.

Also encouraged is to order the faces in groups per material. This will lead to fewer state changes when the geometry is rendered, and thus improved performance.

Properties
PropertyFormatDescription
mstringAdds a material to the mesh material table.
v(x,y,z)Defines and adds a vertex.
t(u,v)Defines and adds a texture coordinate.
n(x,y,z)Defines and adds a normal vector. Normals should be normalized.
f(v1,v2,v3),(t1,t2,t3),(n1,n2,n3),mFace indices. First triplet indexes the vertices. Second triplet indexes the texture coordinates. Third triplet indexes the normal vectors. The last index points to the material table.

Compression
To compress files, duplicate vertices, texture coordinates and normals may be merged, resulting in less data. Face indices will then need to be altered. For example, a flat shaded box has 2 * 6 = 12 faces. Each face has 3 vertex normals, resulting in a total of 3 * 12 = 36 normals. This can be reduced to only 6 normals, one for each side of the box, by removing the duplicates. The same applies to vertices and texture coordinates.

Skin

Skin elements are almost identical to mesh elements. Skin elements however include some additional: vertex weights. In order to deform models, it needs to be known which vertices are bound to which bones in the skeleton. Skins include an extra index for each vertex, which is the bone number. This number may be zero, meaning it is not bound to any bone, but during deformation this may lead to undefined behavior.

Example Code
skin "TestSkin"
{
 m = "default"
 v = (-1.0,-0.5,0.0),1
 v = (1.0,-0.5,0.0),1
 v = (-1.0,0.5,0.0),3
 v = (1.0,0.5,0.0),2
 t = (0.0,0.0)
 t = (1.0,0.0)
 t = (0.0,1.0)
 t = (1.0,1.0)
 n = (0.0,0.0,1.0)
 f = (3,1,4),(3,1,4),(1,1,1),1
 f = (2,4,1),(2,4,1),(1,1,1),1
}
Properties
PropertyFormatDescription
v(x,y,z),wDefines and adds a vertex. w is the index of the bone the vertex is attached to.
For more properties, see mesh.

Bone

Bones are nodes used to deform skins, interconnected in a hierarchy that functions as 'skeleton'. While called "bones", they are actually joints. For example, for a lower arm bone is really the elbow joint, and the foot bone is the angle joint.
Skin vertices are assigned to move along with the respective bones in the hierarchy, thus deforming the geometry.

Example Code
bone "$JRaptorB23"
{
 position = (0.002930,1.740082,0.810120)
 rotation = (31.740742,-0.000009,0.000010)
 Anim00 = 7
 Anim01 = 8
 Ratio = 0.500000
 RotationRatio = 0.500000
}
Properties
PropertyFormatDescription
position(x,y,z)Defines the XYZ position of the origin on the bone.
rotation(x,y,z)Defines the XYZ position of the origin on the bone.
A number of extra, arbitrary properties may be present. These are usually T-Script values that may used for editing or displaying. Implementations are allowed to ignore these additional values for use, but they must be preserved in a conversion process.

Acknowledgments

The format was initially designed by Martijn Buijs, with many contributions by Andres James. Andres also provided excellent implementations of the TPM format in both TresEd and GeomAdd, and additionally helped with the export scripts and wrote the import scripts for 3dsmax. Numerous others within the Trespasser community have helped to improve the format in one way or another.

This document was written by Martijn Buijs (a.k.a. Remdul) on August 5, 2007.

This document may be freely reproduced.
TresCom 2007.