2017-09-14 4 views
-2

Ich habe meine eigene 3D Game Engine in den letzten paar Jahren geschrieben und wollte sie eigentlich für ein Spiel verwenden.Terrain Objekt Kollisionserkennung

stolperte ich accros das folgende Problem:

ich mehrere Flugzeuge in meinem Spiel, aber lässt über eine einzige Ebene sprechen. Natürlich können Flugzeuge nicht in den Boden eintauchen und unter dem Gelände fliegen. Dafür muss ich etwas implementieren, das die Kollision zwischen einem Flugzeug/Jet und meinem Boden erkennt.

Die angegebenen Informationen sind die folgenden:

  1. Gitter von Gelände [2- dimensionales Array; bei entsprechend x speichert Höhe Koordinate z]
  2. Hitbox meiner Ebene (es mit meiner Ebene bewegt, so dass die Grenzen usw. sind alle bereits berechnet und angegeben)

So über die Hitboxen: I zwar über welche Methode zu verwenden. Der beste in Bezug auf die Leistung scheinen einfache Kugeln mit unterschiedlichem Radius zu sein.

über den Boden: Grafisch wird der Boden in Dreiecke unterteilt: enter image description here

Also, was ich jetzt brauche, ist die optimale Art der Hitbox (Kugel, AABB, ...) und die nach effizientesten Berechnungen.

Mein Versuch war, jedes umgebende Dreieck zu bekommen und den Abstand von diesem zu jedem Zentrum meiner Hitbox-Sphären zu berechnen. Wenn der Abstand kleiner als der Radius ist, hat er erfolgreich eine Kollision erkannt. Aber wenn ich bis zu 10/20 Kugeln in meinem Flugzeug habe und wie 100 Dreiecke zu überprüfen, wird es zu viel Zeit brauchen.

Ein weiterer Versuch bestand darin, aus jeder Hitbox-Sphäre den vertikalen Abstand zum Boden zu ermitteln. Dieser benötigt viel weniger Berechnungen, scheitert aber, wenn er in die Nähe von steilen Oberflächen kommt.

Ich würde mich sehr freuen, wenn mir jemand helfen könnte eine effiziente Version von Flugzeug/Geländekollisionserkennung Umsetzung :)

+0

Die Beantwortung dieser Frage wäre wirklich breit. Sie sollten über [Octree] (https://en.wikipedia.org/wiki/Octree) lesen - siehe auch [Bester Algorithmus für effiziente Kollisionserkennung zwischen Objekten] (https: // stackoverflow.com/questions/7107231/best-algorithm-for-efficient-Kollisionserkennung-zwischen-Objekten) und [Bounding-Boxen in Octrees] (https://gamedev.stackexchange.com/questions/25626/bounding-boxes-in- octrees) – Rabbid76

+0

für gerenderte Ebenen können Sie dies im Shader tun. Ich nehme an, dass das Terrain vor Objekten gerendert wird, sobald Sie versuchen, das Ebenenfragment unterhalb der Oberfläche zu rendern (Sie testen die vorgespeicherte Tiefenstruktur aus dem vorherigen Durchgang). Sie wissen, dass eine Kollision auftritt, damit Sie die ID ausgeben können. Dieser Weg ist pixelgenau und kann sogar den Ort des Treffers angeben. – Spektre

+0

Nun, um die Geschwindigkeit meiner Shader zu erhöhen, berechnete ich vorher die Höhe jedes Eckpunkts. Es gibt also keine "Tiefenstruktur". Ich könnte auch die Eckpunktpositionen ändern, nachdem ich sie von meiner Höhenkarte gelesen habe. – Luecx

Antwort

0
  1. Gelände machen

    Sie liner depth buffer versuchen könnte sein Kann die Genauigkeit zu verbessern .

  2. Lesetiefe Textur

    Sie glReadPixels mit GL_DEPTH_COMPONENT und GL_FLOAT verwenden können. Dadurch wird der Tiefenpuffer in den Seitenspeicher CPU kopiert. So, jetzt können Sie tun, auch Kollision auf CPU Seite oder jede Berechnung im Hinblick auf Masse bezogen ...

  3. verwenden, um die Tiefenpuffer als Textur

    so kopieren zurück GPU mit glTexImage2D.Ich weiß, das ist langsam (aber wahrscheinlich viel schneller als Ihre aktuelle Berechnung der Kollision. Wenn Sie nicht verwenden Intel HD Graphics Sie können stattdessen # 2, # 3 verwenden FBO für die Tiefe, die Tiefe Puffer direkt zu rendern Textur. Aber auf Intel dies nicht zuverlässig funktioniert (oder überhaupt).

  4. jetzt Ihre Objekte (off-Screen) mit GLSL Shader

    innen Fragmente macht nur mit der Tiefe gemacht Position vergleichen (als Textur angebracht Wenn unten in den Compute Shadern die Kollision ausgegeben wird, können Sie die Ergebnisse in einer Textur speichern . Oder Sie könnten dafür einen Anhang oder FBO verwenden.

    Wenn Sie FBO nicht verwenden können, können Sie auf "Bildschirm" mit speziell farbcodierten Kollisionen rendern. lesen Sie es dann mit glReadPixels und scannen für sie zu handhaben, was immer Kollision Logik, die Sie auf CPU Seite haben ...

    Schreiben Sie nicht auf Tiefenpuffer in diesem Pass !!! Und verwenden Sie auch nicht CULL_FACE, weil das eine Kollision der Rückseite Ihres Objekts verpassen könnte.

  5. machen jetzt die Objekte normalerweise

    falls Sie in # machen nicht 4 oder Sie kodieren Kollision in den Bildschirmpuffer müssen Sie das Zeug zu überschreiben/machen. Ansonsten wird dieser Schritt nicht benötigt. Das Rendern nach der Kollisionserkennung ist jedoch gut, da Sie im Falle einer Kollision höchstwahrscheinlich die Objektposition/Orientierung/Gitter ändern und bereits gerenderte Objekte die veränderte behindern könnten.

[Notizen]

Kopieren von Bild zwischen CPU und GPU langsam ist so FBO verwenden und Textur machen, wenn Sie können, statt.

Wenn Sie nicht vertraut mit mehreren Pass-Rendering sehen einige QAs sind für Inspiration:

Dies funktioniert nur in Sicht ... aber man kann einfach Kollision tun Rendering-Durchlauf (pro Objekt). Render mit der Kamera von oben nach unten (Birdseye) zu sehen und nur Bereich um Ihr Objekt abdecken ... Auch brauchen Sie nicht zu große Auflösung für diese, so sollte es relativ schnell sein ... So können Sie Ihren Bildschirm auf das Quadrat zu teilen Bereiche (mit glViewport) Testen mehr Objekte in einem einzigen Frame, um die Synchronisierungszeit Verlangsamungen so viel wie möglich zu finden (weniger Anrufe glReadPixel verwenden). Sie benötigen dafür auch keine Eckpunktfarben oder Texturen.

Verwandte Themen