使用glm以局部和全局方向旋转和平移对象

C0d*_*0dR 5 c++ opengl math rotation glm-math

我正在尝试实现函数,我可以使用glm在局部或全局方向上旋转/平移对象,就像在3D建模软件中一样.像这样的东西:

void Rotate(float x, float y, float z, bool localOrientation);
Run Code Online (Sandbox Code Playgroud)

但我不知道如何让它工作.局部旋转旋转应该是这样的(?):

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)
Run Code Online (Sandbox Code Playgroud)

但如何将其与当地定位相结合?实际上我需要在世界方向旋转旋转矩阵,对吧?我希望你知道我对于本地和全球导向的旋转/翻译的意义,就像在3D建模程序中一样.在大多数情况下,您可以在本地和全局之间切换按钮.

那么我如何计算前进/右/向上矢量呢?通常它应该是这样的,对吧?:

forward = m_Orientation * glm::vec4(0,0,-1,0);
Run Code Online (Sandbox Code Playgroud)

我用这个尝试了全局轮换:

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);
Run Code Online (Sandbox Code Playgroud)

但是只有x旋转处于全局方向,y和z旋转处于局部方向,因为它已经围绕x轴旋转.所以我需要一次旋转所有3个角度(?)

翻译本地应该只是将翻译值添加到当前翻译中,而本地翻译应该是glm :: inverse(m_Orientation)*translationVector对吗?

Nic*_*ler 16

在我提出你的问题之前,让我解释一下矩阵的一些核心概念.

假设我们有以下矩阵:

矩阵

wher T是一个平移,R是一个旋转矩阵.

当我们使用这个矩阵来变换顶点(甚至是网格)时,有一个唯一的结果.但是,我们可以借助两种解释来得到这个结果:

解释1:从右到左进行评估

如果我们从右到左评估矩阵,则所有变换都在全局坐标系中执行.因此,如果我们变换位于原点的三角形,我们得到以下结果:

从右到左的转变

解释2:从左到右进行评估

在另一种情况下,所有转换都在本地坐标系中执行:

从左到右转换

当然,我们得到了相同的结果.

所以回到你的问题.如果将对象的位置和方向存储为矩阵T.您可以通过将旋转矩阵乘以当前矩阵的右侧来在此局部坐标系中旋转此对象.并且在全球系统中将其乘以左侧.这同样适用于翻译:

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;
}
Run Code Online (Sandbox Code Playgroud)

右/前/上向量是矩阵的列向量T.您可以直接读取它们,也可以通过将矩阵乘以(1, 0, 0, 0)(右),(0, 1, 0, 0)(向上),(0, 0, 1, 0)(用于/向后)或(0, 0, 0, 1)(位置)来获取它们.

如果您想了解更多相关信息,请查看我的博客文章,了解DirectX中的矩阵.但它适用于使用转置矩阵的DirectX.因此,矩阵顺序是相反的.阅读文章时要注意这一点.