Difference between revisions of "Importing md2 and md3 files"
(No difference)
|
Latest revision as of 17:59, 12 December 2014
There are tons of existing Quake MD2 and MD3 files, so if you're interested in learning how to get these to import and look good in Sauerbraten read on!
Contents
The Basics
MD2 files are collection of animated vertices. All the animations must start/stop at specific frames, these are hard coded into the model and the game engines. There is one texture map used for the whole mesh, head to toe. It is one solid piece, so it rotates/bends as a whole unit.
MD3 files are three separate collections of animated vertices, the lower, the torso and the head. There should be an animation.cfg file that comes with the model that contains the start/length of each animation, but the animations must come in a fixed order in the models. There can be multiple texture maps, even within one section of the model. The model will rotate as a whole unit, but each piece can be made to bend separately.
Importing MD2 files
The most important thing is creating the MD2.cfg file to match the model you want to import. For MD2 files this process is really straight forward. Just use any text editor and create the file with the contents below.
Example MD2.cfg
mdlspec -1 // turn off speculars mdlscale 100 // keep original scale mdltrans 0 0 24 // raise feet up to surface plane md2pitch 1 0 -30 30
Please refer to the documentation page Sauer Models Doc for more details on each of these commands, but here are some of my notes on each.
- mdlspec -1 -- This will turn off speculars, or make it so the model isn't shiny. Of course you'll want to adjust this to suit each particular model.
- mdlscale 100 -- typically the default scale of MD2s look good in Sauer, but you can tweak how tall your model is here.
- mdltrans 0 0 24 -- most quake models have 0,0,0 at the waist of the model. Sauer wants this to be at the feet, so we add 24 to the Z axis to raise the model up. You may need to adjust this up or down a little if your toon appears to float or have its feet stuck in the ground.
- md2pitch 1 0 -30 30 -- the docs don't mention it, but you can clamp the pitch on an MD2. This makes it so the toon will only rotate so far when the player adjusts the pitch (up and down) of the toon. If you don't clamp this and the player looks down at the ground, the entire toon will rotate until it's parallel to the ground and looks rather silly. NOTE: If you have a toon that's a robot, like a Dalek or something, that you don't want to have rotate up and down at all, use md2pitch 1 0 0 1. If you try to use 0 0 for the last two arguments it will disable clamping, not clamp to 0 as you might have guessed.
Adding a skin
The only other thing you need to do to import an MD2 is to provide a skin for your toon. Sauer is going to look for either skin.jpg or skin.png, so rename one of the existing skins that came with the model. If it is another file format such as .PCX, .TIF, .TGA, etc. be sure to use a tool to convert it. Some of these may not be exact widths/height of a power of two. So far, I haven't noticed this to be a problem for Sauer, but if it is for you, just use your image tool to resize the image so that the contents are stretched.
Importing MD3 files
You should try your hand at a couple MD2 files before trying an MD3 as they are a little more complicated to import. Hopefully the model comes with an animation.cfg file, this file contains where to find all the animation offsets you will need. There will also be various *.skin files. If it has ones named lower_default.skin, upper_default.skin, and head_default.skin, I'd use the textures found in those. To start off with you want to create an MD3.cfg file.
Example MD3.cfg
md3load lower.md3 // always start with the mesh for the legs, named lower.md3 md3skin l_lower joker256.png // refer to lower_default.skin for any textures, there may be multiple ones you need to add md3pitch 1 0 0 1 // you want the toon to bend at the waist, so totally disable the pitch for the legs md3anim dying 0 30 25 // extract from line 0, BOTH_DEATH1 in animation.cfg md3anim dead 0 30 25 // extract from line 1, BOTH_DEAD1 md3anim "lag|edit" 90 1 20 // extract from line 13, LEGS_WALKCR NOTE: set frames to 1 so the toon doesn't animate md3anim "forward|left|right" 98 12 20 // extract from line 14, LEGS_WALK md3anim backward 119 10 20 // extract from line 16, LEGS_BACK md3anim swim 129 10 15 // extract from line 17, LEGS_SWIM md3anim jump 139 8 15 // extract from line 18, LEGS_JUMP md3anim idle 173 6 7 // extract from line 22, LEGS_IDLE md3load upper.md3 // the upper or torso comes next md3skin u_upper joker256.png // refer to upper_default.skin and include any textures listed in this file md3pitch 1 0 -30 30 // let the toon bend up to 30 degrees either way at the waist md3anim dying 0 30 25 // extract from line 0, BOTH_DEATH1 in animation.cfg md3anim dead 29 1 25 // extract from line 1, BOTH_DEAD1 md3anim "idle|lag|edit" 151 1 15 // extract from line 11, TORSO_STAND md3anim shoot 130 6 15 // extract from line 7, TORSO_ATTACK md3anim punch 136 6 15 // extract from line 8, TORSO_ATTACK2 md3anim taunt 90 40 17 // extract from line 6, TORSO_GESTURE md3load head.md3 // last comes the head md3skin h_head head256.png // refer to head_default.skin for any textures listed // heads cannot be animated, so there are no animations md3link 0 1 tag_torso // these lines will link the three chunks together md3link 1 2 tag_head // thankfully these are identical for 99% of the models mdlspec -1 // turn off speculars mdlscale 100 // keep original scale mdltrans 0 0 24 // raise feet up to surface plane
Extracting Animations
By far the trickiest part of this process is learning to extract the animations from the animation.cfg to convert them into your MD3.cfg. In my comments above, I included a line offset and the comment to look for. Please note, the line indices are 0 based not 1. Hopefully your animation.cfg has the comments on each line animation that says what it is. Typically every animation has a line in this file with the starting frame, the number of frames, looping frames (unused by Sauer, so we will ignore) and the speed of the animation, followed by a comment describing the animation.
Sample Animation.cfg:
// first frame, num frames, looping frames (ignored by Sauer), frames per second 0 30 0 25 // BOTH_DEATH1 29 1 0 25 // BOTH_DEAD1 30 27 0 30 // BOTH_DEATH2 57 1 0 25 // BOTH_DEAD2 60 30 0 25 // BOTH_DEATH3 89 1 0 25 // BOTH_DEAD3 90 40 0 17 // TORSO_GESTURE 130 6 0 15 // TORSO_ATTACK (MUST NOT CHANGE -- hand animation is synced to this) 136 6 0 15 // TORSO_ATTACK2 (MUST NOT CHANGE -- hand animation is synced to this) 142 5 0 20 // TORSO_DROP (MUST NOT CHANGE -- hand animation is synced to this) 147 4 0 20 // TORSO_RAISE (MUST NOT CHANGE -- hand animation is synced to this) 151 1 0 15 // TORSO_STAND 152 1 0 15 // TORSO_STAND2 153 8 8 20 // LEGS_WALKCR 161 12 12 20 // LEGS_WALK 173 8 8 15 // LEGS_RUN 182 10 10 20 // LEGS_BACK 192 10 10 15 // LEGS_SWIM 202 8 0 15 // LEGS_JUMP 210 1 0 15 // LEGS_LAND 218 10 0 15 // LEGS_JUMPB 229 1 0 15 // LEGS_LANDB 236 6 6 7 // LEGS_IDLE 250 1 1 15 // LEGS_IDLECR 240 7 7 15 // LEGS_TURN
So for each md3anim you need to look up the corresponding animation I documented in the MD3.cfg above and extract the first, second, and fourth columns to get the three numbers to pass into your md3anim. The first number, the start frame, may take some work, I'll explain next. The second and fourth numbers become your second and third numbers to use. We are ignoring the third column of numbers in the animation.cfg.
The first column is the starting frame of the animation. The torso animations you can alway use the number given as the start frame as your start frame. Heads don't have animations, so no worries there. However, not all models save the leg animations stored the same way, so you may have to adjust the starting frames shown in the animation.cfg for all the leg animations.
To see if you need to offset the start frames, subtract the start frame for the LEGS_WALKCR animation from the start frame of the TORSO_GESTURE animation. In this example these are 153 and 90, so subtracting we have an offset of 63. So for every LEG animation you must take the start frame of the animation and subtract 63 before you put it in the md3anim. For example, LEGS_SWIM starts on frame 192, so we subtract 63 and get 129 for the start frame. In our MD3.cfg we will have md3anim swim 129 10 15. Now if LEGS_WALKCR and TORSO_GESTURE both started at the same number, then they already lined up and we would subtract zero, in other words, just use the same number.
Example:
192 10 10 15 // LEGS_SWIM \_ignored md3anim swim 129 10 15 ^ ^ ^ 192 - 63 = _/ | \_taken from fourth column \_taken from second column
MD3 Textures
No big surprise here, for every texture you referenced in your MD3.cfg file you need to make sure you include and it has been converted to a .JPG or .PNG file. Getting which textures to use is just a matter of looking at the xxxxx_default.skin files.
Example lower_default.skin file:
l_lower,models/players/Joker/Joker256.tga tag_torso, tag_floor,
So in this example, we want to add md3skin l_lower joker256.png to our MD3.cfg and convert the Joker256.tga to a .png file.
Importing into Sauer
After you get your model ready for importing, you want to make a folder for each model under packages/models/ This is the only place Sauer will look for them. Unfortunately you cannot use new models for yourself without making a change to the code and recompiling Sauer. If you're feeling up to this, open fpsrender.h and look for the following code:
fpsrender.h code excerpt:
static const playermodelinfo playermodels[4] = // increase the length of the array if you add models!!! { // here i've added a hansolo model, he doesn't have red team/blue team special versions { "hansolo", "hansolo", "hansolo", NULL, NULL, { NULL, NULL, NULL }, "hansolo", "hansolo", "hansolo" }, { "mrfixit", "mrfixit/blue", "mrfixit/red", NULL, "mrfixit/horns", { "mrfixit/armor/blue", "mrfixit/armor/green", "mrfixit/armor/yellow" }, "mrfixit", "mrfixit_blue", "mrfixit_red" }, { "ironsnout", "ironsnout/blue", "ironsnout/red", NULL, "quadspheres", { "shield/blue", "shield/green", "shield/yellow" }, "ironsnout", "ironsnout_blue", "ironsnout_red" }, { "monster/ogro", "monster/ogro/blue", "monster/ogro/red", "monster/ogro/vwep", NULL, { NULL, NULL, NULL }, "ogro", "ogro", "ogro" } };