Wednesday, June 25, 2025

Two Level Alignment Transformations

I am making an attempt to find out the transformation steps (place, scale, rotation) wanted to be utilized to an object in order that two factors, domestically positioned in that object, line up with two world house positions.

The setup presently is:

  • E is a prefab with two remodel youngsters (A, B)
  • Transforms C and D are additionally inside a prefab (F)
  • We’ve got a world place, scale and rotation that F will instantiate with
  • Previous to any instantiation, calculate the transformation that should happen for E to finish up in the appropriate place.

Two Level Alignment Transformations

The answer I’ve in the mean time is shut however the rotation by no means appears to line up completely, affecting the positioning.

public static (Vector3, Quaternion, Vector3) GetChildPosLeg(
    Remodel topReference, // A
    Remodel bottomReference, // B
    Remodel topTarget, // C
    Remodel bottomTarget, // D
    Vector3 scale // Scale of root instantiated object
    )
{
    // World topTarget
    Vector3 topTargetPos = (Vector3.Scale(topTarget.place, scale));
    Vector3 bottomTargetPos = (Vector3.Scale(bottomTarget.place, scale));

    // Scale
    float refDist = Vector3.Distance(topReference.place, bottomReference.place);
    float targetDist = Vector3.Distance(topTargetPos, bottomTargetPos);

    float scaleRatio = targetDist / refDist;
    Vector3 finalScale = new Vector3(0.5f, 1f, 0.5f) * scaleRatio;

    // Rotation
    Vector3 targetDir = topTarget.place - bottomTarget.place;
    Vector3 refDir =  bottomReference.localPosition - topReference.localPosition;

    Quaternion objectRotation = Quaternion.FromToRotation(refDir, targetDir);

    // Place
    Vector3 childNodePos = Vector3.Scale(topReference.localPosition, finalScale);
    childNodePos = objectRotation * childNodePos;
    Vector3 finalPosition = topTargetPos + childNodePos;

    return (finalPosition, objectRotation, finalScale);
}

EDIT:
The answer I ended up with is:

    public static (Vector3, Quaternion, Vector3) GetChildPosLeg(
    Remodel bottomReference,
    Remodel topReference,
    Remodel topTarget,
    Remodel bottomTarget,
    Vector3 parentScale,
    Vector3 itemScaleRatio
    )
{
    // World targets
    Vector3 targetAWorldPos = (Vector3.Scale(topTarget.place, parentScale));
    Vector3 targetBWorldPos = (Vector3.Scale(bottomTarget.place, parentScale));

    // Scale
    Vector3 scaledBottom = Vector3.Scale(bottomReference.place, itemScaleRatio);
    Vector3 scaledTop = Vector3.Scale(topReference.place, itemScaleRatio);
    float incomingDistance = Vector3.Distance(scaledBottom, scaledTop);
    float targetDistance = Vector3.Distance(targetAWorldPos, targetBWorldPos);

    float scaleRatio = targetDistance / incomingDistance;
    Vector3 finalScale = itemScaleRatio * scaleRatio;

    // Rotation
    Vector3 refDir = scaledBottom - scaledTop;
    Vector3 targetDir = topTarget.place - bottomTarget.place;

    // Native 'up' vector of the incoming object
    Vector3 refUp = refDir.normalized;

    // Native 'ahead' vector of the incoming object (outline this primarily based on prefab orientation)
    Vector3 refForward = Vector3.Cross(refUp, bottomReference.ahead).normalized; // assuming 'proper' is orthogonal
    Quaternion refRotation = Quaternion.LookRotation(refForward, refUp);

    //Construct a goal rotation from the goal node
    Vector3 targetUp = targetDir.normalized;
    Vector3 targetForward = topTarget.ahead; // assuming the prefab is aligned the identical means
    Quaternion targetRotation = Quaternion.LookRotation(targetForward, targetUp);

    Quaternion finalRotation = targetRotation * Quaternion.Inverse(refRotation);

    // Place
    // Scale it
    Vector3 scaledOffset = Vector3.Scale(scaledBottom, finalScale);

    // Rotate it
    Vector3 rotatedOffset = finalRotation * scaledOffset;

    //  Subtract that offset from the goal place
    Vector3 finalPosition = targetAWorldPos - rotatedOffset;

    return (finalPosition, finalRotation, finalScale);
}

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles