2011/06/19

11-06-19 Obtener los valores globales de un punto en OpenGL

Hola a todos!

Este post me parece que es importante para muchos que sufrimos por obtener los valores globales de un punto en OpenGL.

Para que todos nos podamos entender, si nosotros definimos un punto en OpenGL, digamos el punto [0,0,0], en un arreglo este siempre conservara estos valores mientras nosotros no los modifiquemos directamente, por otro lado, si aplicamos una transacción del tipo glTranslatef(1,0,0) el punto no se dibujara en (0,0,0), sino por lógica en (1,0,0), sin embargo los valores de nuestro arreglo no cambiaron, seguirán siendo [0,0,0], esto, al momento de dibujar realmente no nos preocupa, pues el punto se dibuja en la posición que queremos, sin embargo imaginemos un caso mas particular, imaginemos que nosotros ideamos una rutina en la que cuando el punto se encuentre en [1,0,0] ocurra un evento explicito, aunque para nosotros el punto se encuentra en (1,0,0) los valores del arreglo siguen siendo [0,0,0] esto es porque los valores del arreglo están dadas en coordenadas locales y si queremos evaluar la posición en coordenadas globales TODOS los cálculos tendremos que hacerlos a mano.

En el ejemplo anterior bastara con sumar 1 en las coordenadas de x para hacer la comprobación en coordenadas globales, pero esto ya implico llevar una cuenta a mano, en traslaciones esto pudiera ser un caso sin importancia, solo tendríamos que saber cuanto incrementar en x, en y, en z para saber las coordenadas globales de un punto dadas sus coordenadas locales y las traslaciones que se han hecho, nada del otro mundo... sin embargo que ocurre cuando metemos rotaciones a esta ensalada? La respuesta es muy simple: CAOS.

Podemos tener una librería de Matrices muy bien programada, pero esto desperdicia ciclos preciosos que podríamos aprovechar en otra cosa, podríamos hacer la cuenta a mano mediante senos y cosenos, sin embargo no se ustedes pero a mi eso de la trigonometria no se me da con tanta facilidad, y estar pensando en conversiones de grados a radianes y cosas por el estilo me complica la existencia y hace que pierda mas cabello.

Les propongo una solución mucho mas sencilla, utilizar la misma matriz de proyección de OpenGL para obtener los valores que queremos, veran, si bien es cierto que OpenGL no nos muestra directamente el valor de un punto en coordenadas globales si lo sabe... si no de que otra manera calcularía las proyecciones en pantalla? Aunque hay que hacer un pequeño truco para obtener la información que queremos de el. El chiste consiste realmente en resetear la matriz de proyección a la de identidad, de esta manera todos los cálculos que realicemos estarán basados en la matriz identidad y después de los movimientos requeridos le preguntamos a OpenGL por esta matriz, los valores de la matriz en m[12], m[13] y m[14] nos darán la posición original del punto, un ejemplo:

// Estructura donde almacenamos los valores de nuestro punto
struct tPunto
{
  float x;
float y;
float z;
tPunto()
{
x = y = z = 0.0f;
};


tPunto(float _x, float _y, float _z)
{
x = _x;
y = _y;
z = _z;
};

}mPunto (1.0f, 1.0f, 1.0f);

float matrix[16]; // Esta es la matriz donde vaciaremos la matriz de proyección
glPushMatrix(); // respaldamos la matriz de proyección para poder seguir trabajando en ella después de esto.
glLoadIdentity(); //Reseteamos la matriz a la identidad

glRotatef( 25, 1, 0, 0);//Rotación arbitraria
glRotatef( 20, 1, 0, 0);//Rotación arbitraria (sumada con la de arriba tendremos 45 grados en x)
glTranslatef( 1, 0, 0);//Traslación arbitraria

glTranslatef( mPunto.x, mPunto.y, mPunto.z); // Trasladamos por ultimo en la dirección del punto

glGetFloatv(GL_MODELVIEW_MATRIX , matrix);// Preguntamos a OpenGL por la matriz de proy.

mPunto = tPunto(matrix[12],matrix[13],matrix[14]);//obtenemos las coordenadas globales del punto.
glPopMatrix();//Regresamos la matriz a como la encontramos

Como ven lo realmente importante es trasladar en la posición del punto después de hacer todas las transformaciones que ocupamos y preguntar por la matriz. Esto les salvara muchos dolores de cabeza y estar calculando ángulos.

Espero les sirva, a mi me ha ayudado mucho.

Yo soy Alberto y ese ha sido mi post.
Yo soy Alberto y ese ha sido mi post. Happy Codding!

1 comentario:

Luis dijo...

Funciona perfecto, muchas gracias me ha ayudado mucho :P