【发布时间】:2013-08-11 13:25:40
【问题描述】:
我正在尝试编写一个使用 glm::quat 表示旋转的查看函数,基于此answer。但是,我在获得正确的角度时遇到了麻烦。这是我的查看功能:
void Camera::LookAt(float x, float y, float z) {
glm::vec3 lookVector = glm::vec3(x, y, z);
assert(lookVector != position);
glm::vec3 direction = glm::normalize(lookVector-position);
float dot = glm::dot(glm::vec3(0, 0, -1), direction);
if (fabs(dot - (-1.0f)) < 0.000001f)
rotation = glm::quat(RadiansToDegrees(M_PI), 0.0f, 1.0f, 0.0f);
if (fabs(dot - (1.0f)) < 0.000001f)
rotation = glm::quat();
float angle = RadiansToDegrees(acosf(dot));
glm::vec3 cross = (glm::cross(glm::vec3(0, 0, -1), direction));
rotation = glm::normalize(glm::angleAxis(angle, cross));
std::cout << glm::eulerAngles(rotation).x << " " << glm::eulerAngles(rotation).y << " " << glm::eulerAngles(rotation).z << "\n";
}
当我的相机位于 (0.0f, 0.0f, -10.0f) 时,当我调用 LookAt(0.0f, 0.0f, 0.0f) 时,这会输出正确的旋转 0,0,0。但是,如果我将相机转换为 (0.0f, -0.01f, -10.0f) 或更多,我会得到大约 124,0,0 的旋转。如果我继续将 y 翻译为 -0.01f,这会下降。如果我不规范化四元数,我不会遇到这个问题。绕x轴旋转仍然是124,但外观很好。但是,如果我稍后将四元数标准化,它似乎再次旋转到大约 124。我无法标准化cross,因为这样做会引发断言。什么会导致我从我的查看函数中得到关于 x 的 124 欧拉角,我该如何解决?
【问题讨论】:
-
正如GLM documentation 所说,
glm::angleAxis的轴必须标准化,但您的情况并非如此。当您尝试规范化cross时会抛出什么样的断言?只要direction不平行于(0, 0, -1)应该没有问题。 -
调试代码,我刚刚意识到 cross 是
(0.0f, 0.0f, 0.0f),它解释了从 inversesrt 抛出的断言。 -
啊.. 在这种情况下
dot == -1和rotation已经设置好了。但是,您尝试再次计算它,这是没有意义的。所以只需添加一个else块。 -
现在轮换大约是
(180, 0, 0)。这个还是不看(0,0,0) -
这就是你在第一种情况下定义的。您可能想再次使用
angleAxis()而不是纯构造函数。
标签: c++ opengl quaternions glm-math