我正在尝试实现“行星”世界。因此,在使用旧相机类别的任何时候,我都得到这样的结果:相机类更新代码为:
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更新前向矢量,但真的不知道如何。
在这里找到解决方案: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);
}