Always Touch The Floor
In this section, we shall position the root bone of the armature such that the lowest bone is touching the floor. Since the ankle/heel bone's local z axis is perpendicular to the global z axis, the head and tail z locations are identical and since the tip/tail of the toe bone will be the last bone touching the floor, to identify the lowest bone, we shall use the location of the tail instead of the head.
First, we compute the index of the bone with the lowest tail z value by using numpy's
argmin() function, the input of the function should be a memory view of the values computed using the
asMemoryView() method, so the expression becomes:
To get the minimum value itself, we simply get the value at that output index as follows:
Now, we should move the armature along the global z axis—By moving the root bone
Spine—to make the lowest bone touch the floor, this is done by subtracting the lowest z value from the z value of the root and assign the new location by using the expression:
object.pose.bones["spine"].matrix.translation = location
The result is the lowest bone always touching the floor which concludes this section.
In this section, we shall displace the armature—By displacing the root/spine bone—based on the displacement of the bone that is touching the floor, that is, the lowest bone which we know from the foregoing section. To compute the displacement of all bones, we shall use the method I described in this question. Note, however, that all bones are children of the root bone and thus any displacement in the root bone causes further displacement on all the children, so, to get the actual displacement of the bones without the displacement caused by the root, we should add the displacement of the root to the displacement of the bones. Now that we have the displacement of all bones, we can get the displacement of the lowest bone using the index we already computed in the foregoing section.
Notice that the Get List Element node with zero index is the one that gets the the position of the root bone and the subtract gets the displacement, also notice how we add that displacement to the displacement of the bones.
Now, all we have to do is displace the root by the displacement we computed by adding it to its original position (Or subtracting depending on how we computed the displacement, which is the case here). Note that we already have the z location of the root from the foregoing section, so we just need the x and y locations. One last thing to do is reset the location of the root bone to some initial location of your choice at the initial frame, zero location for instance. This is done by checking if the current frame is the start frame and use a Switch node to switch between the current and the initial location.
And the result is as you might expect.
Blend file for study: