GLM相机的X、Y旋转引入Z旋转的问题

3
所以我在使用GLM库编写OpenGL和C++相机时遇到了问题。我的目标是实现一种可以轻松探索3D世界的飞行相机。我已经成功地让相机工作,它非常流畅,可以环顾四周,移动看起来也非常正确。
唯一的问题是,沿着相机的X和Y轴旋转(上下看)会引入一些关于Z轴的旋转。这导致在移动过程中世界会略微倾斜。
例如...如果我在相机前方有一个正方形,并将相机以圆形运动移动,就好像你在围绕着头看圈,一旦运动完成,方块就会稍微倾斜,就好像你已经歪了头一样。
我的相机目前是一个组件,可以附加到场景中的对象/实体上。每个实体都有一个“Frame”,这基本上是该实体的模型矩阵。Frame包含以下属性:
glm::mat4 m_Matrix;
glm::vec3 m_Position;
glm::vec3 m_Up;
glm::vec3 m_Forward;

然后相机使用这些向量创建相应的viewMatrix,如下所示:

const glm::mat4& CameraComponent::GetViewMatrix()
{
    //Get the transform of the object
    const Frame& transform = GetOwnerGO()->GetTransform();

    //Update the viewMatrix
    m_ViewMatrix = glm::lookAt(transform.GetPosition(), //position of camera
                           transform.GetPosition() + transform.GetForward(), //position to look at
                           transform.GetUp()); //up vector

    //return reference to the view matrix
    return m_ViewMatrix; 
}

现在,这是我在Frame对象中的旋转X和Y方法,我猜这可能是问题所在:

void Frame::RotateX( float delta )
{
    glm::vec3 cross = glm::normalize(glm::cross(m_Up, m_Forward)); //calculate x axis

    glm::mat4 Rotation = glm::rotate(glm::mat4(1.0f), delta, cross);

    m_Forward = glm::normalize(glm::vec3(Rotation * glm::vec4(m_Forward, 0.0f))); //Rotate forward vector by new rotation

    m_Up = glm::normalize(glm::vec3(Rotation * glm::vec4(m_Up, 0.0f))); //Rotate up vector by new rotation
}


void Frame::RotateY( float delta )
{
    glm::mat4 Rotation = glm::rotate(glm::mat4(1.0f), delta,  m_Up);    

    //Rotate forward vector by new rotation
    m_Forward = glm::normalize(glm::vec3(Rotation * glm::vec4(m_Forward, 0.0f))); 
}

所以,问题就出在其中,我一直在寻找解决方法。我已经试了几天了,尝试各种方法,但不是得到相同的结果,就是z轴旋转固定,但会出现其他错误,例如不正确的X、Y轴旋转和相机移动。

我看了万向节锁定(gimbal lock),但从我理解的来看,这个问题似乎并不像是万向节锁定。但我可能错了。

2个回答

7

存储当前的俯仰/偏航角度并即时生成相机矩阵,而不是试图在中间向量上累积微小变化。


0
在你的RotateY函数中,将其从这里更改:
glm::mat4 Rotation = glm::rotate(glm::mat4(1.0f), delta,  m_Up);

转换为:

glm::mat4 Rotation = glm::rotate(glm::mat4(1.0f), delta,  glm::vec3(0,1,0));

如果有人给我点了踩,能否解释一下原因,我将不胜感激。 - Kaa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接