Skeleton

From Valve Developer Community
Jump to navigation Jump to search
Wikipedia - Letter.png
This article has not been added to any content Wikipedia icon categories. Please help out by Wikipedia icon adding categories.

A model's Skeleton is a hierarchy of one or more bones. It is analogous the real skeletons inside of humans and animals, providing models with a framework for posing, animation, and physics interactions.

Model skeletons enable artists and animators to design and animate characters in a way that is both familiar and realistic. In the same way that our skin is attached to our bones and bends & stretches as our bones move, the vertex geometry of a character is attached to its skeleton and bends & stretches as its bones move. The process of associating each vertex to one or more bones in the skeleton is known as skinning, which controls how the model's visible surfaces deform when its bones are moved.

Sometimes, a model's skeleton is referred to and/or acts as its rig, blurring the line between the actual skeleton and a separate animation rig that might exist on top of it.

Hierarchy Basics

In Source, every model has a hidden, implicit root bone, which positions and orients the model relative to its Model Entity. This special bone is created by studiomdl during MDL compilation and serves as the boundary between the model's internal structure and its location in the world. The model is not aware of its implicit root bone; ergo, this bone cannot be animated by a model's $sequences.

All other bone chains - those defined in the model's SMD/DMX file(s) or with $definebone in its QC - become children of the implicit root bone. These user-defined bones constitute the model's actual skeleton. Since a model cannot animate its implicit root bone, it is common practice to create a user-defined "root' bone in the character's skeleton, which actually becomes an immediate child of the implicit root bone. In typical Valve biped skeletons, this would be ValveBiped.Bip01_Pelvis. If the model's SMD/DMX contains no bones, then the output MDL's skeleton will only have the implicit root bone. This is often the case for static props, such as boxes or tables.

Bone count limit

Each Source engine branch and game specifies a limit on the number of bones that a model can have. This limit includes the implicit root bone, effectively limiting the number of user-defined bones to MAXSTUDIOBONES - 1.

Most games built upon this engine branch defer to this limit, including Half-Life 2, Counter-Strike: Source, Portal, and Team Fortress 2
Garry's Mod is based on Source 2013, but has several key modifications including overall increased engine limits
Todo: Determine the limit for other notable games, including Alien Swarm, Portal 2

Skeleton Articulation

Articulation is the process by which is a skeleton's bones move, pulling the model's skinned meshes along with them.

Rigid skeletons

Models which only possess the implicit root bone are said to be rigid "skeletons". There is only one bone; therefore, the entire model follows that single bone. This is most appropriate for rigid objects that are constructed of solid materials, like wood or metal.

Jointed skeletons

The typical parent-child bone pair in a skeleton forms a joint that can bend. For example, consider a human elbow. There is no "elbow" bone; rather, the "elbow" is the joint that exists between the humerus bone and the ulna & radius bones. Most characters have skeletons that are based on this ball-and-socket relationship between child-parent bone pairs. The bending (and sometimes stretching) of joints provides the fundamental backbone (no pun intended) of character animation and ragdoll physics.

Jointed skeletons can be as simple as the handle on a door, as complex as an entire human body, or somewhere in between. Additionally, since skeletal animation is by far the cheapest of all deformation techniques, it is commonplace to approximate complex motion, such as that of cloth, with specially-designed skeletons instead of simulating prohibitively expensive accurate physics. The Half-Life 2 mattress ragdoll is a prime example of this.


Todo: Clean up everything below this line

Movement hierarchy

Source's movement hierarchy system is used to attach different entities to one another, but the same logic can be used to understand how Skeletal bones are linked together.

By default, each object constrained in a movement hierarchy inherits its position and orientation from the position and orientation of its parent's attachment point. The $attachment point is part of the parent's geometry, but has its own offset properties, i.e. its own position and orientation relative to its Origin's position and orientation. When the child-object attaches, its Origin and Angles are aligned to the position and orientation defined by the $attachment point.

If the parent-object moves the attached child-object moves (parallel) with it. If the parent object rotates (about its own origin), the child-object will orbit the parent's origin.

  • WorldOrigin [worldspawn]
    • (Vehicle) WorldPosition : all entities' position and orientation are relative to WorldOrigin.
      • (Seat) Parent Entity Attachment point is offset from its WorldPosition
        • (NPC) Child Entity Model offset [$origin]
          • (Pelvis) Skeleton Root_bone_end offset
            • (Chest) Joint_bone1_end offset
              • (Torch) Attachment point offset
                • (Torchbeam) Sprite
              • (Arm) Joint_bone2_end offset
                • (Sleeve) Mesh vertex offset
                • (Muscle) Physbox vertex offset
                • (Hand) Attachment point offset
                  • (Shotgun) Sub-model Root_bone_end offset
                    • (Muzzleflash) Sprite


  • Entity : the entity's position and orientation in the World are "inherited" by the
    • Model Origin : is the reference point for ... offset with $origin ...?
      • rootbone : is any bone "parented" (directly) to the Origin. Usually only one root bone per model... offset with $root
        • bone_joint : where this bone connects to its parentbone
        • bone_name (See also SMD#nodes)
        • bone_attach : Has position and orientation properties, = the "origin" for this bone's children :
          • mesh : Render model vertices are enveloped to one or (weightmapped to) more than one bone.
          • physbox : Collision model vertices are enveloped to one bone.
          • attachment : Hooks where another entity's model (e.g. w_weapons) may attach to this model.
          • childbone : the next named bone in the skeleton hierarchy
  • nb sub-models include "rigged" weapons (w_weapon, $bonemerge) and movement hierarchy children ...
  • LOD skeleton : bonetreecollapse, replacebone,
  • IK chains

Joints, bones & attachments

Bones & Joints
If we think of each named bone as having a ball-end and a socket-end, the ball-end of the bone is called its joint - and is always connected to this bone's parentbone. When this bone moves, it pivots about its joint, so the joint could also be called the bone's local Origin. The socket-end of the bone, which orbits at a fixed distance around the joint, seems to be called the bone. Any childbones, attachments, and/or vertex envelopes "parented" to this bone use the bone (rather than the joint) location and orientation as their origin position. Note that a childbone is "parented" to a parentbone, not a joint.
Bone_names
Joints are referred to by their bone_name, not their parentbone_name; e.g. ankle = foot_bone, knee = shin_bone, etc. Sometimes bones are named after the joint, e.g. foot = ankle_bone, shin = knee_bone. However this can cause confusion: something attached to the knee_bone will be offset from the ankle joint rather than the knee joint.
Difference between Attachments and Joints
A bone is linked to its parentbone via a joint. The joint properties (angles etc.) are defined by the bone, not the parent; the child attaches itself to the parent. By contrast, an attachment point is part of the parent's skeleton, and when it connects to an object (e.g. a weapon), the attachment point defines the (rigid) joint properties (angles, etc.); the parent attaches to the child. An attachment point should really be called a constraint. This is why w_weapons are rigged with $bonemerge rather than attachment points ... ?

A skeleton is comprised of "chains" of bones, joints, effectors, and a root. Some good things to know:

  • Root: Where your skeleton starts. Moving the root moves the skeleton as one unit. Apex of the skeletal movement hierarchy.
  • Joint: Joins two bones, and is where bending and IK occur.
  • Bone: This is the principle object in the skeleton and is what the mesh will be attached to.
  • Effector: These move a bone system around. The end point of a bone chain.

Root

Root or rootbone is a special kind of bone. It is parented to the EntityOrigin, and therefore aligns all of the skelton's geometry to the Entity's World position and orientation.

A "default" skeleton has nothing but a rootbone, with zero length, all vertices enveloped to it are aligned to the Origin.

// e.g.: a "default" SMD skeleton :
version 1
nodes
  0 "root_bone" -1
end
skeleton
time 0
  0 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000   
end
  • To offset part or all of the model from the Entity's position on the map, see $origin and $root.

Rigging

  • Todo: clarify:
    rigged, rigging, rig ... if "rig" = the whole skinned, enveloped, jointed, etc. model, ready and waiting for animations to be applied, then "rigged" means animation-ready or complete, and "rigging" is the process of attaching & tweaking the relationships (uvmap, weightmap, jointconstraints, etc.) between all the elements. On the other hand, "rigging" might refer specifically to configuring all the bone properties for a given skeleton - jointconstraints, attachments, IKrules, etc. - so "rig" = a NotRigid skeleton, and "rigged" still means "animation-ready".
  • Todo: clarify:
    deformer = a bone, deforms the mesh, so the "deformation" would be applied to the mesh & skin, ... however if deformation = a bone movement, either animation or (ragdoll) vphysics applied to the bone, then bone = "deformee" !
  • $weightlist defines the skeleton's bone weights, used for "cross-fading" when blend animations are combined.
  • $jointconstraints are local vphysics forces used only for ragdolls. They have no effect in sequence animation.
  • $ikchains are


Surface geometry

Todo: probably move this section out to its own page Surface geometry or Vertex geometry ?

An object's surface geometry (also known as its envelope or body or hull or skin or mesh or vertex geometry or model geometry) defines the exact shape and size of the spatial volumes that are each completely enclosed by a continuous surface.

  • Two main types of surface geometry with distinctive properties:
    • Rendering geometry ... at the end of the day only the Skin texels are rendered, but the skin hangs on a 3D mesh which is deformed by skeletal animation.
    • Collision geometry ... is invisible in game but defines this object's Solidity to other objects.
      • bbox (bounding box, surrounding bounds, == cbox?, collision hull, movement hull, player hull, npc hull)
      • hbox (hit box) used for bullet hit tests (and local damage modifiers ... crowbar, crossbow, phys-object hit locations?)
      • physbox (physmodel, collisionmodel, ragdoll) is used only for vphysics reactions, including ragdoll motion/animation.

In Source, Surface Geometry data is always defined as a system of Vertices in 3D space.

Todo: differences between Brush, Model and Sprite.
  • Vertex Location data : (X Y Z) coordintates relative to its parent Origin within the movement hierarchy.
  • Vertex Orientation data : (vertex normalvector) defines its Orientation relative to its adjacent vertices ? ... see Vertex smoothing.
  • Vertex Skin data (UV) coordinates and name of skin.vmt ... see UV map (only used on Rendered surfaces)
  • Vertex Weight data : (float value defaulting to 1.0) ... : see Weightmap (only used on Deformable Rendered surfaces)
  • Todo:  a rectangular box is defined by a pair of ("min" and "max") coordinates relative to the origin which represent opposing corners; the other 6 vertex coords are deduced as necessary. A non-rectangular polygonal mesh is a network of triangles connected by their vertices. Because GPU pipelines are optimised to process triangles, rectangular (brush) surfaces are split into two triangles for Rendering.


Non-surface geometry

  • Silhouette geometry (outline or profile)... non-collision raytrace tests; i.e. Shadows & LOS. Usually derived automatically from Render model at runtime, but can use other geometry for greater efficiency. ($shadowlod, etc.?) (See also sprite)
  • Skeletal geometry ... kinematic movement hierarchies ... attachment is offset from parent's origin & angles. (Rigid / NotRigid)
  • Spatial geometry ... Some Entity Properties use non-vertex geometry:

Vertex Editors