No meu mecanismo de física 2D, posso detectar colisões AABB vs AABB e resolvê-las, encontrando o menor vetor de penetração e adicionando-o à posição da AABB.
Fazer isso "empurra" o primeiro AABB para fora do segundo AABB, mas não lida com as mudanças de velocidade / aceleração.
Se eu adicionar aceleração por gravidade à minha simulação, a velocidade do primeiro AABB dinâmico continua crescendo, mesmo quando está apoiada no segundo AABB estático. Eventualmente, a velocidade se tornará muito grande e a colisão não será detectada (o AABB dinâmico passará pelo estático).
Tentei ajustar a velocidade para zero após a resolução, mas obviamente não funcionou bem e criei simulações irrealistas.
Li online que a resolução de colisões trabalhando manualmente na posição ou a velocidade não está correta. Tentei implementar forças (massa é um "codificado" 1 por enquanto):
void Body::applyForce(sf::Vector2f mForce) { acceleration += mForce; }
void Body::integrate(float mFrameTime)
{
velocity += acceleration * mFrameTime;
position += velocity * mFrameTime;
acceleration = {0, 0};
}
Se eu aplicar o menor vetor de penetração como força durante a resolução de colisão, o AABB dinâmico será "empurrado" para fora do estático, mas sua velocidade nunca diminuirá em uma simulação sem gravidade e continuará se movendo para sempre.
Existe uma maneira de aplicar uma força "temporária"? Uma força que lida com empurrar o primeiro AABB para fora do segundo AABB e depois para quando o AABB não colide mais?
Código fonte completo disponível aqui: https://github.com/SuperV1234/SSVSCollision
fonte
Respostas:
Primeiro, recomendo o uso de uma biblioteca física gratuita e de código aberto, como o Box2D, e focando apenas nos aspectos do seu jogo que o tornam único! Se você insistir em reinventar a roda, continue lendo ... note que todos os mecanismos de física são aproximações e, embora o método descrito abaixo seja mais preciso do que o seu modelo atual, os resultados do Box2D serão muito mais realistas.
Para uma maneira rápida de modelar uma resolução de colisão mais precisa de dois objetos A e B:
Por favor, dê uma olhada no meu programa de asteróides de amostra que demonstra esses conceitos.
Em seguida, considere os objetos empilhados:
Como você observou, o uso da velocidade para simular objetos empilhados / em repouso não funciona bem: velocidade é a velocidade que um objeto está se movendo; portanto, se estiver descansando em um objeto estático, a velocidade deve estar próxima de 0. Não faz sentido aumentar a velocidade de um objeto para fazê-lo aparecer em repouso:
O que realmente deveria acontecer é uma força de aceleração que está indo na direção oposta, pois a gravidade deve cancelar a gravidade. (Isso é chamado de força de contato normal). Um atalho é simplesmente não aplicar gravidade a corpos que não estão no ar:
Atualizar:
fonte
Resolver este problema requer o ajuste da posição e possivelmente da velocidade. Os motores de física do corpo rígido têm um solucionador que marcha os objetos para a frente no tempo, usando as leis do movimento de Newton, além de resolver restrições de atrito e não penetração. Esses mecanismos podem calcular a combinação certa de movimento linear e angular para criar trajetórias plausíveis.
Se você deseja resolver apenas a sobreposição, pode usar pseudo-velocidades que geram trajetórias de separação sem aumentar o momento. Isso é feito no solucionador de posição do Box2D.
Eu recomendo minhas apresentações do GDC de 2006 e 2007 aqui:
http://code.google.com/p/box2d/downloads/list
Além disso, você pode consultar o Box2D Lite para uma implementação simplificada.
fonte
No mundo real, não há força que "empurre" um corpo para fora de outro, porque os objetos nunca se penetram. O mais próximo é a força normal : criada no momento do contato em colisões no mundo real, impede a penetração em primeiro lugar.
O ângulo dessa força normal é perpendicular à superfície de contato dos dois objetos em colisão. A magnitude depende de quanta força é necessária para impedir a penetração. (Observe que apenas o componente y da força normal deve ser usado, a menos que outras forças como a força de atrito também sejam modeladas).
Embora seja possível modelar explicitamente a força normal, é mais simples modelar apenas seus efeitos:
Descrevi isso de maneira um pouco diferente em minha outra resposta, que é mais sobre colisões em geral .
fonte