当 z <= 0 时 glm::lookAt 垂直相机翻转
Posted
技术标签:
【中文标题】当 z <= 0 时 glm::lookAt 垂直相机翻转【英文标题】:glm::lookAt vertical camera flips when z <= 0 【发布时间】:2013-07-23 09:53:01 【问题描述】:我正在开发 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】:我不完全确定问题出在哪里,但是当我将 LookAt 用于 FPS cam 时,我还包含了一个前向单位向量。
例如(从我拥有的一些代码中复制相关段)- 使用四元数(方向),但我确信矩阵将具有相同的结果)
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 cam 设置 quat
pLocalOrientation =
glm::angleAxis(pLocalEularAngles.x, glm::vec3(1, 0, 0)) *
glm::angleAxis(pLocalEularAngles.y, glm::vec3(0, 1, 0));
pLocalOrientation == 方向(例如)
如果你决定使用quats。
【讨论】:
我喜欢这个想法,并试图看看前向向量是否能解决我的问题,但没有不幸的是,据我所知,我的旋转没问题。除了翻转之外,一切都完美无缺。即使在翻转之后,方向向量也是相同的。我还没有开始研究四元数,所以现在不行:) 我推荐 quats 用于这些目的。 (pLocalOrientation = glm::quat(glm::radians(pRotationIncr)) * pLocalOrientation;) - 如果你需要它会做 6dof。 pRotationIncr = 在框架中旋转的量 (vec3)。 我知道,据我所知,四元数似乎消除了矩阵和 eular 角度的所有问题,并且代码更少(AFAIK),我最终会开始学习这些,但目前我学习 OpenGL,我会一步一步地学习 :) Quats 是为了以后 ;) 并不是不可能得到一个像样的 FPS 相机,我只是有一个奇怪的错误 :) 如果您只使用两个轴,那么您是否尝试过使用正弦和余弦方法?它可以帮助您在不依赖 glm 数学的情况下了解正在发生的事情。这并不难,而且我认为 Nehe 有一个旧教程。 是的,我知道正弦和余弦方法:)以上是关于当 z <= 0 时 glm::lookAt 垂直相机翻转的主要内容,如果未能解决你的问题,请参考以下文章