将矩阵转换为四元数以及再次转换时出现问题

8

我想将旋转矩阵存储为四元数,然后在需要进行变换时再将其转换回来。我正在使用glm库,该库提供了mat4_cast和quat_cast函数来完成这个功能。但是,当我执行以下代码时:

glm::mat4 origTest = glm::lookAt(position, lookAtPt, up);
glm::quat quatTest = glm::quat_cast(origTest);
glm::mat4 mat4Test = glm::mat4_cast(quatTest);

我对origTest和mat4Test得到了不同的值,我有什么遗漏吗? position、lookAtPt和up是glm::vec3类型。

有多不同?会有一些舍入误差。 - Jaa-c
不,这不是一个舍入误差。对于我尝试的值,矩阵的第四行完全不同:即位置(0,0,5);lookAtPt(0,0,0)和up(0,1,0)。 - shaveenk
我已经部分地弄清楚了。转换的方式没有考虑到位置参数。所以,我提供了位置vec3(0)并在lookAtPt上进行了反向平移,而不是提供任何来自原点的位置偏移量。现在,origTest和mat4Test都提供相同的值。但我真的需要它考虑整个4x4矩阵才能有用。 - shaveenk
1个回答

11

我已经解决了。四元数存储物体在局部空间中的旋转。因此,为了得出你可以从glm :: lookAt()获得的完整视图矩阵,你需要先将局部空间中的四元数转换为矩阵。然后,你需要按所需的位置平移一个单位矩阵,并进行SRT乘法以得到最终的视图矩阵。在这种情况下,你需要反转平移矩阵,因为我们正在对相机进行反向平移,还需要使用适当的“lookAt”向量,它与(lookAtPt - position)方向相同。

/* Mat4 to Quat */
glm::vec3 lookAtPt = direction;
glm::mat4 rotMatrix = glm::lookAt(glm::vec3(0), lookAtPt, up);
glm::quat rotation = glm::quat_cast(rotMatrix);

/* Quat to Mat4 */    
glm::mat4 identityMat = glm::mat4(1.0f);
glm::mat4 rotMatrix = glm::mat4_cast(rotation);   //rotation is glm::quat
glm::mat4 transMatrix = glm::translate(identityMat, position); 
glm::mat4 viewMatrix = rotMatrix * glm::inverse(transMatrix);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接