body
and skin
groups in GoldSource models.
$body studio "<reference_smd>"
The above sets the main reference mesh. This mesh is always rendered.$bodygroup <groupname>
{
studio "<part1_smd>"
studio "<part2_smd>"
blank // optional
}
The above sets a body group. Only one of the meshes in the group is rendered at any one time. If you put blank
as one of the lines in the group you can choose to render nothing for the group.$bodygroup <groupname>
{
studio "<onlypart_smd>"
}
This group above, with only a single member, will always be rendered. This is often used when your reference mesh is too big and need to be split up into several meshes (i.e. smd files), so you reference each part in its own single-item bodygroup.body
valuebody
keyvalue first by fitting them into lists that are powers of 2 long e.g. 2,4,8,16... and then bit-shifting the subsequent groups the appropriate places to the left.body
):
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
Here's the $body
and $bodygroup
of models/hgrunt_opfor.mdl
(from Opposing Force). We will comment our enumeration of the values in decimal and binary.
$body studio "grunt_fatigues_reference"
$bodygroup heads
{ // DEC BIN
studio "grunt_head_mask_reference" // 0 000
studio "grunt_head_commander_reference" // 1 001
studio "grunt_head_shotgun_reference" // 2 010
studio "grunt_head_saw_wht_reference" // 3 011
studio "grunt_head_saw_blk_reference" // 4 100
studio "grunt_head_MP_reference" // 5 101
studio "grunt_head_major_reference" // 6 110
studio "grunt_head_commander_blk_reference" // 7 111
}
$bodygroup torso
{
studio "grunt_reg_torso_reference" // 0 000
studio "grunt_saw_gunner_torso_reference" // 1 001
studio "grunt_noback_torso_reference" // 2 010
studio "grunt_shotgun_torso_reference" // 3 011
}
$bodygroup weapons
{
studio "MP5_reference" // 0 000
studio "shotgun_reference" // 1 001
studio "SAW_reference" // 2 010
blank // 3 011
}
As you can see, the heads group takes up three binary places to enumerate everything. The other 2 groups on the other hand only goes up to 2 binary places. This means the heads group occupy 3 bits, and torso and weapons groups take up 2 bits. Let's map that onto our binary representation:
0000 0000 0000 0000 0000 0000 0CCB BAAA
The first group (A) goes to the right-most place on the binary number representation. The second group (B) is to the left of (A) shifted left by three places (A's width), and the third (C) by 5 (width of A+B). The other places are unused, so we fill it with zeroes.// CCB BAAA
0000 0000 0000 0000 0000 0000 0001 0110
And that translates into decimal as 22. We can then take this value for body
in entities like cycler
or monster_generic
.
As another example, here's the $body
and $bodygroup
part of a QC file for a complex model that had to have its meshes split into 4 smd files:
$body studio "space_shuttle.1_p1"
$bodygroup pt2 {
studio "space_shuttle.1_p2"
}
$bodygroup pt3 {
studio "space_shuttle.1_p3"
}
$bodygroup pt4 {
studio "space_shuttle.1_p4"
}
None of the groups have more than one entry, and this is reflected in HLAM where there's only 1 selection for all groups, and the resulting body
value is always 0:
$texturegroup <groupname>
{
{ "tex1_base.bmp" "tex2_base.bmp" ⋯ "texN_base.bmp" }
{ "tex1_alt1.bmp" "tex2_alt1.bmp" ⋯ "texN_alt1.bmp" }
{ "tex1_alt2.bmp" "tex2_alt2.bmp" ⋯ "texN_alt2.bmp" }
⋮ ⋮ ⋱ ⋮
{ "tex1_altN.bmp" "tex2_altN.bmp" ⋯ "texN_altN.bmp" }
}
In the first row, you list all the textures from the base model (i.e. the textures you sculpt the models with) that you want to have different skins for. In the subsequent rows, you list the alternative textures to replace the base textures for that selection, according to column position. In the above example, selecting the third row means "tex1_base.bmp" is replaced with "tex1_alt2.bmp", "tex2_base.bmp" with "tex2_alt2.bmp", and so on...
This works well for one dimension of skin changes e.g. changing the skin colour of NPCs or the paint colour of cars. If you want to add a second dimension e.g. clean vs blood-soaked vs torn clothing, or different decal patterns on cars, you just have a second $texturegroup
, right? $texturegroup
s.$texturegroup
. Combining 2 sets is just a matter of creating unique pairs from the elements of the 2 sets. An example of set A of size 2 and set B of size 3 would be:
A = ⎡X⎤
⎣Y⎦
B = [ 1 2 3]
A×B = ⎡X1 X2 X3⎤
⎣Y1 Y2 Y3⎦
Then we roll the elements of A×B into a list, and expand the elements to their constituent texture(s). The following is an example of a model with 2 head and 3 fatigue variations:
// elements of A
$texturegroup headvars {
{ "helmet.BMP" "beret_black.BMP" } // X
{ "helmet2.BMP" "beret_red.BMP" } // Y
}
// elements of B
$texturegroup fatigues {
{ "fatigues.BMP" "boots.BMP" } // 1
{ "fatiguesDIRT1.BMP" "bootsDIRT1.BMP" } // 2
{ "fatiguesDIRT2.BMP" "bootsDIRT2.BMP" } // 3
}
// combination of A and B
$texturegroup variations
{
// [--------ITEMS FROM A---------] [-----------ITEMS FROM B-----------]
{ "helmet.BMP" "beret_black.BMP" "fatigues.BMP" "boots.BMP" } // X1
{ "helmet2.BMP" "beret_red.BMP" "fatigues.BMP" "boots.BMP" } // Y1
{ "helmet.BMP" "beret_black.BMP" "fatiguesDIRT1.BMP" "bootsDIRT1.BMP" } // X2
{ "helmet2.BMP" "beret_red.BMP" "fatiguesDIRT1.BMP" "bootsDIRT1.BMP" } // Y2
{ "helmet.BMP" "beret_black.BMP" "fatiguesDIRT2.BMP" "bootsDIRT2.BMP" } // X3
{ "helmet2.BMP" "beret_red.BMP" "fatiguesDIRT2.BMP" "bootsDIRT2.BMP" } // Y3
}
body
keyvalue.skin
.You must log in to post a comment. You can login or register a new account.
body
property packing. 🙂