OpenGL - движущаяся камера с мышью - PullRequest
5 голосов
/ 15 сентября 2009

Я не уверен, как именно это объяснить, но, надеюсь, вы поймете, что я имею в виду.

По сути, я нарисовал куб и хочу перетащить мышь, чтобы просмотреть все стороны. Вращение только по горизонтали или вертикали - это хорошо, но если я попытаюсь объединить их, все пойдет немного странно.

например. если я поверну на 180 градусов по вертикали (чтобы перевернуть вверх дном), а затем перетащу мышь горизонтально, то куб будет вращаться в направлении, противоположном движению мыши.

Это соответствующий код:

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;
    }
}

Ответы [ 5 ]

4 голосов
/ 13 января 2011

Как уже говорили другие, использование кватернионов является решением. Ken Shoemake предоставляет превосходный код для преобразования кватернионов в углы Эйлера в графических кристаллах IV (см. примеры кода здесь , см. «Преобразование углов Эйлера»). Он также имеет преобразования в и из матриц вращения.

Если вы хотите выполнять вращение с помощью мыши, возможно, «золотым стандартом» является интерфейс «Arcball», описанный Shoemake в Graphics Gems IV (доступно здесь , на данный момент). Улучшенная версия Arcball распространяется с библиотекой Glut как «трекбол», который предлагает более интуитивный интерфейс, когда щелчки происходят за пределами сферы вращения. Он был написан Гэвином Беллом и доступен здесь и здесь . Трекбол Белла - это подход, используемый в проекте Blender , и я предполагаю, что коммерческие пакеты используют нечто подобное.

4 голосов
/ 15 сентября 2009

Вы используете углы Эйлера и, следовательно, имеете проблему блокировки карданного подвеса.

Простое решение - сохранить вращение внутри вашей модели-матрицы и вращать эту матрицу вместо сохранения только 2 углов (с использованием умножения матрицы).

Посмотрите на этот ответ для получения дополнительной информации: Будет ли это причиной блокировки карданного подвеса?

более сложным решением является хранение кватернионов

2 голосов
/ 28 сентября 2009

В большинстве приложений допускается вращение вверх / вниз только на 90 градусов; в противном случае вид перевернут и да слева направо перевернут. Для большинства приложений не имеет смысла поворачиваться так далеко, чтобы вы смотрели на мир с ног на голову.

Кроме того, это не карданный замок, как сказали два других ответчика; Карданный замок требует трех (или более?) осей вращения. Проще говоря, фиксация карданного подвеса происходит, когда одна ось повернута на 90 градусов в любом направлении, так что две другие оси совпадают; и затем вращение вокруг любой из двух других осей вызывает тот же эффект. Изображение самолета на полпути вниз по странице википедии это хорошо показывает.

В любом случае, лучше всего ограничить camera_angle_v диапазоном (-90,90); другими словами, всякий раз, когда вы добавляете или вычитаете его, затем проверяете, больше ли оно 90, и установите 90, или если оно меньше -90, то установите на -90.

Также хочу отметить, что в прошлом у меня действительно были проблемы, когда угол v точно равен 90 или -90, поэтому вместо этого я бы зафиксировал его на +/- 89,9.

2 голосов
/ 15 сентября 2009

Звучит так, как будто ваше приложение страдает от карданного замка . Есть несколько способов исправить это, самый простой - зажать разрешенные вращения.

0 голосов
/ 30 сентября 2009

Поскольку вы используете GLUT, у вас, вероятно, есть код для решения этой проблемы в вашей системе. Посмотрите на исходные файлы trackball.c и trackball.h. Погуглив для них, также найдут источник. Это простая библиотека, которая поможет вам решить эту проблему. Некоторые примеры GLUT, которые их используют, - это диноспин, отскок и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...