Glm四元数查找功能 [英] Glm Quaternion lookat function

查看:100
本文介绍了Glm四元数查找功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试基于此 answer 来编写一个使用glm :: quat表示旋转的外观函数..但是,我在获取正确角度时遇到了麻烦.这是我的查找功能:

I am trying to write a lookat function that uses glm::quat to represent rotations, based of off this answer. 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";
}

当我的相机处于(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的欧拉角,我该如何解决?

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. However if I translate my camera to (0.0f, -0.01f, -10.0f) or more I get a rotation of about 124,0,0. This goes down if I continue to translate y by -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. 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. What would cause me to get euler angles of 124 about x from my lookat function, and how can I fix it?

推荐答案

从0.9.9.0版开始,< glm/gtx/quaternion.hpp> 中就有一个函数可以满足您的大部分需求:

Since version 0.9.9.0 there is a function in <glm/gtx/quaternion.hpp> doing mostly what you want:

template<typename T, qualifier Q>
tquat<T, Q> quatLookAt(vec<3, T, Q> const& direction, vec<3, T, Q> const& up);

它是由此拉取请求添加的,并已合并到主服务器中2017年7月24日.

It was added by this pull request and has been merged into master July 24, 2017.

但是:

  1. 方向必须是归一化的向量!
  2. 方向不能平行!

因此,您可能想为该函数编写一个更安全的包装器:

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);
    }
}

这篇关于Glm四元数查找功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆