Cómo resolver la penetración de dos cuerpos que chocan

9

He implementado un simple motor de física de juegos en 3D. Ya tengo una detección de colisión decente, ahora estoy tratando de averiguar la parte de respuesta a colisión. Estoy usando un método basado en impulsos para calcular las velocidades posteriores a la colisión. Esto funciona bastante bien, sin embargo, no evita por completo que los cuerpos sigan interpenetrando. Entonces tengo un código adicional para resolver la penetración. Actualmente, solo muevo los cuerpos a lo largo del contacto normal a la mitad de la profundidad de penetración: primer cuerpo en la dirección del contacto normal, segundo cuerpo en la dirección opuesta.

Esto está bien la mayor parte del tiempo, pero hay algunos efectos indeseables. Por ejemplo, imagine un corredor estrecho y un objeto moviéndose a través de él. Si el objeto golpea una de las paredes del corredor, la resolución de penetración lo mueve hacia la pared opuesta, luego, en el siguiente cuadro, nuevamente dentro de la primera pared y así sucesivamente. El efecto es que el objeto vibra muy rápido entre las paredes, lo que no es bonito.

Entonces, mi pregunta es si hay una mejor manera de resolver la penetración. Quizás no mueva los cuerpos, solo ajuste de alguna manera sus velocidades (además del cálculo del impulso) para que dejen de moverse el uno hacia el otro y la penetración se resuelva en los próximos dos cuadros. Solo estoy adivinando aquí. ¿Algunas ideas?

Adán
fuente

Respuestas:

3

Cuando detecte una colisión, determine a qué hora / punto los cuerpos comenzaron a colisionar por primera vez y trate la colisión en este punto. Es posible que aún tenga una ligera penetración que resolver en este punto, pero será mucho más pequeña y [típicamente] no producirá los problemas de oscilación que está teniendo.

Digamos que tiene pasos de simulación de 100 ms y que en algún cuadro, tiene dos bolas que chocan a la mitad (50 ms) dentro del cuadro. Primero, detectará que colisionaron en cualquier punto del marco (lo que confío en que ya lo esté haciendo de manera efectiva). Determinarán en qué punto durante el cuadro chocaron. Ahora maneje la colisión, incluidos los primeros 50 ms del marco en el que no colisionaron. Ahora tendrá las nuevas velocidades de las bolas, y también puede tomar medidas ahora para asegurarse de que no penetren (estas deberían ser muy pequeñas ya que "simplemente sucedió"). Finalmente, simulará los próximos 50s de el marco. Tenga en cuenta que durante este período, es muy posible que haya otra colisión con una o ambas bolas.

notlesh
fuente
1
Entonces, básicamente, sugiere implementar la detección de colisión continua y luego manejar las penetraciones que aún quedan de la misma manera que ya lo hago, ya que probablemente serán muy pequeñas. Esto podría funcionar, supongo. Ahora solo tengo que descubrir cómo hacer que mi detección de colisión sea continua :)
Adam
No estoy seguro de lo que quieres decir con continuo. Estrictamente hablando, no hay nada continuo en la simulación física, ya que todo siempre se divide en pasos discretos de algún tamaño. Tomar pasos más pequeños, que es esencialmente lo que sugiero, generará errores mucho más pequeños (y más fáciles de corregir). Otra forma de pensar en esto es que existe una relación directa entre el tamaño del paso y los errores (como la penetración). Entonces, cuando detecte dicho error, divídalo en pasos más pequeños hasta que el error sea trivialmente reparable.
notlesh
La detección de colisión continua significa que, en lugar de verificar la intersección entre dos objetos estáticos (un problema 3d), verifica el contacto de dos objetos en movimiento (básicamente, un problema 4d). Por lo general, es suficiente considerar solo las velocidades constantes, porque puede aproximar las trayectorias con curvas lineales por partes. La ventaja es que la distancia de penetración siempre será cero (o cercana a, debido a errores de redondeo de flotación). Pensé que estabas hablando de esto, pero ¿tal vez interpreté mal tu respuesta?
Adam
@adam Sí, de eso estoy hablando.
notlesh
2

Echa un vistazo a este artículo, que se ha publicado aquí muchas veces antes, solo busca a través de las preguntas y respuestas etiquetadas de detección de colisión: te muestra cómo hacer la resolución de colisión "continua" de la que hablaba Stephelton:

http://www.gamasutra.com/view/feature/3383/simple_intersection_tests_for_games.php?page=3

Básicamente, resuelve algunas ecuaciones cinemáticas básicas para el punto de tiempo exacto cuando sus dos cuadros delimitadores comenzaron a cruzarse. Resuelve sus colisiones en ese momento exacto y luego continúa con el tiempo restante en su marco. Es posible que tenga que volver a simular lo que sucede después del momento de la colisión, ya que las velocidades / aceleraciones de sus objetos habrán cambiado. Pero ahí está tu punto de partida, de todos modos ... ¡salud!

Mediocrito
fuente
Gracias, revisé el artículo. La cosa es que estoy usando una representación diferente de mis objetos. Estoy usando poliedros convexos y probando la colisión usando el teorema del eje de separación. Esto se puede extender para manejar cuerpos que se mueven con velocidades lineales constantes (que sé cómo hacerlo), pero no tengo idea de cómo manejar también velocidades angulares. Pero haré una pregunta por separado si decido seguir este camino.
Adam