In einer Physik-Engine, die ich (zum Lernen) mit love-2d entwickle , habe ich Kollisionsauflösungen folgendermaßen implementiert:
FixedUpdate(dt) // I use fixed timestep
foreach collide c1 in allNotStaticColliders
c1.integartePhysic // i.e. apply gravitational force..
foreach collider c2 "near" c1 // "near"= I use spatial hashing
if collide(c1,c2)
resolve collision (c1,c2) // the heavy operation
collison callbacks c1
collison callbacks c2
...
Wie Sie am Ende der GIF-Animation sehen können, kommt es zu einem FPS-Abfall, wenn alle Collider fast über einem statischen Objekt geerdet sind.
Dies liegt daran, dass die Anzahl der Kollisionsauflösungen zunimmt, wenn Objekte mehr Zeit damit verbringen, sich zu berühren, während sie sich niederlassen. Viele der Berechnungen sind jedoch "nutzlos", da sich Objekte bereits in stabilen Positionen gegeneinander niedergelassen haben.
Was ist die beste Vorgehensweise (hoffentlich ohne Abschluss in Physik), um diese "nutzlosen" Kollisionserkennungen zu vermeiden?
Bearbeiten: DMGregory-Hinweise akzeptiert und zu diesem Ergebnis kommen (noch nicht optimal)
(Rot = statisch, Blau = aktiv, Grün = schlafend)
quelle
Antworten:
Ich vermutete, dass OP diesen Ansatz bereits kannte, also erwähnte ich ihn in einem Kommentar nur als Ausgangspunkt, aber ich werde versuchen, ihn ein bisschen weiter zu konkretisieren ...
Die meisten Physik-Engines teilen dynamische Objekte in zwei Gruppen ein: " wach " und " schlafend ".
Objekte schlafen, wenn sie in Ruhe sitzen, und wachen auf, wenn sie durch äußere Einflüsse bewegt oder beschleunigt werden.
Ein schlafendes Objekt verhält sich in vielerlei Hinsicht wie ein statisches Objekt - seine Bewegung wird im Laufe der Zeit nicht integriert (weil es sich in Ruhe befindet, also keine Bewegung hat) und die Engine ignoriert Kollisionen zwischen schlafenden oder statischen Objekten.
Ein schlafendes Objekt, das auf einem statischen Boden sitzt, fällt trotz fehlender Kollisionsreaktion nicht durch, da die gesamte Bewegungsintegration für schlafende Objekte, einschließlich der Schwerkraft, übersprungen wird.
Daher müssen nur Kollisionen mit mindestens einem wachen dynamischen Objekt überprüft werden:
Dies kann die Anzahl der Objekte, die eine aktive Simulation benötigen, drastisch reduzieren, insbesondere bei Pfählen, bei denen, wie in der Frage dargestellt, viele gegenseitige Kollisionen auftreten, um festzustellen, ob keine oder nur geringe Nettobewegungen vorliegen.
Das Schlafen hilft jedoch erst, wenn die Objekte tatsächlich zur Ruhe kommen, was eine Weile dauern kann.
Einige Dinge, die Sie tun können, um früher zur Ruhe zu kommen:
Haben Sie eine Mindestgeschwindigkeit oder einen Mindestimpuls ungleich Null und klemmen Sie alles, was darunter fällt, auf Null. (Dies ist im Grunde ein Epsilon, das üblicherweise beim Vergleichen von Schwimmern verwendet wird.)
Verwenden Sie Reibung, Dämpfung und unelastische Kollisionen, um Energie aus dem System abzusaugen und es insgesamt schneller zur Ruhe zu bringen.
Erhöhen Sie die Reibung / Dämpfung / Unelastizität bei sich langsam bewegenden Objekten selektiv , um ihnen den letzten Anstoß zum Ausruhen zu geben, ohne das Verhalten energetischerer Körper zu beeinträchtigen.
quelle