当z <= 0时,glm :: lookAt垂直相机翻转

时间:2013-07-23 09:53:02

标签: c++ opengl glm-math

我正在使用FPS风格的相机使用OpenGL在我的3D场景中飞行。我使用GLM进行数学运算,然后使用鼠标移动计算x轴和y轴上的glm :: rotate的方向向量。我有一个静态向上矢量,因为我可以在横轴上扫描并且不需要任何滚动。

然而,当我向负z方向前进并且我最终到达场景的中心点(z = 0)时,垂直相机翻转(y方向)。向下移动鼠标现在将导致向上运动。方向向量的计算方式应该是这样的,所以我猜测它与glm :: lookAt如何计算其视图矩阵有关?

以下是相关代码:

// Player movement
glm::vec3 position(0.0f, 0.0f, 5.0f);
glm::vec3 direction(0.0f, 0.0f, -1.0f);
glm::vec3 up(0.0f, 1.0f, 0.0f);
float speed = 0.05f;
bool warped = false;
...

void render()
{
    ...
    view = glm::lookAt(position, position + direction, up); 
    glUniformMatrix4fv(glGetUniformLocation(basicShader.shaderProgram, "view"), 1, GL_FALSE, glm::value_ptr(view));
    ...    
}


void handleKeyboard()
{
    float speed = 0.05f;
    if(keys['w'])
        position += speed * direction;
    if(keys['s'])
        position -= speed * direction;
    if(keys['a'])
        position -= speed * glm::cross(direction, up);
    if(keys['d'])
        position += speed * glm::cross(direction, up); 
    if(keys['q'])
        exit(1);
}

// Set with following callbacks:
// glutMotionFunc(mouse);
// glutPassiveMotionFunc(mouse);
void mouse(int x, int y)
{  
    if(!warped)
    {
        float mouseSensitivity = 15.0f;

        float horizontal = (width / 2) - x;
        float vertical = (height / 2) - y;

        horizontal /= mouseSensitivity;
        vertical /= mouseSensitivity;

        direction = glm::rotate(direction, horizontal, glm::vec3(0.0f, 1.0f, 0.0f));
        direction = glm::rotate(direction, vertical, glm::vec3(1.0f, 0.0f, 0.0f));

        warped = true;
        glutWarpPointer((width / 2), (height / 2));
    }
    else
        warped = false;
}

1 个答案:

答案 0 :(得分:3)

我不完全确定问题是什么,但当我使用LookAt作为FPS凸轮时,我还包括一个前向单位矢量。

E.g(从我的一些代码中复制相关的段) - 使用四元数(方向),但我确定矩阵将具有相同的结果)

static glm::vec3 defaultUpVector() { return glm::vec3(0, 1, 0); }
static glm::vec3 defaultForwardVector() { return glm::vec3(0, 0, -1); }

pUpVector = defaultUpVector() * orientation;
pLookAt = position + (defaultForwardVector() * orientation);
pView = glm::lookAt(position, pLookAt, pUpVector);

upvector和lookat都是vec3,view是mat4

希望这有帮助。

编辑:我注意到你正在使用方向,所以我可能会看看你在哪里使用旋转。

这将设置没有滚动的FPS凸轮的quat

pLocalOrientation = 
    glm::angleAxis(pLocalEularAngles.x, glm::vec3(1, 0, 0)) *
    glm::angleAxis(pLocalEularAngles.y, glm::vec3(0, 1, 0));

pLocalOrientation == orientation(例如)

如果你决定使用quats。