Imagine that each time you added a room to a map, the rest of your brushes got snapped to a new grid. This is the reality of making a model in mdl format – the whole thing has to sit in a 256x256x256 grid, and any time a new animation strays outside of this grid the whole thing needs to be recalculated. If you were to animate a model starting with standing, then walking, running, attacking and dying, each one involves larger movements than the one before, so you would probably end up changing this grid with each new animation.
If you do this within a mdl editor like QMe in a single session, the vertices are stored at higher precision in memory. But if you save and reopen a model in mdl format you’ve fixed the rounding, and doing this often enough accumulates rounding error. I opened with a mapping analogy, and I invite you now to start thinking of making mdl files as being like compiling a bsp file. The mdl you get is something you rebuild if you want to update it, not something you edit directly.
I’m going to describe my own model compiling pipeline, but you have lots of options at the first stage, and there’s no reason why you can’t adapt other stages as well. If we’re going to compile a model, we need some tools to do it. Today’s pipeline uses two of the tools I host on this site:
You can let them download while you read on….
This pipeline, like the pipeline for mapping, allows you to pick the editor you feel most comfortable with. I use the free version of 3dsmax called gmax(now found at http://www.turbosquid.com/gmax). If you have the full version of 3dsmax or maya then you can use them. If you like things that are both free and free then you can use blender(www.blender.org). Picking a tool that suits you is very important, because you’ll now be spending most of your time in that editor.
When it comes to compiling maps, it doesn’t matter which editor we use because they all export to the map format, and the compilers all know how to read it. In the same way, we can pick from a selection of modelling suites at the start of the model pipeline, because we’re going to export to md3 format. md3 is my recommendation for a number of reasons. Internally it’s like a more precise version of the mdl format, which suits us well. It’s a very popular format (unlike mdl!) so all the major modelling packages have a way to export to it. Most importantly, the first tool you downloaded up there can read a md3 and spit out a mdl.
Before we move any further down the pipeline, a quick note on saving the files. If we were compiling a map, we probably wouldn’t keep a plain map file as our only copy of the work, we’d use the native format of our editor to preserve all the extra info. This is even more important for modelling programs, because there’s lots more of that kind of information: animation controls, bones, smoothing and unwrapping. So keep a copy in your editor’s own format as well.
This tool which I wrote some time ago is still a vital part of the pipeline today, because it gives us an actual .mdl file. I believe that it converts the md3 to mdl format as accurately as possible. Two of the features which give it an edge over conventional mdl creation are:
1) It preserves the vertex normals that the md3 file had (to the limits of quake precision). This lets you use smoothing groups on your model and see them in-engine.
2) It faithfully converts the skin map of the md3, allowing you to unwrap your model’s skin properly
These two features actually go hand-in-hand on a technical level – the md3 has already split all the vertices along the seams of the skinmap, and md3tomdl copies the geometry. If it then calculated the normals afresh it would expose these seams.
So a quick guide on how to use md3tomdl. The tool relies on having a short text file to control it, I suggest creating model.txt with this:
md3file model.md3 skinfile model.pcx mdlfile model.mdl
Gather your skin file and your md3, and you can then “compile” your mdl file with the command
md3tomdl model.txt. The very generic names for all these files are intentional, as we will see later.
If your modelling package is anything like gmax, you will now have a model with a single animation sequence, a single skin, no flags and none of the other tweaks you’d make with a mdl editor. The model might work okay if you don’t need grouped animations, but it’s not very polished. model.py is the way we put all of these things right – we write a little script which creates the animation sequences, sets flags and imports the rest of our skins. The exciting thing is that having this script here opens up some new possibilities, like manipulating the vertex normals to create special effects. We’ll keep it straightforward today though.
I’ll give an example of the model.py file I used to compile my forcefield model, in two segments:
from qmdl.mdl import Mdl from qmdl.palette import palette from PIL import Image, ImagePalette def rename_range(frames, start, name, length): for i in range(length): frames[i + start].name = (name + str(i + 1)).encode("ascii") def rename_frames(mdl, names): i = 0 for name in names: rename_range(mdl.frames, i, *(name)) i += name def append_skin(mdl, filename): im=Image.open(filename) pim=Image.new("P", (mdl.skinwidth, mdl.skinheight)) pim.putpalette(palette) pim=im.quantize(palette=pim) sk=Mdl.Skin(mdl.skinwidth, mdl.skinheight) sk.pixels=pim.tostring() mdl.skins.append(sk)
This is the ‘header’ of the file, typically reused for each model. The first few lines import the modules we need to use, from the qmdl package linked above and the Python Image Library (PIL) for loading skins. Then we have 3 very useful functions, for renaming sequences of frames and for importing skins. Don’t worry if you don’t understand everything these functions do, in the next section we’ll see how to use them!
Next we have instructions specific to this model:
mymdl = Mdl() with open("model.mdl", "rb") as infile: mymdl.read(infile) #apply new sequential names to the frames rename_frames(mymdl, [("activate", 16),("active",17),("deactivate",17)]) #import these skinfiles skinlist = ["gold.pcx", "ruby.pcx", "amber.pcx"] for skin in skinlist: append_skin(mymdl, skin) with open("field.mdl", "wb") as outfile: mymdl.write(outfile)
The first three lines create a new Mdl object and read the contents of model.mdl into that object. We then run the
rename_frames function we defined in the header. The first set of ’s contain a comma separated list of pairs. Each pair has a sequence name in double quotes, followed by a sequence length. This is the first point you would customise, by listing all the animations your model has in order, with a (“name”, length) pair for each one.
skinlist is the next point of customisation. Between the ’s is a comma separated list of filenames in double quotes. The next two lines load each of those files as a skin on the model. Update the list to contain each skin you want to load. If you don’t need any more skins on your model, you can leave the ’s empty, or delete all three lines. Finally the last two line write the modified model back out to disk. Notice that we are writing the file to a different filename, you should alter this to the final name you want for your model.
We don’t want to have to mess around with a bunch of command line tools every time we update the model, especially when we’re trying to get something just right in-game by experimenting with settings in our editor. So the natural thing to do is set up a batch file which runs all the bits of our pipeline for us. Mine looks like:
md3tomdl model.txt python model.py
Short and simple. I recommend creating a new directory for each model you are working on. You can just copy the model.txt, model.py, model.bat, model.pcx, model.md3 files each time you start a new model and pop them into a new directory, then replace the model.pcx and model.md3 files with the ones for the new model as you create them. With this set-up, for a new model the only file you need to worry about changing is model.py. As a final tip, you can add extra commands to the end of model.bat, for example copying the model into your quake progs directory so you can test it straight away. Your pipeline from modelling package to game is complete!
I hope you’ll give this pipeline idea a try. The upfront investment in having to set it up weights against it, especially creating the bits first time around and getting to grips with how it runs. But not only do you get models which have animations as clean as you can get, with proper skinmaps and smoothing groups; it actually makes it easier to make tweaks and adjustments! Running the batch file doesn’t just update your geometry, it also pulls in your latest skin – less fiddly than running your model editor to import it. If you export to mdl format and then edit further in QME, you face a dilemma if you want to make changes back in the modelling package – will you throw away the QME edits to make those changes? With the pipeline you keep everything in sync, so your changes at any step go straight to the end model.