Autor Beitrag
Sternkuccker
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Sa 12.12.09 21:52 
Kugelkoordinaten sind für diese Aufgabe wie geschaffen :D .

user profile iconSternkuccker hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
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)
BeitragVerfasst: So 13.12.09 00:38 
Hey,

das geht mit gluLookAt zeimlich schlecht. Ich mach das immer so:
ausblenden 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, 100);
  glRotatef(Turn, 010);
  //[...]
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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: So 13.12.09 01:53 
Hallo Bergmann,

vielen Dank, das funktioniert schon mal super!
Ich habe jetzt stehen:

ausblenden Delphi-Quelltext
1:
2:
3:
  glRotatef(Tilt, 100);
  glRotatef(Turn, 010);
  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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
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)
BeitragVerfasst: 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:
ausblenden 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, 100);
  glRotatef(Turn, 010);
  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:
ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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:
ausblenden 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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
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)
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
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)
BeitragVerfasst: So 13.12.09 22:52 
Hey,

hab das ganze mal zusammen gebastelt.
die Variablen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var 
//Position der Kamera/des Fixpunktes
//|     DrehWinkel der Kamera, Drehung um X-, Y- und Z-Achse(Z-Achse ungenutzt, ist für Rolldrehung vorgesehen)
  pos, cam: TGLVector3f; //Vector (Array) aus 3 Float-Werten
  zoom: Single;
const
  MOVE_SPPED = 10;

die Steuerung (W/A - vor/zurück, A/D - links/rechts, R/F - hoch/runter):
ausblenden 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:
ausblenden Delphi-Quelltext
1:
2:
3:
  glRotatef(cam[0], 100);
  glRotatef(cam[1], 010);
  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):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  glTranslatef(0,0,-zoom);
  glRotatef(cam[0], 100);
  glRotatef(cam[1], 010);
  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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
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)
BeitragVerfasst: Mo 14.12.09 17:55 
Hey,

user profile iconSternkuccker hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 24.12.09 15:08 
user profile iconSternkuccker hat folgendes geschrieben Zum zitierten Posting springen:
Es ist ein Projekt an der Schnittstelle zwischen Astrophysik und Volkswirtschaftslehre

Ich wunder mich grad, was die beiden Fachgebiete denn gemeinsam haben könnten ... :nixweiss:

_________________
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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
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)
BeitragVerfasst: Fr 25.12.09 15:45 
Hey,

es geht bestimmt um die Auswirkung der Sternenbilder auf das Kaufverhalten :D
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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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.