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!






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.