- Home /
Parent Rotation to Get Target Child Rotation
Assuming that I have a parent transform that is a parent to a child transform (not necessarily a direct parent though, could be several levels between parent and child), I need a function to calculate the proper world rotation of the parent transform in order to achieve a specific target world rotation of the child transform.
So, this would look something like...
// Should return the correct value for parent.rotation such
// that child.rotation equals targetChildRotation
// (assuming that parent is a direct or indirect parent of child)
public static Quaternion CalculateParentRotation(Transform parent, Transform child, Quaternion targetChildRotation) {
// What goes here?
}
Probably a simple problem but the answer is escaping me. What does this function look like?
So, if C represents the world rotation of the child, P represents the world rotation of the parent, and R represents the relative rotation between the C and P then I believe this can be expressed as...
R = Quaternion.Inverse(C) * P
Or alternatively...
C = R * P
However, I basically need to solve for P given that I know R and C. Hmmmm.
Answer by aldonaletto · May 18, 2012 at 12:23 AM
You must find the children rotation relative to the root object at Start: "divide" the children rotation by the root rotation. If you find the target rotation somehow (with LookRotation or FromToRotation, for instance), you can just "divide" it by the relative rotation:
Quaternion relRot; public Transform rootObj;
void Start(){ relRot = Quaternion.Inverse(rootObj.rotation) * transform.rotation; }
void AlignParent(Quaternion targetChildRot){ rootObj.rotation = Quaternion.Inverse(relRot) targetChildRot; } Maybe the "division" order is reversed (should it be Inverse rotation?) - I can't test this right now, but will do it soon and edit the question if there's any error.
EDITED: In fact, the order was reversed - it's fixed now. Alternatively, it's possible to avoid one Inverse operation if relRot is calculated in the reverse order, because this would be the result of rootObj.rotation/transform.rotation:
Quaternion relRot; public Transform rootObj;
void Start(){ relRot = transform.rotation * Quaternion.Inverse(rootObj.rotation); }
void AlignParent(Quaternion targetChildRot){ rootObj.rotation = relRot * targetChildRot; }
Answer by firesharkstudios · May 18, 2012 at 12:25 AM
Turns out to be just basic matrix math -- here is the solution...
C = P * R
where C is child, P is parent, and R is relative rotation between parent and child then you can solve for P or R as follows...
P = C * Quaternion.Inverse(R)
R = Quaternion.Inverse(P) * C
This solution is correct for any situation where parent and child are facing any arbitrary direction.
For also calculating the child to target rotation, here is my full working code:
// Current and target child rotations
Vector3 newChildForward = lookTarget.transform.position - child.transform.position;
newChildForward.Normalize();
Quaternion C1 = child.transform.rotation;
Quaternion C2 = Quaternion.LookRotation(newChildForward, child.transform.up);
// Relative rotation
Quaternion R = Quaternion.Inverse(parent.transform.rotation) * C1;
// Parent rotation to match target child rotation
Quaternion P = C2 * Quaternion.Inverse(R);
parent.transform.rotation = P;
Your answer