Unofficial MD3 Format Specification


Overview

MD3 is defined as a triangle mesh using morph target animation. Surfaces make up the basic model. They are described by geometry, color and animation data. Tags complement the format.

Geometry of a surface is described by grouping vertices into a triangle. Triangles are then grouped into a surface.

Colorization of a surface is done by defining UV-maps and references to shaders. The UV-maps are used to color surfaces with solid color from a 2D image. Shaders manipulate surface properties. These properties define how the surface interacts with light sources present in a scene. Additionally vertex normals manipulate the shading of a surface.

Animation of a surface is done by storing vertex positions per frame. This animation technique is also known as "morph target animation". The way it works is that for each key frame a series of vertex positions is stored. Between two successive frames, the vertices are then interpolated between the positions. MD3 stores absolute vertex positions as opposed to MDC, which can store offsets relative to a base frame.

Tags provide the possibility to attach external models to the model.

Symbols

Name Description
UINT8 unsigned 8-bit integer
INT16 signed 16-bit integer
UINT16 unsigned 16-bit integer
INT32 signed 32-bit integer
UINT32 unsigned 32-bit integer
F32 32-bit floating-point (IEEE-754)
ASCII 8-bit ASCII character
(*) Marks a list of objects of the same type. There can be multiple appearances of * inside those round brackets, for example (**) describes a list of lists.

Tables

MD3

Name Description Type
header reference to MD3Header object. MD3Header
frame_infos list of MD3FrameInfo objects, size=num_frames. MD3FrameInfo (*)
tags list of list objects, size=num_frames. Each nested list contains MD3FrameTag objects, size=num_tags. MD3FrameTag (**)
surfaces list of MD3Surface objects, size=num_surfaces. MD3Surface (*)

Notes:

Container object. References all MD3 data.

MD3Header

Name Description Type
ident magic number, ASCII encoded, length 4, reads "IDP3". 4*ASCII
version version number, latest known is 15. UINT32
name model name, usually its pathname, ASCII encoded, null-terminated, length 64. 64*ASCII
flags not used. UINT32
num_frames number of animation frames. UINT32
num_tags number of tags. UINT32
num_surfaces number of surfaces. UINT32
num_skins not used. UINT32
ofs_frame_infos file offset to field of frame infos. UINT32
ofs_tags file offset to field of tags. UINT32
ofs_surfaces file offset to field of surfaces. UINT32
ofs_end file offset to end of file. UINT32

Notes:

General information about MD3 data. Used mainly to navigate file data.

MD3FrameInfo

Name Description Type
min_bound location coordinates of min corner of minimum bounding box. 3*F32
max_bound location coordinates of max corner of minimum bounding box. 3*F32
local_origin TODO 3*F32
radius TODO F32
name name of frame, ASCII encoded, null-terminated, length 16, does not seem to be used. 16*ASCII

Notes:

Describes bounding volume information: axially aligned bounding box and bounding sphere.

MD3FrameTag

Name Description Type
name name of tag, ASCII encoded, null-terminated, length 64. 64*ASCII
location location coordinates in this frame. 3*F32
orientation orientation as rotation matrix in frame. Each sequence of 3 floats make up the coordinates of a basis vector. The first 3 floats make up the x basis vector, etc. 9*F32

Notes:

A tag in a specific frame.

Background:

Tags are used to attach external models to a model. Attachment means that the external models origin aligns itself with the models tag location and orientation. As the external model is parented to the tag (nested in tag space), any animation of the tag will also affect the external model.

Domain specific scripts tell the engine which external models to attach to a given tag. These scripts are either located in mapscript files (attachtotag command) or .skin files. Sometimes they are also hard coded.

An example use case is a hat model (defined separately) attached to a head model. This way, characters can be assembled with different looks without having to duplicate their model definitions. Tags therefore support reuse.

Another example use case is that of a tank turret model attached to a tank model. Instead of having a shooting animation (rotate turret left, shoot, rotate turret right) be recorded as vertex positions across several key-frames inside a single MD3 model, a tag can be used to control the shooting animation of a separated model. This safes memory, as the tags animation data most likely takes much less space compared to the animation data of the tank turret inside a single model.

However, reuse and memory savings are traded against loss in performance. Vertex positions of the external models have to be recalculated against the current frame tags location and orientation.

MD3Surface

Name Description Type
header reference to MD3SurfaceHeader object. MD3SurfaceHeader
triangles list of MD3Triangle objects, size=num_triangles. MD3Triangle (*)
shaders list of MD3Shader objects, size=num_shaders. MD3Shader (*)
tex_coords list of MD3TexCoords objects, size=num_vertices. MD3TexCoords (*)
vertices list of list objects, size=num_frames. Each nested list contains MD3FrameVertex objects, size=num_vertices. MD3FrameVertex (**)

Notes:

Container object. References surface data.

Background:

Surfaces are described by geometry, color and animation data. A model can consist of multiple surfaces.

MD3SurfaceHeader

Name Description Type
ident magic number, ASCII encoded, length 4, reads "IDP3". 4*ASCII
name surface name, ASCII encoded, null-terminated, length 64. 64*ASCII
flags not used. UINT32
num_frames number of animation frames. UINT32
num_shaders number of shaders. UINT32
num_vertices number of vertices. UINT32
num_triangles number of triangles. UINT32
ofs_triangles file offset to field of triangles. UINT32
ofs_shaders file offset to field of shaders. UINT32
ofs_tex_coords file offset to field of texture coordinates. UINT32
ofs_vertices file offset to field of vertices. UINT32
ofs_end file offset to end of surface. UINT32

Notes:

General information about a surface. Used mainly to navigate surface data.

MD3Triangle

Name Description Type
indices indices into the list of vertices. The order defines in which direction the face normal is pointing. 3*UINT32

Notes:

A triangle for a surface.

MD3Shader

Name Description Type
name shader name, ASCII encoded, null-terminated, length 64. 64*ASCII
shader_index used in-game only. UINT32

Notes:

Shader for a surface. The name of the shader is a reference to either a shader inside a script file, or a path from top level directory to an texture image. Suffixes like .tga or .jpg can be omitted. Search order is: shader, .tga, .jpg. First found will be used.

Background:

Shaders manipulate surface properties. These properties define how the surface interacts with light sources present in a scene.

The term can be a bit confusing, since a shader in this context can either mean a script file (with references to texture images) or an texture image.

MD3TexCoords

Name Description Type
tex_coords u and v coordinates in UV-space. 2*F32

Notes:

Texture coordinates for a single vertex. UV coordinates are given so that u points right, and v points down. Each value should be in range of [0, 1]. Values outside this range are interpreted as repeating. Each vertex is mapped exactly once to UV-space. Therefore, seams will most likely cause an exporter to add additional vertices along the seam line to enforce bijection. UV-maps are stored once per surface.

Background:

The UV-map is used to color the surface with solid color from a 2D image. Texture coordinates make up UV-space.

MD3FrameVertex

Name Description Type
location location coordinates in frame. 3*INT16
normal vertex normal in spherical coordinates. Index 0 = latitude, index 1 = longitude. 2*UINT8

Notes:

Vertex location and normal in a specific frame. Each key frame contains a list of vertex locations and normals.

Vertex location values from file are given as compressed 16-Bit integers. To convert this range to a range of floats, the given value is linearly mapped. For this, a hard coded scale value is used.

Vertex normals manipulate the shading of a surface (for example smooth or flat). They are given in spherical coordinates. Since the coordinates describe the direction of a normal, the radius value is omitted and only latitude and longitude values are given as unsigned 8-bit values from file. To convert them to cartesian space, the upwards vector is first rotated by the latitude value, then by the longitude value. Latitude range is within [0, 180] degrees. Longitude range is within [0, 360) degrees. To obtain the values in degrees, the given range of [0, 255] from file needs to be linearly mapped to [0, 360) degrees.

UML View

UML view of MD3 file format
Figure: UML view of MD3 file format