我有一个以下列方式构建的变换矩阵4x4:
glm::mat4 matrix;
glm::quat orientation = toQuaternion(rotation);
matrix*= glm::mat4_cast(orientation);
matrix= glm::translate(matrix, position);
matrix= glm::scale(matrix, scale);
orientation = toQuaternion(localRotation);
matrix*= glm::mat4_cast(orientation);
matrix= glm::scale(matrix, localScale);
其中rotation,position,scale,localRotation和localScale都是vector3&#39。根据许多不同论坛上许多不同问题的建议,应可以从结果矩阵中捕获本地方向,如下所示:
right = glm::vec3(matrix[0][0], matrix[0][1], matrix[0][2]);
up = glm::vec3(matrix[1][0], matrix[1][1], matrix[1][2]);
forward = glm::vec3(matrix[2][0], matrix[2][1], matrix[2][2]);
所有这些方向都归一化。然后我使用这些方向得到一个像这样的视图矩阵:
glm::lookAt(position, position + forward, up);
这一切都很有效 - 除了:当我在一个场景中飞行时,向右和向上的向量是完全错误的。前进方向总是完全正确。当我在0,0,-1看0,0,0时,所有方向都是正确的。但是当我向不同的方向看时(除了从0,0,-1看起源的反转),右和上是不一致的。它们不是世界载体,也不是局部载体。它们似乎几乎是随机的。我哪里错了?如何从4x4变换矩阵中获得一致的局部向上和局部右向量?
答案 0 :(得分:2)
matrix
是一个从本地到世界的转换,而视图矩阵是世界到本地的,这意味着在这种情况下matrix
是逆视图矩阵。您当前的代码仅适用于视图矩阵。只需交换行和列:
right = glm::vec3(matrix[0][0], matrix[1][0], matrix[2][0]);
up = glm::vec3(matrix[0][1], matrix[1][1], matrix[2][1]);
forward = glm::vec3(matrix[0][2], matrix[1][2], matrix[2][2]);
它适用于(0, -1, 0)
的一个可能原因是因为视图矩阵的旋转/缩放部分如下所示:
1 0 0
0 0 1
0 1 0
matrix
的相应部分与上述相反,当然是相同的。尝试另一个方向。