如何使用现代 OpenGL 的 GLM 或 JOML 矩阵正确转换(平移、旋转、缩放)对象

Posted

技术标签:

【中文标题】如何使用现代 OpenGL 的 GLM 或 JOML 矩阵正确转换(平移、旋转、缩放)对象【英文标题】:How to transform (translate, rotate, scale) object correctly using GLM or JOML matrices for modern OpenGL 【发布时间】:2018-06-09 03:54:49 【问题描述】:

我正在尝试使用矩阵来实现对象的转换,但它的工作原理很奇怪。对象中心坐标不是 (0,0,0)。平移和缩放看起来不错,但旋转是围绕 (0,0,0) 坐标执行的(不是围绕对象的中心)。

我的 Java 代码:

Matrix4f moveOriginMat = new Matrix4f();
Vector3d centroid = new Vector3f(pickedObject.getCentroid().getX() + translationMatrix.m30(), pickedObject.getCentroid().getY() + translationMatrix.m31(), pickedObject.getCentroid().getZ() + translationMatrix.m32());
moveOriginMat.translation(-(float)centroid.x * (scaleMat.m00() - 1), -(float)centroid.y * (scaleMat.m11() - 1), -(float)centroid.z * (scaleMat.m22() - 1));
modelMatrix.set(moveOriginMat);
modelMatrix.mul(scaleMat);
modelMatrix.mul(xRotationMatrix);
modelMatrix.mul(yRotationMatrix);
modelMatrix.mul(zRotationMatrix);
modelMatrix.mul(translationMatrix);

我做错了什么?我需要围绕自己的轴旋转对象,而不是围绕世界的中心。

【问题讨论】:

【参考方案1】:

解决方案:

Matrix4f moveOriginMat = new Matrix4f();
Vector3d centroid = getPickedObjectLocalCentroid();
moveOriginMat.translation(-(float)centroid.x * (scaleMat.m00() - 1), -(float)centroid.y * (scaleMat.m11() - 1), -(float)centroid.z * (scaleMat.m22() - 1));
modelMatrix.set(moveOriginMat);
modelMatrix.mul(scaleMat);
modelMatrix.translate((float)centroid.x, (float)centroid.y, (float)centroid.z);
modelMatrix.mul(zRotationMatrix);
modelMatrix.mul(yRotationMatrix);
modelMatrix.mul(xRotationMatrix);
modelMatrix.translate(-(float)centroid.x, -(float)centroid.y, -(float)centroid.z);
modelMatrix.mul(translationMatrix);

我只需要在旋转之前将翻译添加到原点,然后在此之后添加翻译。翻译的标志也让我感到困惑。

【讨论】:

以上是关于如何使用现代 OpenGL 的 GLM 或 JOML 矩阵正确转换(平移、旋转、缩放)对象的主要内容,如果未能解决你的问题,请参考以下文章

为 3D Cup 创建圆柱体基础(现代 OpenGL、GLM)

现代 OpenGL:如何获得立方体的矢量位置?

如何在 glRotatef 中使用 glm::mat4

如何在glRotatef中使用glm :: mat4

使用 GLM 库在 OpenGL 中绘制顶点时如何使用常规坐标系

如何使用 GLM 在 OpenGL 中正确计算旋转