使用 glm 在局部和全局方向旋转和平移对象
我正在尝试实现功能,我可以使用 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);
我尝试了全局轮换:
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:
解读一:从右到左评价
如果我们从右到左计算矩阵,所有的变换都是在全局坐标系中进行的.所以如果我们变换一个位于原点的三角形,我们会得到以下结果:
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)
(右),(0, 1, 0, 0)
(up), (0, 0, 1, 0)
(for/backward) 或 (0, 0, 0, 1)
(位置).
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.
相关文章