Player Models HowTo
|Wolfenstein: Enemy Territory Documentation
© 2003 Splash Damage, Ltd. All Rights Reserved.
The player model system in Enemy Territory exists out of multiple parts. This document will elaborate on all the different files needed, how to create them and how to fit them together. There are quite a few files involved per player model, so good media management is a requirement.
|.mdm||Skeletal meshes. These files contain all surfaces with vertex positions, their bone weighting and UV information. Tags are saved to this file as well.|
|.mdx||Skeletal animation files. These files contain the bone positions for multiple frames. Frame bounding box data is present too.|
|.md3||MD3 files are old Q3 style meshes. They can be vertex-animated and are primarily used for head and attachment models.|
|.anim||Animation groups. These files reference a set of mdx files and include their animation frame descriptors.|
|.aninc||Animation inclusion files. They contain the names of animation sequences and their properties like starting frame, duration, frame rate, etc.|
|.skin||Skin definition files. They are used in combination with a mesh to define the shader to be used with specific surfaces. They are also used to specify which models the game code has to attach to player models.|
|.script||Animation script files. These define possible state combinations and are used by the game code to find out which animation sequences to play in those situations.|
|.char||Character files. They combine all of the above files into a valid character that can be referenced from game code and map scripts to spawn a player or bot with a certain look.|
A Quick Overview of the Exporting Process
It all starts with a mesh tied to a biped in MAX. Using the SkelOut plugin, this will be saved to a SKL file. Then, BuildMDS will use this file to create a MDM file and one or more MDX files. Tie these together with an animation group, an animation script and some skin files and you have yourself a new model.
The export process for an ET compatible version 2 SKL file requires you to have everything you don’t want in the game hidden in MAX. All surfaces and tags that remain and will have to be exported into the MDM files will have to be frozen; else they’ll get converted into bones. The only objects that remain unfrozen and unhidden should be the biped sections that the skeleton uses.
It’s very important to make sure the biped is set to rigid, both during development and exporting to ensure what you see in MAX is the same as what you will see in-game.
Now hit file->export, select Wolfenstein Skeleton Export (*.SKL) from the dropdown box and enter a filename. Click on save and you will get a dialog box where you can enter multiple values for exporting.
Specify the start frame, end frame and the frame rate at which you want to have the SKL exported. The default frame and sample rate of 15 should be fine in all cases. Make sure you select version 2 for MDM exports, else you won’t be able to create proper MDM or MDX files.
Hit OK and the plugin should start exporting. Minimize MAX for the process to go faster as it won’t have to render the frames as it goes.
Providing no error messages pop up you should have made yourself a SKL file.
The reason these model formats have their meshes and animation data separated is so that multiple meshes can share the same animation data which has the potential to greatly reduce the games’ memory footage. There is only one requirement to make this work, namely that all bones that a mesh references must be present in the animation data. So basically the bone structure in the MDX files always has to be the same, or a superset of, the bone structure in the MDM files. To ensure this, a parent MDX file will have to be specified when exporting related MDM or MDX files. How this file is generated and where it has to be referenced will be explained later on.
Before you will be able to convert a SKL file, you need two additional files. A .skd file and a .ski file. The skd file is used to define the spine bones and the way the torso bends. Besides that it contains information about the models’ LOD. Here is an example of a skd file:
// MDS definition file
// (read in by BUILDMDS when building the MDS file)
// NOTE: cant use the “spine” since it is the parent of the thigh’s
“Bip01 Spine1” 0.30
// LODSCALE can be used to vary the speed at which a model decreases it’s LOD with range. It would
// LODBIAS can be used to set a fixed amount by which to adjust all LOD calculations for this model.
The comments in this example should explain the syntax and the usage well enough for you to create your own skd files.
The ski file is the export information file that BuildMDS uses to know which base MDX to use and which MDX files to export from a certain SKL file. An example:
// MDX export information file
// (read in by BUILDMDS when building the MDM/MDX files)
// COMPILEBONESFILE links to the .mdx skeletal file that this mdm uses during compile, to grab the
// NUMMDXFILES is the number of mdx files we generate from this skl file using this definition file
// Here are the mdx file details listed. Syntax is <outputfilename> <startframe in .skl> <endframe in .skl>
“base.mdx” 0 4869
This file should be self-explanatory as well, but to ensure nothing will go wrong some extra information regarding the COMPILEBONESFILE entry is needed. When exporting the first MDM and set of MDX files from a SKL that will provide the base MDX, the value of COMPILEBONESFILE needs to be set to “BASEMDX”. This is required to show BuildMDS that we are using this SKL as a base.
Whenever a MDM or MDX is exported from other SKL files belonging to the same set of shared animations and meshes as this base MDX, COMPILEBONESFILE should point at a MDX file generated from the base SKL. This allows BuildMDS to remap the bones in other SKL files to ensure compatible MDM and MDX files are generated.
Keep in mind that whenever a new bones structure is required; for example if more bones are being used than the base provides, a new base MDX will have to be generated and all MDM and MDX files in the same set of animations will have to be converted again.
Now let’s move on to the actual usage of BuildMDS. If you want to generate a MDM file and optionally a set of MDX files (you can set NUMMDXFILES to 0 in the ski file to choose not to generate any of these), you use the following command line:
buildmds <sklfile> -mdm [-verbose] [-force] [-dest name]
The SKL filename should be specified without extension. Verbose can be specified to generate extra information about the conversion process, force can be used to override the up-to-date checks done on MDM and MDX files relative to the source SKL file and force an export at all times. The MDM will be named after the SKL file, although this can be overwritten by using the dest parameter.
To only generate MDX files, the following command line is to be used:
buildmds <sklfile> -mdx [-verbose] [-force]
Both the command lines mentioned use the ski file to determine the filenames of the MDX files to generate.
There are more command line parameters available for BuildMDS, but most aren’t relevant to the MDM and MDX conversion process. Some of them aren’t used at all while some others might actually cause the process to malfunction. So unless you know what you’re doing it’s best to stay away from them.
animfile <mdx file>
#include <aninc file>
There is no limit to the amount of mdx files that can be specified in one animation group.
The aninc file that is included through the #include statement specifies which animation sequences are present in the related MDX file and has the following syntax:
<animation name> <first frame> <length> <looping> <fps> <move speed> <transition> <reversed>
All of which should be on one line. Any number of animation sequences can be specified in one aninc file, the only limit is the total amount of individual animation sequences that can be handled by the game. A small example aninc file:
| // SELF INJECT
self_inject 0 16 0 15 0 0 0
This one specifies only one animation, but every MDX file can have one or multiple animation sequences.
You can create multiple animation groups for a set of compatible MDX files, to create subsets for certain characters. This is useful if there is, for example, a cigarette smoking animation that is compatible with the default human set but this sequence is only used on certain levels. A separate animation group can be created for humans that smoke and referenced from a character definition that gets used only in those levels that require the animation. This prevents the game from having to load the smoking animation on levels that don’t use it.
Another use is if you have two characters that use the same animation set and script, but each has its own death animations (which will be referenced from the animation script using the same animation names, such as death_knife), you then can create two animation groups for these characters and tie them up in two different character definitions. Useful if you have, for example, a scripted character you want to die in a certain way.
Skin files have two functions. They are used in combination with models where their primary function is to define which shaders are to be used on the surfaces of a model. Their secondary function, which only applies to skin files for the head and body models, is to attach accessory models to the body or head. The syntax is very basic, namely:
If the key is the name of a surface, the value is an absolute path to a shader or texture to be used for this surface. For accessory attachment keys, the value is an absolute path to a model to attach.
The following keys are supported for the body skin file:
|md3_beltr||Attaches to tag tag_bright.|
|md3_beltl||Attaches to tag tag_bleft.|
|md3_belt||Attaches to tag tag_ubelt.|
|md3_back||Attaches to tag tag_back.|
|md3_weapon||Attaches to tag tag_weapon.|
|md3_weapon2||Attaches to tag tag_weapon2.|
And for the head skin file:
|md3_hat||Attaches to tag_mouth, gets removed when a headshot is given.|
|md3_hat2||Attaches to tag tag_mouth.|
|md3_hat3||Attaches to tag tag_mouth.|
<keys and values>
The following set of keys is supported:
|mesh <mesh>||The mesh file to use. (MDM or MDS)|
|animationgroup <animation group>||The animation group. If a MDS is used, this should point to an old-style animation config.|
|animationscript <animation script>||This points to an animation script file.|
|skin <skin file>||The skin file used for the mesh. The actual filename gets derived from this string and the mesh filename. If you have “players/soldier/body.mdm” as mesh and “default” as skin, it will look for “players/soldier/body_default.skin”.|
|animatedHead||If this keyword is present, the code assumes the head model used for this character supports facial animation.|
|undressedCorpseModel <mesh>||Mesh used for when a Covert Ops steals the uniform of a corpse. (MDM or MDS)|
|undressedCorpseSkin <skin>||The skin file used for the undressed corpse.|
|hudHead <head model>||Mesh to use for the hud head. (MD3)|
|hudHeadSkin <skin>||The skin file used for the hud head.|
|hudHeadAnims <animation inclusion file>||Hud head animation descriptions.|
|-[animations] – contains animation group files (*.anim)
| | |
| | |-[base] – contains human/base animation set files (*.mdx/*.aninc)
| |-[scripts] – contains animation scripts
| |-[allied] – contains Allied character definitions
| |-[axis] – contains Axis character definitions
|-[allied] – contains subdirectories with Allied character media
|-[axis] – contains subdirectories with Axis character media
A subdirectory with themed and teamed character media will use a structure similar to the following example:
|-[acc] – accessory models and skin textures
| |-backpack.md3 – backpack model
| |-backpack.tga – backpack texture
| |-helmet.md3 – helmet model
| |-helmet.tga – helmet texture
|-body.mdm – the body mesh
|-body.tga – the body (torso) texture
|-legs.tga – the body (legs) texture
|-body_default.skin – the “default” body skin
|-head.md3 – the head model
|-head.tga – the head texture
|-head_default.skin – the “default” head skin
Note: only allied and axis as types of players were taken into consideration here. In case another party is added, like civilians, it can slot in next to the Allied and Axis directories.
Through working with this model system, we’ve setup a set of procedures that makes getting the models into the game relatively fast and painless. First of all we created a MAX file that contains the base biped with a bunch of weighted dummy triangles around it to ensure every single bone that will ever be used in game is actually referenced. This MAX file has only 1 frame, frame 0, and this frame gets exported into a SKL file that is used to create the base MDX.
Next to that, there is a set of MAX files that contain our animations. These MAX files use the same dummy mesh as the base frame. Because MDX files in a set all must have exactly the same bone setup, this method ensures that that will be the case. These MAX files are then exported to SKL files ready for converting into MDX.
The last set of MAX files is the meshes. They are single frame and the biped setup is the animation frame used to create the collapse map for LOD.
To convert everything into MDM and MDX, a batch file and a file tree that mirrors the layout of the one used by the game are combined to make it all happen with one single run of the batch file.
The picture at the right shows the basic layout of the tree and a here is a little section from the batch file, that sits next to the BuildMDS executable in the ‘Player Models Exporting’ directory:
echo Generating Base MDX
echo Generating Human/Base animations
echo Generating Temperate/Allied meshes
Due to the width of this document the lines above might wrapped, but copying and pasting it into notepad will show the proper formatting. Just in case it doesn’t, every line starting with ‘buildmds’ takes two lines in this document but only one line in the batch file. It has the skl file listed on its line, the conversion type (-mdm or -mdx) and a destination directory.
The base MDX file sits in source/animations/human/base and all ski files should reference this file. By default, BuildMDS converts files only if there is a need for converting, which is the case if the source SKL is newer than the destination MDM or MDX. This check also applies to the base MDX. If it’s newer than the MDM or MDX that is dependant on it, then this will get re-converted.
Multi Player and Single Player won’t have to duplicate their meshes and animation data anymore. They’ll use the same meshes and animation data will be referenced through characters and animation groups.
Because the animation logic behind human players will be the same, you should only ever need one single animation script for the whole human set. Custom animations can be played by combining the script with a different animation group.