I have a projectile object that is moving along a velocity vector. I need to ensure that the object is always facing in the direction of the velocity vector. Furthermore, I am representing object rotation using quaternions, not matrices.
I know that the first step is to find an orthogonal basis:
forward = direction of velocity vector
up = vector.new(0, 1, 0)
right = cross(up, forward)
up = cross(forward, right)
How might I convert the basis into a rotation quaternion?
Solution
Note, I'd like to give credit to Noel Hughes for providing the answer, but I want to clarify with my own experiences. Pseudocode follows:
vec3 vel = direction of velocity vector
vec3 forward = (1, 0, 0) // Depends on direction your model faces. See below.
vec3 axis = cross(forward, vel)
if (axis == 0) then quit // Already facing the right direction!
axis = normalize(axis)
float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
quat result = (0, axis.y * sin(theta/2), axis.z * sin(theta/2), cos(theta/2)
The last element of the quaternion is the scalar part, the first three elements are the imaginary parts. Also, the above pseudocode assumes that your object in "model space" points down the positive x-axis. In my case, the object actually pointed down the positive y-axis, in which case I made the following changes:
vec3 vel = direction of velocity vector
vec3 forward = (0, 1, 0) // Note that y-component is now 1
vec3 axis = cross(forward, vel)
if (axis == 0) then quit
axis = normalize(axis)
float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
quat result = (axis.x * sin(theta/2), 0, axis.z * sin(theta/2), cos(theta/2)
// Note that SECOND component above is now 0