2 个 4x4 矩阵之间的插值
Interpolation Between 2 4x4 Matrices
对于使用 colladas 的骨骼动画,我需要在 2 个矩阵之间进行线性插值。我在某个地方看到我可以使用四元数在矩阵之间进行插值,但这只适用于旋转分量,我还需要保留变换。这是我的代码,除了翻译部分外,它是有效的:
float total = (orderedBones[i]->Animation->keyFrames[nextKeyFrame] - orderedBones[i]->Animation->keyFrames[nextKeyFrame - 1]) * 100.0;
float progress = orderedBones[i]->Animation->accumTime - orderedBones[i]->Animation->keyFrames[nextKeyFrame - 1] * 100.0;
float interpolation = progress / total;
glm::quat firstQuat = glm::quat_cast(orderedBones[i]->Animation->Matrices[nextKeyFrame - 1]);
glm::quat secondQuat = glm::quat_cast(orderedBones[i]->Animation->Matrices[nextKeyFrame]);
glm::quat finalQuat = glm::slerp(firstQuat, secondQuat, interpolation);
orderedBones[i]->Animation->interpoltaedMatrix = glm::mat4_cast(finalQuat);
有什么方法可以做到这一点吗?
我最终通过更多的网上冲浪解决了我的问题。为了将来参考,这里是如何做的。
转换组件存储在一个 4x4 矩阵中,如下所示:
r r r t
r r r t
r r r t
0 0 0 1
其中 r 是旋转分量,t 是平移分量。正因为如此,我们可以将翻译分量表示为一个向量。 2 向量可以线性插值,所以我们对这两个向量进行插值,然后在完成后将它们推回旋转矩阵。这是最终代码,但有点乱:
float total = (orderedBones[i]->Animation->keyFrames[nextKeyFrame] - orderedBones[i]->Animation->keyFrames[nextKeyFrame - 1]) * ANIMATION_MULTIPLICATION_CONST;
float progress = orderedBones[i]->Animation->accumTime - orderedBones[i]->Animation->keyFrames[nextKeyFrame - 1] * ANIMATION_MULTIPLICATION_CONST;
float interpolation = progress / total;
glm::quat firstQuat = glm::quat_cast(orderedBones[i]->Animation->Matrices[nextKeyFrame - 1]);
glm::quat secondQuat = glm::quat_cast(orderedBones[i]->Animation->Matrices[nextKeyFrame]);
glm::quat finalQuat = glm::slerp(firstQuat, secondQuat, interpolation);
orderedBones[i]->Animation->interpoltaedMatrix = glm::mat4_cast(finalQuat);
glm::vec4 transformComp1 = glm::vec4(
orderedBones[i]->Animation->Matrices[nextKeyFrame - 1][0][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame - 1][1][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame - 1][2][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame - 1][3][3]);
glm::vec4 transformComp2 = glm::vec4(
orderedBones[i]->Animation->Matrices[nextKeyFrame][0][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame][1][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame][2][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame][3][3]);
glm::vec4 finalTrans = (float)(1.0 - interpolation) * transformComp1 + transformComp2 * interpolation;
// good for now, although in future the 2 transformation components need to be interpolated
orderedBones[i]->Animation->interpoltaedMatrix[0][3] = finalTrans.x;
orderedBones[i]->Animation->interpoltaedMatrix[1][3] = finalTrans.y;
orderedBones[i]->Animation->interpoltaedMatrix[2][3] = finalTrans.z;
orderedBones[i]->Animation->interpoltaedMatrix[3][3] = finalTrans.w;
希望能回答其他人的问题:)
这个功能对我有用:
glm::mat4 interpolate(glm::mat4& _mat1, glm::mat4& _mat2, float _time)
{
glm::quat rot0 = glm::quat_cast(_mat1);
glm::quat rot1= glm::quat_cast(_mat2);
glm::quat finalRot = glm::slerp(rot0, rot1, _time);
glm::mat4 finalMat = glm::mat4_cast(finalRot);
finalMat[3] = _mat1[3] * (1 - _time) + _mat2[3] * _time;
return finalMat;
}
对于使用 colladas 的骨骼动画,我需要在 2 个矩阵之间进行线性插值。我在某个地方看到我可以使用四元数在矩阵之间进行插值,但这只适用于旋转分量,我还需要保留变换。这是我的代码,除了翻译部分外,它是有效的:
float total = (orderedBones[i]->Animation->keyFrames[nextKeyFrame] - orderedBones[i]->Animation->keyFrames[nextKeyFrame - 1]) * 100.0;
float progress = orderedBones[i]->Animation->accumTime - orderedBones[i]->Animation->keyFrames[nextKeyFrame - 1] * 100.0;
float interpolation = progress / total;
glm::quat firstQuat = glm::quat_cast(orderedBones[i]->Animation->Matrices[nextKeyFrame - 1]);
glm::quat secondQuat = glm::quat_cast(orderedBones[i]->Animation->Matrices[nextKeyFrame]);
glm::quat finalQuat = glm::slerp(firstQuat, secondQuat, interpolation);
orderedBones[i]->Animation->interpoltaedMatrix = glm::mat4_cast(finalQuat);
有什么方法可以做到这一点吗?
我最终通过更多的网上冲浪解决了我的问题。为了将来参考,这里是如何做的。
转换组件存储在一个 4x4 矩阵中,如下所示:
r r r t
r r r t
r r r t
0 0 0 1
其中 r 是旋转分量,t 是平移分量。正因为如此,我们可以将翻译分量表示为一个向量。 2 向量可以线性插值,所以我们对这两个向量进行插值,然后在完成后将它们推回旋转矩阵。这是最终代码,但有点乱:
float total = (orderedBones[i]->Animation->keyFrames[nextKeyFrame] - orderedBones[i]->Animation->keyFrames[nextKeyFrame - 1]) * ANIMATION_MULTIPLICATION_CONST;
float progress = orderedBones[i]->Animation->accumTime - orderedBones[i]->Animation->keyFrames[nextKeyFrame - 1] * ANIMATION_MULTIPLICATION_CONST;
float interpolation = progress / total;
glm::quat firstQuat = glm::quat_cast(orderedBones[i]->Animation->Matrices[nextKeyFrame - 1]);
glm::quat secondQuat = glm::quat_cast(orderedBones[i]->Animation->Matrices[nextKeyFrame]);
glm::quat finalQuat = glm::slerp(firstQuat, secondQuat, interpolation);
orderedBones[i]->Animation->interpoltaedMatrix = glm::mat4_cast(finalQuat);
glm::vec4 transformComp1 = glm::vec4(
orderedBones[i]->Animation->Matrices[nextKeyFrame - 1][0][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame - 1][1][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame - 1][2][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame - 1][3][3]);
glm::vec4 transformComp2 = glm::vec4(
orderedBones[i]->Animation->Matrices[nextKeyFrame][0][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame][1][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame][2][3],
orderedBones[i]->Animation->Matrices[nextKeyFrame][3][3]);
glm::vec4 finalTrans = (float)(1.0 - interpolation) * transformComp1 + transformComp2 * interpolation;
// good for now, although in future the 2 transformation components need to be interpolated
orderedBones[i]->Animation->interpoltaedMatrix[0][3] = finalTrans.x;
orderedBones[i]->Animation->interpoltaedMatrix[1][3] = finalTrans.y;
orderedBones[i]->Animation->interpoltaedMatrix[2][3] = finalTrans.z;
orderedBones[i]->Animation->interpoltaedMatrix[3][3] = finalTrans.w;
希望能回答其他人的问题:)
这个功能对我有用:
glm::mat4 interpolate(glm::mat4& _mat1, glm::mat4& _mat2, float _time)
{
glm::quat rot0 = glm::quat_cast(_mat1);
glm::quat rot1= glm::quat_cast(_mat2);
glm::quat finalRot = glm::slerp(rot0, rot1, _time);
glm::mat4 finalMat = glm::mat4_cast(finalRot);
finalMat[3] = _mat1[3] * (1 - _time) + _mat2[3] * _time;
return finalMat;
}