用自定义“ world up”矢量更新“ front”矢量的正确方法是什么?

问题描述 投票:1回答:1

我正在尝试实现“行星”世界。因此,在使用旧相机类别的任何时候,我都得到这样的结果:enter image description here相机类更新代码为:

void cCamera::ProcessMouseMovement(GLdouble dt, glm::vec2 curOffset)
{
    curOffset.x *= static_cast<GLfloat>(dt * m_MouseSensitivity);
    curOffset.y *= static_cast<GLfloat>(dt * m_MouseSensitivity);

    m_fPitch += curOffset.x;
    m_fYaw   += curOffset.y;

    if (m_fYaw > 89.0f)
        m_fYaw = 89.0f;

    if (m_fYaw < -89.0f)
        m_fYaw = -89.0f;

    UpdateCameraVectors();
}

void cCamera::UpdateCameraVectors(void)
{
    float fYawRad   = glm::radians(m_fYaw);
    float fPitchRad = glm::radians(m_fPitch);
    float fYawCos   = cos(fYawRad);

    glm::vec3 front { cos(fPitchRad) * fYawCos,
                      sin(fYawRad),
                      sin(fPitchRad) * fYawCos };

    *m_pCameraFront = glm::normalize(front);
    m_Right         = glm::normalize(glm::cross(*m_pCameraFront, m_WorldUp));
    m_Up            = glm::normalize(glm::cross(m_Right, front));

    *m_pViewMatrix = glm::lookAt(glm::vec3(0.f), glm::vec3(0.f) + *m_pCameraFront, m_Up);
}

因为(0,0,0)是行星中心,我假设我应该以这种方式对m_WorldUp向量进行求和:

m_WorldUp = glm::normalize(*m_pPos);

的确,结果很好:相机以正确的方向旋转,但是旋转被打破了。偏航和俯仰仍然取决于旧世界。我认为,我应该使用新的m_WorldUp更新前向矢量,但真的不知道如何。

c++ math opengl camera glm-math
1个回答
0
投票

在这里找到解决方案:https://gamedev.stackexchange.com/questions/73588/how-do-i-fix-my-planet-facing-camera

在我的情况下,代码是

void cCamera::UpdateCameraVectors(void)
{
    m_WorldUp = glm::normalize(*m_pPos);

    glm::quat world_axes_rotation = glm::angleAxis(glm::radians(m_fPitch), glm::vec3(0.0f, -1.0f, 0.0f));
    world_axes_rotation = glm::normalize(world_axes_rotation);
    world_axes_rotation = glm::rotate(world_axes_rotation, glm::radians(m_fYaw), glm::vec3(1.0f, 0.0f, 0.0f));

    m_Pole = glm::normalize(m_Pole - glm::dot(m_WorldUp, m_Pole) * m_WorldUp);

    glm::mat4 local_transform;
    local_transform[0]  = glm::vec4(m_Pole,                         0.0f);
    local_transform[1]  = glm::vec4(m_WorldUp,                      0.0f);
    local_transform[2]  = glm::vec4(glm::cross(m_Pole, m_WorldUp),  0.0f);
    local_transform[3]  = glm::vec4(0.f, 0.f, 0.f,                  1.0f);

    world_axes_rotation = glm::normalize(world_axes_rotation);
    *m_pViewMatrix      = local_transform * glm::mat4_cast(world_axes_rotation);
    *m_pCameraFront     = -1.0f * glm::vec3((*m_pViewMatrix)[2]);
    m_Up                = glm::vec3((*m_pViewMatrix)[1]);
    m_Right             = glm::vec3((*m_pViewMatrix)[0]);

    *m_pViewMatrix = glm::inverse(*m_pViewMatrix);
}
© www.soinside.com 2019 - 2024. All rights reserved.