平移 - 旋转 - 使用 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。