如何使用 glm::mat4 手动正确编写旋转矩阵?

Posted

技术标签:

【中文标题】如何使用 glm::mat4 手动正确编写旋转矩阵?【英文标题】:How to correctly write rotation matrices by hand using glm::mat4? 【发布时间】:2016-10-03 22:58:35 【问题描述】:

我正在编写一个 OpenGL 程序,并且对于该程序,我正在尝试手动编写一些旋转矩阵(我知道 glm::rotate,但这是针对一个类,所以我不能使用该函数),但是它似乎不像我想要的那样工作。

我正在绘制一个场景,其中有一个停车场和一辆汽车,轮胎是分开绘制的,轮胎随着相机移动而不是原地不动: 如您所见,轮胎朝相机方向略微旋转,看起来像。

编辑:此外,在绘制其他对象(旋转的)时,它们似乎会倾斜:

注意高度倾斜的建筑。

据我了解,旋转矩阵应该是这样的:

这就是我在代码中所做的(为简洁起见,关于翻译和缩放的部分省略了):

//glm::mat4 rotXMatrix = glm::rotate(rotation.x, glm::vec3(1, 0, 0));
glm::mat4 rotXMatrix = glm::mat4(1.0f);
rotXMatrix[1][1] = cos(rotation.x);
rotXMatrix[1][2] = sin(rotation.x);
rotXMatrix[2][1] = -sin(rotation.x);
rotXMatrix[2][2] = cos(rotation.x);
//glm::mat4 rotYMatrix = glm::rotate(rotation.y, glm::vec3(0, 1, 0));
glm::mat4 rotYMatrix = glm::mat4(1.0f);
rotXMatrix[0][0] = cos(rotation.y);
rotXMatrix[0][2] = -sin(rotation.y);
rotXMatrix[2][0] = sin(rotation.y);
rotXMatrix[2][2] = cos(rotation.y);
//glm::mat4 rotZMatrix = glm::rotate(rotation.z, glm::vec3(0, 0, 1));
glm::mat4 rotZMatrix = glm::mat4(1.0f);
rotXMatrix[0][0] = cos(rotation.z);
rotXMatrix[0][1] = sin(rotation.z);
rotXMatrix[1][0] = -sin(rotation.z);
rotXMatrix[1][1] = cos(rotation.z);

glm::mat4 rotMatrix = rotZMatrix * rotYMatrix * rotXMatrix;
return posMatrix * rotMatrix * scaleMatrix;

当我不手动操作时它可以正常工作(使用glm::rot,如注释掉的部分所示,所以我想知道我对旋转矩阵的构造方式有什么误解。我很确定[] 的顺序是正确的,因为我可以使用相同的符号手动构建用于平移和缩放的矩阵,并且它可以正确缩放和移动对象。

编辑:请注意,这些变换矩阵是针对对象的,不是相机的。

【问题讨论】:

【参考方案1】:

您正在修改错误的矩阵

glm::mat4 rotYMatrix = glm::mat4(1.0f);
rotXMatrix[0][0] = cos(rotation.y);
rotXMatrix[0][2] = -sin(rotation.y);
rotXMatrix[2][0] = sin(rotation.y);
rotXMatrix[2][2] = cos(rotation.y);

您正在构造rotYMatrix,但修改rotXMatrix

【讨论】:

哦。呃……谢谢。我没有意识到我忘记将 X 更改为 Y 然后更改为 Z

以上是关于如何使用 glm::mat4 手动正确编写旋转矩阵?的主要内容,如果未能解决你的问题,请参考以下文章

glm - 将 mat4 分解为平移和旋转?

如何从 glm::quat 和 glm::mat4 中提取偏航俯仰滚动

GLM 旋转矩阵与预期结果不同

平行于全局轴的矩阵旋转

绕轴旋转相机?

从旋转矩阵获取绕 y 轴的旋转