En mi motor de física 2D, puedo detectar colisiones AABB vs AABB, y resolverlas al encontrar el vector de penetración más corto y agregarlo a la posición de AABB.
Hacer esto "empuja" al primer AABB fuera del segundo AABB, pero no trata en absoluto los cambios de velocidad / aceleración.
Si agrego aceleración por gravedad a mi simulación, la velocidad del primer AABB dinámico sigue creciendo incluso cuando descansa sobre el segundo AABB estático. Finalmente, la velocidad será demasiado grande y no se detectará la colisión (el AABB dinámico caerá a través del estático).
Intenté establecer la velocidad a cero después de la resolución, pero obviamente no funcionó bien, y creé simulaciones poco realistas.
Leí en línea que resolver colisiones trabajando manualmente en la posición o la velocidad no es correcta. Intenté implementar fuerzas (la masa es un "codificado" 1 por ahora):
void Body::applyForce(sf::Vector2f mForce) { acceleration += mForce; }
void Body::integrate(float mFrameTime)
{
velocity += acceleration * mFrameTime;
position += velocity * mFrameTime;
acceleration = {0, 0};
}
Si aplico el vector de penetración más corto como fuerza durante la resolución de colisión, el AABB dinámico será "expulsado" del estático, pero su velocidad nunca disminuirá en una simulación sin gravedad y seguirá moviéndose para siempre.
¿Hay alguna forma de aplicar una fuerza "temporal"? ¿Una fuerza que trata de empujar al primer AABB fuera del segundo AABB, y luego se detiene cuando el AABB ya no choca?
Todo el código fuente disponible aquí: https://github.com/SuperV1234/SSVSCollision
fuente
Respuestas:
Primero, recomiendo usar una biblioteca de física gratuita y de código abierto como Box2D y ¡solo enfocarme en los aspectos de tu juego que lo hacen único! Si insiste en reinventar la rueda, siga leyendo ... tenga en cuenta que todos los motores de física son aproximaciones, y aunque el método que describo a continuación será más preciso que su modelo actual, los resultados de Box2D serán mucho más realistas.
Para una forma rápida de modelar una resolución de colisión más precisa de dos objetos A y B:
Eche un vistazo a mi programa de muestra de asteroides que demuestra estos conceptos.
A continuación, tenga en cuenta los objetos apilados:
Como ha notado, usar la velocidad para simular objetos apilados / en reposo no funciona bien: la velocidad es la velocidad a la que se mueve un objeto, por lo que si está descansando sobre un objeto estático, la velocidad debería estar cerca de 0. No tiene sentido aumentar La velocidad de un objeto para que aparezca en reposo:
Lo que realmente debería suceder es una fuerza de aceleración que vaya en la dirección opuesta, ya que la gravedad debería cancelar la gravedad. (Esto se llama la fuerza de contacto normal). Un atajo es simplemente no aplicar la gravedad a los cuerpos que no están en el aire:
Actualizar:
fuente
Resolver este problema requiere ajustar la posición y posiblemente la velocidad. Los motores de física de cuerpo rígido tienen un solucionador que hace avanzar los objetos en el tiempo usando las leyes de movimiento de Newton y al mismo tiempo resuelve las restricciones de no penetración y la fricción. Estos motores pueden calcular la combinación correcta de movimiento lineal y angular para crear trayectorias plausibles.
Si solo desea resolver la superposición, puede usar pseudovelocidades que generan trayectorias de separación sin agregar impulso. Esto se hace en el solucionador de posición de Box2D.
Recomiendo obtener mis presentaciones de GDC de 2006 y 2007 aquí:
http://code.google.com/p/box2d/downloads/list
Además, puede mirar Box2D Lite para una implementación simplificada.
fuente
En el mundo real, no hay fuerza que "empuje" un cuerpo fuera de otro porque los objetos nunca se penetran entre sí. Lo más cercano es la fuerza normal : creada en el momento del contacto en colisiones del mundo real, evita la penetración en primer lugar.
El ángulo de esta fuerza normal es perpendicular a la superficie de contacto de los dos objetos que chocan. La magnitud depende de cuánta fuerza se necesita para evitar la penetración. (Tenga en cuenta que solo se debe usar el componente y de la fuerza normal a menos que también se modelen otras fuerzas como la fuerza de fricción).
Si bien es posible modelar explícitamente la fuerza normal, es más sencillo modelar solo sus efectos:
Describí esto de manera ligeramente diferente en mi otra respuesta, que es más sobre colisiones en general .
fuente