相对于lookAt目标的OpenGL FPS Camera运动

时间:2012-12-12 12:47:30

标签: math opengl perspectivecamera

我在OpenGL中有一个摄像头。在添加FPS控制器之前我没有问题。问题是基本的FPS行为没问题。摄像机向前,向后,向左和向右移动+朝向鼠标输入提供的方向旋转。摄像机移动到目标位置的两侧或后面时会出现问题。在这种情况下,摄像机本地向前,向后,向左,向右方向不会根据其当前前向外观进行更新,但保持不变,就好像它位于目标前方一样。例如: 如果目标物体位置位于(0,0,0)且摄像机位置位于(-50,0,0)(目标左侧)并且摄像机正在查看目标,则来回移动它我必须使用键进行左右移动,而后退/前进键则将相机侧向移动。 这是我用来计算相机位置,旋转和LookAt矩阵的代码:

void LookAtTarget(const vec3 &eye,const  vec3 &center,const  vec3 &up)
{


    this->_eye = eye;
    this->_center = center;
    this->_up = up;
    this->_direction =normalize((center - eye)); 

    _viewMatrix=lookAt( eye,  center , up);
    _transform.SetModel(_viewMatrix );
    UpdateViewFrustum();
}

void SetPosition(const vec3 &position){
    this->_eye=position;
    this->_center=position + _direction;
    LookAtTarget(_eye,_center,_up);
}
void SetRotation(float rz , float ry ,float rx){
    _rotationMatrix=mat4(1);
    vec3 direction(0.0f, 0.0f, -1.0f);
    vec3 up(0.0f, 1.0f, 0.0f);

    _rotationMatrix=eulerAngleYXZ(ry,rx,rz);
    vec4 rotatedDir= _rotationMatrix * vec4(direction,1) ;
    this->_center = this->_eye + vec3(rotatedDir);

    this->_up =vec3( _rotationMatrix * vec4(up,1));

    LookAtTarget(_eye, _center, up);


}

然后在渲染循环中我设置了摄像机的转换:

 while(true)
{
    display();
    fps->print(GetElapsedTime());
    if(glfwGetKey(GLFW_KEY_ESC) || !glfwGetWindowParam(GLFW_OPENED)){
        break;
    }

    calculateCameraMovement();

    moveCamera();

    view->GetScene()->GetCurrentCam()->SetRotation(0,-camYRot,-camXRot);

    view->GetScene()->GetCurrentCam()->SetPosition(camXPos,camYPos,camZPos);

}

lookAt()方法来自GLM math lib。 我很确定我必须将一些矢量(眼睛,中心等)与旋转矩阵相乘,但我不确定哪些。我试图将_viewMatrix乘以_rotationMatrix,但它会造成混乱.FPS摄像头位置的代码和旋转计算取自here。但对于实际渲染,我使用可编程管道。

更新 我通过添加一个单独的方法解决了这个问题,该方法不使用lookAt计算相机矩阵,而是使用通常的基本方法:

void FpsMove(GLfloat x, GLfloat y , GLfloat z,float pitch,float yaw){
    _viewMatrix =rotate(mat4(1.0f), pitch, vec3(1, 0, 0));
    _viewMatrix=rotate(_viewMatrix, yaw, vec3(0, 1, 0));
    _viewMatrix= translate(_viewMatrix, vec3(-x, -y, -z));
    _transform.SetModel( _viewMatrix );
}

它解决了这个问题,但我仍然想知道如何使用我在这里介绍的lookAt()方法。

1 个答案:

答案 0 :(得分:0)

您需要更改相机的前进方向,大概固定为(0,0,-1)。您可以通过使用camYRot旋转y轴的方向(在lookat函数中计算)来执行此操作,以使向前方向与摄像机指向的方向相同(在z轴和x轴的平面中)。