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

Issue with GLM Camera X,Y Rotation introducing Z Rotation

本文关键字:旋转 问题 GLM 相机      更新时间:2023-10-16

所以我在OpenGL和c++中使用GLM库实现的相机一直遇到麻烦。我所瞄准的相机类型是一种可以轻松探索3D世界的飞行相机。我已经设法让相机工作,它很好,平滑,环顾四周,运动似乎很好,正确的。

我似乎唯一的问题是,旋转沿着相机的X和Y轴(向上和向下看)引入了一些旋转关于它的Z轴。这将导致世界在旅行时轻微滚动。

举个例子…如果我在镜头前有一个方形的四边形,并以圆周运动移动相机,就像用你的头环顾四周一样,一旦运动完成,四边形就会轻微滚动,就好像你倾斜了你的头。

我的相机目前是一个组件,我可以附加到一个对象/实体在我的场景。每个实体都有一个"框架",它基本上是该实体的模型矩阵。框架包含以下属性:

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旋转和相机运动。

我看了一下万向锁,但从我对它的理解来看,这个问题对我来说似乎不太像万向锁。但我可能错了。

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

在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));