$ikchain
$ikchain
is a QC command available in all Source games. Source's inverse kinematics system allows characters' feet to connect accurately with uneven ground surfaces.
IK calculates the position of a middle_joint based on fixed distances from the positions of a top_joint and an end_joint. A good example is an ankle-knee-hip IK chain, where the ankle (end_joint) is positioned relative to the ground, the hip (top_joint) is locked in place, and the knee (middle_joint) is moved to a position such that the shin and thigh bones maintain their original length. Depending in the specific ikrule used, when the end_joint is moved into the needed position, the top_joint's position is assumed to be fixed, and the IK system positions the middle_joint so that the distances between the joints (ie the bone lengths) remain constant.
- ikchains are used only to apply ikrule and iklock options to an animation $sequence.
- See also $ikautoplaylock.
- Bug:HLMV will not display IK rules from sequences with
blendlayer
. [todo tested in?]
Contents
Syntax
$ikchain (name) (end_bone) [(axis) (value)] [height (units)] [pad (units)] [floor (units)] [knee (X) (Y) (Z)] [center (X) (Y) (Z)]
name
: defines the "ikchainname" for this IK chain.end_bone
: The three bones affected by this IK chain are defined by specifying the bone farthest down in the chain. The next two bones are automatically found by climbing the Bone hierarchy. An IK chain may only have three bones.- axis should be one of these X,Y,Z,XR,YR,ZR,LX,LY,LZ,LXR,LYR,LZR,LM,LQ. value is a float. Todo: what does it do?
height
:Todo: ?pad
:Todo: ?floor
:Todo: ?knee
: Doesn't actually mean it's a knee. It could be a hip, ankle, toes...Todo: confirm: This vector specifies the direction of the jointcenter
:Todo: confirm: vector for center
- QC example :
$ikchain rhand ValveBiped.Bip01_R_Hand knee 0.707 0.707 0.000 $ikchain lhand ValveBiped.Bip01_L_Hand Z 0 $ikchain rfoot ValveBiped.Bip01_R_Foot height 10 floor 5 $ikchain lfoot ValveBiped.Bip01_L_Foot pad 5 center 0 1 0
$ikchain rules
iklock
iklock (ikchainname) (lock_position) (maintain local rotation)
iklock keeps track of the position/orientation of the specific chain before the sequence is applied, then after it’s applied, does a local IK rule to move it back into position/orientation. This is used to keep the specified IK chains from moving during this sequence, which can be useful when applying pelvis or body motion to a model but you want the hands or feet to remain in place.
ikchainname
: The name of the $ikchain that the rule will apply to.lock_position
: the weight of the lock is a floating point value from 0.0 to 1.0.maintain local rotation
: the weight of rotation lock is a floating point value from 0.0 to 1.0.
ikrule
ikrule (ikchainname) [type] [options...]
ikchainname
: The name of the $ikchain that the rule will apply to.type
: See "ikrule types" for valid types.options
: See "ikrule options" for valid options.
ikrule types
footstep <slot #>
- Adds an IK rule where a subsequent body part (such as a foot) needs to be moved relative to the ground.
touch <bone name>
- Adds an IK rule where a bone needs to be positioned relative to another part of the body. This is useful when the hand needs to touch some other part of the model, such as the face, hip, other hand, etc., and that other body part may be not in the original animated location due to additional animation layers, bone controllers, or other IK rules. Tip:Specify a bonename of "" to get the chain to move relative to the models origin instead of an animated bone.
release
- Releases the IK rules of animations below a delta. This is useful for reloading animations that use their own IK rules applied over a base animation.
unlatch
- [Todo]
attachment <attachment name>
- Sets the IK goal to the specified external attachment. Rather than targeting a specific entity, the client code will search for an entity with this attachment near the chain's position and stick to it. Note:The code looks for an entity within
64
units and then requires the attachment to be within the units given in theradius
option.Tip: Used to move NPCs' hands to the handles onfunc_tank
turret models.
ikrule options
range <start> <peak> <tail> <end>
- Sets the fade-in, hold, and fade-out frame numbers for the ikrule. A period . can be placed in any of the parameters to leave the default value.
height <units>
- Used by footstep rules, specifies how high to start the search above the desired ground height. The default is the height of the ikchain.
floor <units>
- Used by footstep rules, specifies where the actual ground is ground height. The default is the floor of the ikchain.
radius <units>
- Used by footstep rules, specifies how big the ground contact check should be. The default is the radius of the ikchain.
pad <units>
- same as radius but divides units by 2. radius = pad / 2;
contact <frame>
- Used by footstep rules, specifies what frame to use when checking for ground position.
usesource
- Use the original animation source to determine the IK goals. This is use useful if the current sequence is a composite that is different from the source animation and you want to get the movement back to its original form.
usesequence
- Run all the sequence rules, including blendlayer and addlayer rules to determine the IK goals.
fakeorigin <x> <y> <z>
- Sets a fake origin for the IK rule detached from any previously specified bones.
fakerotation <pitch> <yaw> <roll>
- Sets a fake rotation for the IK rule detached from any previously specified bones.
Example
$sequence foo { ikrule lfoot footstep 0 range 4 10 19 25 ikrule rfoot footstep 1 range 18 26 3 10 iklock rfoot 1 0 iklock lfoot 1 0 }
Enabling IK in your mod
Unless your mod has been compiled with HL2_CLIENT_DLL
and HL2_DLL
, IK code is excluded from:
CPlayerMove::StartCommand
(server)CInput::CreateMove
(client)
You can remove the surrounding #ifdef
statements to enable it (or compile as HL2, but that may have unforeseen consequences).
IK in multiplayer
Ken Birdwell, who wrote the IK system, has said:
As it's currently written, the server doesn't do IK, only the clients. The main issue is that the client can't do the drop all on its own, the server needs to do the adjustment so that it can do accurate collision detection for bullets. In order for the model to drop enough below the AABB for the feet to touch the ground, there's backchannel in the client->server networking for when the IK fails. All it really is is if the npc is too high, it tells the server how much it needs to drop so that the feet will hit the ground. See CBaseAnimating::SetIKGroundContactInfo() and related code. The funky cycling you're seeing is the IK enabling and disabling itself on the client after failure.