1
$\begingroup$

In reference to this report on mis-behaving IK rigs-- https://developer.blender.org/T76158

The answer is, IK rigs with dependency cycles have undefined (glitchy) behavior.

My follow up questions are:

1: How are these dependencies created?

It can't be just from creating a simple IK rig. Is it created by complex IK rigs such as the 'overlapping/cascading' ik controls as shown here: https://www.youtube.com/watch?v=p0htATi5tpA ?

Is it created by creating drivers for my IK controls? Is it created by placing the controls for the drivers on a bone that is the antecedent of the bones with IK constraints on them?

2: How can I remove/fix them?!

FILE 282+ only (if you can't get it from the developer page) https://pasteall.org/media/5/2/52b156a866b10f79670d4d4c8f4c1862.blend

Construction:

The horse front and hind limbs have IK chains of 5 joints each. They are using ITaSC solvers.

Each Leg has an IK toggle switch, located on the COG bone (the root of the movable skeleton, but child of the origin bone). These are keyframable, so IK can be turned on and off during an animation.

In addition, there is a switch to turn off/on "Snap IK to FK rig," which activates the IK control bones' constraints to copy the loc/rot of their respective hoof bones. This is inactive, and only used when the IK controls are off, to snap the IK bones back into place when the animation is ready to keyframe the IK back on. This is certainly a circular dependency, but one that I believe is a 'false' dependency, because it is not active. Maybe.

Oh... there are also targetless IK chains that can be used to move the whole limb by dragging its descendents. I don't use those, i could delete them... Okay, I just saved the file with all those deleted, and i got TWELVE dependency cycles detected instead of 10. I cannot explain those results.

Anyway, this is what the 282 console tells me about the dependencies... I have no clue what the heck it is talking about :/

What is an 'IK Chain Overlap'?

Blender Console Info: (is there a spoiler tag? this is so spammy. oh, it doesn't actually fold it up. sorry.)

Dependency cycle detected: OB_HorseMainRig/Pose Component/POSE_INIT_IK() depends on OB_HorseMainRig/IK Target Front R/BONE_DONE() via 'IK' OB_HorseMainRig/IK Target Front R/BONE_READY() via 'Ready ->! Done' OB_HorseMainRig/IK Target Front R/BONE_CONSTRAINTS() via 'Constraints ->! Ready '
OB_HorseMainRig/ElbowRight/BONE_DONE() via 'Copy Location'
OB_HorseMainRig/CollarRight/POSE_IK_SOLVER() via 'IK Solver Result'
OB_HorseMainRig/Torso/BONE_DONE() via 'IK Chain Overlap'
OB_HorseMainRig/COG/POSE_IK_SOLVER() via 'IK Solver Result'
OB_HorseMainRig/Pose Component/POSE_INIT_IK() via 'Init IK ->! IK Solver' Dependency cycle detected: OB_HorseMainRig/Pose Component/POSE_INIT_IK() depends on OB_HorseMainRig/IK Front R/BONE_DONE() via 'IK' OB_HorseMainRig/IK Front R/BONE_READY() via 'Ready ->! Done' OB_HorseMainRig/IK Front R/BONE_CONSTRAINTS() via 'Constraints ->! Ready' OB_HorseMainRig/HandMiddle1Right/BONE_DONE() via 'Copy Rotation' OB_HorseMainRig/HandMiddle1Right/BONE_READY() via 'Ready ->! Done'
OB_HorseMainRig/HandMiddle1Right/BONE_CONSTRAINTS() via 'Constraints ->! Ready' OB_HorseMainRig/HandMiddle1Right/BONE_POSE_PARENT() via 'Pose -> Constraints S tack' OB_HorseMainRig/HandMiddle0Right/BONE_DONE() via 'Parent Bone ->! Child Bone'
OB_HorseMainRig/HandMiddle0Right/BONE_READY() via 'Ready ->! Done'
OB_HorseMainRig/HandMiddle0Right/BONE_POSE_PARENT() via 'Pose -> Ready' OB_HorseMainRig/WristRight/BONE_DONE() via 'Parent Bone -> Child Bone' OB_HorseMainRig/CollarRight/POSE_IK_SOLVER() via 'IK Solver Result' OB_HorseMainRig/Torso/BONE_DONE() via 'IK Chain Overlap' OB_HorseMainRig/COG/POSE_IK_SOLVER() via 'IK Solver Result' OB_HorseMainRig/Pose Component/POSE_INIT_IK() via 'Init IK ->! IK Solver' Dependency cycle detected:
OB_HorseMainRig/HandMiddle1Right/BONE_CONSTRAINTS() depends on
OB_HorseMainRig/IK Front R/BONE_DONE() via 'Copy Rotation'
OB_HorseMainRig/IK Front R/BONE_READY() via 'Ready ->! Done'
OB_HorseMainRig/IK Front R/BONE_CONSTRAINTS() via 'Constraints -> Ready' OB_HorseMainRig/HandMiddle1Right/BONE_DONE() via 'Copy Rotation' OB_HorseMainRig/HandMiddle1Right/BONE_READY() via 'Ready ->! Done' OB_HorseMainRig/HandMiddle1Right/BONE_CONSTRAINTS() via 'Constraints ->! Ready' Dependency cycle detected: OB_HorseMainRig/Pose Component/POSE_INIT_IK() depends on OB_HorseMainRig/IK Target Front L/BONE_DONE() via 'IK' OB_HorseMainRig/IK Target Front L/BONE_READY() via 'Ready ->! Done' OB_HorseMainRig/IK Target Front L/BONE_CONSTRAINTS() via 'Constraints ->! Ready '
OB_HorseMainRig/ElbowLeft/BONE_DONE() via 'Copy Location'
OB_HorseMainRig/CollarLeft/POSE_IK_SOLVER() via 'IK Solver Result'
OB_HorseMainRig/Torso/BONE_DONE() via 'IK Chain Overlap'
OB_HorseMainRig/COG/POSE_IK_SOLVER() via 'IK Solver Result'
OB_HorseMainRig/Pose Component/POSE_INIT_IK() via 'Init IK ->! IK Solver' Dependency cycle detected: OB_HorseMainRig/Pose Component/POSE_INIT_IK() depends on OB_HorseMainRig/IK Front L/BONE_DONE() via 'IK' OB_HorseMainRig/IK Front L/BONE_READY() via 'Ready ->! Done' OB_HorseMainRig/IK Front L/BONE_CONSTRAINTS() via 'Constraints ->! Ready' OB_HorseMainRig/HandMiddle1Left/BONE_DONE() via 'Copy Rotation' OB_HorseMainRig/HandMiddle1Left/BONE_READY() via 'Ready ->! Done' OB_HorseMainRig/HandMiddle1Left/BONE_CONSTRAINTS() via 'Constraints ->! Ready'
OB_HorseMainRig/HandMiddle1Left/BONE_POSE_PARENT() via 'Pose -> Constraints St ack' OB_HorseMainRig/HandMiddle0Left/BONE_DONE() via 'Parent Bone ->! Child Bone'
OB_HorseMainRig/HandMiddle0Left/BONE_READY() via 'Ready ->! Done'
OB_HorseMainRig/HandMiddle0Left/BONE_POSE_PARENT() via 'Pose ->! Ready' OB_HorseMainRig/WristLeft/BONE_DONE() via 'Parent Bone ->! Child Bone' OB_HorseMainRig/CollarLeft/POSE_IK_SOLVER() via 'IK Solver Result'
OB_HorseMainRig/Torso/BONE_DONE() via 'IK Chain Overlap'
OB_HorseMainRig/COG/POSE_IK_SOLVER() via 'IK Solver Result'
OB_HorseMainRig/Pose Component/POSE_INIT_IK() via 'Init IK ->! IK Solver' Dependency cycle detected:
OB_HorseMainRig/HandMiddle1Left/BONE_CONSTRAINTS() depends on
OB_HorseMainRig/IK Front L/BONE_DONE() via 'Copy Rotation'
OB_HorseMainRig/IK Front L/BONE_READY() via 'Ready ->! Done'
OB_HorseMainRig/IK Front L/BONE_CONSTRAINTS() via 'Constraints -> Ready' OB_HorseMainRig/HandMiddle1Left/BONE_DONE() via 'Copy Rotation' OB_HorseMainRig/HandMiddle1Left/BONE_READY() via 'Ready -> Done' OB_HorseMainRig/HandMiddle1Left/BONE_CONSTRAINTS() via 'Constraints ->! Ready' Dependency cycle detected: OB_HorseMainRig/Pose Component/POSE_INIT_IK() depends on OB_HorseMainRig/IK Target Hind L/BONE_DONE() via 'IK' OB_HorseMainRig/IK Target Hind L/BONE_READY() via 'Ready ->! Done' OB_HorseMainRig/IK Target Hind L/BONE_CONSTRAINTS() via 'Constraints ->! Ready' OB_HorseMainRig/AnkleLeft/BONE_DONE() via 'Copy Location'
OB_HorseMainRig/KneeLeft/POSE_IK_SOLVER() via 'IK Chain Result'
OB_HorseMainRig/HipLeft/BONE_DONE() via 'IK Chain Overlap'
OB_HorseMainRig/HipLeft/POSE_IK_SOLVER() via 'IK Chain Result'
OB_HorseMainRig/PelvisInv/BONE_DONE() via 'IK Chain Overlap'
OB_HorseMainRig/PelvisInv/POSE_IK_SOLVER() via 'IK Chain Result'
OB_HorseMainRig/COG/BONE_DONE() via 'IK Chain Overlap'
OB_HorseMainRig/COG/POSE_IK_SOLVER() via 'IK Chain Result'
OB_HorseMainRig/Pose Component/POSE_INIT_IK() via 'Init IK ->! IK Solver' Dependency cycle detected: OB_HorseMainRig/Pose Component/POSE_INIT_IK() depends on OB_HorseMainRig/IK Target Hind R/BONE_DONE() via 'IK' OB_HorseMainRig/IK Target Hind R/BONE_READY() via 'Ready ->! Done' OB_HorseMainRig/IK Target Hind R/BONE_CONSTRAINTS() via 'Constraints ->! Ready' OB_HorseMainRig/AnkleRight/BONE_DONE() via 'Copy Location'
OB_HorseMainRig/HipRight/POSE_IK_SOLVER() via 'IK Solver Result'
OB_HorseMainRig/PelvisInv/BONE_DONE() via 'IK Chain Overlap'
OB_HorseMainRig/PelvisInv/POSE_IK_SOLVER() via 'IK Chain Result'
OB_HorseMainRig/COG/BONE_DONE() via 'IK Chain Overlap'
OB_HorseMainRig/COG/POSE_IK_SOLVER() via 'IK Chain Result'
OB_HorseMainRig/Pose Component/POSE_INIT_IK() via 'Init IK ->! IK Solver' Dependency cycle detected:
OB_HorseMainRig/ToeLeft/BONE_CONSTRAINTS() depends on
OB_HorseMainRig/IK Hind L/BONE_READY() via 'Copy Rotation'
OB_HorseMainRig/IK Hind L/BONE_CONSTRAINTS() via 'Constraints -> Ready' OB_HorseMainRig/ToeLeft/BONE_READY() via 'Copy Rotation'
OB_HorseMainRig/ToeLeft/BONE_CONSTRAINTS() via 'Constraints ->! Ready' Dependency cycle detected:
OB_HorseMainRig/ToeRight/BONE_CONSTRAINTS() depends on
OB_HorseMainRig/IK Hind R/BONE_READY() via 'Copy Rotation'
OB_HorseMainRig/IK Hind R/BONE_CONSTRAINTS() via 'Constraints -> Ready' OB_HorseMainRig/ToeRight/BONE_READY() via 'Copy Rotation'
OB_HorseMainRig/ToeRight/BONE_CONSTRAINTS() via 'Constraints ->! Ready' Detected 10 dependency cycles

TESTING: i'm using 2.79, as it has readable console messages. following standard ik creation instructions.

1: extrude ik target and ik pole. no circular dependencies.

2: set parent of target/pole to root bone. no circular dependencies.

3: add ik constraint to the limb, chain length 2. Circular Dependency Created!
Dependency cycle detected: IK.Target.Leg.L depends on Origin through Parent Relation. Origin depends on IK.Target.Leg.L through IK Constraint.

how is my origin (the root bone in this rig) dependent on the leg ik target, when the ik chain doesn't even come anywhere near it?

what should i be setting the ik target parent to, if it isn't the root bone?

$\endgroup$
0

2 Answers 2

1
$\begingroup$

When you first add an IK constraint to a bone chain, the chain will include ALL the bones right back to your root bone. If your control bone or pole target are parented to the armature at this point you will have a cyclic dependency, which cannot be resolved. The code calculation fails and the armature is then broken.

If you set up the IK constraint first, shortening the chain to only the bones you want the IK to affect, and only then parent the controller or pole target to the root bone, the cyclic dependency doesn't happen. There is a "gap" between the last IK bone and the root bone.

The same is true (with a proviso) of any constraint you have added to a bone chain to "connect" a non connected bone. The moment you add an IK constraint to it you will get a cyclic dependency.

Dependency is directional. The child of another bone or object depends on it's parent. But the parent does not depend on the child. Similarly, every relational constraint has a "source" bone or object and an "owner" bone or object. The behaviour of the "owner" bone (which is the one that has the constraint applied to it) depends on the behaviour of the "source" bone or object.

If you imagine an arrow representing the direction of dependency, so that the information from the base of the arrow affects the object the arrow is pointing at, then any constraint that does not violate this directionality with regard to other constraints on the same armature will not create a cyclic dependency.

The same is true of drivers and actions that create relationships between objects. If you add a driver on a parent object that takes values from it's child object, you will have a cyclic dependency which will fail.

$\endgroup$
0
$\begingroup$

I think I have figured it out.

If you create the IK Target/Pole and parent them to the Root before you create the IK control, it doesn't work.

If you clear the IK Target/Pole parent, then set up the IK constraints, then parent the Target to the Root, it's fine.

Proper Steps:

  1. Extrude/Create your IK control bones.
  2. Clear their Parents.
  3. Set up the IK constraints on your rig.
  4. Set the actual Parents of your IK control bones.
$\endgroup$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .