GLM矩阵中的旋转方向,使用四元数

时间:2013-06-11 07:28:20

标签: c++ opengl matrix quaternions glm-math

我正在进行3D渲染设置(使用GLM for OpenGL完成所有数学运算),除了我希望我的转换工作之外,它都能正常工作。 我为每个实体创建了一个矩阵,如下所示:

matrix = mat4(1);
vec3 scale = GetWorldScale();
vec3 pos = GetWorldPosition(); // Returns pos + parent->pos
quat rot = GetWorldRotationQuat(); // Returns parent->rot * rot

matrix = glm::translate(matrix, pos);
matrix *= mat4_cast(rot);
matrix = glm::scale(matrix, scale);

right = matrix[0].xyz;
up = matrix[1].xyz;
direction = matrix[2].xyz;

使用它,它通常可以正常工作,除了我不确定如何调整它的一部分作为首选项。也就是说,使用它,在X轴上的平移被翻转(例如,左边是正的,并且在Z轴上向前是正的,但是我对它的判别较少),并且在Y轴上的旋转被翻转。

为此目的看其他代码,似乎很多人否定了我用于方向(对于相机)。我也是这样做的,并且平移是正确的,但是所有旋转轴都与首选旋转轴相反(尽管X上的旋转是相同的,无论方向是否被否定)。

我不太确定我应该做些什么来帮助纠正这个问题,除非在使用前否定X轴平移和Y轴旋转,但我觉得这不是最好的方法。想法?

1 个答案:

答案 0 :(得分:0)

我认为问题来自于你混合变换的顺序,特别是平移和旋转。这些变换(缩放,平移和旋转)中的每一个都定义了如何将一个坐标系转换为另一个坐标系。

让我们来看一个例子:你有一个子对象c和它的父p。它们每个都有平移t,旋转r和尺度s。为了简单起见,每个都是4x4矩阵。目前你做了

matrix = p.t * c.t * p.r * c.r * p.s * c.s

想象一下由这个矩阵(长度为1的xyz轴)变换的孩子的局部坐标系。点数从右侧乘以,所以我们必须从右到左阅读。首先,坐标系由孩子缩放,然后由父母缩放。然后它被孩子旋转。然后由父母。现在应用了孩子的翻译。这意味着子转换应用于旋转坐标系。由于您已经应用了孩子的父项的旋转,因此它会旋转到父级的坐标系中。所以孩子的坐标被解释为它们是父坐标。

那么你应该做什么:在你的方法中,计算对象矩阵m = c.t * c.r * c.s。然后,对象的世界矩阵定义为wm = pm * m,其中父矩阵pm是父对象的世界矩阵。这样你就会得到一个世界矩阵:

c.wm = (c.pm) * (c.o) = (p.t * p.r * p.s) * (c.t * c.r * c.s)

这意味着孩子的翻译在孩子的坐标系中,父母的翻译在父母的坐标系中。