3D-вращение в OpenGL и локальное вращение - PullRequest
1 голос
/ 18 сентября 2009

Я пытаюсь создать прототип симулятора космического полета в OpenGL, но после прочтения многих статей в Интернете у меня все еще возникают проблемы с правильной работой поворотов (у меня была камера кватерниона, которую я плохо понимал, но она дрейфует и имеет другое странное поведение).

Я пытаюсь сделать следующее:

1) Локальное вращение - когда пользователь нажимает клавиши со стрелками, вращение происходит относительно области просмотра (например, вращение «вверх» направлено к верхней части экрана). Две клавиши, такие как Z и X, будут контролировать «крен» корабля (вращение вокруг текущего вида).

2) Повороты будут сохраняться в формате угла оси (что наиболее естественно для OpenGL, и один вызов поворота с вектором камеры должен правильно вращать сцену). Поэтому, учитывая начальный вектор оси угла и одно или несколько локальных поворотов, отмеченных выше (мы могли бы локально назвать «X» левой / правой осью, «Y» верхней / нижней осью и «Z» ось крена ), Я хотел бы, чтобы конечный результат был новым вектором угла оси.

3) Избегайте четвертичных чисел и минимизируйте использование матриц (по некоторым причинам я нахожу оба неинтуитивными). Вместо матричной записи, пожалуйста, просто покажите в psuedocode компоненты вектора и то, что происходит.

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

5) Начальное состояние камеры находится в координатах (0,0,0), обращенных к вектору угла оси (0,0,1,0 - ось z без начального вращения). «вверх» равен (0,1,0).

1 Ответ

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

Использование углов Эйлера неправильно с spaceim. Я попробовал этот подход и быстро должен был сдаться. Игрок хочет всех степеней свободы, а углы Эйлера этого не обеспечивают или сильно усложняют.

То, что вы действительно, действительно хотите - это кватернионы. Это часть моего кода обновления.

            Quaternion qtmp1, qtmp2, qtmp3;

            Rotation r(........);
            qtmp1.CreateFromAxisAngle(1., 0., 0., r.j*m_updatediff);
            qtmp2.CreateFromAxisAngle(0., 1., 0., r.i*m_updatediff);
            qtmp3.CreateFromAxisAngle(0., 0., 1., r.k*m_updatediff);
            m_rotq = qtmp1 * qtmp2 * qtmp3 * m_rotq;

r.i, r.j и r.k содержат текущую скорость вращения вокруг определенной оси. Для получения ощущения, подобного космическому, нужно просто умножить эти кватернионы.

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

Ваша ежедневная рекомендация: кватернионы.

...