I was trying to solve a problem when I had an object (a point helper) in a scene that was part of a hierarchy (in a rig) but I wanted the object to transform in a different object’s space than was its parent! Essentially, this means transforming objects in “AUX” pivots’ space (if you know MotionBuilder, you know where I’m going with this).
There is a simple way to get object’s transformation value in their parent space, the equation is as follows:
objectsOffsetTM = $myObject.transform * inverse $myObject.parent.transform
The resulting matrix3 value yields the exact transform of the object “MyObject” extracted in its parent space, which is extremely useful if you’ve done some, slightly advanced, rigging. Now, from this equation and with very basic math knowledge, one’d assume that when the only unknow in this formula would be the $MyObject.transform value, you’d divide the entire equation by the “inverse $MyObject.parent.transform” value and so you’d get something like this:
$myObject.transform = objectsOffsetTM / inverse $myObject.parent.transform
In fact, this is not possible as there’s no formal mathematical way defined for matrix divisions. Trying to do this will produce an error. However, with a little knowledge of math, you’ll be able to quickly rewrite the equation so that it uses defined math methods for matrices and get the transform for your object. In my case, however, I didn’t want to calculate the object’s parent space transformation from its own parent, but instead, I wanted to calculate the object’s parent space transformation from a completely separate object, which, in fact, lied on a totally different level of the hierarchy (in my rig). So, instead of using the formula above, you’d only swap the “parent” transformation value for a completely different transformation value, like so:
$myObject.transform = objectsOffsetTM / inverse $differentObject.transform
This formula is to give you an idea (off of the names of the variables used) what I needed. Now, this still throws an error, since, as stated above, you can’t divide matrices. How did I go about this issue then? Let’s use a simplified example to show the math principle behind this. The equation I’m using here is of this kind:
x = A * B
But, what if you don’t know “A”? How do you get the unknown “A” then?
A = x/B
Great, we finally arrived at the very destination which isn’t possible, as we can’t use divisions. Think for a second a division is inverse multiplication, right? So, a variable “B” has to be inversed in order to use multiplication in the equation above. How to do that? Simple, a “B” on the power of 1 yields exactly the same value “B”, right? Inversion is defined as a power of “negative” exponent, which in this case is -1, so, the modified equation with this knowledge applied looks like this:
A = x * B^(-1)
That’s it! That’s all I needed for calculating the object’s transform from a known offset and a known different object transform. There’s only one little problem left to solve. How do you square a matrix? It’s easy when the exponent is positive, however, what if, like in this case, the exponent is actually negative? The math definition for non-positive exponent square in relation to the matrices is their “inverse” value. Thankfully, there’s a function in Max that does exactly that, it’s logically called “inverse” Now, there’s nothing standing in our way to solve the problem! The resulting equation with all the math involved looks like this:
$myObject.transform = objectsOffsetTM * inverse(inverse $differentObject.transform)
You can simplify this as inverting an already inverse matrix is the matrix itself:
$myObject.transform = objectsOffsetTM * $differentObject.transform
See how simple that is This equation in practice applied to an object in a scene looks as if the object was linked (parented) to the master object, while in fact, it’s not, which was the whole point of this example:
One last note about matrices, don’t forget that matrices are not commutative, which means that A * B != B * A, so in this case the differentObject’s transform has to be pre-multiplied by the objectsOffsetTM matrix and not the other way around.