Autor |
Beitrag |
Sternkuccker
Hält's aus hier
Beiträge: 10
|
Verfasst: Sa 12.12.09 21:13
Hallo Programmierfreunde,
ich habe eine Frage zur freien Drehung der gluLookAt-Kamera. Könnt ihr mir sagen, wie die Variablen für gluLookAt verändert werden müssen, wenn ich als Input xDelta und yDelta von der Maus habe und mich frei in alle Richtungen drehen möchte?
Kurz zum Hintergrund: Ich schreibe momentan eine wissenschaftliche Simulation, die als "Bonus" eine Visualisierung des Rechenergebnisses beinhaltet. Da ich mich mit 3D-Darstellungen bis vor kurzem nicht auskannte, hatte ich schonmal im Forum nachgefragt und den Tip mit OpenGL erhalten. Ich habe es dank guter Tutorials geschafft, eine OpenGL-Welt zu bauen, die meine Rechenergebnisse (Sterne mit definierter Färbung) als Spheres darstellt. Das funktioniert soweit gut.
Was ich nicht sauber hinbekomme: Mit der Maus frei in der Welt zu drehen. Um mich herum sind überall "Sterne" (Kugeln), und ich möchte gerne in alle Richtungen schauen. Was ich bisher habe:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| if LeftMousePressed then begin eyeX := eyeX+(MouseXDelta*0.05); eyeY := eyeY+(MouseYDelta*0.05); end;
(...)
GluLookAt(eyeX,eyeY,eyeZ,centerX,centerY,centerZ,UpX,UpY,UpZ); |
Wenn ich nun die Maus bewege, kann ich die Ansicht bis max. 90° nach oben/unten und links/rechts drehen. Es ist aber nicht möglich, sich komplett umzudrehen und nach hinten zu schauen. Da wir uns im Weltraum befinden, soll frei gedreht werden.
Ich habe diverse Kamera-Tutorials gelesen, aber nur die Hälfte verstanden. Wenn ich mir die Situation auf Papier aufzeichne, scheint mir klar zu sein, dass sich z.B. beim nach oben schauen auch der Kopfvektor verändern sollte, um einen bestimmten Winkel. Das ist aber leider nicht mein Spezialgebiet.
Danke für jede Hilfe!
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Sa 12.12.09 21:52
Kugelkoordinaten sind für diese Aufgabe wie geschaffen  .
Sternkuccker hat folgendes geschrieben : | Wenn ich mir die Situation auf Papier aufzeichne, scheint mir klar zu sein, dass sich z.B. beim nach oben schauen auch der Kopfvektor verändern sollte, um einen bestimmten Winkel. |
Nein, den kannst du stehen lassen. OpenGL sollte es egal sein, ob die beiden Vektoren orthogonal zueinander sind.
_________________ >λ=
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: So 13.12.09 00:38
Hey,
das geht mit gluLookAt zeimlich schlecht. Ich mach das immer so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure TForm1.Render; begin glTranslatef(0,0,-5); glRotatef(Tilt, 1, 0, 0); glRotatef(Turn, 0, 1, 0); end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if ssLeft in Shift then begin Turn := Turn - (OldMousePos.X - X); Tilt := Tilt - (OldMousePos.Y - Y); end; OldMousePos := Point(X, Y); end; | Schonma bei www.delphigl.com geguckt? Da gibts auch paar Tutorials zur KameraBewegung...
€: ich dreh jetz bei mir das Objekt, um nur die Kamera zu drehen, musst du die Rotation vor der Translation aufrufen, du kannst ja ma mit den 3 Zeile spielen, es kommt immer was anderes raus, kommt halt drauf an was dir besser gefällt, bzw was besser zu deinem Problem passt.
MfG Bergmann
Einloggen, um Attachments anzusehen!
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
Sternkuccker 
Hält's aus hier
Beiträge: 10
|
Verfasst: So 13.12.09 01:53
Hallo Bergmann,
vielen Dank, das funktioniert schon mal super!
Ich habe jetzt stehen:
Delphi-Quelltext 1: 2: 3:
| glRotatef(Tilt, 1, 0, 0); glRotatef(Turn, 0, 1, 0); glTranslatef(eyeX,eyeY,eyeZ); |
Damit dreht man sich um die "eigene" Achse, und nicht um den Mittelpunkt der Welt.
Leider hat mir das eine andere Routine zerschossen, die ich mit gluLookAt gemacht hatte. Das war ein "hineinschreiten" in die Welt. Ich habe per Mausrad den Standpunkt des Beobachters (centerX,Y,Z) nach vorne bzw. hinten verlegt, um einen Schritt auf genau den Punkt der Welt zu machen, der gerade im Mittelpunkt des Bildschirmes steht. Das funktioniert jetzt nicht mehr.
Hast Du für dieses Feature auch so einen prima OpenGL-Code? Die Kamera-Bewegung hatte ich mir aus einem Tutorial bei delphigl abgeschaut, aber das funzt jetzt nicht mehr...
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: So 13.12.09 03:01
Hey,
dazu musst du einfach nur dein eyeZ nach hinten bewegen, oder hab ich dich jetzt falsch verstanden?!
Wenn du sowas wie ne Zoom-Fkt auf den Punkt auf den du grad guckst suchst, dann guck dir nochma meinen Code an. Das Translatef(0,0,-5) bewegt die Camera 5 Einheiten nach hinten und dreht sie dann um diesen Punkt:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure TForm1.Render; begin glTranslatef(0,0,-Zoom); glRotatef(Tilt, 1, 0, 0); glRotatef(Turn, 0, 1, 0); gltranslatef(eyeX, eyeY, eyeZ); end;
procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); begin Zoom := Zoom - WheelDelta/100; end; | Das dreht wie Camera jetzt mit dem Abstand von Zoom um den Punkt(eyeX, eyeY, eyeZ)...
€: wenn du die Camera in Blickrichtung verschieben willst, dann musst du das auch über deine eye-Variabeln machen, nur das du vorher mit dem Winkeln Tilt un Turn berechnest, in welche Richtung du musst:
Delphi-Quelltext 1: 2: 3:
| eyeX := eyeX + MoveDelta*sin(Turn); eyeY := eyeY + MoveDelta*sin(Tilt); eyeZ := eyeZ + MoveDelta*cos(Turn); | ich weiß ncih genau ob das Richtig is, aber das sollte in etwa stimmen, wenn du Probleme hast sag bescheid da rechne ich das nochma genau durch. Auf jedenfall sind das alles ganz einfache sin, cos un tan Aufgaben^^
MfG Bergmann.
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
Sternkuccker 
Hält's aus hier
Beiträge: 10
|
Verfasst: So 13.12.09 14:31
Hallo Bergmann,
ja, ich möchte die Kamera in Blickrichtung verschieben, mich also "in die Welt hineinbewegen", nach da, wohin ich schaue.
Danke für Deine Hilfe, leider klappt es aber nur zur Hälfte. Wenn ich folgendes versuche:
Quelltext 1: 2: 3: 4: 5: 6:
| MouseZoom := MouseZoom - WheelDelta; // (...) glTranslatef(0,0,-WheelDelta); glRotatef(Tilt, 1, 0, 0); glRotatef(Turn, 0, 1, 0); glTranslatef(eyeX,eyeY,eyeZ); |
dann geht der Zoom korrekt (juhu!), aber das Drehen läuft wieder um den Weltmittelpunkt! Soll ja um die eigene Achse gehen. Ohne das "glTranslatef(0,0,-Wheeldelta);" macht es das ja auch.
Wenn ich versuche, die Kamera zu verschieben:
Quelltext 1: 2: 3: 4: 5: 6: 7:
| eyeX := eyeX + WheelDelta*sin(Turn); eyeY := eyeY + WheelDelta*sin(Tilt); eyeZ := eyeZ + WheelDelta*cos(Turn); // (...) glRotatef(Tilt, 1, 0, 0); glRotatef(Turn, 0, 1, 0); gltranslatef(eyeX, eyeY, eyeZ); |
Dann scheint etwas mit den Werten nicht zu stimmen, die Kamera verschiebt sich schräg. Ich habe es auch inkl. DegToRad versucht, ebenso falsch.
Dann habe ich versucht, die glTranslate mit Wheeldelta und eyeXYZ zu kombinieren, aber dann werden Hüpfer daraus. Ich denke, die beste Lösung wäre es, glTranslate mit der Drehung auszuführen (geht ja sauber) und für den Zoom den Augenpunkt zu bewegen. Kannst Du mir mit den korrekten sinus/cosinus für die Augpunktverschiebung nochmal helfen? Dake Dir!
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: So 13.12.09 18:35
Hey,
wenn du den Blickpunkt bewegst is es ja in dem Sinne keine Zoom-Funktion
ich hab grad wenig Zeit, ich guck mir das ganze heut Nacht mal an un lad dir das ganze mal hoch...
MfG Bergmann.
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
Sternkuccker 
Hält's aus hier
Beiträge: 10
|
Verfasst: So 13.12.09 19:15
Stimmt, es ist keine Zoom-Funktion. Es ist ein Bewegen in die Welt hinein. Das Ergebnis soll sein, dass man sich wie ein Raumschiff fühlt: Meine "Welt" sind Sterne (Spheres) in alle Richtungen. Man kann sich frei drehen und in die Blickrichtung bewegen.
Die Sterne stammen übrigens aus dem Hipparcos-Katalog. Wenn das ganze läuft, kann ich gerne mal einen Screenshot machen.
Freue mich auf Deinen Upload!
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: So 13.12.09 22:52
Hey,
hab das ganze mal zusammen gebastelt.
die Variablen: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| var pos, cam: TGLVector3f; zoom: Single; const MOVE_SPPED = 10; |
die Steuerung (W/A - vor/zurück, A/D - links/rechts, R/F - hoch/runter): Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| if IsKeyDown('w') or IsKeyDown('s') then begin if IsKeyDown('w') then speed := CAM_SPEED else speed := -CAM_SPEED; pos[0] := pos[0] + cos(cam[1]/180*Pi+Pi/2)*cos(cam[0]/180*Pi)*speed*DeltaTime/1000; pos[1] := pos[1] + sin(cam[0]/180*Pi)*speed*DeltaTime/1000; pos[2] := pos[2] + sin(cam[1]/180*Pi+Pi/2)*cos(cam[0]/180*Pi)*speed*DeltaTime/1000; end; if IsKeyDown('a') or IsKeyDown('d') then begin if IsKeyDown('a') then speed := CAM_SPEED else speed := -CAM_SPEED; pos[0] := pos[0] + cos(cam[1]/180*Pi)*speed*DeltaTime/1000; pos[2] := pos[2] + sin(cam[1]/180*Pi)*speed*DeltaTime/1000; end; if IsKeyDown('r') or IsKeyDown('f') then begin if IsKeyDown('f') then speed := CAM_SPEED else speed := -CAM_SPEED; pos[0] := pos[0] + cos(cam[1]/180*Pi+Pi/2)*cos(cam[0]/180*Pi+Pi/2)*speed*DeltaTime/1000; pos[1] := pos[1] + sin(cam[0]/180*Pi+Pi/2)*speed*DeltaTime/1000; pos[2] := pos[2] + sin(cam[1]/180*Pi+Pi/2)*cos(cam[0]/180*Pi+Pi/2)*speed*DeltaTime/1000; end; |
Die komplett frei bewegbare Kamera: Delphi-Quelltext 1: 2: 3:
| glRotatef(cam[0], 1, 0, 0); glRotatef(cam[1], 0, 1, 0); glTranslatef(pos[0], pos[1], pos[2]); |
Die Camera mit festem Fixpunkt und Zoom auf den Fixpunkt (is ganz praktisch wenn man die Kamera an einen Planeten binden will): Delphi-Quelltext 1: 2: 3: 4:
| glTranslatef(0,0,-zoom); glRotatef(cam[0], 1, 0, 0); glRotatef(cam[1], 0, 1, 0); glTranslatef(pos[0], pos[1], pos[2]); |
so das sollte jetzt alles sein, was du brauchst. im anhang nochma das projekt wenn du nochma genau gucken willst.
würd mich auch freuen, wenn du mal die exe hochladen kannst (sofern du damit nicht igrendwelche Rechte verletzt).
Würde mir das ganze gern mal ansehen...
MfG Bergmann
Einloggen, um Attachments anzusehen!
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
Sternkuccker 
Hält's aus hier
Beiträge: 10
|
Verfasst: Mo 14.12.09 12:11
Hallo Bergmann,
wow, das sieht super aus! Vielen lieben Dank, das ist unglaublich hilfreich.
Ich werde die Routinen in mein Programm einbauen - dann zeige ich es dir gerne mal. Es ist im Grunde ein kleines Programm, das Daten für eine wissenschaftliche Untersuchung bzw. schließlich Publikation liefern soll. Und ob die Daten, die in der Simulation generiert werden, stimmen - das möchte ich mit OpenGL visualisieren. Quasi ein grafischer Debugger, der für diesen speziellen Anwendungsfall unabdinglich ist. Bereits jetzt hat sich die OpenGL-Ansicht als extrem hilfreich erwiesen.
Ich möchte das Programm vor einer Publikation natürlich nicht verbreiten - deshalb werde ich Dir in den nächsten Tagen eine PN schicken, falls Du die hier im Forum abrufst? Sonst per Mail. Kleiner Appetizer: Es ist ein Projekt an der Schnittstelle zwischen Astrophysik und Volkswirtschaftslehre - sehr exotisch, aber keine Sorge, kein bullshit...
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Mo 14.12.09 17:55
Hey,
Sternkuccker hat folgendes geschrieben : | Es ist ein Projekt an der Schnittstelle zwischen Astrophysik und Volkswirtschaftslehre - sehr exotisch |
Das klingt sehr interessant, ich bin gespannt.
Kannst mir alles per PN schicken, bin eig jeden Tag mind einmal hier unterwegs...
MfG Bergmann
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 24.12.09 15:08
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Fr 25.12.09 15:45
Hey,
es geht bestimmt um die Auswirkung der Sternenbilder auf das Kaufverhalten
OK, Spaß bei Seite. Ich hab mir genau die gleiche Frage wie du gestellt, deshalb bin ich ja so gespannt drauf wie das Ganze aussieht...
MfG Bergmann.
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
Sternkuccker 
Hält's aus hier
Beiträge: 10
|
Verfasst: So 27.12.09 19:32
Ja, die Frage ist berechtigt! Das Projekt ist leider noch nicht vorzeigbar, aber ich werde es dann gerne präsentieren. Dürfte aber bis Januar dauern...
Ein wenig kann ich aber schon verraten: Angenommen, man möchte eine gewisse Anzahl an Zielen erforschen. Wenn die Ziele im Weltraum liegen, und verschiedene physikalische Regeln beachtet werden müssen, nenne ich das mal den astrophysikalischen Teil. Die Überlegung, wo man wann welche Explorationsvehikel baut, gehört u.a. zum Bereich der Volkswirtschaftslehre (genau genommen Mikroökonomik, das habe ich studiert) - Stichwort z.B. "economies of scale".
Für mein Projekt sind beide Bereiche wichtig. Auf einem theoretischen Fundament soll eine Simulation entstehen, die ich grafisch debugge. Klingt das sehr "abge-spaced"?  Endziel ist ein Paper in einem Journal, um die Ergebnisse zu veröffentlichen.
|
|
|