2012-09-10 17 views
6

Quiero evitar que mi jugador pueda pararse dentro de las paredes. Cada tic del juego mi jugador se mueve una pequeña distancia y/o gira.colisionando con una malla de loci

TL; DR favor suministrar una variante de la línea del segmento clásico -> - algoritmo de intersección triángulo que devuelve cuasiaccidentes también, o resolver el problema de otra manera El segmento de línea se cruza si pasa dentro de una distancia dada del triángulo. Hay mucha sutileza en el problema, como las esquinas del lugar geométrico del triángulo redondeadas y si el segmento de línea es tangencial al triángulo.

Tengo el código de intersección de rayos/triángulos habitual.

Sin embargo, un rayo es una muy mala aproximación de un jugador en movimiento! Tengo problemas con los bordes faltantes del centro del jugador, pero la malla del jugador los atraviesa.

¿Cómo se puede determinar de manera eficiente cuándo y dónde un jugador colisiona con paredes y obstáculos en un entorno 3D?

Una aproximación general sería tener un código de triángulo casi perdido, donde el rayo es un cilindro con bola.

La solución general que he intentado hacer es imaginar que el jugador es una esfera; convirtiendo esto de adentro hacia afuera, he intentado hacer una malla cuyo radio es más grande que las paredes reales y hacer rayos de colisión en eso. Quiero calcular una malla que esté a cierta distancia fija en frente de esta malla, es decir, un cubo se expandiría para ser un cubo ligeramente más grande con bordes redondeados y esquinas. (Mis mallas son bastante menos regulares que un cubo. Imagine una representación en malla del interior de una sala de calderas, e imagine que intenta calcular una malla que está a 20 cm de todas las paredes, calderas y marcos de puertas y demás en esa habitación). Aquí es un simple malla alrededor de un barril:

enter image description here

Para cada cara puedo calcular la superficie normal; así es como sé qué camino está 'fuera'.

Mi tormenta de ideas me hace imaginar multiplicando la normalidad de cada cara por la distancia fija y luego emitiendo un triángulo con el desplazamiento correspondiente.

Esto sin embargo dejaría agujeros en los bordes y podría (?) Causar que algunos bordes pasen por esquinas agudas muy apretadas?

También me puedo imaginar unir cada borde como cilindros con bola, y así sucesivamente.

El enfoque que utilicé para el cañón anterior es calcular el promedio normal de todas las caras que comparten un vértice y luego multiplicarlo por el radio de colisión. No cubre bien los ángulos agudos, y ¿qué hacer si un vértice se comparte falsamente entre caras que están en lados opuestos?

Estaré computando esta malla, y luego realizando intersecciones de rayos, en Javacsript. Entonces el rendimiento es una consideración también. Una malla demasiado fina y detallada será costosa para detectar colisiones.

¿Cómo se puede calcular de manera efectiva una malla loci lo suficientemente buena? ¿O hacer una intersección de triángulos borrosos conscientes de loci? ¿O existe una mejor manera de colisionar, y puede modelar de alguna manera que las cosas se muevan en arcos en lugar de hacerlo en línea recta?

+0

¿Realmente necesita la malla ampliada? ¿No puedes usar la malla original y considerar las colisiones como una distancia inferior a tu umbral (en lugar de la intersección)? –

+0

@ Anony-Mousse Tuve problemas con los rayos que faltaban en los bordes del triángulo, pero el jugador los atravesaba. ¿Cómo se puede hacer la intersección de la malla y la pared del jugador en un camino? Todo parece difícil, por desgracia. – Will

+0

Los enfoques que conozco funcionan solo con calcular las distancias. Si sus mallas son convexas, debería estar bien calcular las distancias entre el vértice y el triángulo. Y si asumes que el jugador es esférico, solo necesitarás calcular las distancias jugador-triángulo, y restar el tamaño del jugador de la distancia. –

Respuesta

0

(nadie recogió la recompensa :(Nathan Reed on gamedev.stackexchange ayudó con la terminología. Se llama intersección cápsula-triángulo.)

Su matemática sorprendentemente difícil y Google no encuentra mucho código listo para copiar.

A standard way es extruir el triángulo por el radio, agregar también probar cada uno de los tres bordes del triángulo como cápsulas.

Para extruir el triángulo, solo debe multiplicar la normal del triángulo por el radio de la cápsula, desplazar cada esquina del triángulo en esa cantidad y luego hacer la prueba triangular de segmento de línea normal en su contra.

La prueba de la cápsula para cada borde triangular es bastante más cara ya que tiene que hacerlo tres veces. Es posible que usar las coordenadas baricéntricas de la prueba triangular ayude a evitar algunas de las pruebas de borde de la cápsula, pero no lo he pensado bien. También puede evitar la prueba de cápsula en los bordes que se comparten con otros triángulos que son lo suficientemente obtusos; podrías calcular esto y marcar esos bordes. No me he molestado (aún).

Descubrí que precomputar la esfera delimitadora de cada cara y hacer una prueba de intersección con la esfera delimitadora de la cápsula era una forma superbarata de evitar esta costosa prueba la mayor parte del tiempo. También precalculo las normales de cada cara, aunque esa es una ganancia menor.

Como la prueba es tan cara, lo mejor que puede hacer es tratar al jugador como una sola esfera y hacer que el código de intersección muestre una lista de las intersecciones de la cara. Luego puede modelar al jugador como una serie de esferas más pequeñas volando en formación, y solo tiene que hacer el código de intersección de la cara de la cápsula para las caras que encuentra el primer pase con la esfera más grande.

Cuestiones relacionadas