C ++ OpenGL如何从quaterion中获取旋转x,y,z

时间:2018-01-18 00:32:39

标签: c++ opengl quaternions

我一直在通过存储对象的x,y和z旋转来处理引擎中的对象旋转,然后当我要渲染时,我正在创建这样的变换矩阵。

    // entity.getRotation() returns a glm::vec3 where I use these
    //values to rotate the object.

    glm::mat4 model;
    model = glm::translate(model, entity.getPosition());
    model = glm::rotate(model, glm::radians(entity.getRotation().x), glm::vec3(1.0f, 0.0f, 0.0f));
    model = glm::rotate(model, glm::radians(entity.getRotation().y), glm::vec3(0.0f, 1.0f, 0.0f));
    model = glm::rotate(model, glm::radians(entity.getRotation().z), glm::vec3(0.0f, 0.0f, 1.0f));
    model = glm::scale(model, glm::vec3(entity.getScale(), entity.getScale(), entity.getScale()));

现在,我在我的引擎中实现了一个AntTweakBar GUI,其中有一个选项可以在GUI上旋转对象。我目前正试图在GUI中旋转对象并在引擎中查看生成的旋转。问题是GUI使用四元数,而在我的引擎对象中,旋转被存储为3个x,y,z旋转量的浮点数。

我的问题是,如何将四元数转换为x,y,z旋转,以便我可以使用上面提到的方法来创建变换矩阵?

我在glm中找到了这个方法

glm::eulerAngles(glm::quat(q[0], q[1], q[2], q[3]));

但是看完返回的vec3后,它似乎并不像我要找的那样。我相信当我尝试使用这些值来创建我的转换矩阵时,eulerAngles返回的音高,偏航和滚动行为都不正确。

编辑: 我发现了自己的错误。事实证明我的旧解决方案很好(虽然有人在评论中指出使用quats可能会更快)。问题在于我从quat的浮点数组表示(AntTweakBar的float数组表示)转换为角度。看起来AntTweakBar在浮点数组中以不同的顺序存储quat中的x,y,z,w组件。 float数组中的正确顺序是y,z,w,x,但我不知道为什么会这样。

1 个答案:

答案 0 :(得分:1)

使用GLM有几个选项,您已经提到过一个选项,但请确保您的角度测量值是一致的。如果您正在使用并依赖radians大多数GLM's库方法,那么现在预计所有正在传递到其旋转的角度都会在radians中根据其工作时的文档进行操作使用四元数并使用glm::eulerAngles();除非定义了pitch as X,否则它会以度为单位返回角度yaw as Yroll as ZGLM_FORCE_RADIANS

另一种选择是使用这两种方法:

  • glm::mat4_cast
    GLM_FUNC_DECL tmat4x4<T, P> glm::mat4_cast  ( tquat< T, P > const &  x )  
    
         

    将四元数转换为4 * 4矩阵。

         

    另请参阅GLM_GTC_quaternion引用的glm::toMat4()

  • glm::quat_cast
    GLM_FUNC_DECL tquat<T, P> glm::quat_cast  ( tmat4x4< T, P > const &  x )  
    
         

    将4 * 4矩阵转换为四元数。

         

    另见GLM_GTC_quaternion

如果您的GUI使用Quaternions,您可以检索该信息并将其保存到glm::quaternion,然后从那里您可以使用这些功能之一将其转换为4x4矩阵。还有3x3 matrix-quat&amp;这些转换函数的quat-3x3 matrix版本。