平移 - 旋转 - 使用 XMMATRIX 向后平移
Translate - Rotate - Translate Back using XMMATRIX
如果我只知道一个对象的世界矩阵(因为它的 x/y/z 位置未被跟踪,这会更容易),我该如何围绕它的中心旋转它?
如果我知道位置,它会像这样简单:
XMMATRIX world = pMissile->GetWorldMatrix();
XMMATRIX matrixTranslation = XMMatrixTranslationFromVector(pMissile->GetPosition());
XMMATRIX matrixInvTranslations = XMMatrixInverse(nullptr, matrixTranslation);
float rotationAmount = (60 * XMConvertToRadians((float)fElapsedTime / 2.0f));
XMMATRIX missileWorld = world *
matrixInvTranslations
* XMMatrixRotationX(rotationAmount)
* XMMatrixRotationY(rotationAmount)
* XMMatrixRotationZ(rotationAmount)
* matrixTranslation;
pMissile->SetWorldMatrix(missileWorld);
不幸的是,由于我不知道职位,我不知道该怎么做。基本上我需要能够从世界矩阵中获得 "Translate back to the origin" 。在我开始从矩阵中提取元素之前,必须有一个 DirectX 或 DirectXTK 函数来执行此操作,不是吗?
目前我正在分解矩阵得到它:
XMVECTOR vectorTranslation, vectorScale, rotationQuat;
XMMatrixDecompose(&vectorScale, &rotationQuat, &vectorTranslation, world)
如果那是 right/best 方式,请告诉我!
有点切线,正如你所看到的,在我将它翻译到原点进行旋转之前,我使用了对 "move it back" 的翻译的逆向。很多样本都跳过了这一点 - 我是否遗漏了一些你不需要在最后翻译回来的东西?
XMMatrixDecompose
是获取任意变换矩阵元素的正确、完全通用的方法。计算是昂贵的,所以大多数人对矩阵中的内容做出假设——因为他们在所有点上都控制着它。例如,避免非均匀缩放确实可以简化事情。
许多游戏独家使用旋转和平移,避免缩放或至少避免非均匀缩放。您可以通过转置上面的 3x3 元素然后取反最后一行的 x、y 和 z 元素来快速计算此类矩阵的逆。
如果您知道您的矩阵只包含旋转和平移,从不包含缩放,那么旋转矩阵只是上面的 3x3 元素。只要你的矩阵是齐次的(即最后一列是 [0 0 0 1]
),你可以只读出最后一行的翻译:world.r[3]
应该是 (x, y, z, 1)
.
如果您是 DirectXMath 的新手,您应该考虑使用 SimpleMath wrapper in the DirectX Tool Kit。它更自动地处理了对齐的复杂性,并包括像 Matrix::Translation
这样方便的助手,它只提取等效的 world.r[3]
x、y 和 z。
如果我只知道一个对象的世界矩阵(因为它的 x/y/z 位置未被跟踪,这会更容易),我该如何围绕它的中心旋转它?
如果我知道位置,它会像这样简单:
XMMATRIX world = pMissile->GetWorldMatrix();
XMMATRIX matrixTranslation = XMMatrixTranslationFromVector(pMissile->GetPosition());
XMMATRIX matrixInvTranslations = XMMatrixInverse(nullptr, matrixTranslation);
float rotationAmount = (60 * XMConvertToRadians((float)fElapsedTime / 2.0f));
XMMATRIX missileWorld = world *
matrixInvTranslations
* XMMatrixRotationX(rotationAmount)
* XMMatrixRotationY(rotationAmount)
* XMMatrixRotationZ(rotationAmount)
* matrixTranslation;
pMissile->SetWorldMatrix(missileWorld);
不幸的是,由于我不知道职位,我不知道该怎么做。基本上我需要能够从世界矩阵中获得 "Translate back to the origin" 。在我开始从矩阵中提取元素之前,必须有一个 DirectX 或 DirectXTK 函数来执行此操作,不是吗?
目前我正在分解矩阵得到它:
XMVECTOR vectorTranslation, vectorScale, rotationQuat;
XMMatrixDecompose(&vectorScale, &rotationQuat, &vectorTranslation, world)
如果那是 right/best 方式,请告诉我!
有点切线,正如你所看到的,在我将它翻译到原点进行旋转之前,我使用了对 "move it back" 的翻译的逆向。很多样本都跳过了这一点 - 我是否遗漏了一些你不需要在最后翻译回来的东西?
XMMatrixDecompose
是获取任意变换矩阵元素的正确、完全通用的方法。计算是昂贵的,所以大多数人对矩阵中的内容做出假设——因为他们在所有点上都控制着它。例如,避免非均匀缩放确实可以简化事情。
许多游戏独家使用旋转和平移,避免缩放或至少避免非均匀缩放。您可以通过转置上面的 3x3 元素然后取反最后一行的 x、y 和 z 元素来快速计算此类矩阵的逆。
如果您知道您的矩阵只包含旋转和平移,从不包含缩放,那么旋转矩阵只是上面的 3x3 元素。只要你的矩阵是齐次的(即最后一列是 [0 0 0 1]
),你可以只读出最后一行的翻译:world.r[3]
应该是 (x, y, z, 1)
.
如果您是 DirectXMath 的新手,您应该考虑使用 SimpleMath wrapper in the DirectX Tool Kit。它更自动地处理了对齐的复杂性,并包括像 Matrix::Translation
这样方便的助手,它只提取等效的 world.r[3]
x、y 和 z。