2009-08-01 2 views
2

Ich arbeite seit einiger Zeit an einer Weltraumsimulation. Zuerst benutzte ich meine eigene 3D-Engine mit Software-Rasterizer.Rotieren eines Raumschiffmodells für einen Weltraumsimulator/Spiel

Aber ich habe, wenn die Zeit für die Implementierung Texturen zurückzuführen war. Nun habe ich nach einiger Zeit wieder angefangen und benutze jetzt OpenGL (mit SDL) um die 3D Modelle zu rendern.

Aber jetzt schlug ich eine andere Mauer.

Ich kann nicht herausfinden, wie man eine gute Drehungen zu machen. Als Raum-Simulator I ähnliche Kontrollen zu einem flighsim

mit

glRotatef(angleX, 1.0f, 0.0f, 0.0f); 
glRotatef(angleY, 0.0f, 1.0f, 0.0f); 
glRotatef(angleZ, 0.0f, 0.0f, 1.0f); 

oder ähnliche wollen,
nicht richtig funktioniert, wenn ich das Modell (Raumschiff) zunächst um 90 Grad nach links drehen und dann drehe es nach oben. Stattdessen rollt es.

Hier ist ein Bild, das mein Problem darstellt.

Image Link

Ich habe versucht, einige Tricks, dies zu versuchen und zu begegnen, aber irgendwie fühle ich mich etwas fehlt. Es hilft auch nicht, dass Simulator Stil Rotation Beispiele sind fast unmöglich zu finden.

Also suche ich nach Beispielen, Links und der Theorie, ein 3D-Modell (wie ein Raumschiff, ein Flugzeug) zu drehen.

Soll ich drei Vektoren (links, oben, vorwärts) zur Orientierung verwenden, wie ich auch Dinge wie Beschleunigung von Thrustern und Sachen, die sich mit der Rotation (Orientierung?) Und von den Modellen ändern wird berechnen müssen Perspektive zeigt in eine Richtung wie Raketentriebwerke.

ich mit Mathe bin nicht sehr gut und versucht, eine Lösung zu visualisieren nur Kopfschmerzen geben

+0

Endlich knacke ich es! Ich verwende eine Matrix, die die Ausrichtung der Modelle beschreibt. Wenn ich die Aufwärts-Taste drücke, ruft eine Funktion auf, die eine Rotationsmatrix erzeugt, die ich um den gewünschten Betrag rotiere, und multipliziere diese dann mit der Orientierungsmatrix der Modelle. – kvasan

Antwort

2

Was Sie hier wollen gehen zu verwenden sind Quaternionen. Sie beseitigen die seltsamen Verhaltensweisen, die Sie erleben. Denken an sie als eine Matrix auf Steroiden mit ähnlicher Funktionalität. Sie können Matrizen besser verwenden als Sie (in Ihrem obigen Code), indem Sie die OpenGL-Funktionalität verwenden, die es Ihnen ermöglicht, eine Rotationsmatrix auf einem bestimmten Rotationsachsenvektor zu erzeugen, aber Ihre Rotationen für zukünftige Modifikationen speichern. Beispielsweise beginnen Sie mit einer Identitätsquaternion und drehen sie auf einem bestimmten Achsenvektor. Die Quaternion wird dann in eine Weltmatrix für Ihr Objekt übersetzt, aber Sie behalten die Quaternion in Ihrem Objekt gespeichert. Wenn Sie das nächste Mal eine Drehung durchführen müssen, ändern Sie diese Quaternion nur noch, anstatt die X-, Y- und Z-Achsenrotationsgrade usw. zu verfolgen.

Meine Erfahrung liegt innerhalb von directx (sorry, kein OpenGL erfahre hier), obwohl ich einmal auf dein Problem gestoßen bin, als ich versucht habe, Beachballs zu drehen, die in einem Raum rotierten, während sie auf Böden, Wände und einander stießen.

Google hat eine Reihe von Optionen auf „OpenGL Quaternion“, aber dies, insbesondere scheint, eine gute Quelle zu sein:

http://gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation

Wie Sie schon erraten haben, Quaternionen sind für Umgang mit Kameras in Ihrer Umgebung. Hier ist ein großes Tutorial:

http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=Quaternion_Camera_Class

4

Ich bin mir nicht sicher, ob ich völlig die Situation verstehen, aber es klingt wie Sie gimbal lock beschreiben könnten. Vielleicht möchten Sie mit quaternions Ihre Rotationen darstellen.

+0

Ich habe schon mit Quaternionen experimentiert, habe es aber noch einmal versucht. Nun, es scheint die Rotationen richtiger zu machen, aber jetzt wird die Box ein bisschen verzerrt, wenn ich sie rotiere. – kvasan

4

Es kann schwierig sein, dieses Recht zu bekommen. Das Problem, vor dem Sie stehen, ist, dass Sie dieselben Transformationsmatrizen für Rotationen verwenden, unabhängig davon, wie das "Schiff" bereits ausgerichtet ist. Aber du willst dein Schiff nicht drehen, je nachdem, wie es sich drehen würde, wenn es nach vorne zeigt, du möchtest es basierend darauf drehen, wie es jetzt aussieht. Um dies zu tun, solltest du deine kontrollierten Zugmatrizen auf die gleiche Weise transformieren, wie du dein Schiff verwandelst.

Zum Beispiel sagen wir, dass wir drei Matrizen haben, die jeweils die Art von Umdrehungen repräsentieren, die wir machen wollen.

float theta = 10.0*(pi/180.0) 

matrix<float> roll = [[ cos(theta), sin(theta), 0] 
         [ -sin(theta), cos(theta), 0] 
         [ 0, 0, 1] 

matrix<float> pitch = [[ cos(theta), 0, sin(theta)] 
         [ 0, 1, 0] 
         [ -sin(theta), 0, cos(theta)] 

matrix<float> yaw = [[1, 0, 0] 
        [0, cos(theta), sin(theta)] 
        [0, -sin(theta), cos(theta)]] 

matrix<float> orientation = [[1, 0, 0] 
          [0, 1, 0] 
          [0, 0, 1]] 

, die jeweils 10 Grad Drehung über jede der drei Fluglagenachsen darstellen. Auch haben wir eine Matrix für die Orientierung Ihres Schiffes, anfangs gerade geradeaus. Sie werden die Eckpunkte Ihres Schiffes mit dieser Orientierungsmatrix umwandeln, um sie anzuzeigen.

Um sich nach einer Runde orientieren zu können, müssen Sie nur ein wenig Cleverness machen, zuerst die Lagekontrollmatrizen in die Koordinaten des Spielers umwandeln und dann auf die Orientierung anwenden, um eine neue Orientierung zu erhalten: so etwas wie

function do_roll(float amount): 
    matrix<float> local_roll = amount * (roll * orientation) 
    orientation = orientation * local_roll 

function do_pitch(float amount): 
    matrix<float> local_pitch = amount * (pitch * orientation) 
    orientation = orientation * pitch_roll 

function do_yaw(float amount): 
    matrix<float> local_yaw = amount * (yaw * orientation) 
    orientation = orientation * local_yaw 

so dass Sie jedes Mal, wenn Sie auf die eine oder andere Weise rotieren möchten, eine dieser Funktionen aufrufen.

1

Quaternionen können helfen, aber eine einfachere Lösung kann eine strikte Reihenfolge der Rotationen sein. Es klingt, als ob du dich um y drehst und dich dann um x drehst. Sie müssen immer erst x, dann y, dann z drehen. Nicht, dass es etwas besonders Spezielles an diesem Auftrag gibt, nur dass, wenn Sie es so machen, Rotationen dazu tendieren, ein bisschen näher daran zu arbeiten, wie Sie erwarten, dass sie funktionieren.

Edit: Um ein wenig zu verdeutlichen, sollte man sich auch nicht kumulativ über die Zeit im Spiel drehen. Bei jedem Frame sollten Sie Ihr Modell in der Identitätsposition starten und dann x, y und dann z an der neuen Position dieses Frames drehen.

+0

damnit Ich kann nur einmal dafür –

1

Allgemeine Rotationen sind schwierig. Physiker neigen dazu, einige so genannte Euler angles zu verwenden, um sie zu beschreiben. Bei diesem Verfahren wird eine allgemeine Drehung durch drei Winkel beschrieben, die um drei Achsen in einer festen Folge genommen werden. Aber die drei Achsen sind nicht die X-, Y- und Z-Achse des Originalrahmens. Sie sind oft die Z-, Y- und Z-Achse des ursprünglichen Rahmens (ja, es ist wirklich völlig allgemein), oder zwei Achsen vom ursprünglichen Rahmen gefolgt von einer Achse im Zwischenrahmen. Viele Auswahlmöglichkeiten sind verfügbar, und es kann sehr mühsam sein, die gleiche Konvention zu befolgen.

2

Sie sollten 3D-Mathematik studieren, um tiefer zu verstehen, wie Sie Rotationen steuern können. Wenn Sie die Theorie nicht kennen, kann es schwierig sein, sie korrekt zu kopieren und einzufügen.Insbesondere Texte wie 3D Mathe Primer (Amazon) und relevante Sites wie werden Ihnen in Ihrem Projekt (und allen zukünftigen) erheblich helfen.

Ich verstehe, dass Sie Mathe jetzt vielleicht nicht mögen, aber das Erlernen der relevanten Arithmetik wird die beste Lösung für Ihr Problem sein.

+0

Ich habe bereits 3D Math Primer und es hat mir sehr geholfen, als ich anfing. War irgendwann ich lese es durch, scheint, als müsste ich es wieder durchlesen. – kvasan