Rotating vector to align with other vector

I have one vector3 (let’s call it meshVector) that describes where my mesh points, which is (1, 0, 0). I have another vector3 (dirVector) that describes which direction my mesh should point. Both of those vectors always have y = 0. How can I rotate my mesh so that meshVector aligns with dirVector?

What I did so far is calculate the angle between the two vectors in a function which returns a number for the angle. Then I set mesh.rotation.y to that number and I’m done (PG to illustrate how I did it until now). However, I noticed that the angle that my function returns sometimes has the wrong sign, meaning my mesh gets rotated the wrong way around. I looked for a solution online that always returns the right angle with the right sign, but I didn’t find anything.
Is it even possible to do this with a simple number or do I need quaternions? (I did find some answers showing how to do it with quaternions)

Our Matrix class has the function LookAtLH that accepts the current direction, the new direction and the up vector, and provides a matrix that can be used as a rotation matrix:

    const vec = new BABYLON.Vector3(1, 0, 0);
    const dir = new BABYLON.Vector3(Math.random(), 0, Math.random());
    dir.normalize();

    const rotation = BABYLON.Quaternion.FromRotationMatrix(BABYLON.Matrix.LookAtLH(vec, dir, BABYLON.Vector3.UpReadOnly));
    console.log(rotation, rotation.toEulerAngles());

It fits your use case, especially since you are saying that the rotation is eventually on the Y axis.

But why not use quaternions? They provide a wonderful solution for rotation representation

2 Likes

I agree, that looks like the perfect fit for my problem.
The reason I tried doing it with numbers instead of quaternions is quite simple; I have never worked with / heard of them before, and from a quick google search they seemed a bit intimidating :slightly_smiling_face:. Also, I already use the function that calculates the angle for different meshes in my scene, so a solution that also returns a number would have meant less refactoring.

I tried implementing your solution into my PG, but failed at first. My mesh pointed to a completely wrong direction. I looked at the doc for it and noticed that the first parameter is called ‘eye’ and describes the position, not the direction. So I changed my meshVec to be (0, 0, 0), the position of my mesh, instead of (1, 0, 0), which is the direction my mesh “looks”. This way it works perfectly. (PG)
Is the direction my mesh currently looks not important for this calculation then?

Edit: I tried doing what I did in the playground in my project, where I use mesh.rotationQuaternion = BABYLON.Quaternion.FromRotationMatrix(BABYLON.Matrix.LookAtLH(mesh.position, dirVector, BABYLON.Vector3.UpReadOnly));
This once again produces weird, wrong results. However, if I replace mesh.position with Vector3.Zero(), it works perfectly. Did I understand something wrong or do you have any idea why this is?

Thanks a lot for the help already, this is better than everything I tried so far!

1 Like

I have set up a playground with quaternion for your case:

Or without quaternion:

1 Like

A work in progress but RotationFromTo one vector to another may be of interest

3 Likes

Maybe I’m missing something, but that doesn’t produce the rotations that I would expect. If I set dirVector to (1, 0, 0), I’d expect the box to point in the direction of the X-axis (red arrow). But it points in direction of the Z-axis

Will check that out but cannot do it until tomorrow

Absolutely no problem at all, I tried looking into it as well but all I found out is that cross-product of two vectors is the zero-vector, which makes sense.

As @JohnK mentioned, we’re currently working on this PR that adds a function for getting the rotation from one vector to another. Hopefully this will be released soon!

The below PG should have a polyfill available for the short term: https://playground.babylonjs.com/#ZUFVG7#8

Edit: This is not fully worked out yet, so expect it to be buggy.

1 Like