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

Matrix glm-将mat4分解为平移和旋转?,matrix,orientation,translation,decomposition,Matrix,Orientation,Translation,Decomposition,为了便于lerping,我需要将4x4矩阵分解为四元数和vec3。 获取四元数很简单,因为您可以将矩阵传递到构造函数中,但我找不到获取转换的方法。 肯定有办法吗?

为了便于lerping,我需要将4x4矩阵分解为四元数和vec3。 获取四元数很简单,因为您可以将矩阵传递到构造函数中,但我找不到获取转换的方法。
肯定有办法吗?

是位置向量(假设
m
glm::mat4

看起来glm 0.9.6支持矩阵分解

#包括
glm::mat4转换;//你的变换矩阵。
glm::vec3量表;
glm::四元旋转;
glm::vec3翻译;
glm::vec3偏斜;
glm::vec4透视图;
glm::分解(变换、缩放、旋转、平移、倾斜、透视);

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

#包括

要使用它:

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);
请记住,在中生成的四元数是不正确的。 它返回它的共轭体

要修复此问题,请将其添加到代码中:


rotation=glm::共轭(旋转)

我想我会发布一份2019年的更新完整答案。这是基于valmo的回答,包括Konstantinos Roditakis回答中的一些项目以及我遇到的一些附加信息

无论如何,从版本0.9.9开始,您仍然可以使用实验矩阵分解:

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

\define GLM\u ENABLE\u
接下来,您必须包括:

#包括
最后,一个使用示例:

glm::mat4转换;//你的变换矩阵。
glm::vec3量表;
glm::四元旋转;
glm::vec3翻译;
glm::vec3偏斜;
glm::vec4透视图;
glm::分解(变换、缩放、旋转、平移、倾斜、透视);
此外,康斯坦蒂诺斯·罗迪塔基斯(Konstantinos Roditakis)的回答中所述的四元数确实不正确,可以通过应用以下公式来修正:

rotation=glm::共轭(旋转);

很抱歉迟到了。实际上,在计算四元数的x、y、z分量时,必须共轭结果quat的原因是矩阵分量的减法顺序错误

是一个解释和示例代码

所以基本上在glm中,decompose()方法,matrix_decompose.inl文件:

我们有:

    orientation.x = root * (Row[1].z - Row[2].y);
    orientation.y = root * (Row[2].x - Row[0].z);
    orientation.z = root * (Row[0].y - Row[1].x);
何时应该:

    orientation.x = root * (Row[2].y - Row[1].z);
    orientation.y = root * (Row[0].z - Row[2].x);
    orientation.z = root * (Row[1].x - Row[0].y);

还有一个impl,它看起来非常接近GLM中的一个,但它是正确的。

该文档在该文档上有点过时(即使对于当前的v0.9.7),您需要包括,而不是让它工作。应该注意的是,如果您只需要翻译向量,这种方法的计算效率非常低@克里姆在下面的回答会快得多。比一堆,真的很奇怪。我认为值得解释一下为什么这样做。翻译矩阵只是一个4x4单位矩阵,其位置在第四列(第四行是
1
)。在GLM中,
mat4
vec4
的4-数组,其中每个
vec4
表示一列;数组的索引为零,因此
[3]
获取第四列。然后,
glm::vec3(…)
将其转换为vec3,丢弃第四个(未使用的)部分,并仅给出转换距离。
    orientation.x = root * (Row[2].y - Row[1].z);
    orientation.y = root * (Row[0].z - Row[2].x);
    orientation.z = root * (Row[1].x - Row[0].y);