简体   繁体   English

第一人称视角相机运动问题

[英]First Person Camera movement issues

I'm implementing a first person camera using the GLM library that provides me with some useful functions that calculate perspective and 'lookAt' matrices. 我正在使用GLM库实现第一人称相机,该库为我提供了一些有用的功能,这些功能可以计算透视图和“ lookAt”矩阵。 I'm also using OpenGL but that shouldn't make a difference in this code. 我也在使用OpenGL,但这在代码中没有什么不同。

Basically, what I'm experiencing is that I can look around, much like in a regular FPS, and move around. 基本上,我所经历的是我可以环顾四周,就像在常规FPS中那样四处移动。 But the movement is constrained to the three axes in a way that if I rotate the camera, I would still move in the same direction as if I had not rotated it... Let me illustrate (in 2D, to simplify things). 但是运动被限制在三个轴上,如果我旋转相机,我仍然会像没有旋转一样朝着相同的方向移动...让我举例说明(以2D简化)。 在此处输入图片说明

In this image, you can see four camera positions. 在此图像中,您可以看到四个相机位置。 Those marked with a one are before movement, those marked with a two are after movement. 标有“ 1”的标记是在移动之前,标有“ 2”的标记是在移动之后。 The red triangles represent a camera that is oriented straight forward along the z axis. 红色三角形代表沿z轴笔直定向的摄像机。 The blue triangles represent a camera that hasbeen rotated to look backward along the x axis (to the left). 蓝色三角形代表已旋转以沿x轴(向左)向后看的摄像机。 When I press the 'forward movement key', the camera moves forward along the z axis in both cases, disregarding the camera orientation. 当我按下“向前移动键”时,两种情况下相机都会沿z轴向前移动,而无需考虑相机的方向。

What I want is a more FPS-like behaviour, where pressing forward moves me in the direction the camera is facing. 我想要的是一种更加类似于FPS的行为,向前推动会使我朝着相机所面对的方向移动。 I thought that with the arguments I pass to glm::lookAt , this would be achieved. 我认为,通过传递给glm::lookAt的参数,可以实现这一点。 Apparently not. 显然不是。

What is wrong with my calculations? 我的计算有什么问题?

// Calculate the camera's orientation
float angleHori = -mMouseSpeed * Mouse::x; // Note that (0, 0) is the center of the screen
float angleVert = -mMouseSpeed * Mouse::y;

glm::vec3 dir(
    cos(angleVert) * sin(angleHori),
    sin(angleVert),
    cos(angleVert) * cos(angleHori)
);

glm::vec3 right(
    sin(angleHori - M_PI / 2.0f),
    0.0f,
    cos(angleHori - M_PI / 2.0f)
);

glm::vec3 up = glm::cross(right, dir);

// Calculate projection and view matrix
glm::mat4 projMatrix = glm::perspective(mFOV, mViewPortSizeX / (float)mViewPortSizeY, mZNear, mZFar);
glm::mat4 viewMatrix = glm::lookAt(mPosition, mPosition + dir, up);

gluLookAt takes 3 parameters: eye, centre and up. gluLookAt具有3个参数:eye,center和up。 The first two are positions while the last is a vector. 前两个是位置,最后一个是向量。 If you're planning on using this function it's better that you maintain only these three parameters consistently. 如果您打算使用此功能,最好只保持这三个参数不变。

Coming to the issue with the calculation. 谈到计算问题。 I see that the position variable is unchanged throughout the code. 我看到position变量在整个代码中都没有改变。 All that changes is the look at point Ie centre only. 所发生的所有变化仅是在Ie centre The right thing to do is to first do position += dir , which will move the camera (position) along the direction pointed to by dir . 正确的做法是首先执行position += dir ,这将使摄像机(位置)沿dir指向的方向移动。 Now to update the centre , the second parameter can be left as-is: position + dir ; 现在要更新centre ,第二个参数可以保持不变: position + dir ; this will work since the position was already updated to the new position and from there we've a point farther in dir direction to look at. 这将起作用,因为该位置已经更新到新位置,并且从那里我们在dir方向上有一个更远的地方可以查看。

The issue was actually in another method. 问题实际上是另一种方法。 When moving the camera, I needed to do this: 移动相机时,我需要这样做:

void Camera::moveX(char s)
{
    mPosition += s * mSpeed * mRight;
}

void Camera::moveY(char s)
{
    mPosition += s * mSpeed * mUp;
}

void Camera::moveZ(chars)
{
    mPosition += s * mSpeed * mDirection;
}

To make the camera move across the correct axes. 使摄像机沿正确的轴移动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM