Ich suche nach Informationen darüber, wie der Laufzeitzustand starrer Körper mit Bullet Physics gespeichert werden kann. Der größte Teil meiner Welt besteht aus statischen Objekten, aber ich habe auch einige dynamische und kinematische Objekte. Ich muss einen Schnappschuss des Spielstatus machen und später genau denselben Status wiederherstellen, damit dieselbe Simulation erzeugt wird, als ob es keine Pause gäbe. Ich kann leicht (und lieber) die ganze Welt neu erschaffen, einschließlich der starren Körper, ihrer Konfiguration, Kollisionsformen und Einschränkungen.
Außerdem muss ich die Objekte in ihren Ausgangszustand zurücksetzen, aber ich denke, dass das Lösen des Problems beim Speichern / Wiederherstellen auch das Zurücksetzen löst.
Ich verwende JBullet , das auf Bullet Version 2.72 basiert. Dies bedeutet, dass die integrierte Serialisierung für mich nicht verfügbar ist, da sie in Version 2.76 hinzugefügt wurde. Antworten, die die Serialisierung verwenden, sind jedoch ebenfalls willkommen, da Java über eine integrierte Serialisierung verfügt und andere dies möglicherweise nützlich finden. Die Beschreibung auf der Wiki-Seite klingt jedoch so, als ob sie zum Speichern ganzer Welten und nicht nur des Laufzeitstatus gedacht ist.
Wenn Sie den Quellcode von RigidBody und CollisionObject überprüfen, werden viele interne nicht endgültige Felder angezeigt, von denen viele Zeiger statt Grundelemente sind. Ich weiß nicht, welches der Felder ich speichern soll und wie ich mit den nicht primitiven Feldern umgehen soll.
Ich bin überrascht, dass ich im Internet keine Informationen dazu gefunden habe, da ich denke, dass dies für jedes Spiel mit Bullet-Physik erforderlich ist und genaue Funktionen zum Speichern und Wiederherstellen erfordert. Ich würde eine Lösung bevorzugen, die nur die öffentliche API erfordert, aber ich bin auch offen für andere Lösungen, einschließlich der Änderung des Quellcodes als letztes Mittel. Ich bin mir auch der Unterschiede bei Gleitkommaoperationen zwischen Plattformen bewusst, aber das ist für mich kein Problem.
Bearbeiten:
Ich habe die von Byte56 vorgeschlagene Lösung implementiert . Ich speichere jetzt WorldTransform, LinearVelocity und AngularVelocity und stelle sie wieder her. Ich habe auch motionState ausprobiert, aber das hatte keine Auswirkungen. Nach dem Wiederherstellen des Zustands scheint mein Objekt die korrekte Flugbahn bis zur ersten Kollision mit einer (statischen) Wand fortzusetzen. Nach der Kollision folgt das Objekt nicht mehr demselben Pfad. Interessanterweise scheint es nur 5-7 leicht unterschiedliche Pfade zu geben, die das Objekt zufällig auswählt.
Ohne das Speichern und Wiederherstellen ist meine Simulation vollständig deterministisch und liefert immer genau die gleichen Ergebnisse, wenn sie mehrmals mit denselben Startwerten ausgeführt wird.
Ich dachte, dass die Zufälligkeit auf eine ungerade Anzahl von Simulationsschritten zurückzuführen sein könnte. Ich verwende das Überspringen von Frames und das Übergeben von 1.0 / 60 als Deltazeit für stepSimulation : dynamicsWorld.stepSimulation(deltaTime, 100, 1.0f / 200);
. Ich habe versucht, 200 auf 180 zu ändern, aber das hat nicht geholfen. Ich frage mich, ob es in der DiscreteDynamicsWorld etwas gibt, das ich auch speichern sollte. Ich habe auch versucht, DiscreteDynamicsWorld.localTime
durch Nachdenken zu sparen , aber kein Glück.
Edit2:
Bei näherer Betrachtung ist sogar die anfängliche Flugbahn vor Kollisionen leicht verschoben. Es scheint jedoch nur einen konstanten Versatz in den Koordinaten zu geben, und nach der ersten Kollision ändert der Pfad die Richtung im Vergleich zum Original.
Ich habe einen benutzerdefinierten Serializer mithilfe der Java Reflection-API implementiert, in dem alle primitiven Felder von RigidBody
und rekursiv gespeichert werden DiscreteDynamicsWorld
. Das hat nicht geholfen. Ich habe auch versucht, die Physik-Aktualisierung auf einfach zu ändern dynamicsWorld.stepSimulation(1.0f / 60.0f);
, aber auch dort kein Glück. Jetzt habe ich keine Ideen mehr, wie ich vorgehen soll.
setRandSeed
Funktion hat, dielong
als Argument dient. Vielleicht hilft das Speichern und Zurücksetzen eines Samens? Ich habe es noch nicht ausprobiert, dachte nur, ich würde dich wissen lassen, um etwas zu untersuchen. Ich bin nicht sicher, wofür der Löser zufällige Werte verwendet ...