If an object is attached to another one and you need to set its position, rotation and scale in global space, what do you do to get the local versions of these values, knowing the same values for the "parent" object?
1 Answer
You will want to store translation, rotation, and scale independently to make this easier (and in various cases, faster), but matrix decomposition will work.
The method for each of the three parameters is different but extremely easy.
First, let's look at what you already know: how to get the world position from the child's local position and its parent's world position.
For translation, simply add the parent's translation from the child's. If the parent is at (10,2,7) and the child's local translation is (1,-3,4), then the child's world position is (10+1,2-3,7+4) = (11,-1,11).
For rotation, apply the parent's rotation to the child's. If you're using a simplified quaternion class, this would mean simply multiplying the parent's rotation against the child, probably using an overloaded operator, e.g. world = parent.otation * child.rotation. Note that that is not the "proper" notation for quaternions, but it's how they're generally implemented in C++/C#/Java math libraries.
For scale, multiply the components of the parent against the child's. If the parent is (2,2,2) and the child is (0.5,1,2), then the world scale is (2*0.5,2*1,2*2) = (1,2,4).
To go the other way, simply do the complementary operations.
To get the local translation, subtract the parent's world translation from the child's world translation. Using the same sample numbers from before: (11-10,-1-2,11-4) = (1,-3,7).
To get the local rotation, you'll want to multiply the child's world rotation by the parent's conjugate. The conjugate is simply the original quaternion with the vector parts negated, e.g. (-x,-y,-z,w).
To get the local scale, multiply the child's world scale with the reciprocal of the parent's world scale. With the previous example numbers, the parent had a uniform scale of 2, so its reciprocal would be a uniform 0.5: (1*0.5, 2*0.5, 4*0.5) = (0.5,1,2).
-
\$\begingroup\$ Maybe it would be helpful for others to also mention what needs to be done when rotation is in euler or a rotation matrix. \$\endgroup\$– user17402Commented Aug 16, 2012 at 11:13
-
\$\begingroup\$ You don't consider the parent's rotation and scale while calculating the child's translation, do you? And the result is incorrect. \$\endgroup\$– arsdeverCommented Dec 2 at 21:35