So lösen Sie das Eindringen zweier kollidierender Körper

9

Ich habe eine einfache 3D-Spielphysik-Engine implementiert. Ich habe bereits eine anständige Kollisionserkennung eingerichtet, jetzt versuche ich, den Teil der Kollisionsreaktion herauszufinden. Ich verwende eine impulsbasierte Methode, um die Geschwindigkeiten nach der Kollision zu berechnen. Dies funktioniert ziemlich gut, verhindert jedoch nicht vollständig, dass sich die Körper weiter gegenseitig durchdringen. Ich habe also zusätzlichen Code, um das Eindringen zu beheben. Derzeit bewege ich die Körper nur entlang der Kontaktnormalen um die Hälfte der Eindringtiefe - erster Körper in Richtung der Kontaktnormalen, zweiter Körper in entgegengesetzter Richtung.

Dies ist die meiste Zeit in Ordnung, aber es gibt einige unerwünschte Effekte. Stellen Sie sich zum Beispiel einen engen Korridor und ein Objekt vor, das sich durch ihn bewegt. Wenn das Objekt auf eine der Wände des Korridors trifft, verschiebt die Durchdringungsauflösung es in die gegenüberliegende Wand, dann im nächsten Bild zurück in die erste Wand und so weiter. Der Effekt ist, dass das Objekt zwischen den Wänden sehr schnell vibriert, was nicht schön ist.

Meine Frage ist also, ob es einen besseren Weg gibt, um das Eindringen zu beheben. Vielleicht bewegen Sie die Körper nicht, sondern passen ihre Geschwindigkeiten (zusätzlich zur Impulsberechnung) an, damit sie sich nicht mehr aufeinander zu bewegen und die Penetration sich in den nächsten paar Bildern von selbst auflöst. Ich rate nur hier. Irgendwelche Ideen?

Adam
quelle

Antworten:

3

Wenn Sie eine Kollision feststellen, bestimmen Sie, zu welchem ​​Zeitpunkt / zu welchem ​​Zeitpunkt die Körper zum ersten Mal kollidierten, und behandeln Sie die Kollision an diesem Punkt. Möglicherweise müssen Sie zu diesem Zeitpunkt noch eine leichte Penetration beheben, diese ist jedoch viel kleiner und führt [normalerweise] nicht zu den Schwingungsproblemen, die Sie haben.

Nehmen wir an, Sie haben 100-ms-Simulationsschritte und in einigen Frames zwei Kugeln, die auf halber Strecke (50 ms) im Frame kollidieren. Zuerst werden Sie feststellen, dass sie an jedem Punkt im Frame kollidierten (was Sie sicher bereits effektiv tun). Sie bestimmen, an welchem ​​Punkt während des Frames sie kollidierten. Behandeln Sie nun die Kollision, einschließlich der ersten 50 ms des Rahmens, in dem sie nicht kollidierten. Sie haben jetzt die neuen Geschwindigkeiten der Bälle und können jetzt auch Schritte unternehmen, um sicherzustellen, dass sie nicht eindringen (diese sollten sehr klein sein, da es "gerade passiert" ist). Schließlich simulieren Sie die nächsten 50er Jahre der Rahmen. Beachten Sie, dass es während dieser Zeit sehr wohl zu einer weiteren Kollision mit einer oder beiden dieser Kugeln kommen kann.

notlesh
quelle
1
Sie schlagen also grundsätzlich vor, eine kontinuierliche Kollisionserkennung zu implementieren und dann die noch verbleibenden Durchdringungen so zu behandeln, wie ich es bereits getan habe, da sie wahrscheinlich sehr klein sein werden. Das könnte funktionieren, nehme ich an. Jetzt muss ich nur noch herausfinden, wie ich meine Kollisionserkennung kontinuierlich machen kann :)
Adam
Ich bin mir nicht sicher, was du mit kontinuierlich meinst. Genau genommen gibt es in der Physiksimulation nichts Kontinuierliches, da alles immer in diskrete Schritte unterteilt ist. Wenn Sie kleinere Schritte ausführen, was im Wesentlichen das ist, was ich vorschlage, ergeben sich viel kleinere (und leichter zu korrigierende) Fehler. Eine andere Möglichkeit, darüber nachzudenken, besteht darin, dass ein direkter Zusammenhang zwischen Schrittgröße und Fehlern (z. B. Penetration) besteht. Wenn Sie einen solchen Fehler feststellen, teilen Sie ihn in kleinere Schritte auf, bis der Fehler trivial behoben werden kann.
Notlesh
Kontinuierliche Kollisionserkennung bedeutet, dass Sie anstelle der Überprüfung des Schnittpunkts zwischen zwei statischen Objekten (ein 3D-Problem) den Kontakt zweier sich bewegender Objekte überprüfen (im Grunde ein 4d-Problem). Normalerweise reicht es aus, nur konstante Geschwindigkeiten zu berücksichtigen, da Sie die Trajektorien mit stückweise linearen Kurven approximieren können. Der Vorteil ist, dass der Eindringabstand immer Null ist (oder aufgrund von Schwimmerrundungsfehlern nahe daran liegt). Ich dachte, Sie haben darüber gesprochen, aber vielleicht habe ich Ihre Antwort falsch interpretiert?
Adam
@adam Ja, das ist es, worüber ich rede.
Notlesh
2

Schauen Sie sich diesen Artikel an, der schon oft hier veröffentlicht wurde. Durchsuchen Sie einfach die mit Fragen und Antworten gekennzeichneten Kollisionserkennungen. Er zeigt Ihnen, wie Sie die "kontinuierliche" Kollisionsauflösung durchführen, von der Stephelton gesprochen hat:

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

Grundsätzlich lösen Sie einige grundlegende kinematische Gleichungen für den genauen Zeitpunkt, zu dem sich Ihre beiden Begrenzungsrahmen zu schneiden begannen. Sie lösen Ihre Kollisionen genau in diesem Moment und fahren dann mit der verbleibenden Zeit in Ihrem Frame fort. Möglicherweise müssen Sie erneut simulieren, was nach dem Moment der Kollision passiert, da sich die Geschwindigkeiten / Beschleunigungen Ihrer Objekte geändert haben. Aber da ist trotzdem dein Ausgangspunkt ... Prost!

Mediocritus
quelle
Danke, habe den Artikel überprüft. Ich verwende eine andere Darstellung meiner Objekte. Ich verwende konvexe Polyeder und teste die Kollision mithilfe des Trennachsensatzes. Dies kann erweitert werden, um Körper zu handhaben, die sich mit konstanten linearen Geschwindigkeiten bewegen (was ich zu tun weiß), aber keine Ahnung, wie auch Winkelgeschwindigkeiten zu handhaben sind. Aber ich werde eine separate Frage stellen, wenn ich mich dazu entscheide.
Adam