Función “lookAt” del cuaternión

Estoy luchando con el siguiente problema. Estoy trabajando con animación ósea y quiero (es decir) que la cabeza del jugador siga a otro objeto en el espacio. Mi eje hacia arriba es + Z Mi eje hacia adelante es + Y, y la magnitud del cuaternión está en W. Intenté usar el código de mesa para gluLookAt y usar la matriz 3x3 para transformar a un cuaternión, pero no funciona como se esperaba. Así que voy en otra dirección ...

Hasta ahora obtuve el siguiente código que está "casi" funcionando al menos la cabeza del jugador está girando (sin embargo, el ángulo X parece afectar al eje de rotación Y) en la buena dirección, pero en lugar de eso está mirando hacia arriba al seguir un objeto El piso a unos 65 grados:

qt LookRotation( v3 lookAt, v3 upDirection )
{
qt t;

v3 forward = lookAt;
v3 up = upDirection;

OrthoNormalize( &forward, &up );

v3 right = v3_cross( up, forward );

mat3 m = mat3_make( right.x, up.x, forward.x,
                    right.y, up.y, forward.y,
                    right.z, up.z, forward.z );

t.w = sqrtf( 1.0f +
             m.r[ 0 ].x +
             m.r[ 1 ].y +
             m.r[ 2 ].z ) * 0.5f;

float w4_recip = 1.0f / ( 4.0f * t.w );

t.x = ( m.r[ 2 ].y - m.r[ 1 ].z ) * w4_recip;

t.y = ( m.r[ 0 ].z - m.r[ 2 ].x ) * w4_recip;

t.z = ( m.r[ 1 ].x - m.r[ 0 ].y ) * w4_recip;

t = qt_normalize( t );

return t;
}

... ...

v3 v = v3_sub( vec4_to_v3( transform.world.r[ 3 ] /* The object XYZ location in the world */),
           skeleton->final_pose.location[ i ] /* i = The head joint location */ );

v = v3_normalize( v );

qt q = LookRotation( v,
        v3_make( 0.0f, 0.0f, 1.0f ) );

¿Puede alguien ayudarme a resolver este problema? Soy un poco nuevo con los cuaterniones y realmente no sé dónde podría haber arruinado. Después de bastante investigación, básicamente lo que quiero hacer es algo como la API de Unity:http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.LookRotation.html

Respuestas a la pregunta(3)

Su respuesta a la pregunta