Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 15:52

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Do Mai 25, 2006 17:23 
Offline
DGL Member

Registriert: Mo Mai 22, 2006 16:33
Beiträge: 9
Hallo,

ich möchte gerne eingelesene .objs um die eigenen Achsen drehen lassen, also in x, y, und z Richtung, aber auf der Stelle.
Dazu habe ich einmal die Mitte der Bounding Box berechnet:
Code:
  1.  
  2.     model->Center.x = model->Min.x + (model->Max.x - model->Min.x) / 2;
  3.     model->Center.y = model->Min.y + (model->Max.y - model->Min.y) / 2;
  4.     model->Center.z = model->Min.z + (model->Max.z - model->Min.z) / 2;
  5.  

mit der Berechnung der min/max:
Code:
  1.    
  2.         if (model->Max.x < model->VertexArray[nVertexes].x) {
  3.         model->Max.x = model->VertexArray[nVertexes].x;
  4.     }
  5.     if (model->Min.x > model->VertexArray[nVertexes].x) {
  6.         model->Min.x = model->VertexArray[nVertexes].x;
  7.     }
  8.         // y und z analog
  9.  


oder auch über den Schwerpunkt die Mitte berechnet:
Code:
  1.  
  2.     model->Center.x = 0;
  3.     model->Center.y = 0;
  4.     model->Center.z = 0;
  5.     for (i=0; i<nVertexes - 1; i++) {
  6.         model->Center.x += model->VertexArray[i].x;
  7.         model->Center.y += model->VertexArray[i].y;
  8.         model->Center.z += model->VertexArray[i].z;
  9.     }
  10.     model->Center.x = model->Center.x / nVertexes;
  11.     model->Center.y = model->Center.y / nVertexes;
  12.     model->Center.z = model->Center.z / nVertexes;
  13.  


Die Rotation erfolgt so:
Code:
  1.  
  2.     if (rotationenable == TRUE) {
  3.         glTranslatef(model->Center.x, model->Center.y, model->Center.z);
  4.         glRotatef(angle[0], 1.0, 0.0, 0.0);
  5.         glRotatef(angle[1], 0.0, 1.0, 0.0);
  6.         glRotatef(angle[2], 0.0, 0.0, 1.0);
  7.         glTranslatef(-model->Center.x, -model->Center.y, -model->Center.z);
  8.         //rotationenable = FALSE;
  9.     }
  10.  

wobei angle[] in 20 Einheiten dekrementiert oder inkrementiert wird, je nach dem in welche Richtung, wobei die drei angle mit 0.0f initialisiert sind

bei hand1.obj funktioniert alles richtig, aber z.B. beim Eifelturm (tour.obj) wird nur korrekt um die y-Achse gedreht, beim Magic Mirror.obj wird um keine Achse korrekt gedreht.
Kann mir jemand erklären, warum?

Außerdem noch eine Frage: Wenn ich die min/max-Werte der Bounding Box habe, wie setzte ich die gluLookAt-Parameter um das entspr. Objekt direkt in der Mitte zu haben?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Mai 25, 2006 19:48 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Wegen gluLookAt.
Du gibst bei dem Befehl 3 Vectoren an:

1. Die Position an der sich die Kamera befinden soll.
2. Die Position zu der die Kamera hingucken soll.
3. Ein Vector der angibt wo "oben" ist.

Ich denke für deine Zwecke solltest du folgende Werte nehmen:

1. Blickpunkt = zentrum deines Modells
2. CamPos = Blickpunk aber um einen beliebigen Wert (z.B. 15) in die Z-Richtung verschoben.
3. UpVector = 0,1,0


Wieso das mit dem Zentrum nicht funktioniert versteh ich nicht. Das Zentrum sollte eigentlich stimmen, wenn du es anhand der Bounding Box berechnest. Wie man richtig dreht (reihenfolge ist wichtig) steht im Tutorial_Matrix2

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Mai 25, 2006 21:01 
Offline
DGL Member

Registriert: So Sep 26, 2004 05:57
Beiträge: 190
Wohnort: Linz
Du verwendest des öfteren eine Division mit einem Integer, das solltest du auf Float umstellen, also statt
model->Center.x = model->Min.x + (model->Max.x - model->Min.x) / 2;
besser
model->Center.x = model->Min.x + (model->Max.x - model->Min.x) / 2.0f;

und statt
model->Center.x = model->Center.x / nVertexes;
besser
model->Center.x = model->Center.x / (float) nVertexes;

Dadurch schließt du dann Rundungsfehler aus, was vor allem bei kleineren Modellen zu Problemen führen kann.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Mai 25, 2006 21:55 
Offline
DGL Member

Registriert: Mo Mai 22, 2006 16:33
Beiträge: 9
Zitat:
von Lyr:
Du verwendest des öfteren eine Division mit einem Integer, das solltest du auf Float umstellen, also statt
model->Center.x = model->Min.x + (model->Max.x - model->Min.x) / 2;
besser
model->Center.x = model->Min.x + (model->Max.x - model->Min.x) / 2.0f;

und statt
model->Center.x = model->Center.x / nVertexes;
besser
model->Center.x = model->Center.x / (float) nVertexes;

Dadurch schließt du dann Rundungsfehler aus, was vor allem bei kleineren Modellen zu Problemen führen kann.
Vielen Dank, das waren gute Hinweise, ich habe an anderen Stellen auch evtl. Konvertierungsprobleme gefunden.
Leider hat sich das Dehverhalten nicht verändert.



Zitat:
von Flash
Wegen gluLookAt.
Du gibst bei dem Befehl 3 Vectoren an:

1. Die Position an der sich die Kamera befinden soll.
2. Die Position zu der die Kamera hingucken soll.
3. Ein Vector der angibt wo "oben" ist.

Ich denke für deine Zwecke solltest du folgende Werte nehmen:

1. Blickpunkt = zentrum deines Modells
2. CamPos = Blickpunk aber um einen beliebigen Wert (z.B. 15) in die Z-Richtung verschoben.
3. UpVector = 0,1,0
Jetzt ist die Ausrichtung viel besser! :D
Dankeschön!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 27, 2006 18:01 
Offline
DGL Member

Registriert: So Sep 26, 2004 05:57
Beiträge: 190
Wohnort: Linz
Beschreib evntl. mal etwas genauer wie du es habe willst und wie es jetzt ist das Drehverhalten. Und zeichne dir auch mal das Model-Center ein, damit du siehst ob daran etwas falsch ist, also entweder die Achsen oder nur den Punkt (wo du dann wahrscheinlich für diesen Punkt den Tiefenbuffer ausschalten müsstest).

Oder ist der Punkt um den herum rotiert wird korrekt nur die Achsen um die gedreht wird falsch? Bei deinem Code ist es klar, dass immer um die aktuelle lokale y und z - Achse des Objektes gedreht wird, nicht um die globalen Achsen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 28, 2006 00:46 
Offline
DGL Member

Registriert: Mo Mai 22, 2006 16:33
Beiträge: 9
Hi Lyr,
die Rotation um die 3 Achsen funktioniert nun korrekt. :D
Allerdings kann ich nicht genau sagen, woran es lag, hab rumgefrickelt und plötzlich funktionierte es korrekt.

Ich habe aber noch eine Frage zu deinen Anmerkungen:
Du schreibst, man erkennt an meinem Code, dass ich um die lokalen Achse drehe, nicht um die globalen.
Was bedeutet das? Ich dachte, dass wenn ich die Rotation auf die Modelviewmatrix anwende, ich alles, also global, ändere.
Die zusätzlich eingezeichneten Koordinatenachsen drehen sich nämlich auch mit.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 28, 2006 04:27 
Offline
DGL Member

Registriert: So Sep 26, 2004 05:57
Beiträge: 190
Wohnort: Linz
Mit lokaler Drehung meine ich, dass du einfach hintereinander um jede Achse drehst.

Bei
glRotatef(angle[0], 1.0, 0.0, 0.0);
änderst du dein (lokales) Koordinatensystem indem du um die X-Achse drehst. Vor dieser Drehung bist du (von den Drehungen her) noch im globalen Koordinatensytem, wodurch diese Drehung auch korrekt erfolgt (zumindest sollte es so sein :-) ). Bei deinem neuen (lokalen) Koordinatensystem ist nun jedoch die y- und die z- Achse nicht mehr gleich wie beim Globalen.

Das
glRotatef(angle[1], 0.0, 1.0, 0.0);
dreht nun also nicht mehr um die globale y-Achse, sondern um die etwas um die x-Achse rotierte lokale y-Achse. Durch diese Drehung ändert sich wiederum die lokale z-Achse (natürlich auch die x-Achse aber die ist nicht mehr relevant).

Und zum Zeitpunkt von
glRotatef(angle[2], 0.0, 0.0, 1.0);
hat deine aktuelle lokale z-Achse kaum noch etwas mit der globalen z-Achse zu tun, die zeigt nun in irgend eine Richtung.

Eine mögliche Form das zu umgehen wäre wohl, dass du dir eine Quaternion-Klasse zulegst (sollte eh die ein oder andere auch Open Source sein, vielleicht findest sogar eine in einem Tutorial), damit kannst du dann auswählen ob du eine lokale oder eine globale Drehung haben möchtest, sofern du überhaupt globale Drehungen einbauen willst.

Eine andere Möglichkeit wäre, dass du die Matrixmanipulationen händisch durchführst, also die deine Modelview-Matrix entweder merkst oder dir zu dem Zeitpunkt wo du eine Rotation um eine globale Achse durchführen möchtest holst, danach die Mulitplikation mit der entsprechenden Rotationsmatrix entweder Pre oder Post multiplizierst (oder wie das auch immer heißt :-) ), also bei Matrizen macht es ja einen Unterschied ob du schreibst A*B oder B*A. Einmal wird um die globale und einmal um die lokale Achse gedreht.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 28, 2006 14:55 
Offline
DGL Member

Registriert: Mo Mai 22, 2006 16:33
Beiträge: 9
Hallo Lyr,

vielen Dank für deine ausführlichen Erklärungen, jetzt habe ich das mit dem lokalen und globalen Koordinatensystem verstanden.
Ich werde es erstmal beim jetztigen Stand belassen, da freie Bewegungen nicht das Hauptaugenmerk meiner Applikation sein wird.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 14 Queries | GZIP : On ]