Dans mon moteur de physique 2D, je peux détecter les collisions AABB vs AABB et les résoudre en trouvant le vecteur de pénétration le plus court et en l'ajoutant à la position de l'AABB.
Faire cela "pousse" le premier AABB en dehors du second AABB, mais ne gère pas du tout les changements de vitesse / accélération.
Si j'ajoute une accélération de la gravité à ma simulation, la vitesse du premier AABB dynamique continue de croître même lorsqu'il repose sur le deuxième AABB statique. Finalement, la vitesse deviendra trop grande et la collision ne sera pas détectée (l'AABB dynamique tombera à travers la statique).
J'ai essayé de mettre la vitesse à zéro après la résolution, mais cela n'a évidemment pas bien fonctionné et j'ai créé des simulations irréalistes.
J'ai lu en ligne que la résolution des collisions en travaillant manuellement sur la position ou la vitesse n'est pas correcte. J'ai essayé de mettre en œuvre des forces (la masse est "codée en dur" 1 pour l'instant):
void Body::applyForce(sf::Vector2f mForce) { acceleration += mForce; }
void Body::integrate(float mFrameTime)
{
velocity += acceleration * mFrameTime;
position += velocity * mFrameTime;
acceleration = {0, 0};
}
Si j'applique le vecteur de pénétration le plus court en tant que force pendant la résolution de la collision, l'AABB dynamique sera "expulsé" du statique, mais sa vitesse ne diminuera jamais dans une simulation sans gravité et il continuera de se déplacer pour toujours.
Existe-t-il un moyen d'appliquer une force "temporaire"? Une force qui s'occupe de pousser le premier AABB hors du second AABB, puis s'arrête lorsque l'AABB ne se heurte plus?
Code source complet disponible ici: https://github.com/SuperV1234/SSVSCollision
la source
Réponses:
Tout d'abord, je recommande d'utiliser une bibliothèque de physique libre et open source comme Box2D et de se concentrer uniquement sur les aspects de votre jeu qui le rendent unique! Si vous insistez pour réinventer la roue, lisez la suite ... notez que tous les moteurs physiques sont des approximations, et bien que la méthode que je décris ci-dessous soit plus précise que votre modèle actuel, les résultats de Box2D seront beaucoup plus réalistes.
Pour un moyen rapide de modéliser une résolution de collision plus précise de deux objets A et B:
Veuillez jeter un œil à mon exemple de programme d'astéroïdes qui illustre ces concepts.
Ensuite, comptez les objets empilés:
Comme vous l'avez noté, l'utilisation de la vitesse pour simuler des objets empilés / au repos ne fonctionne pas bien: la vitesse est la vitesse à laquelle un objet se déplace, donc s'il repose sur un objet statique, la vitesse doit être proche de 0. Il n'est pas logique d'augmenter la vitesse d'un objet pour le faire apparaître au repos:
Ce qui devrait vraiment se produire, c'est une force d'accélération qui va dans la direction opposée car la gravité devrait annuler la gravité. (C'est ce qu'on appelle la force de contact normale). Un raccourci consiste simplement à ne pas appliquer la gravité aux corps qui ne sont pas dans l'air:
Mise à jour:
la source
La résolution de ce problème nécessite d'ajuster la position et éventuellement la vitesse. Les moteurs de physique des corps rigides ont un solveur qui fait avancer les objets dans le temps en utilisant les lois du mouvement de Newton tout en résolvant les contraintes de non-pénétration et les frottements. Ces moteurs peuvent calculer la bonne combinaison de mouvement linéaire et angulaire pour créer des trajectoires plausibles.
Si vous souhaitez uniquement résoudre le chevauchement, vous pouvez utiliser des pseudo-vitesses qui génèrent des trajectoires de séparation sans ajouter à l'élan. Cela se fait dans le solveur de position de Box2D.
Je recommande de recevoir mes présentations GDC de 2006 et 2007 ici:
http://code.google.com/p/box2d/downloads/list
Vous pouvez également consulter Box2D Lite pour une implémentation simplifiée.
la source
Dans le monde réel, il n'y a aucune force qui "pousse" un corps à l'extérieur d'un autre corps parce que les objets ne se pénètrent jamais. La chose la plus proche est la force normale : créée au moment du contact lors de collisions réelles, elle empêche en premier lieu la pénétration.
L'angle de cette force normale est perpendiculaire à la surface de contact des deux objets en collision. L'ampleur dépend de la force nécessaire pour empêcher la pénétration. (Notez que seule la composante y de la force normale doit être utilisée à moins que d'autres forces comme la force de friction ne soient également modélisées).
Bien qu'il soit possible de modéliser explicitement la force normale, il est plus simple de modéliser uniquement ses effets:
Je l'ai décrit légèrement différemment dans mon autre réponse qui concerne davantage les collisions en général .
la source