Home > Back-end >  Rotate Container to align with a Vector Direction based on reference points
Rotate Container to align with a Vector Direction based on reference points

Time:12-20

I have a scene set up with this heirarchy:

- Environment
  -RealWorldRefA
  -RealWorldRefB
  -3dModelContainer
    -ModelRefA
    -ModelRefB
    -Model

The goal is to press a button and the 3d modelcontainer will be scaled and rotated such that ModelRefA and ModelRefB are in the positions as the real world reference points.

The purpose here is eventually to have a 3d scanned model of my home climbing wall. I aim to set to reference points in the real world in AR (on quest 2) and then use these to scale and superimpose the 3d model onto the real world.

So far, my test script for this scene has 3 steps:

    if (Input.GetKeyDown("space"))
    {
        AlignFirstReferencePoint();
        ScaleModelToMatchRealReferenceDistance();
        RotateModelToMatchReferenceAlignment();
    }

The first to steps work fine but I am stuck on step 3.

In step 1, the container position is set equal to the position of the real world ref A

private void AlignFirstReferencePoint()
{
    modelContainer.transform.position = realWorldRefA.transform.position;
}

Great... then step 2, the distance between RealWorldRefA B are compared to the distance between the model ref A and B and then the container is scaled so that these match:

private void ScaleModelToMatchRealReferenceDistance()
{
    float distanceBetweenRealRefs = Vector3.Distance(realWorldRefA.transform.position, transform.position);
    float distanceBetweenModelRefs = Vector3.Distance(modelRefA.transform.position, modelRefB.transform.position);
    float distanceRatio = distanceBetweenRealRefs / distanceBetweenModelRefs;

    var x = modelContainer.transform.localScale.x;
    var y = modelContainer.transform.localScale.y;
    var z = modelContainer.transform.localScale.z;

    modelContainer.transform.localScale = new Vector3(x*distanceRatio, y distanceRatio, z distanceRatio);

}

In step 3, I need to rotate the model... but we're into adding vectors directions and quarternions and I get a bit lost here...

In my first attempt I simply tried: modelContainer.transform.LookAt(realWorldRefB.transform);

But this doesn't give the correct orientation. I guess the model and everything inside the container would have to be aligned along a specific axis of the container for this to work, so this is no good.

What I would like to do is something more like:

private void RotateModelToMatchReferenceAlignment()
{
    Vector3 realWorldRefsDirection = realWorldRefA.transform.position   realWorldRefB.transform.position;
    Vector3 modelRefsDirection = modelRefA.transform.position   modelRefB.transform.position;

    //DO SOMETHING HERE TO ROTATE THE CONTAINER UNTIL THESE TWO VECTORS MATCH??
}

I've had a read through some existing posts but a) they go a bit over my head and b) they don't seem to use reference points like I am using, which may add some complexity so I can't easily adapt those solutions.

CodePudding user response:

First of all direction is the delta between two positions, not the sum!

So if you want a vector pointing from realWorldRefA towards realWorldRefB what you want is

var realWorldRefsDirection = realWorldRefB.transform.position - realWorldRefA.transform.position;

and accordingly

var modelRefsDirection = modelRefB.transform.position - modelRefA.transform.position;

And then you could use Quaternion.FromToRotation like e.g.

var deltaRotation = Quaternion.FromToRotation(modelRefsDirection, realWorldRefsDirection); 
modelContainer.transform.rotation *= deltaRotation; 
  • Related