Wie kann ich btCollisionAlgorithm erweitern, um eine Kollision mit einem Voxel-Terrain zu ermöglichen?

8

Ich verwende Bullet und versuche, einen Kollisionsalgorithmus zu erstellen, der Kontaktpunkte aus einem würfelbasierten Gelände zusammen mit der entsprechenden Kollisionsantwort generiert. Ich habe auch vor, dies auf Nicht-Box-Formen auszudehnen, aber das ist im Moment nicht wichtig. Ich habe festgestellt, dass die Verwendung eines Dreiecksnetzes für große Karten zu viel RAM ist.

Ich habe das hier von Byte56 beschriebene Verfahren ausprobiert , habe jedoch eine Reihe von Fragen zur Implementierung mit Bullet:

  • Wie erzeugt man eine Kollisionsform für die Welt? Verwenden Sie eine benutzerdefinierte Form? Was willst du m_shapeTypedrauf haben?
  • Oder verwenden Sie immer noch eine Kastenform von der Größe der Welt?
  • Wie stellen Sie sicher, dass Kontaktstellen freigegeben werden?
  • Wie genau modifizierst du processCollision?

Was ich getan habe:

  • Ich habe eine that extendsTerrainShape btBoxShape , the only difference being thatm_shapeType = CUSTOM_CONVEX_SHAPE_TYPE` erstellt, damit ich beim Dispatcher einen neuen Kollisionsalgorithmus für Objekte mit nur dieser Form registrieren kann.
  • Ich habe die btRigidBodyKlasse auf ähnliche Weise wie Byte56 in seiner Frage erweitert (siehe den Link im 2. Absatz), gebe jedoch checkCollisionWith(CollisionObject * co)true zurück, wenn ein Voxel im AABB von conicht air ist.
  • Ich habe die erweiterte btCollisionAlgorithmKlasse, in ähnlicher Weise wie btCompoundCollisionAlgorithmmit processCollisiondem folgenden Aktionen ausführen:

    1. Überprüfen Sie die kollidierenden Objekte, die als Argumente übergeben wurden, und bestimmen Sie, welches das Terrain und welches die Entität ist.
    2. Löschen Sie die Verteiler aller untergeordneten Algorithmen.
    3. Anruf resultOut->setPersistantManifold(resultOut)
    4. Generieren Sie neue Boxformen und Transformationen in der AABB, die von der kollidierenden Entität belegt wird, und rufen Sie dann auf m_dispatcher->findAlgorithm. Speichern Sie die Form, Transformation und den gefundenen Algorithmus in einer untergeordneten Algorithmusstruktur für jedes Voxel innerhalb des AABB.
    5. Durchlaufen Sie alle untergeordneten Algorithmen und rufen Sie sie auf proccessCollision.
    6. Durchlaufen Sie alle untergeordneten Algorithmen und entfernen Sie alle jetzt außerhalb des AABB der kollidierenden Entität. (ruft ~btCollisionAlgorithm()dann an m_dispatcher->freeCollisionAlgorithm())
    7. Rufen Sie an resultOut->refreshContactPoints().

Was funktioniert: processCollisionWird immer dann aufgerufen, wenn sich der AABB des Spielers mit Nicht-Luft-Voxeln schneidet.

Was nicht: Die Kollisionsreaktion ist einfach komisch ... Die Spielerentität beginnt nach oben zu schweben. Wenn es in etwas hineingeht, prallt es heftig ab. Manchmal kann es sich nicht mehr auf einer Achse bewegen, nachdem es in etwas hineingegangen ist. Was ich vermute, ist, dass Kontaktpunkte nach einer Kollisionsreaktion nicht freigegeben werden, möglicherweise weil sich die Spielerentität immer im AABB des Weltobjekts befindet. Ich bin gespannt, ob ich in Bezug auf den richtigen Baum belle processCollision?

SnapperTT
quelle
Hast du das überhaupt geklärt? Ich habe ein sehr ähnliches Problem.
Timoxley
Ein bisschen spät, sorry, ich habe deine Frage nicht gesehen. Wenn Sie dies noch nicht herausgefunden haben, haben Sie versucht, Ihre Physikkörper zu debuggen? Der AABB, mit dem Sie die Kollision erkennen, bindet den von Ihnen verwendeten Physikkörper nicht. Wenn Sie also die Kollision erkennen, befindet sich Ihr Objekt bereits weit darin. Dies erklärt, warum Ihre Kollisionsreaktionen so seltsam sind.
MichaelHouse
1
Siehe meine neueste Antwort auf meine Frage: gamedev.stackexchange.com/questions/27405/…
MichaelHouse

Antworten:

1

Leider konnte ich mit der in der Antwort, auf die Sie sich beziehen, beschriebenen Methode keine zuverlässigen Ergebnisse erzielen . Ähnlich wie bei Ihnen würde ich seltsame schwebende Ereignisse bekommen oder Situationen, in denen das Entfernen eines Voxels dazu führen würde, dass darüber schwebende Objekte in der Luft schweben oder eine seltsame oszillierende Feder zu Boden fällt. Ich habe diese Strategie für eine neue Strategie aufgegeben.

Ich fing an, benutzerdefinierte Kollisionsnetze für jedes Stück Voxel-Terrain zu erstellen. Ich mache das mit dem BvhTriangleMeshShape. Das funktioniert ganz gut:

Geben Sie hier die Bildbeschreibung ein

Weitere Details zur Implementierung der benutzerdefinierten Kollisionsnetze finden Sie hier .

MichaelHouse
quelle