2015-07-19 3 views
1

У меня есть объект сетки/игры для вращения с glRotatef, используя библиотеку FreeGLUT:Как выполнять вращения относительно локальных (а не глобальных) осей объекта с помощью glRotatef?

glPushMatrix(); 
    glTranslatef(GlobalPos_x, GlobalPos_y, GlobalPos_z); 

    glRotatef(Global_Yaw,0,1,0); 
    glRotatef(Global_Pitch,1,0,0); 
    glRotatef(Global_Roll,0,0,1); 

    RenderMesh(mesh_Plane); 
glPopMatrix(); 

При запуске объекта выравнивается с прямой Z-оси; Ось Y идет вверх, а ось X идет влево.


'Controls':

Вт: Pitch + 5 град за кадр

S: Шаг -5 град на кадр

А: рыскания + 5 град за кадр

D: Yaw -5 град на фрейм


ЦЕЛЬ: значения Global_Yaw, Global_Pitch и Global_Roll должны как-то увеличиваться от этих элементов управления (диапазоны от -180 до +180, от -90 до +90 и от -180 до +180 соответственно).

Проблема в том, если самолет уже разбили на 90 градусов от оригинальной positon «рыскания» вместо того, чтобы сделать это будет вращаться вокруг Y-ось (карданный замок), который должен произойти только в первого Человек шутер.

Так просто делать 'if (GetAsyncKeyState (Key_A)) Global_Yaw + = 5;' не то, что я ищу.


Edit: Square 2

После напоминания tkausl, я откопал одну из моих предыдущих попыток. Моя идея заключалась в том, что я бы преобразовать существующие глобальные ракурсы самолета в матрицу, необходимо умножить эту матрицу с другой матрицей, порожденной ключевыми входами проигрывателя, а затем какой-то образом, используя эту матрицу, чтобы получить новый Global_Yaw, Global_Pitch и Global_Roll значения:

// Convert ORIENTATION to MATRIX 
Omatrix00 = cos(Global_Pitch)*cos(Global_Yaw); 
Omatrix01 = sin(Global_Pitch); 
Omatrix02 = cos(Global_Pitch)*sin(Global_Yaw); 
Omatrix03 = 0; 
Omatrix10 = -cos(Global_Roll)*sin(Global_Pitch)*cos(Global_Yaw)+sin(Global_Roll)*sin(Global_Yaw); 
Omatrix11 = cos(Global_Roll)*cos(Global_Pitch); 
Omatrix12 = -cos(Global_Roll)*sin(Global_Pitch)*sin(Global_Yaw)-sin(Global_Roll)*cos(Global_Yaw); 
Omatrix13 = 0; 
Omatrix20 = -sin(Global_Roll)*sin(Global_Pitch)*cos(Global_Yaw)-cos(Global_Roll)*sin(Global_Yaw); 
Omatrix21 = sin(Global_Roll)*cos(Global_Pitch); 
Omatrix22 = cos(Global_Roll)*cos(Global_Yaw)-sin(Global_Roll)*sin(Global_Pitch)*sin(Global_Yaw); 
Omatrix23 = 0; 
Omatrix30 = 0; 
Omatrix31 = 0; 
Omatrix32 = 0; 
Omatrix33 = 1; 


// Convert Commanded Turn Angles to MATRIX 
matrix00 = cos(pitch_speed)*cos(yaw_speed); 
matrix02 = cos(pitch_speed)*sin(yaw_speed); 
matrix01 = sin(pitch_speed); 
matrix03 = 0; 
matrix10 = -cos(roll_speed)*sin(pitch_speed)*cos(yaw_speed)+sin(roll_speed)*sin(yaw_speed); 
matrix11 = cos(roll_speed)*cos(pitch_speed); 
matrix12 = -cos(roll_speed)*sin(pitch_speed)*sin(yaw_speed)-sin(roll_speed)*cos(yaw_speed); 
matrix13 = 0; 
matrix20 = -sin(roll_speed)*sin(pitch_speed)*cos(yaw_speed)-cos(roll_speed)*sin(yaw_speed); 
matrix21 = sin(roll_speed)*cos(pitch_speed); 
matrix22 = cos(roll_speed)*cos(yaw_speed)-sin(roll_speed)*sin(pitch_speed)*sin(yaw_speed); 
matrix23 = 0; 
matrix30 = 0; 
matrix31 = 0; 
matrix32 = 0; 
matrix33 = 1; 

// Next step: Somehow using this matrix to get new Global_Yaw, Global_Pitch and Global_Roll values... 

Я даже не уверен, что я правильно умножал свои матрицы в моем коде.

ответ

0

Вы должны сначала вращаться вокруг оси x или z, а y - для получения правильного результата. В большинстве типов игр вам не нужен рулон, вы вращаетесь вокруг x, затем вокруг z, и все вращается, как ожидалось.

+0

Это не совсем помогает мне ... Мой вопрос: значения Global_Yaw, Global_Pitch и Global_Roll должны каким-то образом увеличиваться с элементов управления WASD. (От -180 до +180, от -90 до +90 и от -180 до +180 соответственно). Тем не менее, я отредактирую свой вопрос, чтобы лучше отразить мою проблему. –

+0

О, я думаю, я понял. В этом случае вам необходимо использовать кватернионы и матрицы, чтобы предотвратить блокировку карданного вала – tkausl