void Entity::BillboardXZ(Vector3d Target) { Vector3d objToCamProj,objToCam,upAux; Vector3d lookAt(0,0,1); float angleCosine; // objToCamProj es el vector en coordenadas globales que va desde "el que mira" // hasta "lo que ve" proyectado en el plano XZ (Y=0) y normalizado. Target.Subtract(Position,objToCamProj); objToCamProj.y = 0; objToCamProj.Normalize(); // Determinamos si el angulo es positivo o negativo // Para angulos positivos upAux apuntara en una direccion positiva // de lo contrario upAux apuntara hacia abajo, invirtiendo la rotacion upAux = lookAt.CrossProduct(objToCamProj); // Cuando son paralelos el eje de giro no es 0,0,0 como nos da el producto vectorial, sino 0,1,0 if( upAux.x==0 && upAux.y==0 && upAux.z==0 ) upAux.y=1; // Calculamos el angulo angleCosine = lookAt.DotProduct(objToCamProj); // Evitamos posibles problemas de precisión if (angleCosine > 1) angleCosine = 1; else if (angleCosine < -1) angleCosine = -1; // Realizamos el giro de las coordenadas cilíndricas glRotatef( acos(angleCosine) * 180.0f/3.14f, upAux.x, upAux.y, upAux.z); }