使用lookAt进行相机旋转

时间:2013-03-25 02:32:52

标签: c++ opengl glut glm-math

嘿伙计们我正在尝试使用glm库中的lookAt做一个Camera类。我有4个点,第一个是眼睛,即太空中的相机位置,第二个是外观,即相机正在看的点,第三个是upp,设置相机的方向,第四个是侧面,这是一个眼睛和upp -eye的交叉产品。

所以最后我得到了一个3个向量的基础,所有这些向量的起点都在眼点。我有一个相机的坐标系。

在我的相机课上,我希望能够围绕相机的坐标系旋转,而不是围绕世界的坐标系。所以我正在做的是围绕相机坐标系的一个轴旋转。

我用这样的初始值构造类:

void Observer::initialize(glm::vec3 eye, glm::vec3 look, glm::vec3 upp, glm::vec3 side) 
{
    this->eye = eye;        // (0.0, 0.0,  0.0)
    this->look = look;      // (0.0, 0.0, -1.0)
    this->upp = upp;        // (0.0, 1.0,  0.0)
    this->side = side;      // (1.0, 0.0,  0.0)
}

当我想围绕x轴旋转坐标系时,例如我从glm调用函数,如下所示:

void Observer::pitch(GLfloat pitch) 
{
    glm::mat4 rotate(1.0f);

    rotate = glm::rotate(rotate, pitch, side - eye);

    look = glm::vec3(rotate * glm::vec4(look, 1.0f));
    upp = glm::vec3(rotate * glm::vec4(upp, 1.0f));
}

到目前为止,我理解我的所有点仍然形成了相机的坐标系,所有矢量都是相互垂直的。

然后我使用lookAt功能获得的这些点,将相机定位在世界上。

 glm::mat4 view = glm::lookAt(eye, look, upp);

将此矩阵与OpenGL中的modelview矩阵相乘

如果我开始旋转很多,几次旋转后的相机会“反射”旋转,就像我在另一个方向旋转一样(我不知道如何以更好的方式描述真正发生的事情= s )。

我真的不明白发生了什么。我应用旋转后应该对矢量进行标准化吗?我有万向节锁的问题(我不太了解万向节锁)?

1 个答案:

答案 0 :(得分:2)

当您对矢量执行增量旋转时,会出现数值错误。当错误导致向上和观察向量指向几乎相同的方向或彼此相反时,摄像机变换计算是不稳定的,并且可能发生严重的事情。万向节锁。长度变化会导致不同的问题。

对我有用的解决方案是在每次旋转后重新正交化向上和看向向量。为此,计算它们的叉积L,然后通过将L与lookAt交叉来调整(实际替换)向上矢量。在所有这些之后,重新规范化向上和观察单位长度。

虽然正交化归一化是一种快速操作,但您并不需要对每个摄像机动作都这样做。

请注意,当您更正这样的向量时,您实际上正在执行lookAt矩阵计算的一部分,因此请考虑实现自己的以避免不必要的交叉积。参见例如this prior SO article on this topic