Jitter bei Wandkollisionen mit Bullet Physics: Kontakt- / Penetrationstoleranz?

7

Ich benutze die Bullet Physics Engine über Panda3d.

Meine Szene ist immer noch sehr einfach, denken Sie an 'Wolfenstein3d': Fliesenbasierte Wände sind feste Würfel.

Ich erwarte, dass Wände den Spieler blockieren, und ich erwarte, dass der Spieler bei nicht normalem Auftreten an den Wänden entlang rutscht.

Was ich bekomme, ist das, was ich erwarte, mit einem Unterschied: Es gibt etwas Jitter. Wenn ich versuche, mich in die Wand zu zwingen, sehe ich, dass die Rahmen zwischen zwei Positionen schnell blinken. Diese unterscheiden sich um ca. 0,04 Entfernungseinheiten, was in meinem Spiel 4 cm entspricht.

Ich habe an anderer Stelle 4 cm bemerkt: Der Boden meiner Spielerkapsel befindet sich im Ruhezustand 4 cm unter der Erde.

Bedeutet das, dass irgendwo in der Bullet-Engine eine Standardtoleranz von 0,04 Einheiten vorhanden ist, um Kontakt von Kollision zu unterscheiden? Wenn ja, was soll ich tun? Sollte ich den Maßstab meines Spiels so ändern, dass diese 0,04 Einheiten 0,4 cm entsprechen, wodurch der Jitter zehnmal kleiner wird? Oder kann ich die Kugel bitten, ihre Toleranz auf einen kleineren Wert zu ändern?

Bearbeiten

Dies ist der Jitter, den ich bekomme: 6.155 - 6.118 = 0.036

LPoint3f(0, 6.11694, 0.835)
LPoint3f(0, 6.15499, 0.835)
LPoint3f(0, 6.11802, 0.835)
LPoint3f(0, 6.15545, 0.835)
LPoint3f(0, 6.11817, 0.835)
LPoint3f(0, 6.15726, 0.835)
LPoint3f(0, 6.11876, 0.835)
LPoint3f(0, 6.15911, 0.835)
LPoint3f(0, 6.11937, 0.835)

Ich habe eine setMargin-Methode gefunden. Ich habe es sowohl auf der BoxShape für die Wände als auch auf der Kapselform für den Player auf 5 mm eingestellt. Es zittert immer noch um ca. 35 mm, wie in diesem Protokoll dargestellt (11.117 - 11.082 = 0.035):

LPoint3f(0, 11.0821, 0.905)
LPoint3f(0, 11.1169, 0.905)
LPoint3f(0, 11.082, 0.905)
LPoint3f(0, 11.117, 0.905)
LPoint3f(0, 11.082, 0.905)
LPoint3f(0, 11.117, 0.905)
LPoint3f(0, 11.0821, 0.905)
LPoint3f(0, 11.1175, 0.905)
LPoint3f(0, 11.0822, 0.905)
LPoint3f(0, 11.1178, 0.905)
LPoint3f(0, 11.0823, 0.905)
LPoint3f(0, 11.1183, 0.905)

Der Rand auf der Kapsel hat meine Penetration mit dem Boden verändert, ich bin etwas höher (0,905 statt 0,835). Bei der Kollision mit den Wänden änderte sich jedoch nichts.

Wie kann ich die Kollisionen gegen die Wände weniger nervös machen?

Bearbeiten, am Tag danach:

Nach weiteren Untersuchungen scheint sich das dynamische Objekt gut zu verhalten. Mein Problem kommt vom btKinematicCharacterController, mit dem ich meinen Charakter bewege. das Zeug ist laut dem ganzen Internet total abgehört: /.

Niriel
quelle

Antworten:

4

Dies klingt nach numerischer Instabilität aufgrund von Gleitkomma-Ungenauigkeiten. Verwenden Sie die Skalierungsfaktoren für Ihre Szene / Objekte gemäß der Empfehlung des Anbieters?


Bearbeiten:

Allgemeine Checkliste für Physik-Engine-Jitter

  • Stellen Sie sicher, dass Sie die richtigen Skalierungsfaktoren verwenden
  • Stellen Sie sicher, dass die Mengen angemessen sind (z. B. 10 m, 80 kg, ...)
  • Aktivieren Sie das Schlafen, wenn dies ein Objekt ohne interne Kräfte ist (dh es hat keine Steuerung / Kraftgenerator).
  • Entdecken Sie alle Einstellungen zum Ray Casting. Plausible Ursache für Ihr Problem
  • Lockern Sie die Toleranz der Eindringtiefe, um ein gewisses Eindringen zu ermöglichen . Wahrscheinlich Ursache für Ihr Problem


† Dies kann möglicherweise dazu führen, dass Kameras Wände "durchschauen", und kann gelöst werden, indem ein dünnes, unsichtbares Objekt vor die Wand gestellt oder der AABB erweitert wird, um als Puffer zu fungieren.

awdz9nld
quelle
Wenn Sie über den Maßstab meiner 3D-Modelle (und damit Kollisionsboxen / Formen) sprechen, dann sind sie alle 1.
Niriel
Und ungefähr welche Größen und Entfernungen spielen eine Rolle?
awdz9nld
1 Einheit entspricht 1 Meter.
Niriel
1

Klingt so, als ob Ihre Engine ständig versucht, die Parameter dieses Objekts zu aktualisieren. Das Objekt sollte in seiner Position einfrieren, sobald es einen Zustand erreicht, für den sich Bullet als "stabil" entschieden hat. Andernfalls führen numerische Fehler niemals zu einer genauen Kollisionsbehandlung, daher zu einer nervösen Bewegung (Kräfte bauen sich schließlich auf, Objekte dringen wieder ein, es entstehen Schwingungen). Einige Ideen werden hier erwähnt . Ich würde anfangen , das " Schlafproblem " zu untersuchen. Vielleicht könnte jemand, der praktische Erfahrung mit diesem Motor hat, eine Möglichkeit bieten, die Schlafschwelle in Ihrem Fall effizient einzustellen.

Teodron
quelle
Nach weiteren Untersuchungen scheint sich das dynamische Objekt gut zu verhalten. Mein Problem kommt vom btKinematicCharacterController, mit dem ich meinen Charakter bewege. Das Zeug ist laut dem ganzen Internet total abgehört.
Niriel
Es tut mir leid, davon zu hören, ich bin kein Bullet-Experte und hatte noch keine Gelegenheit, mir diesen Mechanismus anzusehen. Eine Beobachtung ist, dass Ihr sich bewegender Charakter nicht in den "Schlafmodus" wechseln konnte, da er ständig Force-Updates erhalten muss, die ihn aus dem "Einfrier- / Schlaf" -Modus herausrutschen lassen.
Teodron
Ich werde diesen Begriff des "Schlafmodus" in Zukunft auf jeden Fall berücksichtigen. Ich sollte auch meine Normalen überprüfen, vielleicht habe ich doppelseitige Polygone?
Niriel
0

Eine Sache, die Sie vielleicht untersuchen möchten, ist eine CCD-Option. In einigen Physik-Engines können Sie die Option "Kontinuierliche Kollisionserkennung" aktivieren.

Es ist viel ressourcenintensiver, aber anstatt die Kollision bei jedem Zeitschritt als Ja / Nein zu lösen, arbeitet es daran, den tatsächlichen Kollisionspunkt zu finden und Sie dort zu stoppen.

Ich bin mit der Bullet Engine nicht vertraut, aber das könnte Ihnen etwas geben, nach dem Sie suchen müssen. Interessanterweise wird es am häufigsten für Dinge wie Kugeln verwendet, um das Eindringen von Wänden zu verhindern.

Sparkky
quelle
kontinuierlich oder nicht, Gleitkomma wird früher oder später immer noch seinen hässlichen Kopf
aufrichten