Even if it looks like I’m not doing anything, that is not completely true. I’m still figuring out various bits of the engine, trying to make a whole picture of its workings. In either case, here’s a bit more of documentation.
Models seem to come in two flavours, distinguished by the first 4 bytes: MIRT
(common format) and 8XOV
(used in about a dozen of files; the format is almost the same but texture-related fields are absent). Animation files also use the same IDs but with a different format and there 8XOV
files are more common than MIRT
ones.
Each MDL file begins with the following header:
- 4 bytes—ID (
MIRT
/8XOV
); - 32-bit int—header size;
- 32-bit int—model ID;
- 16 bytes—ASCIIZ model name;
- 32-bit int—number of meshes in the file;
- 32-bit int—number of textures in the file (
MIRT
only); - 32-bit int—unknown;
- 1024 bytes—palette in ABGR format;
- 32-bit int—offset to texture data (
MIRT
only); - Nx32-bit ints—offsets to the each mesh data.
Mesh data has the following header:
- 16-byte ASCIIZ part name;
- 20×32-bit floats—unknown;
- 32-bit int—number of vertices;
- 32-bit int—number of texture vertices;
- 32-bit int—number of triangles;
- 32-bit int—offset to the vertices data (from the mesh data start, should be 0x7C);
- 32-bit int—offset to the texture vertices data;
- 32-bit int—offset to the face (triangle) data;
- 32-bit int—offset to some unknown data.
Vertices data are triplets of 32-bit floats. Texture vertices are pairs of 32-bit floats. Face data consists of a triplet of 32-bit ints with vertex indices, a triplet of 32-bit texture vertex indices, a 32-bit int texture number and a triplet of 32-bit floats with unknown values. Unknown data consists of quads of signed 32-bit integers (with the same number as the vertices) where the last element seems to be always zero.
Texture data is stored in the following format: first there is an array of 32-bit ints with an offset to the start of each texture (e.g. for single texture this offset will be 4), followed by texture header (32-bit float texture width, 32-bit float texture height, 32-bit int width power of two factor, 32-bit int height power of two factor, 32-bit int width mask and 32-bit int height mask) and texture data (palette indices for each pixel) for each of the textures.
E.g. for 128×64 texture the header values will be 128.0, 64.0, 7, 6, 127, 63.
While I’m yet to render it myself, I’ve written a small tool to covert data into Wavefront .obj
format that various 3D viewers understand. Here’s a rendered part of 063.MDL
as an example:
Beside the head, the model file also contains meshes for: body, tail, up and lower arms (both right and left), hands, shins, feet—13 objects in total. All using parts of the same 512×256 texture.