2013-04-15 3 views
1

У меня, похоже, проблемы с камерой OpenGl. Когда я впервые создал его, все работало нормально. Однако после импорта моделей и создания объектов я заметил странные вещи.Проблемы с движением камеры OpenGL

Во-первых, мой код Heres для движения:

float xRot = (Pitch/180 * 3.141592654f), 
     yRot = (Yaw/180 * 3.141592654f); 

float sinX = float(sin(xRot)) * myInput.Sensitivity, 
     sinY = float(sin(yRot)) * myInput.Sensitivity, 
     cosY = float(cos(yRot)) * myInput.Sensitivity; 

if(myInput.Keys['W']) //Forwards 
{ 
    curPos.x += sinY; 
    curPos.z -= cosY; 
    curPos.y += sinX; 
} 
else if(myInput.Keys['S']) //Backwards 
{ 
    curPos.x -= sinY; 
    curPos.z += cosY; 
    curPos.y -= sinX; 
} 

if(myInput.Keys['A']) //Left 
{ 
    curPos.x -= cosY; 
    curPos.z -= sinY; 
} 
else if(myInput.Keys['D']) //Right 
{ 
    curPos.x += cosY; 
    curPos.z += sinY; 
} 

//Move camera up and down 
if(myInput.Keys['Q']) 
    curPos.y-= myInput.Sensitivity; //up 
else if(myInput.Keys['E']) 
     curPos.y+= myInput.Sensitivity; //down 

//Check col 
if(curPos.y < 0) 
    curPos.y = 0; 
else if(curPos.y >= 300) //Gimbal lock encountered 
    curPos.y = 299; 

Во-вторых, мое движение Heres для расчета gluLookAt:

double cosR, cosP, cosY; //temp values for sin/cos from 
double sinR, sinP, sinY; //the inputed roll/pitch/yaw 

cosY = cosf(Yaw*3.1415/180); 
cosP = cosf(Pitch*3.1415/180); 
cosR = cosf(Roll*3.1415/180); 
sinY = sinf(Yaw*3.1415/180); 
sinP = sinf(Pitch*3.1415/180); 
sinR = sinf(Roll*3.1415/180); 

//forward position 
forwardPos.x = sinY * cosP*360; 
forwardPos.y = sinP * 360; 
forwardPos.z = cosP * -cosY*360; 

//up position 
upPos.x = -cosY * sinR - sinY * sinP * cosR; 
upPos.y = cosP * cosR; 
upPos.z = -sinY * sinR - sinP * cosR * -cosY; 

В основном я заметил, что если камера поднимается выше 300 в Y -Axis, тогда представление начинает вращаться, то же самое происходит, если я слишком сильно перемещаюсь по оси x/z.

Может ли кто-нибудь увидеть, что случилось с моим кодом? Я работаю в граде, когда я должен работать в раде?

ответ

2

Я не проверял ваш код, но этот тип печально известен при использовании углов Эйлера для 3D-поворота.

Это называется gimbal lock (я вижу, что у вас есть комментарий в коде, который показывает, что вы знаете об этом), и самым простым решением для его преодоления является переход на использование quaternions для вычисления ваших матриц вращения.

В Wiki here есть действительно хорошая статья OpenGL.

+0

Черт, я надеялся не делать этого. Спасибо :) – Split

+0

Я понимаю ;-) Но, сделав это один раз, это действительно делает его ловушкой в ​​будущем. Вы можете делать всевозможные симпатичные анимации непосредственно в/из сохраненных позиций путем интерполяции кватернионов (SLERP). –

Смежные вопросы