我正在尝试编写一个使用glm::quat表示旋转的lookat函数,参考了这个答案。然而,我遇到了获取正确角度的问题。这是我的lookat函数:
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
进行归一化,因为这样会引发一个断言。是什么导致我从我的lookat函数中获得关于x轴旋转124的欧拉角,如何修复它?
glm::angleAxis
的轴必须被标准化,而在您的情况下它没有被标准化。当您尝试标准化cross
时会抛出什么样的断言?只要direction
不与(0, 0, -1)
平行,就不应该有问题。 - Nico Schertlerdot == -1
并且rotation
已经被设置。然而,你尝试重新计算它,这是没有意义的。所以只需添加一个else
块即可。 - Nico Schertler(180, 0, 0)
的。这仍然没有看向(0,0,0)
。 - jbillsangleAxis()
而不是纯构造函数。 - Nico Schertler(180, 0, 180)
。 - jbills