Confusion about Quaternion.SetFromToRotation

I’m starting to understand Quaternion.SetLookRotation, which takes an optional up vector to get more information about the final orientation.

However, I noticed Quaternion.SetFromToRotation does not take any up vector, and I’m having trouble understanding how it deals with that.

As a simple example, I imagined that I rotate my head 90 degrees to the left (e.g. turning left to look before crossing a street). This would be represented by SetFromToRotation(vector.forward, vector.left). BUT what if after I turn, I TILT (aka “roll”?) my head 45 degrees at an angle, as if I were a dog expressing curiosity/interest and you had just told me you were taking me on a walk.

How can the quaternion represent this new up angle if it doesn’t take any up vector in SetFromToRotation?

Confusion comes from that you seem to understand what Quaternion.LookRotation(forward,up) is but you also project these expectations onto Quaternion.FromToRotation(from,to) where these are meant to do very different things.


LookRotation

LookRotation is supposed to mean something like “rotation of an object looking in direction”.

Unity - Scripting API: Quaternion.LookRotation


FromToRotation

FromToRotation is supposed to mean something like “rotation from one direction to another where rotation axis is Vector3.Cross(from,to)”.

Unity - Scripting API: Quaternion.FromToRotation
Unity - Scripting API: Quaternion.SetFromToRotation (don’t use these quat.Set_ methods - are adding confusion for no gain)


Please note that FromToRotation implies some kind of transformation - a tool to rotate other quaternions with. Presence of up implies fine control and that is simply not the FromToRotation’s expected job.

It is true that “rotating from direction A to direction B” is underdetermined, i.e. that there are an infinite number of rotations that rotate from A to B. FromToRotation resolves this by always rotating only around the axis that is perpendicular to the two input directions. This rotation also has the minimal angle in axis-angle representation.

It’s basically the same as this:

Quaternion.AngleAxis(Vector3.Angle(A, B), Vector3.Cross(A, B))