问题描述
我正在尝试实现一些功能,在这些功能中我可以使用 glm 以局部或全局方向旋转/平移对象,例如在 3D 建模软件中.像这样:
i am trying to implement functions, where i can rotate/ translate an object in local or global orientation, like in 3D modeling software, using glm. Something like this:
void Rotate(float x, float y, float z, bool localOrientation);
但我不知道如何让它工作.局部旋转旋转应该是这样的(?):
but I dont know how to get it working. Local rotation rotation should just be something like this(?):
m_Orientation *= glm::rotate(x, glm::vec3(1,0,0);
m_Orientation *= glm::rotate(y, glm::vec3(0,1,0);
m_Orientation *= glm::rotate(z, glm::vec3(0,0,1);
// (m_Orientation is glm::mat4)
但是如何将其与本地定位结合起来呢?实际上我需要在世界方向旋转旋转矩阵,对吗?我希望你知道我对面向局部和全局的旋转/平移的意思,就像在 3D 建模程序中一样.在大多数情况下,您有一个按钮可以在本地和全局之间切换.
But how to combine this with local orientation? Actually i need to rotate the rotation matrix in world orientation, right? I hope you know what i mean with local and global oriented rotation/translation, like it is in 3D modeling programs. In most of them you have a button to switch between local and global.
然后我将如何计算向前/向右/向上矢量?通常应该是这样的,对吧?:
And how would i calculating the forward/right/up vector then? normally it should be something like this, right?:
forward = m_Orientation * glm::vec4(0,0,-1,0);
我用这个尝试了全局旋转:
I tried global rotation with this:
m_GlobalOrientation = glm::rotate(m_GlobalRotation.x, glm::vec(1,0,0);
m_GlobalOrientation *= glm::rotate(m_GlobalRotation.y, glm::vec(0,1,0);
m_GlobalOrientation *= glm::rotate(m_GlobalRotation.z, glm::vec(0,0,1);
但是只有 x 旋转处于全局方向,y 和 z 旋转处于局部方向,因为它已经围绕 x 轴旋转.所以我需要一次旋转所有 3 个角度(?)
but then only x rotation is in global orientation, y and z rotation is in local orientation, since it is already rotated around x axis. So I need to rotate all 3 angles at once(?)
翻译本地应该只是将翻译值添加到当前翻译中,而本地翻译应该是 glm::inverse(m_Orientation) * translationVector 对吗?
Translating local should just be adding translation values to current translation, and local translation should be glm::inverse(m_Orientation) * translationVector right?
推荐答案
在回答你的问题之前,让我解释一下矩阵的一些核心概念.
Before I come to your question, let me explain some core concepts of matrices.
假设我们有以下矩阵:
其中 T
是平移,R
是旋转矩阵.
wher T
is a translation and R
is a rotation matrix.
当我们使用这个矩阵来变换一个顶点(甚至网格)时,会有一个独特的结果.但是,我们可以通过两种解释得出这个结果:
When we use this matrix to transform a vertex (or even mesh), there is one unique result. However, we can get to this result with the help of two interpretations:
解读1:从右到左评估
如果我们从右到左评估矩阵,则所有变换都在全局坐标系中执行.所以如果我们变换一个位于原点的三角形,我们会得到以下结果:
If we evaluate the matrix from right to left, all transformations are performed in the global coordinate system. So if we transform a triangle that sits at the origin, we get the following result:
解读2:从左到右评价
在另一种情况下,所有变换都在局部坐标系中进行:
In the other case, all transformations are performed in the local coordinate system:
当然,我们得到了相同的结果.
Of course, we get the same result.
所以回到你的问题.如果将对象的位置和方向存储为矩阵 T
.您可以通过将旋转矩阵乘以当前矩阵的右侧,在其局部坐标系中旋转此对象.在全局系统中通过在左侧乘以它.这同样适用于翻译:
So coming back to your question. If you store the position and orientation of the object as a matrix T
. You can rotate this object in its local coordinate system by multiplying a rotation matrix to the right side of the current matrix. And in the global system by multiplying it at the left side. The same applies for translation:
void Rotate(float x, float y, float z, bool localOrientation)
{
auto rotationMatrix = glm::rotate(x, glm::vec3(1,0,0));
rotationMatrix *= glm::rotate(y, glm::vec3(0,1,0));
rotationMatrix *= glm::rotate(z, glm::vec3(0,0,1));
if(localOrientation)
this->T = this->T * rotationMatrix;
else
this->T = rotationMatrix * this->T;
}
右/前/上向量是矩阵T
的列向量.您可以直接读取它们,也可以通过将矩阵与 (1, 0, 0, 0)
(right), (0, 1, 0, 0)
相乘得到它们(up), (0, 0, 1, 0)
(for/backward) or (0, 0, 0, 1)
(position).
The right / forward / up vectors are the column vectors of the matrix T
. You can either read them directly or get them by multiplying the matrix with (1, 0, 0, 0)
(right), (0, 1, 0, 0)
(up), (0, 0, 1, 0)
(for/backward) or (0, 0, 0, 1)
(position).
如果您想了解更多相关信息,请查看我的 有关 DirectX 中矩阵的博客文章.但它适用于使用转置矩阵的 DirectX.因此矩阵顺序是相反的.阅读文章时请注意这一点.
If you want to read more about this, take a look at my blog article about matrices in DirectX. But it's for DirectX, which uses transposed matrices. Therefore the matrix order is reversed. Watch out for that when reading the article.
这篇关于使用 glm 以局部和全局方向旋转和平移对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!