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:
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
Property | Format | Description |
formatversion | major.minor.revision | Defines the version of the file format. |
name | string | Optional. Contains the name of the content. |
version | major.minor.revision | Optional. Can be used to store the version of the content. |
source | string | Optional. Contains a reference to the source of the content, for example a file name. |
date | m/d/y h:m:s XX | Optional. Time stamp at which the file was created or last changed. Implementations are free to use
file system information instead, which is more reliable. |
comments | string | Optional. May be used to store arbitrary information. |
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
Property | Format | Description |
mesh | string | Name 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. |
scale | number | Scale of the node. This number is a multiplier, so a value of 0.5 means the node will be half the normal size. |
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
Property | Format | Description |
colormap | file path | Optional. File path to color texture map. |
bumpmap | file path | Optional. File path to the bump texture map. |
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
Property | Format | Description |
m | string | Adds 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),m | Face 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 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
Property | Format | Description |
v | (x,y,z),w | Defines and adds a vertex. w is the index of the bone the vertex is attached to. |
For more properties, see mesh. |
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
Property | Format | Description |
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.