In meiner 2D-Physik-Engine kann ich AABB-gegen-AABB-Kollisionen erkennen und beheben, indem ich den kürzesten Penetrationsvektor finde und ihn zur Position der AABB hinzufüge.
Dadurch wird der erste AABB außerhalb des zweiten AABB "gedrückt", es werden jedoch überhaupt keine Geschwindigkeits- / Beschleunigungsänderungen behandelt.
Wenn ich meiner Simulation eine Schwerkraftbeschleunigung hinzufüge, wächst die Geschwindigkeit des ersten dynamischen AABB weiter, selbst wenn er auf dem zweiten statischen AABB aufliegt. Schließlich wird die Geschwindigkeit zu groß und die Kollision wird nicht erkannt (der dynamische AABB fällt durch den statischen).
Ich habe versucht, die Geschwindigkeit nach dem Auflösen auf Null zu setzen, aber es hat offensichtlich nicht gut funktioniert und unrealistische Simulationen erstellt.
Ich habe online gelesen, dass das Auflösen von Kollisionen durch manuelles Bearbeiten der Position oder der Geschwindigkeit nicht korrekt ist. Ich habe versucht, Kräfte zu implementieren (Masse ist vorerst eine "fest codierte" 1):
void Body::applyForce(sf::Vector2f mForce) { acceleration += mForce; }
void Body::integrate(float mFrameTime)
{
velocity += acceleration * mFrameTime;
position += velocity * mFrameTime;
acceleration = {0, 0};
}
Wenn ich während der Kollisionsauflösung den kürzesten Eindringvektor als Kraft anwende, wird der dynamische AABB aus dem statischen "herausgedrückt", aber seine Geschwindigkeit wird in einer Simulation ohne Schwerkraft niemals abnehmen und er wird für immer in Bewegung bleiben.
Gibt es eine Möglichkeit, eine "temporäre" Kraft anzuwenden? Eine Kraft, die sich mit dem Herausdrücken des ersten AABB aus dem zweiten AABB befasst und dann aufhört, wenn der AABB nicht mehr kollidiert?
Der gesamte Quellcode ist hier verfügbar: https://github.com/SuperV1234/SSVSCollision
quelle
Antworten:
Zunächst empfehle ich, eine kostenlose Open-Source- Physikbibliothek wie Box2D zu verwenden und mich nur auf die Aspekte Ihres Spiels zu konzentrieren, die es einzigartig machen! Wenn Sie darauf bestehen, das Rad neu zu erfinden, lesen Sie weiter ... Beachten Sie, dass es sich bei allen Physik-Motoren um Näherungswerte handelt. Die unten beschriebene Methode ist zwar genauer als Ihr aktuelles Modell, die Ergebnisse von Box2D sind jedoch weitaus realistischer.
So modellieren Sie schnell eine genauere Kollisionsauflösung von zwei Objekten A und B:
Bitte schauen Sie sich mein Beispielprogramm für Asteroiden an, das diese Konzepte demonstriert.
Als nächstes berücksichtigen Sie gestapelte Objekte:
Wie Sie bemerkt haben, funktioniert die Verwendung von Geschwindigkeit zur Simulation gestapelter / ruhender Objekte nicht gut: Geschwindigkeit ist die Geschwindigkeit, mit der sich ein Objekt bewegt. Wenn es sich also auf einem statischen Objekt befindet, sollte die Geschwindigkeit nahe 0 sein. Es ist nicht sinnvoll, die Geschwindigkeit zu erhöhen Die Geschwindigkeit eines Objekts, um es in Ruhe erscheinen zu lassen:
Was wirklich passieren sollte, ist eine Beschleunigungskraft, die in die entgegengesetzte Richtung geht, da die Schwerkraft die Schwerkraft aufheben sollte. (Dies wird als normale Kontaktkraft bezeichnet). Eine Abkürzung ist, einfach keine Schwerkraft auf Körper anzuwenden, die nicht in der Luft sind:
Aktualisieren:
quelle
Um dieses Problem zu lösen, müssen Position und möglicherweise Geschwindigkeit angepasst werden. Rigid-Body-Physics-Engines verfügen über einen Solver, mit dem Objekte unter Verwendung der Newtonschen Bewegungsgesetze zeitlich vorwärts bewegt werden und gleichzeitig Nicht-Penetrations-Beschränkungen und Reibung gelöst werden. Diese Motoren können die richtige Kombination aus linearen und winkligen Bewegungen berechnen, um plausible Flugbahnen zu erstellen.
Wenn Sie nur Überlappungen auflösen möchten, können Sie Pseudo-Geschwindigkeiten verwenden, die Trenntrajektorien erzeugen, ohne den Schwung zu erhöhen. Dies geschieht im Positionslöser von Box2D.
Ich empfehle meine GDC-Präsentationen von 2006 und 2007 hier zu bekommen:
http://code.google.com/p/box2d/downloads/list
Sie können sich auch Box2D Lite für eine vereinfachte Implementierung ansehen.
quelle
In der realen Welt gibt es keine Kraft, die einen Körper aus einem anderen "herausdrückt", weil Objekte sich nie gegenseitig durchdringen. Das Nächste ist die Normalkraft : Sie entsteht im Moment des Kontakts bei realen Kollisionen und verhindert das Eindringen.
Der Winkel dieser Normalkraft steht senkrecht zur Kontaktfläche der beiden kollidierenden Objekte. Die Größe hängt davon ab, wie viel Kraft erforderlich ist, um ein Eindringen zu verhindern. (Beachten Sie, dass nur die y-Komponente der Normalkraft verwendet werden sollte, es sei denn, andere Kräfte wie die Reibungskraft werden ebenfalls modelliert.)
Während es möglich ist, die Normalkraft explizit zu modellieren, ist es einfacher, nur ihre Auswirkungen zu modellieren:
Ich habe dies in meiner anderen Antwort, die sich eher auf Kollisionen im Allgemeinen bezieht, etwas anders beschrieben .
quelle