Reputation: 135
Here is the closest thing I can come up with but the position is not correct.... The parent's goal position is what I am trying to determine. Any help is appreciated!
Quaternion rotation = goal.rotation * Quaternion.Inverse(child.rotation) * parent.rotation;
parent.MoveRotation(rotation);
Vector3 position = goal.position + (Quaternion.Inverse(parent.rotation) * child.rotation) * (parent.position - child.position);
parent.MovePosition(position);
Upvotes: 1
Views: 482
Reputation: 90813
If I understand your graphic correctly what you have is
and what you are trying to achieve is
You are somewhat pretty close.
Ignoring the scale (assuming there is no scaling involved in the entire hierarchy until the parent object) basically you can simplified say
finalChildRotation = targetParentRotation * localDeltaRotation;
finalChildPosition = targetParentPosition + parentRotation * localDeltaPosition;
We already know
var finalChildRotation = goal.rotation;
var finalChildPosition = goal.position;
var localDeltaRotation = child.localRotation;
var localDeltaPosition = child.localPosition;
so you can resolve the rest in the order
// orientation as only one unknown -> basically simply rotate back the delta from the given goal rotation
var targetParentRotation = finalChildRotation * Quaternion.Inverse(localDeltaRotation);
// Now that we have our final rotation you can easily calculate the position
var targetParentPosition = finalChildPosition - targetParentRotation * localDeltaPosition;
Little demo
public class Example : MonoBehaviour
{
public Transform goal;
public Transform parent;
public Transform child;
[ContextMenu("Place")]
public void Place()
{
var finalChildRotation = goal.rotation;
var finalChildPosition = goal.position;
var localDeltaRotation = child.localRotation;
var localDeltaPosition = child.localPosition;
var targetParentRotation = finalChildRotation * Quaternion.Inverse(localDeltaRotation);
var targetParentPosition = finalChildPosition - targetParentRotation * localDeltaPosition;
parent.rotation = targetParentRotation;
parent.position = targetParentPosition;
}
}
However, if there is also scaling in play this will probably get more complex!
Upvotes: 3