OpenGL FPS相机相对于lookAt目标的移动



我在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数学库。我很确定我必须用旋转矩阵乘以一些向量(眼睛、中心等),但我不确定是哪一个。我试图将_viewMatrix乘以_rotationMatrix,但它造成了混乱。FPS相机位置和旋转计算的代码取自此处。但对于实际渲染,我使用可编程管道。

更新:我通过添加一种单独的方法解决了这个问题,该方法不使用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()方法。

您需要更改相机的前进方向,该方向可能固定为(0,0,-1)。您可以通过camYRot绕y轴旋转方向(如在lookat函数中计算的)来实现这一点,以便向前与相机指向的方向相同(在z轴和x轴形成的平面中)。

最新更新