glm - 将mat4分解为平移和旋转?

Sil*_*lan 18 translation matrix decomposition orientation

出于目的,我需要将4x4矩阵分解为四元数和vec3.抓取四元数很简单,因为你可以将矩阵传递给构造函数,但我找不到抓取翻译的方法.肯定有办法吗?

ker*_*rim 21

glm::vec3(m[3])是位置向量(假设mglm::mat4)

  • 我认为值得解释_为什么_这是有效的。转换矩阵只是一个 4x4 单位矩阵,其位置在第四列(第四行是“1”)。在 GLM 中,一个 `mat4` 是一个 4-array 的 `vec4`,其中每个 `vec4` 代表一列;数组是零索引的,所以 `[3]` 得到第四列。然后 `glm::vec3(...)` 将其转换为 vec3,丢弃第四个(未使用的)部分,只给你平移距离。 (12认同)

val*_*lmo 18

貌似glm 0.9.6支持矩阵分解 http://glm.g-truc.net/0.9.6/api/a00204.html

glm::mat4 transformation; // your transformation matrix.
glm::vec3 scale;
glm::quat rotation;
glm::vec3 translation;
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(transformation, scale, rotation, translation, skew, perspective);
Run Code Online (Sandbox Code Playgroud)

  • 该文档有点过时(即使对于当前的 v0.9.7),您需要包含 <glm/gtx/matrix_decompose.hpp> 而不是 <glm/gtx/decomposition.hpp> 才能使其工作。 (4认同)

Kon*_*kis 11

在版本glm-0.9.8.1,您必须包括:

#include <glm/gtx/matrix_decompose.hpp>

要使用它:

glm::mat4 transformation; // your transformation matrix.
glm::vec3 scale;
glm::quat rotation;
glm::vec3 translation;
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(transformation, scale, rotation, translation, skew,perspective);
Run Code Online (Sandbox Code Playgroud)

请记住,生成的四元数不正确.它返回它的共轭!

要解决此问题,请将此添加到您的代码:

rotation=glm::conjugate(rotation);

  • 相信一堆,真的很奇怪的API (2认同)

Tra*_*man 9

我想我会发布 2019 年更新和完整的答案。应该归功于它,这是基于 valmo 的答案,包括 Konstantinos Roditakis 的答案中的一些项目以及我遇到的一些其他信息。

无论如何,从 0.9.9 版本开始,您仍然可以使用实验矩阵分解:https : //glm.g-truc.net/0.9.9/api/a00518.html

首先,我要添加的部分是因为我在其他任何地方都看不到它,除非您在下面的包含之前定义以下内容,否则您将收到错误消息:

#define GLM_ENABLE_EXPERIMENTAL
Run Code Online (Sandbox Code Playgroud)

接下来,您必须包括:

#include <glm/gtx/matrix_decompose.hpp>
Run Code Online (Sandbox Code Playgroud)

最后,一个使用示例:

glm::mat4 transformation; // your transformation matrix.
glm::vec3 scale;
glm::quat rotation;
glm::vec3 translation;
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(transformation, scale, rotation, translation, skew,perspective);
Run Code Online (Sandbox Code Playgroud)

此外,正如 Konstantinos Roditakis 的回答中所述,四元数确实不正确,可以通过应用以下内容来修复:

rotation = glm::conjugate(rotation);
Run Code Online (Sandbox Code Playgroud)


tuk*_*ket 7

我制作了自己的分解函数,不需要“倾斜”和“透视”组件。

void decomposeMtx(const glm::mat4& m, glm::vec3& pos, glm::quat& rot, glm::vec3& scale)
{
    pos = m[3];
    for(int i = 0; i < 3; i++)
        scale[i] = glm::length(vec3(m[i]));
    const glm::mat3 rotMtx(
        glm::vec3(m[0]) / scale[0],
        glm::vec3(m[1]) / scale[1],
        glm::vec3(m[2]) / scale[2]);
    rot = glm::quat_cast(rotMtx);
}
Run Code Online (Sandbox Code Playgroud)

如果你也不需要缩放,可以进一步简化:

void decomposeMtx(const glm::mat4& m, glm::vec3& pos, glm::quat& rot)
{
    pos = m[3];
    rot = glm::quat_cast(m);
}
Run Code Online (Sandbox Code Playgroud)