Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Precision en Ray Casting

Iniciado por Prompt, 20 de Junio de 2008, 09:50:24 PM

« anterior - próximo »

Prompt

Llevo unos dias probando mi implementación de Ray Casting, la parte inicial en la que según las coordenadas del ratón X e Y obtengo un vector de origen y una dirección.

Si utilizo gluUnProject a veces falla, para calcular los 2 puntos el inicial y el final, pasando como parametro 0.0 y 1.0 obtengo el punto inicial y el final. A veces el punto final falla.

En GameDev alguien que lo hizo como yo tenia el mismo problema.

He probado como viene en el FAQ de OpenGL

http://www.opengl.org/resources/faq/technical/selection.htm

Pues bien, con esta forma no tengo la misma precisión. Y falla un poco...

Alguien sabe de donde viene que a veces falle gluUnProject ?

Post en GameDev:
http://www.gamedev.net/community/forums/topic.asp?topic_id=396263

Prompt

Por si quereis ayudarme, el código que falla al cambiar el aspect ratio es:

// http://www.opengl.org/resources/faq/technical/selection.htm
// 20.010 How can I know which primitive a user has selected with the mouse?
// Nota: no tiene tanta precision como con gluUnproject
{
int    window_x = mouse_x - m_width / 2;
int    window_y = (m_height - mouse_y) - m_height / 2;

float norm_x   = float(window_x) / float(m_width  / 2);
float norm_y   = float(window_y) / float(m_height / 2);

float zNear  = m_pCamera->getZNear( );
float aspect = m_pCamera->getAspectRatio( );

float x = zNear * aspect * norm_x;
float y = zNear * norm_y;

Vector3 pickRay(x, y, -zNear);
pickRay.normalize( );

Vector3 eyeRay = pickRay * m_pCamera->getViewMatrix( ).inverse( );

return Ray(m_pCamera->getPosition( ), eyeRay);
}


Hay algo que no estoy teniendo en cuenta, pero es igual al del FAQ de OpenGL: http://www.opengl.org/resources/faq/technical/selection.htm

ethernet

Por qué no pruebas a hacer unos test unitarios sobre ese método o función? sobretodo probando los casos mas extremos.

Aparte, qué signigica que "el punto final falle?"

Prompt

Hay que obtener 2 puntos:

- Comienzo del frustum
- Final del frustum

Un rayo tiene un vector de origen y una dirección.

El test unitario da como resultado que al intentar obtener el punto final del frustum de la camara (pasandole a glUnProject 1.0, recordemos que para el inicial Z es 0.0) repitiendo la operación inumerables veces sin modificar nada, el vector obtenido a veces no es correcto.

vDireccion = vFinal - vOrigen

El inicial debe coincidir con la posición de la camara... etc. El rayo no se tira nunca hasta el final en realidad, se obtiene la Z maxima de lo que hay en pantalla y cosas varias.

Lo chungo es que no me pasa solo a mi y he probado mil cosas del FAQ de OpenGL a hacerlo exacto y a aplicar diferentes aspectRatio. Si el aspectRatio es 1.0 graciosamente suele dar el rayo en su sitio. Lo que no recuerdo es si proyectaba bien el rayo dejando la camara quieta y apuntando a las esquinas del Viewport... he hecho mil pruebas ya xD

Lo peor que puede pasar utilizando glUnProject es que descarte los vectores que salgan q sean muy diferentes con alguna comprobación. Lo mas seguro es que me baje del CVS de MESA la función y la revise, debe haber algo chungo.

Saludos.

Prompt

Nota adicional:


float bottomY = viewport[3] - mouse_y;

gluUnProject(mouse_x, bottomY, nominated_screen_z, mModelView, mProj, viewport, &world_x, &world_y, &world_z);

ethernet

He entendido lo siguiente: "si llamo a gluUnproject muchas veces con los mismos valores tengo diferentes valores de retorno".

Yo he usado esa técnica de "desproyectar" y me ha funcionado bien para valores lógicos de near y far (o sea de matriz projection), qué valores tienes para esa matriz?

Prompt

Solved! 3:48 de la mañana.

Al utilizar glGetIntegerv(GL_VIEWPORT, viewport); la altura me la daba mal a veces...

No debería haber usado esto ya que tengo capturado el evento de "resize" de la ventana y modifico mi width y height.

Como sabeis, en OpenGL los valores de coordenada Y empiezan abajo a la izquierda como 0, 0. y hay que hacer:

GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);

float bottomY = viewport[3] - mouse_y;


no uso para nada, glGetIntegerv o glGetDoublev ( para las matrices de proyeccion y modelView ) lo controlo yo todo, imagino que de vez en cuando se hace la picha un lio al redimensionar la ventana de render y daba un valor de 512 en vez de 600 ( por ejemplo o lo q fuere equivalente al valor height real que me da la ventana ) entre frames.

Así que está todo solucionado :) viva el debugger ^^

Gracias por todo ethernet. Un saludo.

AK47

Mamonazos, es proYectar, no proJectar. Qe daño a etxo el inglés...

Sin acrituZ ni tensiones  :lol:

Prompt

hahahaha :P la proJsima vez que nos interrumpas... veras!

Si es que... a mi ya me pasó contigo xD y por eso ya tengo cuidado!