使用glm在本地和全局方向上旋转和平移对象 [英] Rotate and translate object in local and global orientation using glm

查看:408
本文介绍了使用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);

我尝试使用此方法进行全局旋转:

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轴旋转了.所以我需要一次旋转所有三个角度(?)

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.

假设我们具有以下矩阵:

Assume that we have the following matrix:

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)(右),(0, 1, 0, 0)(上),(0, 0, 1, 0)(向前/向后)或(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.

这篇关于使用glm在本地和全局方向上旋转和平移对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆