-
Notifications
You must be signed in to change notification settings - Fork 126
[OUTDATED] SKM, skeletal models
SKM is a skeletal model format designed for QFusion engine integration. A SKM model is composed of two archives, the model.skm and the model.skp. The .skm archive contains the model information and bones references, while the .skp archive contains the frames bones poses.
SKM models can be composed of a maximun of 32 different meshes, with each mesh being able of using a different texture name. When using QFusion, it's also possible to create .skin files, matching Quake 3 skinfile format, for them, so the SKM models are capable of using custom textures on all their meshes.
The SKM model, or the .skp file if you prefer, can contain up to a maximum of 65536 frames, each frame containing up to a maximum of 256 bone poses, since 256 is the maximum number of bones of SKM models. Another limit is that animation names can't be superior to 64 characters lenght. Maximum vertex count is also 65536, which means a limit of 21845 triangles. Obviously that's a triangle count absollutely not recommended to use.
The .skp files contain frame based skeleton poses, to transform the model meshes by them. This skp files can be used with different .skm files, as long as the different skm models were originally binded (or skinned, depending on your favourite modelling tool) to exactly the same skeleton. This means, a skeleton with the same bones, having the same bone names.
SKM models actually don't contain any collision information.
SKM models are compiled from SMD models using the command line program of name skmodel. The next paragraphs explain how a SMD model is converted into any generic (not player model) SKM.
SMD is the ascii model format used by Half Life and Half Life 2 as source to compile their ingame MDL models. There are 2 types of SMD models: the reference SMD and the animation SMD. The reference model contains the model meshes and skeleton information in the bind pose, each other smd model will contain a single animation. A group composed of the reference SMD + as many animation SMDs as wanted is parsed into the skmodel converter, so it compiles a unified SKM (the same process as it's done for HL/HL2 models).
Since SMD models are the official Half Life 2 source model format there are many exporters available in the net. It's important to know if the exporter you are going to use was made for HL or HL2, though. Both HL and HL2 smd exporters will work, but smd exporters created for Half Life (1) only export a single bone influence per vertex, while the exporters for Half Life 2 write several influences, and SKM is capable of making use of those multiple influences. This doesn't only help achieving a smoother animation, but also makes skin binding much easier. For more information about SMDs, and how to export them from each different 3D modelling program, just google for Half Life 2 and SMD.
skmodel is a command line tool. It requires to receive the name of a text file containing the parsing commands. It's run like this:
skmodel model_definition.txt
The model definition text file can contain the following commands:
outputdir <path> The output path. .\ for the program folder
model <name> Name of the .skm and .skin files to be generated
origin <value> <value> <value> Offset the model origin
rotatepicth <value> rotates along the z axis by the given angle
rotateyaw <value> rotates along the z axis by the given angle
rotateroll <value> rotates along the z axis by the given angle
export <name> Name of the .skp file to be generated
cleanbones Removes bones without any vertex link from the final model
scale <value> Scale up or down the model
scene <name.smd> SMD models. Once for the reference model, and repeated for each animation. There are as many 'scene' commands as SMD sources used.
Note: Since the SMD models don't contain meshes names, skmodel will generate the meshes names by their numbers in the meshes array. In short, meshes names in the skin file will be a number.
Skelmod is a QFusion mod which adds animation blending for SKM player models. Animation blending is made by the game code, and it's, in short, the code selecting into what bones it will use what animation. For this reason, it requires information of what animations to play, and what bones are part of each group inside the skeleton. This information is provided by the animation.cfg.
Skelmod accepts up to 3 animations for the player model, but we are, by now, only using 2, upper and lower, since head animation is always at frame 0. For defining what bone belongs to each group, Skelmod uses rootAnims, this is just a name as any other, and it refers to a bone which will mark the starting point in the skeleton tree for an animation to be played. As example, marking as rootanim bone a bone in the elbow of a model will make play that animation at the elbow and all the following bones in the arm (hand, fingers...). There are currently 3 animation-channels to be blended: "lower", "upper" and "head". The bones not belong to any rootanim group will be assigned to "lower" group.
This is the list of available commands to be used in the animation.cfg:
rootanim <animation-channel> <bone name> Sets the animation to the played in this bone and its childs in the skeleton tree.
sex <m or f> Sets player model sex.
fps <value> Sets model FPS ratio. Note, ratio is the same for all the animations.
rotationbone <type> <bone name> Defines that bone as a rotator. There are 2 possible types: upper and head. You can set as many bones as you want as rotators of the same type, the rotation angle will be divided by all them.
tagmask <bone name> <tag name> <offsetForward> <offsetRight> <offsetUp> Defines a tag mask for that bone, so, the bone will be used as the tag when looking for a tag of name <tag name>. This is done so different models, with different skeletons can use the same tag name.
isnumframes Makes the third value in the animation definition to be read as animation frames count, instead of the frame number where the animation finishes.
islastframe The opposite as isnumframes. It's used by default.
offset Makes the first value in the animation lines have offset in it's first value (as Q3 animation configs). By default the offset isn't applied, and every animation is defined by it's real frame value in the model.
alljumps Makes use of the different jump animations to simulate bunny hopping.
And finally, each animation is defined by 4 values in a line, meaning this by default:
<first frame> <last frame> <looping frames> <fps>
Note: looping frames don't have to be the same lenght of the animation extension.
BOTH_DEATH1 Death animation
BOTH_DEAD1 corpse on the ground
BOTH_DEATH2
BOTH_DEAD2
BOTH_DEATH3
BOTH_DEAD3
LEGS_STAND_IDLE
LEGS_WALK_FORWARD
LEGS_WALK_BACK
LEGS_WALK_LEFT
LEGS_WALK_RIGHT
LEGS_RUN_FORWARD
LEGS_RUN_BACK
LEGS_RUN_LEFT
LEGS_RUN_RIGHT
LEGS_JUMP_LEG1 (left leg)
LEGS_JUMP_LEG2
LEGS_JUMP_NEUTRAL
LEGS_LAND
LEGS_CROUCH_IDLE
LEGS_CROUCH_WALK
LEGS_SWIM_FORWARD
LEGS_SWIM_NEUTRAL
LEGS_WALLJUMP
LEGS_WALLJUMP_LEFT
LEGS_WALLJUMP_RIGHT
LEGS_WALLJUMP_BACK
LEGS_DASH
LEGS_DASH_LEFT
LEGS_DASH_RIGHT
LEGS_DASH_BACK
TORSO_HOLD_BLADE GB
TORSO_HOLD_PISTOL LG
TORSO_HOLD_LIGHTGUN PG, RG
TORSO_HOLD_HEAVYGUN RL, GL
TORSO_HOLD_AIMGUN EB
TORSO_SHOOT_BLADE weak GB
TORSO_SHOOT_PISTOL LG, strong GB
TORSO_SHOOT_LIGHTGUN PG, RG
TORSO_SHOOT_HEAVYGUN RL, GL
TORSO_SHOOT_AIMGUN EB
TORSO_WEAPON_SWITCHOUT
TORSO_WEAPON_SWITCHIN
TORSO_DROPHOLD Unused
TORSO_DROP
TORSO_SWIM
TORSO_PAIN1
TORSO_PAIN2
TORSO_PAIN3
//==============================================================
//
// Example of animation.cfg of a Warsow model
//
//==============================================================
sex f
rootanim upper "Bip01 Spine1"
rotationbone upper "Bip01 Spine1"
rotationbone upper "Bip01 Spine2"
rotationbone upper "Bip01 Neck"
rotationbone head "Bip01 Head"
tagmask "Bip01 R Hand" "tag_weapon" -2 0 0 // numbers mean offset forward, right & up
tagmask "Bip01 Spine2" "tag_flag1" 0 -6 0
tagmask "bip01 head" "tag_head" 28 0 0
// first frame, last frame, looping frames, fps
// frames 1 to 39 are reserved for the ui animation
40 58 0 24 // BOTH_DEATH1 Death animation
58 58 0 24 // BOTH_DEAD1 corpse on the ground
59 83 0 24 // BOTH_DEATH2
83 83 0 24 // BOTH_DEAD2
84 107 0 24 // BOTH_DEATH3
107 107 0 24 // BOTH_DEAD3
160 200 40 24 // LEGS_STAND_IDLE
267 291 24 24 // LEGS_WALK_FORWARD
292 316 24 24 // LEGS_WALK_BACK
317 341 24 24 // LEGS_WALK_LEFT
342 366 24 24 // LEGS_WALK_RIGHT
367 383 16 24 // LEGS_RUN_FORWARD
384 400 16 24 // LEGS_RUN_BACK
401 413 12 24 // LEGS_RUN_LEFT
414 426 12 24 // LEGS_RUN_RIGHT
465 484 0 24 // LEGS_JUMP_LEG1 (left leg)
514 533 0 24 // LEGS_JUMP_LEG2
489 509 0 24 // LEGS_JUMP_NEUTRAL
485 488 1 24 // LEGS_LAND
157 159 1 24 // LEGS_CROUCH_IDLE
242 266 24 24 // LEGS_CROUCH_WALK
427 445 18 24 // LEGS_SWIM_FORWARD
446 464 18 24 // LEGS_SWIM_NEUTRAL
605 622 0 24 // LEGS_WALLJUMP
643 658 0 24 // LEGS_WALLJUMP_LEFT
659 674 0 24 // LEGS_WALLJUMP_RIGHT
623 642 0 24 // LEGS_WALLJUMP_BACK
675 690 0 24 // LEGS_DASH
711 726 0 24 // LEGS_DASH_LEFT
727 742 0 24 // LEGS_DASH_RIGHT
695 710 0 24 // LEGS_DASH_BACK
160 162 1 24 // TORSO_HOLD_BLADE GB
160 162 1 24 // TORSO_HOLD_PISTOL LG
160 162 1 24 // TORSO_HOLD_LIGHTGUN PG, RG
160 162 1 24 // TORSO_HOLD_HEAVYGUN RL, GL
160 162 1 24 // TORSO_HOLD_AIMGUN EB
138 156 0 24 // TORSO_SHOOT_BLADE weak GB
123 137 0 24 // TORSO_SHOOT_PISTOL LG, strong GB
123 137 0 24 // TORSO_SHOOT_LIGHTGUN PG, RG
123 137 0 24 // TORSO_SHOOT_HEAVYGUN RL, GL
123 137 0 24 // TORSO_SHOOT_AIMGUN EB
108 110 1 24 // TORSO_WEAPON_SWITCHOUT
111 122 0 24 // TORSO_WEAPON_SWITCHIN
565 605 40 24 // TORSO_DROPHOLD Unused
538 554 0 24 // TORSO_DROP
427 445 18 24 // TORSO_SWIM
555 575 0 24 // TORSO_PAIN1
576 588 0 24 // TORSO_PAIN2
589 604 0 24 // TORSO_PAIN3