2010-03-21 8 views

Respuesta

1

Un pensamiento que tuve fue almacenar en caché los resultados de llamar a gluProject. Esto solo puede ser práctico cuando se trata de una cámara fija. Al final de cualquier cambio en la perspectiva de la cámara, puedo regenerar este caché de "tocadiscos".

Esto también tiene la ventaja adicional de garantizar que solo estoy probando la entrada contra elementos que responderán al tocarse.

¡Agradecería cualquier idea sobre este enfoque!

1

Depende completamente de qué es lo que estás renderizando. Probablemente no deba utilizar el método de picking porque

a) Parece que será lento, especialmente en android. b) Es posible que desee tener una "área táctil" más grande para objetos pequeños para que no tenga que tocar precisamente donde están. c) Realmente no responde la pregunta correcta: le da el resultado "¿Cuál es el elemento gráfico más alto que se ha representado exactamente donde toqué?" mientras que quieres saber "¿Qué entidad de juego tocó o tocó el usuario cerca?"

Como dije, depende completamente de tu juego. Si se trata de un juego 2D o casi 2D, entonces es simple y solo debes introducir las coordenadas táctiles en tu modelo de juego. Para los juegos en 3D, sugeriría este algoritmo simple que me ocurrió en el acto:

  1. Haz una lista de todos los objetos del juego que se puedan haber tocado.
  2. Transforma sus coordenadas centrales en coordenadas de pantalla 3D. (Las coordenadas de la pantalla 2D se describen aquí: http://www.flipcode.com/archives/Plotting_A_3D_Point_On_A_2D_Screen.shtml)
  3. Encuentra la distancia 2D para cada objeto, descarta objetos con una distancia mayor a tu umbral táctil.
  4. Encuentra el objeto más cercano de acuerdo con alguna medida de distancia. Tendrás que experimentar en este punto y de nuevo, depende de la naturaleza del juego.

Para obtener resultados exactos, se podría usar la intersección de línea. Existen algoritmos para eso (búsqueda de 'intersección de línea de plano raycasting').

+0

Asumiendo que la forma de todos los objetos es la misma y que la distancia en 3D a la cámara es la misma. No creo que estas sean suposiciones válidas en la mayoría de los casos. – mnemosyn

4

Si está haciendo una selección de 2D a 3D, debe manipular un poco las matrices y los vectores. GlUnproject no existe para OpenGL ES 1.1, por lo que debe hacer algunas operaciones matemáticas usted mismo.

intersección Ray-objeto es un camino por recorrer en ese momento. La respuesta de Timmmms ya cubre parte de ella, pero hay más. Idea es crear un rayo a 3D a partir de coordenadas 2D. La matriz de visión inversa y de proyección se necesita para eso. Una vez que tiene rayos, puede usar la prueba de intersección de rayos de su elección y, por supuesto, debe seleccionar el objeto más cercano, como en Timmmm 4. Las esferas delimitadoras y los cuadros delimitadores son fáciles de implementar e Internet está lleno de tutoriales de prueba de intersección.

This picking tutorial es para DirectX, pero puede que se haga una idea. La construcción de rayos es la parte más importante.

Editar Android implementa su propia versión de gluUnproject. Se puede usar para crear un rayo, llamándolo por el plano cercano y lejano (0 y 1) y restando los resultados del plano cercano de los resultados del plano lejano para obtener la dirección del rayo. El origen de Ray es la ubicación de la vista. Más here.

+0

Tenía la impresión de que admitía gluUnProject(): http://developer.android.com/reference/android/opengl/GLU.html –

+1

Oh. Efectivamente, Android parece implementar su propia versión entonces. No es parte de OpenGL ES 1.1 de todos modos. Puede usar esa función para crear rayos llamándolo dos veces: http://www.opengl.org/resources/faq/technical/selection.htm – Virne

+0

¿Alguna sugerencia sobre cómo calculo con qué se está cruzando ese rayo? –

2

Creo que para la mayoría de las aplicaciones debe elegir el enfoque 3D correcto: Ray casting.

Tome la ubicación en las coordenadas de pantalla 2D seleccionadas por el usuario y proyectelas en su espacio mundial. Esto le da un rayo 3D que se origina en la cámara y apunta a la escena. Ahora necesita realizar pruebas de colisión en 3D. En la mayoría de los casos, esto se puede lograr reduciendo los objetos a un conjunto de geometrías simples como elipsoides, esferas y cajas para acelerar.

Dada la precisión de los dispositivos portátiles, ya debería haber suficiente precisión. Tenga en cuenta que, dependiendo de la forma del objeto, es posible que necesite usar más de una primitiva básica. Además, no tiene sentido utilizar siempre el mismo primitivo: una esfera delimitadora es una aproximación muy mala para una varilla muy larga, obviamente.

+0

¿Conoces algún tutorial que explique estas pruebas? –

+1

No realmente, desafortunadamente. Hay partes y piezas aquí y allá, pero no pude encontrar una implementación concisa todavía. ¿Qué tan pronto lo necesitas? Tal vez podría escribir algo ... – mnemosyn

+0

¡Nunca diré que no a un nuevo tutorial! ¡Si terminas haciendo uno, me encantaría verlo en el contexto de Java + Android! –

Cuestiones relacionadas