[英]Glm Quaternion lookat function
I am trying to write a lookat function that uses glm::quat to represent rotations, based of off this answer . 我正在尝试基于此答案编写使用glm :: quat表示旋转的lookat函数。 I am running into trouble getting a correct angle however.
但是,我在获取正确角度时遇到了麻烦。 This is my lookat function:
这是我的查阅功能:
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";
}
When I call LookAt(0.0f, 0.0f, 0.0f) when my camera is at (0.0f, 0.0f, -10.0f), this outputs a correct rotation of 0,0,0. 当我的相机位于(0.0f,0.0f,-10.0f)时调用LookAt(0.0f,0.0f,0.0f)时,这将输出正确的旋转0,0,0。 However if I translate my camera to (0.0f, -0.01f, -10.0f) or more I get a rotation of about 124,0,0.
但是,如果将摄影机平移为(0.0f,-0.01f,-10.0f)或更大,则旋转量约为124,0,0。 This goes down if I continue to translate y by -0.01f.
如果我继续将y转换-0.01f,则此值会下降。 If I do not normalize the quaternion I do not get this problem.
如果我不对四元数进行归一化,那么我不会遇到这个问题。 The rotation is still 124 about the x axis, but the appearance is fine.
围绕x轴的旋转仍然是124,但是外观很好。 If however I normalize the quaternion later it once again appears to rotate to about 124. I can not normalize
cross
, because doing so throws an assert. 但是,如果稍后我将四元数归一化,它似乎又会旋转到约124。我无法将
cross
归一化,因为这样做会引发断言。 What would cause me to get euler angles of 124 about x from my lookat function, and how can I fix it? 是什么导致我从我的查阅函数获得关于x的124欧拉角,以及如何解决该问题?
Since version 0.9.9.0 there is a function in <glm/gtx/quaternion.hpp>
doing mostly what you want: 从0.9.9.0版开始,
<glm/gtx/quaternion.hpp>
了一个函数,主要用于执行您想要的操作:
template<typename T, qualifier Q>
tquat<T, Q> quatLookAt(vec<3, T, Q> const& direction, vec<3, T, Q> const& up);
It was added by this pull request and has been merged into master July 24, 2017. 此请求请求已将其添加,并已合并到2017年7月24日的主服务器中。
But : 但是 :
So you may want to write a safer wrapper around the function: 因此,您可能想为该函数编写一个更安全的包装器:
glm::quat safeQuatLookAt(
glm::vec3 const& lookFrom,
glm::vec3 const& lookTo,
glm::vec3 const& up,
glm::vec3 const& alternativeUp)
{
glm::vec3 direction = lookTo - lookFrom;
float directionLength = glm::length(direction);
// Check if the direction is valid; Also deals with NaN
if(!(directionLength > 0.0001))
return glm::quat(1, 0, 0, 0); // Just return identity
// Normalize direction
direction /= directionLength;
// Is the normal up (nearly) parallel to direction?
if(glm::abs(glm::dot(direction, up)) > .9999f) {
// Use alternative up
return glm::quatLookAt(direction, alternativeUp);
}
else {
return glm::quatLookAt(direction, up);
}
}
I have fixed the problem with the following code: 我已使用以下代码解决了该问题:
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::angleAxis(RadiansToDegrees(M_PI), glm::vec3(0, 1, 0));
return;
}
else if (fabs(dot - (1.0f)) < 0.000001f) {
rotation = glm::quat();
return;
}
float angle = -RadiansToDegrees(acosf(dot));
glm::vec3 cross = glm::normalize(glm::cross(glm::vec3(0, 0, 1), direction));
rotation = glm::normalize(glm::angleAxis(angle, cross));
}
I do not however understand the necessity of the negative on angle
. 但是,我不理解否定
angle
的必要性。 It fixed the last of my problems, and an explanation of the math of why would be helpful. 它解决了我的最后一个问题,并解释了为什么会有所帮助的数学方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.