5 Stimmen

OpenGL - Kamera mit der Maus bewegen

Ich weiß nicht genau, wie ich das erklären soll, aber ich hoffe, Sie verstehen, was ich meine.

Im Grunde habe ich einen Würfel gezeichnet und möchte die Maus herumziehen, um alle Seiten zu sehen. Drehen nur horizontal oder vertikal ist in Ordnung, aber wenn ich versuche, diese dann kombinieren Dinge gehen ein wenig seltsam.

Wenn ich z. B. den Würfel vertikal um 180 Grad drehe (um ihn auf den Kopf zu stellen) und dann die Maus horizontal ziehe, dreht sich der Würfel in die entgegengesetzte Richtung zur Mausbewegung.

Dies ist der entsprechende Code:

double camera_angle_h = 0;
double camera_angle_v = 0;

int drag_x_origin;
int drag_y_origin;
int dragging = 0;

void display() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt(0.0, 0.0, 25.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    glRotated(camera_angle_v, 1.0, 0.0, 0.0);
    glRotated(camera_angle_h, 0.0, 1.0, 0.0);

    draw_cube();

    glFlush();
    glutSwapBuffers();
}

void mouse_click(int button, int state, int x, int y) {
    if(button == GLUT_LEFT_BUTTON) {
        if(state == GLUT_DOWN) {
            dragging = 1;
            drag_x_origin = x;
            drag_y_origin = y;
        }
        else
            dragging = 0;
    }
}

void mouse_move(int x, int y) {
    if(dragging) {
        camera_angle_v += (y - drag_y_origin)*0.3;
        camera_angle_h += (x - drag_x_origin)*0.3;
        drag_x_origin = x;
        drag_y_origin = y;
    }
}

5voto

Kyle Simek Punkte 9458

Wie andere bereits gesagt haben, ist die Verwendung von Quaternionen die Lösung. Ken Shoemake bietet einen hervorragenden Code für die Konvertierung zwischen Quaternionen und Euler-Winkeln in Graphics Gems IV (siehe Codebeispiele hier (siehe "Euler-Winkel-Umrechnung"). Es gibt auch Umrechnungen in und aus Drehmatrizen.

Wenn Sie die Rotation mit der Maus durchführen wollen, ist der "Goldstandard" wohl die von Shoemake in Graphics Gems IV beschriebene "Arcball"-Schnittstelle (erhältlich bei aquí (vorläufig). Eine verbesserte Version von Arcball wird mit der Glut-Bibliothek als "Trackball" vertrieben, die eine intuitivere Schnittstelle bietet, wenn Klicks außerhalb des Rotationsbereichs erfolgen. Sie wurde von Gavin Bell geschrieben und ist verfügbar aquí y aquí . Der Bell'sche Trackball ist der Ansatz, den die Blender-Projekt und ich nehme an, dass die kommerziellen Pakete etwas Ähnliches verwenden.

4voto

Peter Parker Punkte 27790

Sie verwenden Euler-Winkel und haben daher das Problem der Kardanverriegelung.

Eine einfache Lösung besteht darin, die Drehung in der Modell-Matrix zu speichern und diese Matrix zu drehen, anstatt nur 2 Winkel zu speichern (mit Hilfe der Matrixmultiplikation).

In dieser Antwort finden Sie weitere Informationen: Kann dies zu einer Kardanblockade führen?

eine komplexere Lösung ist die Speicherung von Quaternionen

3voto

Ricket Punkte 32112

Die meisten Anwendungen lassen nur eine Drehung um bis zu 90 Grad nach oben/unten zu; andernfalls steht die Ansicht auf dem Kopf, und ja, sie wird von links nach rechts gedreht. Für die meisten Anwendungen ist es nicht sinnvoll, die Ansicht so weit zu drehen, dass die Welt auf dem Kopf steht.

Außerdem handelt es sich nicht um eine kardanische Verriegelung, wie die beiden anderen Antwortenden sagten; eine kardanische Verriegelung erfordert drei (oder mehr?) Drehachsen. Vereinfacht ausgedrückt bedeutet Kardanverriegelung, dass eine Achse um 90 Grad in eine beliebige Richtung gedreht wurde, so dass die beiden anderen Achsen übereinstimmen; eine Drehung um eine der beiden anderen Achsen hat dann denselben Effekt. Das Flugzeugbild in der Mitte der Wikipedia-Seite zeigt dies gut.

In jedem Fall ist es am besten, wenn Sie die camera_angle_v auf den Bereich (-90,90); mit anderen Worten, immer wenn Sie addieren oder subtrahieren, prüfen Sie, ob der Wert größer als 90 ist und setzen ihn auf 90, oder wenn er kleiner als -90 ist, setzen Sie ihn auf -90.

Außerdem habe ich in der Vergangenheit Probleme gehabt, wenn ein V-Winkel genau 90 oder -90 beträgt, daher würde ich ihn stattdessen auf +/- 89,9 einstellen.

2voto

unwind Punkte 377331

Es klingt, als ob Ihre Anwendung unter folgenden Problemen leidet Kardansperre . Es gibt mehrere Möglichkeiten, Abhilfe zu schaffen. Die einfachste besteht darin, die zulässigen Umdrehungen festzulegen.

0voto

goger Punkte 590

Da Sie GLUT verwenden, haben Sie wahrscheinlich den entsprechenden Code in Ihrem System. Schauen Sie nach den Quelldateien trackball.c und trackball.h. Wenn Sie danach googeln, finden Sie auch den Quellcode. Dies ist eine einfache Bibliothek, die Ihnen bei genau diesem Problem hilft. Einige GLUT-Beispiele, die sie verwenden, sind dinospin, bounce, etc.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X