Objekt-Größe in PyOpenGL

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Barcellona
User
Beiträge: 74
Registriert: Dienstag 25. Mai 2010, 12:10

Hallo zusammen,

ich versuche gerade OpenGL zu lernen und hab' nun schon ein paar Beispiele durchgearbeitet.

In meinem Skript lade ich nun ein Laternen-Modell im .obj-Format, samt seiner .mtl-Datei.
Ich habe allerdings bisher keine Ahnung wie ich die Größe des geladenen Objekts im Achsenkreuz feststellen kann.

Wenn ich ein zum Beispiel folgenden Würfel betrachte:

Code: Alles auswählen

# Blender3D v249 OBJ File: 
# www.blender3d.org
mtllib cube.mtl
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
usemtl Material
s off
f 1 2 3 4
f 5 8 7 6
f 1 5 6 2
f 2 6 7 3
f 3 7 8 4
f 5 1 4 8
Woher erkenne ich denn dann wie groß der Würfel letztendlich dargstellt wird? (in Pixeln?)
deets

Das ist von der ModesView-Matrix und der Projection-Matrix ab, und die hast ja du alleine in der Hand. Du kannst jetzt natuerlich hingehen & einfach alle Punkte damit durchmultiplizieren in Python, um dann min/max zu berechnen.

Aber gestatte mal die Frage - warum?
Barcellona
User
Beiträge: 74
Registriert: Dienstag 25. Mai 2010, 12:10

Hab' überlegt wie ich eine Kollisionsberechnung schreiben könnte.

In einem 2D-Spiel habe ich dafür bestimmte (x,y)-Koordinaten zweier Gegenstände verglichen,
aber wie soll das im 3D-Raum funktionieren, wenn ich bei dem Modell nicht genau weiß, welche x,y,z-Koordinaten
es abdeckt... :K
deets

Na, da nutzt dir doch deine Bildschirmkoordinate mal gerade nix. Wenn du zB im Hintergrund einen Wuerfel hast, und im Vordergrund geht dein Spieler vorbei - dann kollidieren die doch nicht. Genausowenig wie du mit dem Berliner Fernsehturm kollidierst, wenn du auf dem Alexanderplatz langlaeufst - nur, weil du *vor* ihm durchlaeufst.

Fuer sowas nimmt man eine Physik-Engine ala Bullet oder PyODE. Die haben Kollisions-Bibliotheken fuer 3D-Koerper, und berechnen mittels geschickten raeumlicher Filterung und unter Anwendung der Objekt-Matrizen, ob Dinge kollidieren. Du kannst dann entweder selbst mit diesen Informationen arbeiten, oder laesst die Antwort auf die Kollision durch die Physik-Engine berechnen - was dann die eigentliche Physik darstellt.
Barcellona
User
Beiträge: 74
Registriert: Dienstag 25. Mai 2010, 12:10

Darum geht es ja auch nicht nur um die x und y Koordinate, sondern auch um die z-Koordinate.

Der Punkt (0,0,0) ist ja sicherlich nicht gleich dem Punkt (0,0,3).

Danke für den Hinweis auf die Physik-Engines, aber es müsste doch auch möglich sein sich selbst eine kleine Physik-Engine zu schreiben, die zwei 3D-Objekte
übergeben bekommt und sagt, ob diese sich schneiden oder auseinanderliegen...

Irgendwie muss man doch auch berechnen können, welche Koordinaten (x,y,z) ein Objekt belegt, sei es mittels der Projektionsmatrix...
Ich kann doch auch in OpenGL einen Punkt zeichnen, in dem ich ihm seine drei Koordinaten nenne...
deets

Natuerlich kann man das selbst machen. Diejenigen, die eine Engine geschrieben haben, haben das ja auch gemacht. Aber wenn du schon konzeptionell Probleme hast, zwischen 3D-Raum und 2D-Raum im Bild zu unterscheiden (die Kollision hat naemlich *nichts* mit den okkupierten Pixeln zu tun), dann denke ich wirst du da Schwierigkeiten haben. Denn Kollisionen von Koerpern im Raum sind nicht trivial (sind sie schon nicht in 2D, aber da kann man sich behelfen mit Pixeln, wenn man mag).

Am einfachsten sind zwei Kugeln zu vergleichen, dann wahrscheinlich Achsen-parallele Boxen.

Aber danach musst du dich dann schon mit eine Menge komplexer Algorithmen auseinandersetzen. Bestimmen, ob einer der n Punkte eines konvexen Koerpers in einem anderen konvexen Koerper enthalten ist zB. Usw.

Deine Zeit ist wirklich besser investiert, sich mit einer Physik-Engine auseinanderzusetzen. Installier dir mal PyODE & lass die Beispiele laufen. Daran kannst du dich dan langhangeln.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo

Fange am besten mit den bereits genannten Kugeln an. Nimm dir alle Ecken des Objekts, bestimme das Minimum und das Maximum für jede Achse (x, y, z) und berechne damit den "Mittelpunkt" des Objekts. Den Radius kannst du dann über den Punkt mit dem maximalen Abstand zum Mittelpunkt bestimmen ("genaue Methode") oder über einen Eckpunkt der durch die Minima und Maxima der Achsen gegeben ist.

Eine Kollision zwischen zwei Objekten liegt dann vor, wenn der Abstand der beiden Objektmittelpunkte kleiner ist als die Summe der beiden Radien.

Sebastian

Edit: oder als Begriff zum googlen: "bounding sphere"; wenn du es etwas genauer haben willst: "bounding box". Letzteres gibt es als axis-aligned (AABB) und als object-aligned (OABB). Für den Anfang solltest du aber bei den Kugeln bleiben ;-)
Zuletzt geändert von EyDu am Dienstag 12. Juli 2011, 13:55, insgesamt 1-mal geändert.
Das Leben ist wie ein Tennisball.
Barcellona
User
Beiträge: 74
Registriert: Dienstag 25. Mai 2010, 12:10

Ok, danke, werde mir die Physik-Engine mal anschauen.

Aber nochmal zu dem Koordinaten-System das OpenGL benutzt.

Mit

Code: Alles auswählen

glTranslatef(x,y,z)
kann ich doch ein Objekt um x-Einheiten z.B. nach links bewegen,
wenn ich ein Quadrat male mit GL_QUADS, dann weiß ich bei dem Quadrat doch auch welche Koordinaten es hat.

Da muss es doch irgendwie möglich sein, dass wenn ich obengenannten Würfel aus einer obj-Datei lade, auch seine Ausmaße
in x,y,z-Koordinaten berechnen kann, oder sehe ich das falsch?
Barcellona
User
Beiträge: 74
Registriert: Dienstag 25. Mai 2010, 12:10

EyDu hat geschrieben:Hallo

Fange am besten mit den bereits genannten Kugeln an. Nimm dir alle Ecken des Objekts, bestimme das Minimum und das Maximum für jede Achse (x, y, z) und berechne damit den "Mittelpunkt" des Objekts. Den Radius kannst du dann über den Punkt mit dem maximalen Abstand zum Mittelpunkt bestimmen ("genaue Methode") oder über einen Eckpunkt der durch die Minima und Maxima der Achsen gegeben ist.

Eine Kollision zwischen zwei Objekten liegt dann vor, wenn der Abstand der beiden Objektmittelpunkte kleiner ist als die Summe der beiden Radien.

Sebastian
Genau, so hatte ich mir das vorgestellt... Aber wie berechne ich das Minimum und das Maximum für jede Achse (x,y,z) für den geladenen Würfel aus der obj-Datei?

Code: Alles auswählen

v 1.000000 -1.000000 -1.000000
zB ist doch keine x,y,z-Koordinate... :K
Ich müsste doch die Eckpunkte des Würfels im Koordinaten-System berechnen können (irgendwie)...
deets

*seufz* Du redest immer noch von "malen". Vergiss doch bitte mal alles, was mit Pixeln zu tun hat. Das ist fuer eine Kollisionsberechnung voellig uninteressant.

Und ja, natuerlich kannst (und so macht man das ja auch) du diese Bererchnungen selbst vornehmen. Aber *NICHT* mit OpenGL!!!!!! Das ist fuer *Grafikausgabe* gedacht. Und nur dafuer (CUDA & OpenCL mal aussen vor gelassen).

Man macht es tatsaechlich genau umgekehrt: dein 3D-Objekt-Modell (ob mit oder ohne Physik-Engine) fuehrt fuer jeden Koeper eine Modell-Matrix mit, die letztlich bestimmt, wo im Raum mit welcher Ausrichtung ein Objekt sich "befindet". Und wenn man das malen will mittels OpenGL, dann nimmt man genau diese Modell-Matrix, multipliziert sie noch mit der Kamera-Matrix - und *die* setzt man dann in OpenGL als Model-View-Matrix. Dann fuettert man die Punkte (zB die GL_QUADS) in das System, und zusammen mit der Projektions-Matrix kommt es dann zur Bildschirmdarstellung.

Aber, zum wiederholten mal: OpenGL hat mit Kollisionsberechnung erstmal nichts zu tun.
Barcellona
User
Beiträge: 74
Registriert: Dienstag 25. Mai 2010, 12:10

Ok, danke. Werd' mir dann mal einen anderen Weg überlegen müssen, bzw. mir die Physik-Engines anschauen.
Antworten