(In order for this expression to work you need to enable the Auto Run Python Scripts setting in Blender. On 2.80 it's in Preferences -> Save & Load -> Auto Run Python Scripts and on 2.79 it's in User Preferences -> File -> Auto Run Python Scripts.)
This expression uses the dot product of the bones' aim vectors, a mechanism known as a "pose reader", used with pose space deformation (PSD).
As the bones rotate during animation or posing, the driver will output a value in the range [-1, +1], going from -1 when the bones point in opposite directions, up to 0 when they become perpendicular, up to +1 when they point in the same direction.
- The two bones used in the expression should not be animated in scale (be it their own or inherited scale from their parents), they should only be animated in position and rotation. This means that they need to have a scale of exactly 1 in all axes, for the entire animation, otherwise this will mess with the speed of the driver because it affects the length of the
matrix.col[1]
vector.
- If you need to animate them in scale, simply add a child bone to them and animate the scale of the child and deform the mesh with that child bone, not the parent.
- You can adjust the timing and speed of this driver by playing with the driver graph curve, like using easing or bezier handles. For example, when used with shape keys, you can make the graph minimum be zero and maximum be 1 (click to enlarge):
- The
poseBones
variable in the driver is referencing the .pose.bones property of the armature object (like bpy.data.objects("Armature")) and not the armature data (like bpy.data.armatures("Armature")). That .pose
property exists in objects only.