【发布时间】:2014-01-17 03:54:12
【问题描述】:
我一直在尝试模拟 gluLookAt 功能,但使用四元数。我的每个游戏对象都有一个 TranslationComponent。该组件存储对象的位置 (glm::vec3)、旋转 (glm::quat)和缩放 (glm::vec3)。相机在每个滴答声中计算其位置:
// UP = glm::vec3(0,1,0);
//FORWARD = glm::vec3(0,0,1);
cameraPosition = playerPosition - (UP * distanceUP) - (FORWARD * distanceAway);
这个位置代码的作用是expexted,摄像机位于玩家身后3米处,向上1米处。现在,相机的四元数设置如下:
//Looking at the player's feet
cameraRotation = quatFromToRotation(FORWARD, playerPosition);
渲染引擎现在获取这些值并生成 ViewMatrix(相机)和 ModelMatrix(播放器),然后渲染场景。代码如下所示:
glm::mat4 viewTranslationMatrix =
glm::translate(glm::mat4(1.0f), cameraTransform->getPosition());
glm::mat4 viewScaleMatrix =
glm::scale(glm::mat4(1.0f), cameraTransform->getScale());
glm::mat4 viewRotationMatrix =
glm::mat4_cast(cameraTransform->getRotation());
viewMatrix = viewTranslationMatrix * viewRotationMatrix * viewScaleMatrix;
quatFromToRotation(glm::vec3 from, glm::vec3 to)定义如下:
glm::quat quatFromToRotation(glm::vec3 from, glm::vec3 to)
{
from = glm::normalize(from); to = glm::normalize(to);
float cosTheta = glm::dot(from, to);
glm::vec3 rotationAxis;
if (cosTheta < -1 + 0.001f)
{
rotationAxis = glm::cross(glm::vec3(0.0f, 0.0f, 1.0f), from);
if (glm::length2(rotationAxis) < 0.01f)
rotationAxis = glm::cross(glm::vec3(1.0f, 0.0f, 0.0f), from);
rotationAxis = glm::normalize(rotationAxis);
return glm::angleAxis(180.0f, rotationAxis);
}
rotationAxis = glm::cross(from, to);
float s = sqrt((1.0f + cosTheta) * 2.0f);
float invis = 1.0f / s;
return glm::quat(
s * 0.5f,
rotationAxis.x * invis,
rotationAxis.y * invis,
rotationAxis.z * invis
);
}
我遇到的问题是 cameraRotation 设置不正确。无论玩家在哪里,相机的前方总是(0,0,-1)
【问题讨论】:
-
你在哪里/如何计算相机的
forward? -
假设
FORWARD是一个方向而不是一个位置,我认为这不是你想要的......那么quatToFromRotation (playerPosition + FORWARD, playerPosition);呢? -
另外,您在代码中列出的函数是
quatFromToRotation (...),这与您在正文中讨论的不同。 -
啊,是的,那是一个错字。我编辑了它。
-
请注意,glm 有一个功能上等同于
gluLookAt()的函数,命名为glm::lookAt()并在<glm/gtc/matrix_transform.hpp>中定义。如需更多信息,请查看glm manual 并搜索“lookAt”。你会在那里找到函数文档。
标签: c++ opengl quaternions glm-math glulookat