glm四元数相机在错误的轴上旋转

我试图让我的相机实现了glm::quat用来存储旋转。

但是,每当我用鼠标做圆圈时,相机就会沿着我正在查看的轴线旋转(即我认为它被称为目标轴)。 例如,如果我以顺时针方式旋转鼠标,则相机将围绕轴顺时针旋转。

我像这样初始化了我的四元数:

 void Camera::initialize() { orientationQuaternion_ = glm::quat(); orientationQuaternion_ = glm::normalize(orientationQuaternion_); } 

我这样旋转:

 void Camera::rotate(const glm::detail::float32& degrees, const glm::vec3& axis) { orientationQuaternion_ = orientationQuaternion_ * glm::normalize(glm::angleAxis(degrees, axis)); } 

我设置viewMatrix是这样的:

 void Camera::render() { glm::quat temp = glm::conjugate(orientationQuaternion_); viewMatrix_ = glm::mat4_cast(temp); viewMatrix_ = glm::translate(viewMatrix_, glm::vec3(-pos_.x, -pos_.y, -pos_.z)); } 

我实际上试图旋转的唯一轴是X和Y轴(即(1,0,0)和(0,1,0))。

这里是一个正在发生的video: 相机奇怪的旋转

任何人有任何想法,为什么我看到我的相机旋转目标轴?

编辑

我为正在计算的值添加了一些debugging输出。

第一项是初始化的四元数,用

 std::cout << "quat initialized: " << glm::to_string(glm::eulerAngles(orientationQuaternion_)) << std::endl; 

然后我输出(在rotate方法中)四元数之前和之后,也是旋转。 我输出他们:

 void Camera::rotate(const glm::detail::float32& degrees, const glm::vec3& axis) { std::cout << "orientation before: " << glm::to_string( glm::eulerAngles(orientationQuaternion_) ) << std::endl; orientationQuaternion_ = glm::normalize(orientationQuaternion_) * glm::normalize(glm::angleAxis(degrees, glm::normalize(axis))); orientationQuaternion_ = glm::normalize(orientationQuaternion_); std::cout << "rotation: " << glm::to_string( glm::eulerAngles(glm::angleAxis(degrees, axis)) ) << std::endl; std::cout << "orientation after: " << glm::to_string( glm::eulerAngles(orientationQuaternion_) ) << std::endl; } 

这是输出数据:

 quat initialized: fvec3(0.000000, -0.000000, 0.000000) orientation before: fvec3(0.000000, -0.000000, 0.000000) rotation: fvec3(-0.363636, -0.000000, 0.000000) orientation after: fvec3(-0.363636, 0.000000, 0.000000) orientation before: fvec3(-0.363636, 0.000000, 0.000000) rotation: fvec3(0.000000, -0.545454, 0.000000) orientation after: fvec3(-0.363653, -0.545444, 0.003462) orientation before: fvec3(-0.363653, -0.545444, 0.003462) rotation: fvec3(-4.909091, -0.000000, 0.000000) orientation after: fvec3(-5.272744, -0.545443, 0.003462) orientation before: fvec3(-5.272744, -0.545443, 0.003462) rotation: fvec3(0.000000, 5.272728, 0.000000) orientation after: fvec3(-5.290381, 4.704929, -0.482044) orientation before: fvec3(-5.290381, 4.704929, -0.482044) rotation: fvec3(13.272726, -0.000000, 0.000000) orientation after: fvec3(7.982345, 4.704931, -0.482044) orientation before: fvec3(7.982345, 4.704931, -0.482044) rotation: fvec3(0.000000, 6.909091, 0.000000) orientation after: fvec3(8.120677, 11.546086, 0.494900) orientation before: fvec3(8.120677, 11.546086, 0.494900) rotation: fvec3(7.636363, -0.000000, 0.000000) orientation after: fvec3(15.757041, 11.546085, 0.494900) orientation before: fvec3(15.757041, 11.546085, 0.494900) rotation: fvec3(0.000000, 10.181817, 0.000000) orientation after: fvec3(16.596092, 21.327044, 3.448837) orientation before: fvec3(16.596092, 21.327044, 3.448837) rotation: fvec3(6.181818, -0.000000, 0.000000) orientation after: fvec3(22.777910, 21.327044, 3.448836) orientation before: fvec3(22.777910, 21.327044, 3.448836) rotation: fvec3(0.000000, 12.000000, 0.000000) orientation after: fvec3(25.255577, 32.297348, 8.913291) orientation before: fvec3(25.255577, 32.297348, 8.913291) rotation: fvec3(3.636364, -0.000000, 0.000000) orientation after: fvec3(28.891941, 32.297352, 8.913290) orientation before: fvec3(28.891941, 32.297352, 8.913290) rotation: fvec3(0.000000, 12.727273, 0.000000) orientation after: fvec3(34.057663, 43.175217, 17.306284) orientation before: fvec3(34.057663, 43.175217, 17.306284) rotation: fvec3(0.363636, -0.000000, 0.000000) orientation after: fvec3(34.421299, 43.175220, 17.306288) orientation before: fvec3(34.421299, 43.175220, 17.306288) rotation: fvec3(0.000000, 5.636363, 0.000000) orientation after: fvec3(37.799271, 47.732010, 22.041012) orientation before: fvec3(37.799271, 47.732010, 22.041012) rotation: fvec3(-0.909091, -0.000000, 0.000000) orientation after: fvec3(36.890179, 47.732010, 22.041016) orientation before: fvec3(36.890179, 47.732010, 22.041016) rotation: fvec3(0.000000, 12.545454, 0.000000) orientation after: fvec3(47.936203, 57.054291, 35.913132) orientation before: fvec3(47.936203, 57.054291, 35.913132) rotation: fvec3(-10.727273, -0.000000, 0.000000) orientation after: fvec3(37.208916, 57.054287, 35.913124) orientation before: fvec3(37.208916, 57.054287, 35.913124) rotation: fvec3(0.000000, 2.000000, 0.000000) orientation after: fvec3(39.175983, 58.626469, 38.236393) orientation before: fvec3(39.175983, 58.626469, 38.236393) rotation: fvec3(-4.909091, -0.000000, 0.000000) orientation after: fvec3(34.266888, 58.626469, 38.236393) orientation before: fvec3(34.266888, 58.626469, 38.236393) rotation: fvec3(0.000000, 1.272727, 0.000000) orientation after: fvec3(35.485283, 59.670666, 39.655521) orientation before: fvec3(35.485283, 59.670666, 39.655521) rotation: fvec3(-10.181816, -0.000000, 0.000000) orientation after: fvec3(25.303461, 59.670673, 39.655521) 

它几乎看起来像一个舍入错误? 我不确定。 在计算过程中和计算之后,我尝试了对四元数进行归一化处理,但是没有帮助…

编辑解决scheme

rotate(..)方法更改为:

 void Camera::rotate(const glm::detail::float32& degrees, const glm::vec3& axis) { if ( axis == glm::vec3(0.0f, 1.0f, 0.0f) ) orientationQuaternion_ = glm::normalize(glm::angleAxis(degrees, axis)) * orientationQuaternion_; else orientationQuaternion_ = orientationQuaternion_ * glm::normalize(glm::angleAxis(degrees, axis)); } 

在这里还有一些工作要做,但似乎从前解决了这个问题。

你的摄像机(以及每个有变换的物体)都有自己的局部空间轴,这通常与世界坐标轴不一样。 围绕世界空间轴进行变换将产生与围绕局部空间轴变换不同的结果。 相机通常需要与两者兼容。

您通常想要按照我的经验水平地围绕“世界向上”旋转相机并垂直围绕“相机向右”旋转。