Thorgrim
Knight at Arms
Face Morphs and Vertex Animation
In Mount and Blade, there are three different types of meshes that are used in the game. The first type are static meshes. These are used for items, scene props etc. The second type are the animated meshes which are bound to a skeleton, such as armour, horses etc. Both of these types have been covered in a number of tutorials, and are fairly well explained, however the third type: vertex animation / morph targets is something that is perhaps unknown to most people except myself (and I guess Armagan too ). This type of mesh is currently used for 4 main things: Hands (open and closed states), Arrows (different states depending on how many arrows you have left), Animated map icons for parties, and perhaps most importantly, this format is used for defining the different face morphs that a player or NPC may uses to define the look of their face. Unlike skeletal animation, vertex animation defines the location of each vertex of the mesh, for each frame.
In this tutorial we will cover how to create a new face, with your own custom morphs that will be available to a new race, which will be selectable by the player, as well assignable to NPCs. To simplify the tutorial we will start with the human face, and modify some of the mesh and some of the morph targets. Although we only cover faces in the tutorial, all other meshes that use vertex animation can be created in almost exactly the same way.
Here is an example of what we can do with vertex animation:
This one shows what you can do by adding new head morphs, which is covered in this tutorial: Download (DivX required)
This one is an example of a custom map icon, created using the same process: Download (DivX required)
Before starting this tutorial, you will need 3ds max, or another program capable of exporting VTA files (Half-life vertex animation files)
I assume you have at least a little knowledge of both BRFEdit, and your modelling package of choice.
If you are using 3ds max, you will need the following plugins/scripts:
MAX6/7 SMD Exporter Place both plugins in your plugins directory.
MD3 importing script Place this in your 3ds max scripts / startup directory
Currently you must use VTA format, however BRFEdit may allow MD3 importing, or individual frame importing in the future.
1. Getting your mesh ready
Firstly, we will get the human face into 3ds Max. If you wish to use a face of your own, all you need to do is convert the mesh to an editable mesh (Right click > Convert to), then you can go to part 2, however I advise you to import the default head for size comparison anyway.
Open up BRFEdit, select Open, then choose meshes_face_gen.brf. Select the male_head mesh then click export, and save it as an MD3 file.
Now open up 3ds Max, go and run the MD3 importer script:
Select the MD3 file you exported, and import it.
2. Making some morphs
You should now see half of the head in the viewport. Note that in M&B, heads are mirrored: both the mesh and the UV coordinates. So keep this in mind if you are creating your own head mesh.
Another step you will need to perform when creating your own head mesh is setting up the reference frames. Ignore this step if you are just modifying the default head.
In max, it will interpolate between frames if you do not have keys for every vertex defined for each frame. To add keys for each vertex, you can do the following (let me know if there is a better way to do this)
Select all the vertices
Go to frame 1
Right click the move button (next to rotate, scale etc) to open the translate window
Change Absolute World translation slightly (eg if X is 0, make it 1)
Then change the value you just modified back to what it was previously.
Now you have 2 frames (frame 0 and frame 1) that are both reference poses, with keys for every vertex in your mesh. Clone one of these for each new pose you add, and you should not get the problem you were having.
We will now add some morph targets. To do this we will copy one of the "reference" frames over an existing morph, and then modify it into a morph of our own. Although it is possible to add morphs without replacing existing ones, the in game face editing window does not allow more than the default heads number of morphs. So we will just replace some of them for now.
Copy the first or last frame over a morph target you want to replace, by holding the shift key and dragging the first or last grey block in the timeline over the target frame.
Then scroll to this frame, turn on "Auto Key" mode, and modify the mesh in vertex mode. In this case I have made some pointy ears.
Now, this frame will be used as the maximum morph for this attribute. The minimum morph will be a weighting of the opposite of this (ie if you move a vertex up, the minimum will move it down a certain amount), so keep this in mind.
You can modify as many morphs as you like, and adjust the mesh, adjust the UV co-ordinates etc. I have also added some horns as another morph target:
To do this, I simply attached the horns to the mesh, then added key-frames the frame before, and the frame after to hide the horns just under the skull. In this way the horns will appear to grow out from the head as the user adjusts the slider.
Once you are finished select file > export, and export as a VTA file. If you have created your own head, ensure the first and last frames of your morphs are the same reference pose.
You will also need to export the reference pose in OBJ format: simply scroll to the first or last frame, and export it.
3. Getting it back into a BRF
Open up BRFEdit, and import the obj file containing the heads reference pose. On the import dialog, select a MD3 (50x) for the scale. Add any materials etc for your mesh as normal, then import the VTA file whilst the mesh is selected. On the VTA import dialog you will see a combo box containing a number of templates for importing vertex animations. For now we will use default head, which imports the first and last reference poses, and the 18 morphs. If you later want to try editing map icons, quivers, hands etc, change to the appropriate template. If you want to, you can also create your own templates, by modifying one of the existing templates located in your editorData directory, and saving it as a new template. However even if you create a custom face with fewer morph targets than the default face, you should still be able to use the default face template.
You should now be able to scroll through all your morphs. Little tip for viewing heads: you may find the "flip" and "rotation lock" buttons at the bottom of the screen handy.
Now save the BRF to your mod directory, ensuring you have placed your textures etc in the right locations.
4. Using your new face!
In this step I assume you know how to compile the python scripts, if not, go find a tutorial on it. Note that I wrote this step without checking over it, so let me know if I forgot something.
We will now add a new race that will make use of this new face. To do this, we must modify module_skins.py. Open the file up, and add some keys for your new race. This is the list of keyframes to use for our list of morphs in the character creation screen. If you have a custom face, make sure ALL entries listed here are included in your BRF, or the game will probably crash.
Here are mine:
demon_face_keys = [
(10,0,-0.8,0.6, "chin"),
(20,0,-0.4,1.0, "jaw"),
(30,0,-0.1,0.9, "mouth width"),
(40,0, 1.1, -0.3, "mouth-nose dist"),
(50,0, -0.5,1.0, "cheeks"),
(60,0,-0.5,1.0, "nose height"),
(70,0,-0.5,1.1, "nose width"),
(80,0,1.5,-0.3, "nose size"),
(90,0, 0.0,1.1, "nose bridge"),
(100,0,1.0,-0.5, "cheek bone"),
(110,0,1.0,0.0, "eye to eye dist"),
(120,0,-0.2,1.0, "eye shape"),
(130,0,-0.1,1.6, "eye depth"),
(140,0,-0.2,1.0, "eyelids"),
(150,0,-0.6,1.5, "eye width"),
(160,0,1.0,-0.2, "eyebrow position"),
(170,0,0,1.0, "horns"),
(180,0,0,1.0, "ears"),
(190,0,0.0,1.0, "post-edit"),
]
In this case, we have copied the male face keys, and modified the second last, and third last, that are our two new morphs.
The highlighted numbers represent the minimum and maximum morph. A negative value will moph in the opposite direction to the morph targets we added, so the ears would shrivel up, and the horns would start sticking out of the other side of the head! We probably don't want this, so we have made the minimum 0, and the maximum 1.0.
We have also changed the tags for these attributes to "horns" and "ears".
Now add the race itself, into the skins list:
(
"man", 0,
"man_body", "man_calf_l", "m_handL",
"demon head", demon_face_keys,
["man_hair_s","man_hair_m","man_hair_n","man_hair_o","man_hair_u","man_hair_p","man_hair_r","man_hair_q","man_hair_t"], #man_hair_meshes
["beard_a","beard_e","beard_d","beard_k","beard_l","beard_m","beard_n","beard_i","beard_j","beard_o","beard_p","beard_h","beard_g","beard_c","beard_f","beard_b",], #beard meshes
["hair_blonde", "hair_red", "hair_brunette", "hair_black", "hair_white"], #hair textures
["beard_blonde","beard_red","beard_brunette","beard_black","beard_white"], #beard_materials
[("demon_face_1",0xffebf0f0,["hair_blonde", "hair_red"]),
("demon_face_2",0xfff0f0f0,["hair_black","hair_brunette","hair_red"]),
], #demon_face_textures,
[(voice_die,"snd_man_die"),(voice_hit,"snd_man_hit"),(voice_grunt,"snd_man_grunt"),(voice_grunt_long,"snd_man_grunt_long"),(voice_yell,"snd_man_yell"),(voice_warcry,"snd_man_warcry"),(voice_victory,"snd_man_victory")], #voice sounds
),
In this case I have just copied the man skin entry, and changed it a little. I will not go into the details of all the settings here. Just make sure you change the mesh for the head, and make it use the face keys you have added.
Next we will add to module_game_menus.py, so that the player can select this race.
add the following below the entry for female selection in the game_menus list:
("start_demon",[],"Demon",
[
(troop_set_type,0,3),
(assign,"$character_gender",0),
(troop_raise_attribute, "trp_player",ca_agility,1),
(troop_raise_attribute, "trp_player",ca_intelligence,1),
(jump_to_menu,"mnu_start_game_2")
]
),
The important number here is the value for troop_set_type. We can also use this value for other troops we wish to give this new face to. In our case we have used 3, however if you add more races, you must use the corresponding number, depending on the races position in the skins list.
We can also add a new class for our new race in the "start_game_2" list.
You should now be able to fire up the game and try out your new face!
In Mount and Blade, there are three different types of meshes that are used in the game. The first type are static meshes. These are used for items, scene props etc. The second type are the animated meshes which are bound to a skeleton, such as armour, horses etc. Both of these types have been covered in a number of tutorials, and are fairly well explained, however the third type: vertex animation / morph targets is something that is perhaps unknown to most people except myself (and I guess Armagan too ). This type of mesh is currently used for 4 main things: Hands (open and closed states), Arrows (different states depending on how many arrows you have left), Animated map icons for parties, and perhaps most importantly, this format is used for defining the different face morphs that a player or NPC may uses to define the look of their face. Unlike skeletal animation, vertex animation defines the location of each vertex of the mesh, for each frame.
In this tutorial we will cover how to create a new face, with your own custom morphs that will be available to a new race, which will be selectable by the player, as well assignable to NPCs. To simplify the tutorial we will start with the human face, and modify some of the mesh and some of the morph targets. Although we only cover faces in the tutorial, all other meshes that use vertex animation can be created in almost exactly the same way.
Here is an example of what we can do with vertex animation:
This one shows what you can do by adding new head morphs, which is covered in this tutorial: Download (DivX required)
This one is an example of a custom map icon, created using the same process: Download (DivX required)
Before starting this tutorial, you will need 3ds max, or another program capable of exporting VTA files (Half-life vertex animation files)
I assume you have at least a little knowledge of both BRFEdit, and your modelling package of choice.
If you are using 3ds max, you will need the following plugins/scripts:
MAX6/7 SMD Exporter Place both plugins in your plugins directory.
MD3 importing script Place this in your 3ds max scripts / startup directory
Currently you must use VTA format, however BRFEdit may allow MD3 importing, or individual frame importing in the future.
1. Getting your mesh ready
Firstly, we will get the human face into 3ds Max. If you wish to use a face of your own, all you need to do is convert the mesh to an editable mesh (Right click > Convert to), then you can go to part 2, however I advise you to import the default head for size comparison anyway.
Open up BRFEdit, select Open, then choose meshes_face_gen.brf. Select the male_head mesh then click export, and save it as an MD3 file.
Now open up 3ds Max, go and run the MD3 importer script:
Select the MD3 file you exported, and import it.
2. Making some morphs
You should now see half of the head in the viewport. Note that in M&B, heads are mirrored: both the mesh and the UV coordinates. So keep this in mind if you are creating your own head mesh.
Another step you will need to perform when creating your own head mesh is setting up the reference frames. Ignore this step if you are just modifying the default head.
In max, it will interpolate between frames if you do not have keys for every vertex defined for each frame. To add keys for each vertex, you can do the following (let me know if there is a better way to do this)
Select all the vertices
Go to frame 1
Right click the move button (next to rotate, scale etc) to open the translate window
Change Absolute World translation slightly (eg if X is 0, make it 1)
Then change the value you just modified back to what it was previously.
Now you have 2 frames (frame 0 and frame 1) that are both reference poses, with keys for every vertex in your mesh. Clone one of these for each new pose you add, and you should not get the problem you were having.
We will now add some morph targets. To do this we will copy one of the "reference" frames over an existing morph, and then modify it into a morph of our own. Although it is possible to add morphs without replacing existing ones, the in game face editing window does not allow more than the default heads number of morphs. So we will just replace some of them for now.
Copy the first or last frame over a morph target you want to replace, by holding the shift key and dragging the first or last grey block in the timeline over the target frame.
Then scroll to this frame, turn on "Auto Key" mode, and modify the mesh in vertex mode. In this case I have made some pointy ears.
Now, this frame will be used as the maximum morph for this attribute. The minimum morph will be a weighting of the opposite of this (ie if you move a vertex up, the minimum will move it down a certain amount), so keep this in mind.
You can modify as many morphs as you like, and adjust the mesh, adjust the UV co-ordinates etc. I have also added some horns as another morph target:
To do this, I simply attached the horns to the mesh, then added key-frames the frame before, and the frame after to hide the horns just under the skull. In this way the horns will appear to grow out from the head as the user adjusts the slider.
Once you are finished select file > export, and export as a VTA file. If you have created your own head, ensure the first and last frames of your morphs are the same reference pose.
You will also need to export the reference pose in OBJ format: simply scroll to the first or last frame, and export it.
3. Getting it back into a BRF
Open up BRFEdit, and import the obj file containing the heads reference pose. On the import dialog, select a MD3 (50x) for the scale. Add any materials etc for your mesh as normal, then import the VTA file whilst the mesh is selected. On the VTA import dialog you will see a combo box containing a number of templates for importing vertex animations. For now we will use default head, which imports the first and last reference poses, and the 18 morphs. If you later want to try editing map icons, quivers, hands etc, change to the appropriate template. If you want to, you can also create your own templates, by modifying one of the existing templates located in your editorData directory, and saving it as a new template. However even if you create a custom face with fewer morph targets than the default face, you should still be able to use the default face template.
You should now be able to scroll through all your morphs. Little tip for viewing heads: you may find the "flip" and "rotation lock" buttons at the bottom of the screen handy.
Now save the BRF to your mod directory, ensuring you have placed your textures etc in the right locations.
4. Using your new face!
In this step I assume you know how to compile the python scripts, if not, go find a tutorial on it. Note that I wrote this step without checking over it, so let me know if I forgot something.
We will now add a new race that will make use of this new face. To do this, we must modify module_skins.py. Open the file up, and add some keys for your new race. This is the list of keyframes to use for our list of morphs in the character creation screen. If you have a custom face, make sure ALL entries listed here are included in your BRF, or the game will probably crash.
Here are mine:
demon_face_keys = [
(10,0,-0.8,0.6, "chin"),
(20,0,-0.4,1.0, "jaw"),
(30,0,-0.1,0.9, "mouth width"),
(40,0, 1.1, -0.3, "mouth-nose dist"),
(50,0, -0.5,1.0, "cheeks"),
(60,0,-0.5,1.0, "nose height"),
(70,0,-0.5,1.1, "nose width"),
(80,0,1.5,-0.3, "nose size"),
(90,0, 0.0,1.1, "nose bridge"),
(100,0,1.0,-0.5, "cheek bone"),
(110,0,1.0,0.0, "eye to eye dist"),
(120,0,-0.2,1.0, "eye shape"),
(130,0,-0.1,1.6, "eye depth"),
(140,0,-0.2,1.0, "eyelids"),
(150,0,-0.6,1.5, "eye width"),
(160,0,1.0,-0.2, "eyebrow position"),
(170,0,0,1.0, "horns"),
(180,0,0,1.0, "ears"),
(190,0,0.0,1.0, "post-edit"),
]
In this case, we have copied the male face keys, and modified the second last, and third last, that are our two new morphs.
The highlighted numbers represent the minimum and maximum morph. A negative value will moph in the opposite direction to the morph targets we added, so the ears would shrivel up, and the horns would start sticking out of the other side of the head! We probably don't want this, so we have made the minimum 0, and the maximum 1.0.
We have also changed the tags for these attributes to "horns" and "ears".
Now add the race itself, into the skins list:
(
"man", 0,
"man_body", "man_calf_l", "m_handL",
"demon head", demon_face_keys,
["man_hair_s","man_hair_m","man_hair_n","man_hair_o","man_hair_u","man_hair_p","man_hair_r","man_hair_q","man_hair_t"], #man_hair_meshes
["beard_a","beard_e","beard_d","beard_k","beard_l","beard_m","beard_n","beard_i","beard_j","beard_o","beard_p","beard_h","beard_g","beard_c","beard_f","beard_b",], #beard meshes
["hair_blonde", "hair_red", "hair_brunette", "hair_black", "hair_white"], #hair textures
["beard_blonde","beard_red","beard_brunette","beard_black","beard_white"], #beard_materials
[("demon_face_1",0xffebf0f0,["hair_blonde", "hair_red"]),
("demon_face_2",0xfff0f0f0,["hair_black","hair_brunette","hair_red"]),
], #demon_face_textures,
[(voice_die,"snd_man_die"),(voice_hit,"snd_man_hit"),(voice_grunt,"snd_man_grunt"),(voice_grunt_long,"snd_man_grunt_long"),(voice_yell,"snd_man_yell"),(voice_warcry,"snd_man_warcry"),(voice_victory,"snd_man_victory")], #voice sounds
),
In this case I have just copied the man skin entry, and changed it a little. I will not go into the details of all the settings here. Just make sure you change the mesh for the head, and make it use the face keys you have added.
Next we will add to module_game_menus.py, so that the player can select this race.
add the following below the entry for female selection in the game_menus list:
("start_demon",[],"Demon",
[
(troop_set_type,0,3),
(assign,"$character_gender",0),
(troop_raise_attribute, "trp_player",ca_agility,1),
(troop_raise_attribute, "trp_player",ca_intelligence,1),
(jump_to_menu,"mnu_start_game_2")
]
),
The important number here is the value for troop_set_type. We can also use this value for other troops we wish to give this new face to. In our case we have used 3, however if you add more races, you must use the corresponding number, depending on the races position in the skins list.
We can also add a new class for our new race in the "start_game_2" list.
You should now be able to fire up the game and try out your new face!