Sign in to follow this  
mikeman

MD3 Format

Recommended Posts

mikeman    2942
Does anybody have any links to papers or tutorials that describe the MD3(Quake 3) model format, and how to load them? All I've found in the internet so far was some loaders with source code, but I would prefer to have a tutorial that describe the format in more detail. Thanks in advance.

Share this post


Link to post
Share on other sites
mikeman    2942
Yes, I know, that was what I was talking about in my first post.
It's not too hard I guess to have a look at the code and figure things out, but I was just wondering if there is any paper(like in .pdf format or something) that describes the structure of the file and how to load it, I just find easier to understand those. Thanks anyway.

Share this post


Link to post
Share on other sites
evolutional    1393
I found this and even better this. The latter is from a Delphi OpenGL coding page and it contains a file called "Quake MD3 File Format" -


The file structure of the md3 files, as far as we know at this time:

Last Updated October8 1999

!!Warning!!
This document is very technical!
It is assumed that you, the reader, have knowledge of programming C and have basic knowledge of 3d.

Please note that:

Char is a 8bit integer variable type
Short is a 16bit integer variable type
Int is a 32bit integer variable type
Float is a 32bit floating point variable-type
Vec2 is float[2]
Vec3 is float[3]
Mat3x3 is float[3][3]
TexVec is a texture vector or texture u/v coordinate

First start off with the header of the md3 file.

MD3_HEADER:

char ID[4]; //id of file, always "IDP3"
int Version; //i suspect this is a version
//number, always 15
char FileName[68]; //sometimes left Blank...
//65 chars, 32bit aligned ==
//68 chars
int BoneFrame_num; //number of BoneFrames
int Tag_num; //number of 'tags' per BoneFrame
int Mesh_num; //number of meshes/skins
int MaxSkin_num; //maximum number of unique skins
//used in md3 file
int HeaderLength; //always equal to the length of
//this header
int Tag_Start; //starting position of
//tag-structures
int Tag_End; //ending position of
//tag-structures/starting
//position of mesh-structures
int FileSize; //size of file

comments:
If Tag_Start is the same as Tag_End then there are no tags.

Tag_Num is sometimes 0, this is alright it means that there are no tags...
i'm not sure what Tags are used for, altough there is a clear connection
with boneframe, together they're probably used for bone based animations
(where you rotate meshes around eachother to create animations).



After the header comes a list of tags, if available.
The ammount of tags is the header variable Tag_num times the header variable BoneFrame_num.
So it is highly probably that tags have something to do with boneframes and that objects
can have 0 to n tags 'attached' to them.
Note: We call them 'Tags' because the name in tag usually starts with "tag_".

TAG:

char Name[64]; //name of 'tag' as it's usually
//called in the md3 files try to
//see it as a sub-mesh/seperate
//mesh-part.
//sometimes this 64 string may
//contain some garbage, but
//i've been told this is because
//some tools leave garbage in
//those strings, but they ARE
//strings...
Vec3 Postition; //relative position of tag
Vec3x3 Rotation; //the direction the tag is facing relative to the rest of the model

comments:
fairly obvious i think, the name is the name of the tag.
"position" is the relative position and "rotation" is the relative rotation to the rest of the model.

After the tags come the 'boneframes', frames in the bone animation.
The number of meshframes is usually identical to this number or simply 1.
The header variable BoneFrame_num holds the ammount of BoneFrame..

BONEFRAME:

//unverified:
float Mins[3];
float Maxs[3];
float Position[3];
float scale;
char Creator[16]; //i think this is the
//"creator" name..
//but i'm only guessing.



comments:
Mins, Maxs, and position are very likely to be correct, scale is just a guess.
If you divide the maximum and minimum xyz values of all the vertices from each meshframe you get
the exact values as mins and maxs..
Position is the exact center of mins and maxs, most of the time anyway.

Creator is very probably just the name of the program or file of which it (the boneframe?) was created..
sometimes it's "(from ASE)" sometimes it's the name of a .3ds file.



After the objects in the file are the mesh-headers.
The header variable Mesh_num holds the ammount of Meshes..
Note that a mesh consists out of the mesh-header, the skins, the triangles, the texture u/v coordinates and finally the vertices.
Each mesh contains that data, and the next mesh will only start after the triangles, meshes etc. of the previous mesh.
To my suprise there are .md3 files that don't have any meshes in them! This is something we need to look into.

MESH:

char ID[4]; //id, must be IDP3
char Name[68]; //name of mesh
//65 chars,
//32 bit aligned == 68 chars
int MeshFrame_num; //number of meshframes
//in mesh
int Skin_num; //number of skins in mesh
int Vertex_num; //number of vertices
int Triangle_num; //number of Triangles
int Triangle_Start; //starting position of
//Triangle data, relative
//to start of Mesh_Header
int HeaderSize; //size of header
int TexVec_Start; //starting position of
//texvector data, relative
//to start of Mesh_Header
int Vertex_Start; //starting position of
//vertex data,relative
//to start of Mesh_Header
int MeshSize; //size of mesh


comments:
Meshframe_num is the number of quake1/quake2 type frames in the mesh.
(these frames work on a morph like way, the vertices are moved from one position to another instead of rotated around eachother like in bone-based-animations)
Skin_num is the number of skins in the md3 file..
These skins are animated.
Triangle_Start, TexVec_Start & Vertex_Start are the number of bytes in the file from the start of the mesh header to the start of the triangle, texvec and vertex data (in that order).



After the Mesh header come the skin structures used by the mesh.
The mesh header variable Skin_num holds the ammount of skins..

SKIN:

char Name[68]; //name of skin used by mesh
//65 chars,
//32 bit aligned == 68 chars

comments:
Name holds the name of the texture, relative to the baseq3 path.
Q3 has a peculiar way of handling textures..
The scripts in the /script directory in the baseq3 directory contain scripts that hold information about how some surfaces are drawn and animate (and out of how many layers it consist etc.)
Now the strange thing is, if you remove the ".tga" at the end of the skin, and that name is used in the script files, than that scripted surface is used.
If it isn't mentioned in the script files then the filename is used to load the
tga file.


After the Skins come the triangles.
The mesh header variable Triangle_num holds the ammount of triangles..

TRIANGLE

int Triangle[3]; //vertex 1,2,3 of triangle


comments:
This is the simplest of structures.
A triangle has 3 points which make up the triangle, each point is a vertex and the three ints that the triangle has point to those vertices.
So you have a list of vertices, for example you have a list of 28 vertices and the triangle uses 3 of them: vertex 1, vertex 14 and vertex 7.
Then the ints contain 1, 14 and 7.



After the triangle data come the texture u/v coordinates of each vertex. The mesh header variable Vertex_num holds the ammount of u/v coordinates and vertices..
You have an U/V coordinate per vertex.
TEXTURE U/V COORDINATES:

Vec2 TexVec; //Texture U/V coordinates of vertex


comments:
U/V coordinates are basically the X/Y coordinates on the texture.
This is used by the triangles to know which part of the skin to display.



After the texture u/v coordinates come the vertices.
The mesh header variable Vertex_num holds the ammount of vertices per frame, and the mesh header variable MeshFrame_num contains the ammount of frames in the mesh.
So you have MeshFrame_num times Vertex_num vertices.
VERTICES:


//!!!important!!! signed!
signed short Vec[3]; //vertex X/Y/Z coordinate
unsigned char EnvTex[2]; //enviromental mapping texture coordinates


comments:
Vec contains the 3d xyz coordinates of the vertices that form the model.EnvTex contains the texture coordinates for the enviromental mapping.
Why does md3 have a second set of texture coordinates?
Because:
1. these texture coordinates need to be interpolated when the model changes shape,
2. these texture coordinates are different from the normal texture coordinates but still both need to be used (with shaders you can have multi-layered surfaces, one could be an enviromental map, an other could be a transparent texture)



Might be useful?

Share this post


Link to post
Share on other sites
mikeman    2942
Thanks!!
I will definately have a look at the samples, but I just needed a technical document describing exactly the stucture of the file. It will be very helpful.
I've already rated you up (not that it made a big difference). Thanks again.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this