为了进行lerp,我需要将4x4矩阵分解成四元数和vec3。取四元数很简单,只需将矩阵传入构造函数即可,但我找不到获取平移的方法。肯定有办法吧?
为了进行lerp,我需要将4x4矩阵分解成四元数和vec3。取四元数很简单,只需将矩阵传入构造函数即可,但我找不到获取平移的方法。肯定有办法吧?
glm::vec3(m[3])
是位置向量(假设 m
是 glm::mat4
)
看起来glm 0.9.6支持矩阵分解http://glm.g-truc.net/0.9.6/api/a00204.html
#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);
在版本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);
请记住,得到的四元数不正确。
它返回的是它的共轭!
要解决这个问题,请将以下代码添加到您的代码中:
rotation=glm::conjugate(rotation);
我想我会发布一个2019年的更新和完整答案。应该给予信用,这是基于valmo的答案,包括Konstantinos Roditakis的一些项目以及我遇到的一些额外信息。
无论如何,在版本0.9.9中,您仍然可以使用实验性矩阵分解:https://glm.g-truc.net/0.9.9/api/a00518.html
首先,我要添加的部分是因为我没有在其他地方看到它,除非您在下面的include之前定义以下内容,否则将出现错误:
#define GLM_ENABLE_EXPERIMENTAL
#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);
rotation = glm::conjugate(rotation);
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);
}
void decomposeMtx(const glm::mat4& m, glm::vec3& pos, glm::quat& rot)
{
pos = m[3];
rot = glm::quat_cast(m);
}
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);
同时查看此处的实现非常接近于GLM中发现的那个,但是这是正确的实现。
mat4
是一个4个vec4
的数组,每个vec4
代表一列;由于数组是从零开始索引的,所以[3]
可以获取到第四列。然后,glm::vec3(...)
将其转换为一个vec3
,丢弃第四个(未使用)部分,并给出了移动距离。 - anon