我正在做一个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轴旋转之外,但我觉得这不是最好的方法。有什么想法?
发布于 2013-06-13 03:03:47
我认为问题来自于你混合了变换的顺序,特别是平移和旋转。这些变换(缩放、平移和旋转)中的每一个都定义了如何将一个坐标系转换为另一个坐标系。
让我们来看一个例子:你有一个子对象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)这意味着子代的平移在子代的坐标系中,父代的平移在父代的坐标系中。
https://stackoverflow.com/questions/17038681
复制相似问题