Local Transformation Matrix

To retrieve the local transformation matrix of a node (the transformation of a node relative to its parent) you must perform some matrix arithmetic on the node's world space transformation matrix. This is because 3ds Max does not store the local transformation matrix.

The transformation of a node relative to its parent may be some function of the node's parent's transform. For example, a transform controller takes the parent's transformation matrix and modifies it. When a node evaluates itself it takes the parent's transformation matrix and passes it as an argument when it calls GetValue() on its transform controller. The task of a transform controller in its implementation of GetValue() is to modify this matrix. It applies its transformation to the parent transformation passed in.

In some cases this modification may be just a simple pre-multiplication by what is considered the local transformation matrix. But it may be some other more-complicated process. For example, if rotation or scale inheritance is turned off, the transform controller takes the parent's matrix and perhaps removes rotation from it, or removes scaling from it, and then applies itself. As another example, it may use the parent's position as a function to derive rotation -- as in a Look At controller. Thus, what is considered the local transformation is a function of the transform controller and is not stored by 3ds Max.

3ds Max stores the node's world space transformation matrix. This matrix includes the parent's transformation. To understand how the local transformation can be extracted from the world space transformation consider the following:

Any transformation is made up by starting with the node, and then multiply it by its parent, and then by its parent, and so on, all the way through the ancestors. This is shown below:

NodeWorldTM = NodeLocalTM * ParentLocalTM * ParentLocalTM * ParentLocalTM, etc.

The parents world transformation is equal to the product of all its ancestors, so:

ParentWorldTM = ParentLocalTM * ParentsLocalTM * ParentsLocalTM, etc.

The nodes world transform can then be expressed as:

NodeWorldTM = NodesLocalTM * ParentWorldTM.

If we multiply both sides of this equation by the Inverse of the ParentsWorldTM and simplify we get:

NodeLocalTM = NodeWorldTM * Inverse(ParentWorldTM)

So, to retrieve the local transformation you must get the parent's transform and multiply the node's transform by the inverse of the parent. The way this is computed using the methods of 3ds Max is shown in the following code fragment. This example assumes node is the INode* that we want the local transformation matrix from, and the result will get stored in localTM:

...
Matrix3 nodeTM = node->GetNodeTM(0);
INode* parent = node->GetParentNode();
Matrix3 parentTM = parent->GetNodeTM(0);
Matrix3 localTM = nodeTM*Inverse(parentTM);
...