###### Recent Posts

Planar Projection Onto A Sphere (Improved Eyelid Deformations)

December 15, 2018

1/7

# Bi-Directional Constraints (Three Methods)

March 6, 2018

So here's a deceptively simple challenge. I have two objects, and  I want to be able to switch (not blend) between the first acting as the parent of the second and the second acting as the parent of the first.

Your first instinct might be to create buffer groups above each object and then create parent constraints from each object to the buffer group above the other. But, boom, that's a cycle because the parent constraint is based on the transforms of the buffer group.

But we can do it, in fact we can do it tin a couple different ways.

The Simple Method

The first method involves putting a buffer group above each item in the pseudo-hierarchy and then making the pivot of that group the same as it's pseudo-parent. Then the transforms of the pseudo-parent are plugged into blend color nodes so they can be turned on and off and then they are plugged into the buffer group. This system is simple and lightweight but would require  buffer group for each pseudo-parent above it in the pseudo-hierarchy. It would also require orientation groups for each buffer group unless the chain was in a straight line.  So a 3 object chain could have as many as 8 buffer groups, which in my opinion makes this method only reasonable for 2 object chains.

The Complex Method

The second method involves using matrix multiplication to simulate a parent constraint. If I used an actual parent constraint I would end up with a cycle. But instead of using the world matrix of the driver object I instead multiply the matrix of each object (using compose matrix nodes for a constant offset instead of using the matrices of the buffer groups) in ascending hierarchical order in order to get a world matrix without ever taking inputs from the buffer group.

Here is the script to connect from a multiply matrix node to a wtAddMatrix node (because Autodesk):

sel = cmds.ls(sl = True)

cmds.connectAttr(sel + ".matrixSum", sel + ".wtMatrix.matrixIn")

Now this setup is a lot more robust but it still has some issues, namely that you would have to create a multMatrix node for each possible heirarchy, for each object, meaning the number of nodes would increase exponentially. So a reversible three segment chain would have 6 multMatrix nodes.

Ideally we would just need to set the pseudo-parent of each object in order to create the pseudo-heirarchy, this is possible but it takes another little leap of Maya knowledge.

The Best Method

So let's revisit that first idea, using two parent constraints. If we set it up so only one parent constraints weight is set to 1 at a time and the other ones are set to 0 why does it still give us a cycle warning? The answer involves the dirty flag and attribute dependency.

Now those are two fancy sounding words (well ok, dirty flag doesn't sound fancy) that you may not have heard of but they are two easy to understand concepts.  Attribute dependency is best explained here. One thing that isn't explained on that page is the fact that not all outputs on a node are dependent on all the inputs. For example on a multiply divide node, the outputY attribute is only dependent on the  input1Y and input2Y attributes. If you were to update the input1X attribute there's not reason for maya to recalculate the outputY, so it doesn't.

On a parent constraint, the output transforms are dependent on all the transforms regardless of their weight. So even if the weight is set to 0 if that target moves the parent constraint will run it's calculations. This is why the parent constraint always gives us a cycle warning even when it seems like it shouldn't.

I have to give credit to Tom Bailey  for figuring out that for a choice node the output is only dependent on the currently selected input. His tutorial makes some assumptions about your rigs structure and he alludes to the concept of attribute dependence but doesn't use the term. Below I show off a more general approach.

The above image is the node network for one object. The area in purple is the node network that would be required if you were going to constrain the blue box to the purple box. I have another post with resources that explain how maya matrices work and how these nodes work as a parent constraint. Then we plug the resulting matrices into a choice node (and add an identitiy matrix for when the object has no parent) so that we can choose the parent using an enum attribute which is plugged into the selector. Then we decompose the chosen matrix and plug the transforms into the buffer group above the blue cube.

This system still is not perfect because the user could set two objects to be parented to each other, thus creating a cycle. If I can figure out a good control scheme to prevent this I will make a follow-up post.

This seems like it would be a good way to achieve something along the lines of Pixar's LOU rig, or the New Pioneers rigs. Honestly this is a powerful tool because it allows for any kind of adjustable hierarchies. There's a lot of stuff to experiment with using this technique, if anybody makes something intereseting please tell me, I'd love to hear about it.