Autor Beitrag
battledevil
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 96

WinXP, Win7
C#, C++, VBNET
BeitragVerfasst: Do 28.09.06 22:08 
Hallo Leute,

Ich programmiere grad ein kleines Spiel mit OpenGL, wo man mit einen Schiff entgegenkommenden Objekten ausweichen muss. Also quasi alles in der 2D-Ebene. Jetzt stellt sich mir die Frage, wie ich denn am einfachsten die Kollisionserkennung einbaue. Ich hab da mal gehört, am einfachsten wäre das möglich, wenn man einfach auf Überdeckungen von zwei Objekten im Tiefenbuffer prüft. Hat das schonmal jemand gemacht? Ein kleines Beispiel würde mir echt weiterhelfen, da ich nicht genau weiß, wie ich an die Sache rangehen soll.
Phobeus
ontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 1280

Linux (FC6), WinXP Pro (Box)
D6 Pers, D7 Pro, FPC 2.x
BeitragVerfasst: Fr 29.09.06 11:17 
Ich würde behaupten am einfachsten sind traditionelle Kollisionsabfragen via Spheres und Boxen, da diese nicht nur leicht zu implementieren und schnell sind, sondern auch fast alle Objekte perfekt abdecken. Einen Kollisionstest über den Tiefenbuffer... habe ich bisweilen nicht gesehen, aber ich könnte mir durchaus vorstellen, dass dies bei einem Stencil-Buffer funktionieren könnte. Mit Hilfe von diesem kann man die Umrisse von gezeichneten Objekten in den Buffer schreiben. Wird an einer Stelle in den Stencil geschrieben, obwohl sich dort etwas befindet, lag eine Kollision vor. Das Problem würde ich hier spontan (also ohne denken und Kaffee) dabei sehen, dass es schwer fällt das Objekt zu identifizieren, dass dort zu einer Kollision geführt hat. Sprich: Ob eine Kollision stattgefunden hat ist leicht, die Abfrage zwischen welchen Objekten eher schwerer. Das Verfahren müßte man auch auf den Tiefenbuffer realisieren können, wird allerdings von ähnlichen Problemen begleitet werden. Ergo, ich würde ein solches Verfahren vermutlich nicht bei einem Spiel nutzen, sondern ... vielleicht bei einem Partikelsystem um schnell zu prüfen, ob ein Partikel gegen eine Wand/Objekt geprallt ist. Dies liesse sich damit hervorragend über die GPU prüfen. Aber wie gesagt, alle Angaben ohne Gewähr, da es reine Mutmassungen sind. Ich würde mir ggf. einige Präsentationen/Artikel bzw. die technische Bezeichnung des Verfahrens raussuchen. Würde mich auch interessieren.

_________________
"Menschen sterben nicht wenn man sie zu Grabe trägt, sondern wenn sie ihre Träume verlieren..."
battledevil Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 96

WinXP, Win7
C#, C++, VBNET
BeitragVerfasst: Fr 29.09.06 11:41 
Ich weiß leider nicht, ob diese Technik der Kollisionserkennung schon von jemandem benutzt wurde und ob es dafür einen Namen gibt :?:
Ich hab es einfach umgemünzt aus einer Computergrafik-Vorlesung, wo die Schattenberechnung eines Raytracers über den Z-Buffer und damit die Sichtbarkeistbestimmung läuft.
Ok, zwischen einem Raytracer und OpenGL-Echtzeitgrafik ist ein Unterschied, aber prinzipiell könnte es funktionieren.

Der Witz bei meinem Spiel ist ja, das es eigentlich egal ist, welche Objekte kollidieren, da es nur Kollisionen des Raumschiffs mit anderen Objekten geben kann (man stelle sich ein klassisches "Raumschiff versucht durch Asteroidenfeld zu fliegen" - Szenario vor).

Also bisher bin ich soweit, dass ich mit gluProject aus Objektkoordinaten Fensterkoordinaten berechne, mit denen ich dann über glReadPixels die Tiefe eines Fenster-Pixels bestimmen kann.

Theorie:
Ist die Tiefe eines Pixels geringer als die Tiefe des Objektes, dann wird das Objekt an dieser Stelle durch ein anderes verdeckt, also Kollision.

Praxis:
Funktioniert leider nicht so einfach, denn es müssten ja aus den Eckpunkten der Objektpolygone alle Pixel des Objektes berechnet werden. Keine Ahnung, wie das ohne größeren Aufwand gehen soll.
Deswegen ein alternativer Ansatz: 2D-Boundingbox um das zu prüfende Objekt legen und innerhalb der Box die Tiefenwerte aller Pixel bestimmen. Nachbarpixel vergleichen. Wenn dabei ein Pixel mit Tiefe=Objekt an ein Pixel mit Tiefe=AnderesObjekt angrenzt, dann kann man das auch als Kollision ansehen, auch wenn sie sich eigentlich nur berühren.

Leider funktioniert das Auslesen der Tiefe bisher nur unzuverlässig und liefert unglaublich kleine Zahlen, obwohl ich versucht habe, die Grenzen des Tiefenbuffers von 0..1 auf 0..1000 zu erhöhen.
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Fr 29.09.06 12:03 
Worum handelt es sich denn bei deinen Schiffen überhaupt? Sind das 2D Texturen oder echte 3D Objekte?

Bei Readpixels ist es wichtig, dass du Floats ausließt. Aber da haben wir schon das nächste Problem. ReadPixels ist sehr langsam. Und jedes mal einzelne Pixel auszulesen macht die Sache nicht schneller.

Ich würde auf jeden Fall immer einen Boundingbox test machen. So kannst du im Vornherein schon mal ausschließen, wenn überhaupt keine Kollision vorhanden ist bzw kannst die zu prüfenden Objekte schon vorauswähhlen.

Bei 2D Schiffen könntest du entsprechend die Texturen vergleichen bzw. Bitmasken der Umrisse.

Bei 3D Schiffen wäre es möglich, dass du das zu testende Schiff in den Stencil schreibst. Und den Test so einstellst, dass nur das gezeichnet wird was überlagern würde. Wenn du jetzt das andere Schiff zeichnest würdest du die OcclusionQuerys aktivieren. Diese zählen die Pixel die Tiefen/Stenciltest bestanden haben. Alles andere sollte dir das Tutorial vermitteln können.

Die Extension gibt es auch als ARB-Variante. Ist identisch zu der von NVidia nur, das andere Methoden benutzt werden. Und ab OpenGL 1.5 befindet sich diese Variante auch im Kern von OpenGL.

PS: Die Occlusion würden auch bei 2D Sachen funktionieren allerdings weiß ich nicht ob sich das geschindigkeitstechnisch noch richtig lohnt bzw weiß ich auch nicht ob der Alphatest in der Lage ist die Occlusions zu beeinflussen. Bei der Selektion ist dies nämlich nicht der Fall. Würde bedeuten, dass die Teile die vom Alphatest ausgeschlossen wurden dennoch mit Selektiert werden bzw evtl auch mit in die Occlusion gerechnet werden.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
battledevil Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 96

WinXP, Win7
C#, C++, VBNET
BeitragVerfasst: Sa 30.09.06 09:33 
Danke erstmal, ich schau mir das Tutorial an.
Das Schiff ist tatsächlich ein 3D-Objekt, deswegen auch der Aufwand :wink: