MD2 (file format)
Encyclopedia
MD2 is a model format used by id Software
's id Tech 2 engine and is thus used by Quake II
as well as many other games, most of them using this engine, including SiN and Soldier of Fortune. The format is primarily used for animated player models although it can also be used for static models. Unlike more recent character model formats, MD2 animations are achieved via keyframes on a per-vertex level; the keyframes are stored within the model file and the engine interpolates between them to create a smooth animation.
Dynamic data such as vertices
and normals
are stored within a number of file chunks called frames (or key-frames) which each have their own short headers.
In defining the file structure several data types will be referred to.
int (4 bytes), short (2 bytes), and char (1 byte)
MD2 Header
At the offset ofs_st there are num_st of this structure:
The texture coordinates are multiplied by the texture's size and so are always integers.
To recover the floating-point texture coordinates as used by common 3D display API's such as OpenGl, divide the texture coordinates by the respective size dimensions of the texture:
sfloat = (float)s / texturewidth
tfloat = (float)t / textureheight
At offset ofs_tris there are num_tris of the following structure
short vertexindex[3]
short textureindex[3]
These are indexes to the vertexs and texture coordinates and tell the engine reading the file how to build primitives from the data.
At offset ofs_frames frame data is stored, each frame has a short header followed by a number of vertex and Surface-normal indexes, the frame header structure is like this:
float scale[3]
float translate[3]
char name[16]
Then there is num_xyz of this structure:
unsigned char v[3]
unsigned char lightnormalindex
Each vertex is stored as an integer. To recover the floating-point vertex coordinates, the MD2 reader multiplies each coordinate by the scaling vector for the current frame and then adds the frame's translation vector:
float x = (v[0] * scale[0]) + translate[0]
float y = (v[1] * scale[1]) + translate[1]
float z = (v[2] * scale[2]) + translate[2]
The frames scale and translation vector can be found in the frame's header.
loop while $(int)index is less than $(int)num_tris
texture_function_s $(float)texture_coordinates[ $(short)triangle[ $(int)index ].textureindex[0] ].s / skinwidth
texture_function_t $(float)texture_coordinates[ $(short)triangle[ $(int)index ].textureindex[0] ].t / skinheight
normal_function $(unsigned char)vertex[ $(short)triangle[ $(int)index ].vertexindex[0] ].lightnormalindex
vertex_function_x ($(unsigned char)vertex[ $(short)triangle[ $(int)index ].vertexindex[0] ].v[0] * scale[0]) + translate[0]
vertex_function_y ($(unsigned char)vertex[ $(short)triangle[ $(int)index ].vertexindex[0] ].v[1] * scale[1]) + translate[1]
vertex_function_z ($(unsigned char)vertex[ $(short)triangle[ $(int)index ].vertexindex[0] ].v[2] * scale[2]) + translate[2]
$(int)index = $(int)index + 1
end loop
Id Software
Id Software is an American video game development company with its headquarters in Richardson, Texas. The company was founded in 1991 by four members of the computer company Softdisk: programmers John Carmack and John Romero, game designer Tom Hall, and artist Adrian Carmack...
's id Tech 2 engine and is thus used by Quake II
Quake II
Quake II, released on December 9, 1997, is a first-person shooter computer game developed by Id Software and distributed by Activision. It is not a sequel to Quake; it merely uses the name of the former game due to Id's difficulties in coming up with alternative names.The soundtrack for Quake II...
as well as many other games, most of them using this engine, including SiN and Soldier of Fortune. The format is primarily used for animated player models although it can also be used for static models. Unlike more recent character model formats, MD2 animations are achieved via keyframes on a per-vertex level; the keyframes are stored within the model file and the engine interpolates between them to create a smooth animation.
File format
An MD2 file begins with a fixed length header followed by static model data such as texture coordinates.Dynamic data such as vertices
Vertex (computer graphics)
A vertex in computer graphics is a data structure that describes a point in 2D or 3D space. Display objects are composed of arrays of flat surfaces and vertices define the location and other attributes of the corners of the surfaces.-Application to object models:In computer graphics, objects are...
and normals
Surface normal
A surface normal, or simply normal, to a flat surface is a vector that is perpendicular to that surface. A normal to a non-flat surface at a point P on the surface is a vector perpendicular to the tangent plane to that surface at P. The word "normal" is also used as an adjective: a line normal to a...
are stored within a number of file chunks called frames (or key-frames) which each have their own short headers.
In defining the file structure several data types will be referred to.
int (4 bytes), short (2 bytes), and char (1 byte)
MD2 Header
Offset | Data type | Name | Description |
---|---|---|---|
0 | int | ident | Magic number. Must be equal to "IDP2" |
4 | int | version | MD2 version. Must be equal to 8 |
8 | int | skinwidth | Width of the texture |
12 | int | skinheight | Height of the texture |
16 | int | framesize | Size of one frame in bytes |
20 | int | num_skins | Number of textures |
24 | int | num_xyz | Number of vertices |
28 | int | num_st | Number of texture coordinates |
32 | int | num_tris | Number of triangles |
36 | int | num_glcmds | Number of OpenGL OpenGL OpenGL is a standard specification defining a cross-language, cross-platform API for writing applications that produce 2D and 3D computer graphics. The interface consists of over 250 different function calls which can be used to draw complex three-dimensional scenes from simple primitives. OpenGL... commands |
40 | int | num_frames | Total number of frames |
44 | int | ofs_skins | Offset to skin names (each skin name is an unsigned char[64] and are null terminated) |
48 | int | ofs_st | Offset to s-t texture coordinates |
52 | int | ofs_tris | Offset to triangles |
56 | int | ofs_frames | Offset to frame data |
60 | int | ofs_glcmds | Offset to OpenGL commands |
64 | int | ofs_end | Offset to end of file |
At the offset ofs_st there are num_st of this structure:
Data type | Name |
---|---|
short | s |
short | t |
The texture coordinates are multiplied by the texture's size and so are always integers.
To recover the floating-point texture coordinates as used by common 3D display API's such as OpenGl, divide the texture coordinates by the respective size dimensions of the texture:
sfloat = (float)s / texturewidth
tfloat = (float)t / textureheight
At offset ofs_tris there are num_tris of the following structure
short vertexindex[3]
short textureindex[3]
These are indexes to the vertexs and texture coordinates and tell the engine reading the file how to build primitives from the data.
At offset ofs_frames frame data is stored, each frame has a short header followed by a number of vertex and Surface-normal indexes, the frame header structure is like this:
float scale[3]
float translate[3]
char name[16]
Then there is num_xyz of this structure:
unsigned char v[3]
unsigned char lightnormalindex
Each vertex is stored as an integer. To recover the floating-point vertex coordinates, the MD2 reader multiplies each coordinate by the scaling vector for the current frame and then adds the frame's translation vector:
float x = (v[0] * scale[0]) + translate[0]
float y = (v[1] * scale[1]) + translate[1]
float z = (v[2] * scale[2]) + translate[2]
The frames scale and translation vector can be found in the frame's header.
Example
This is an example of how to decompress a single frame and display it. Its not in any specific programming language to try and make it easy for every one to interpret. variables have $ before them and their typeloop while $(int)index is less than $(int)num_tris
texture_function_s $(float)texture_coordinates[ $(short)triangle[ $(int)index ].textureindex[0] ].s / skinwidth
texture_function_t $(float)texture_coordinates[ $(short)triangle[ $(int)index ].textureindex[0] ].t / skinheight
normal_function $(unsigned char)vertex[ $(short)triangle[ $(int)index ].vertexindex[0] ].lightnormalindex
vertex_function_x ($(unsigned char)vertex[ $(short)triangle[ $(int)index ].vertexindex[0] ].v[0] * scale[0]) + translate[0]
vertex_function_y ($(unsigned char)vertex[ $(short)triangle[ $(int)index ].vertexindex[0] ].v[1] * scale[1]) + translate[1]
vertex_function_z ($(unsigned char)vertex[ $(short)triangle[ $(int)index ].vertexindex[0] ].v[2] * scale[2]) + translate[2]
$(int)index = $(int)index + 1
end loop
Resources
- The Quake II's MD2 file format
- [ftp://ftp.idsoftware.com/idstuff/source/quake2.zip Quake2 Source]