Buenas gente, tengo un problema de matemáticas, es bastante básico pero no puedo encontrar el problema, seguramente estoy haciendo alguna burrada y no me doy cuenta... :( , el tema es así, tengo un modelo 3D y lo estoy haciendo caminar a lo largo de un camino de puntos, el problema está cuando quiero hacer que el modelo mire al punto. o sea que rote y quede mirando al punto donde tiene que caminar , para algunos puntos me anda y para otros no.... acá les dejo el código que calcula el ángulo, alguien encuentra el error? :( o me puede dar una idea... salu2
PD: uso OpenGL
/*!
* \brief
* Calcula el angulo adonde tiene que mierar el npc son 3 parametos porque.
* p(1).------.(p2)
* v1 \
* \ v2
* \
* .p(3)
* En base a estos puntos armo dos vectores, cuando el npc llega a p(2)
* caclulo los dos vectores y después ro, ese ro es el angulo a mirar por el npc
*
*
* \param a
* p(1) punto próximo
*
* \param b
* p(2) punto actual
*
* \param c
* p(3) punto anterior
*
* \returns
* Regresa ro, el ángulo a mirar por el NPC
*
*/
float KNpc::CalculateAngleToFace(Vertex* p1,Vertex* p2,Vertex* p3){
// es el angulo que regreso para usar en la rotación
float realAngle = 0;
// 1. Armo los dos vectores en base a los puntos
Vertex v1,v2;
v1.x = p1->x - p2->x;
v1.y = p1->y - p2->y;
v1.z = p1->z - p2->z;
v2.x = p2->x - p3->x;
v2.y = p2->y - p3->y;
v2.z = p2->z - p3->z;
// 2. saco el producto escalar
float prodEscalar = (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
float normal_y = ((v1.z*v2.x) - (v1.x*v2.z)); // es el producto vectorial
// 3. saco los módulos de los vectores
float modV1 = sqrt( ((v1.x*v1.x) + (v1.y*v1.y) + (v1.z*v1.z)) );
float modV2 = sqrt( ((v2.x*v2.x) + (v2.y*v2.y) + (v2.z*v2.z)) );
// 4. calculo ro
if(modV1 < 1 ) modV1 = 1;
if(modV2 < 1 ) modV2 = 1;
float ro = acos( prodEscalar / (modV1*modV2) );
if(normal_y >=0)
realAngle = RAD_TO_DEG(ro)-modelNpc->GetRotation()->z;
else
realAngle = RAD_TO_DEG(ro)+modelNpc->GetRotation()->z;
if( realAngle >= 360 )
realAngle -= 360;
if( realAngle < 0 )
realAngle += 360;
return realAngle;
}//fx
No entiendo estas lineas:
if(normal_y >=0)
realAngle = RAD_TO_DEG(ro)-modelNpc->GetRotation()->z;
else
realAngle = RAD_TO_DEG(ro)+modelNpc->GetRotation()->z;
Yo creo que no necesitas el punto anterior, te basta con tener el vector frontal al personaje y hacer el producto escalar de los vectores front y P1-P2 normalizados. Luego haces el acos como tu bien has puesto y ya lo tienes.
Trabajas guardando las orientaciones con pitch,yaw,roll? lo digo porque para orientaciones nada mejor que usar cuaterniones. Con el pitch yaw roll puedes tirar si tienes un mundo plano, pero como quieras hacer algo más libre estas jodido.
Ok voy a intentar eso que me comentas, lo de la duda del código ya le he eliminado a esa proción de código, usaba el otro vector, el anterior como el front, en lugar de tener un vector que me represente hacia donde tiene el frente el modelo... modifico las cosas y comento como va...
Creo que es más sencillo calculando el arcotangente2 (normalmente la función es atan2 que suelen tenerla la mayoría de los librerías) y con eso sacas el ángulo que tendrías que rotar en cada eje...