使用自定义 "world up" 向量更新 "front" 向量的正确方法是什么?

What is the right way to update "front" vector with custom "world up" vector?

我正在尝试实现 "planet" 世界。所以在我的旧相机表面的任何一点 class 我得到的结果是这样的: 相机class更新码为:

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 更新 front vector,但真的不知道怎么做。

在此处找到解决方案: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);
}