c++ - 如何在 DirectX11 中围绕其局部轴之一旋转对象

标签 c++ matrix rotation directx-11

我想绕其局部轴之一旋转对象。就我而言,Y 轴。 该对象有自己的世界矩阵,初始化如下:

XMFLOAT4X4 newInstance;

// Construct matrix
XMStoreFloat4x4( &newInstance.worldMatrix, XMMatrixScaling( scale.x, scale.y, scale.z ) *
                 XMMatrixRotationRollPitchYaw( XMConvertToRadians( rotation.x ),
                                               XMConvertToRadians( rotation.y ),
                                               XMConvertToRadians( rotation.z ) ) *
                    XMMatrixTranslation( translation.x, translation.y, translation.z ) ) ;

// Add new instance to collection
mInstanceData.push_back( newInstance );

我的最终目标是根据游戏 handle 的输入旋转我的对象。

没有“数学重”的背景,所以请耐心等待我。 我熟悉矩阵相乘(缩放 * 旋转 * 平移)时顺序的重要性。我尝试了几种方法,但都失败了。

第一种方法

// Create rotation matrix
XMMATRIX rotationMatrix = XMMatrixRotationY( XMConvertToRadians( angle ) );

// Multiply with old matrix AND store back to the old matrix
XMStoreFloat4x4( &newInstance.worldMatrix, XMLoadFloat4X4( &newInstance.worldMatrix ) * rotationMatrix );

这会导致对象绕世界 Y 轴旋转,而不是绕其本地轴旋转。

第二种方法

我想我需要找到我的本地 Y 轴。也许从我现有的世界矩阵中提取它?我发现this有人解释说的帖子 您确实可以从对象的世界矩阵中提取对象的所有局部轴。

A | 1 0 0 0 |
B | 0 1 0 0 |
C | 0 0 1 0 |
D | 0 0 0 1 |
----x y z w

Here, the first three values in row A are your local X-axis = (1,0,0)
first three values in row B are your local Y-axis = (0,1,0)
and first three values in row C are your local z-axis = (0,0,1).

所以我开始从对象世界矩阵中提取 Y 轴。

// Construct axis
XMVECTOR axis =  XMVectorSet( mInstanceData[0].worldMatrix._21, mInstanceData[0].worldMatrix._22, mInstanceData[0].worldMatrix._23, 0 );

// Create rotation matrix based on axis
XMMATRIX rotationMatrix = XMMatrixRotationAxis( axis ,XMConvertToRadians( angle) );

// Multiply with old matrix AND store back to the old matrix
XMStoreFloat4x4( &mInstanceData[0].worldMatrix, XMLoadFloat4x4( &mInstanceData[0].worldMatrix ) * rotationMatrix );

这个方法也失败了。使用 XMMatrixRotationAxis 的结果是围绕世界原点到指定 vector 的轴旋转的对象。

第三种方法

然后我想我也许可以使用与初始化矩阵相同的技术来执行旋转!这意味着我仍然需要从对象世界矩阵中提取一些当前数据。我找到了这个: enter image description here

因此,我尝试从当前世界矩阵中提取任何相关数据并构造新的缩放、旋转和平移矩阵,将它们相乘并存储到对象世界矩阵中。

// Extract scale and translation and construct new matrix
XMStoreFloat4x4( &mInstanceData[0].worldMatrix,  XMMatrixScaling( mInstanceData[0].worldMatrix._11, mInstanceData[0].worldMatrix._22, mInstanceData[0].worldMatrix._33 ) *
        XMMatrixRotationRollPitchYaw( 0.0f, XMConvertToRadians( angle ), 0.0f ) *
        XMMatrixTranslation( mInstanceData[0].worldMatrix._41, mInstanceData[0].worldMatrix._42, mInstanceData[0].worldMatrix._43 ) );

这导致该物体本身变成了难以形容的东西。

当所有事情都失败时,你会转向 stackoverlow.. 有人可以分享一些见解吗?谢谢你!

最佳答案

AFAIU,第一种方法是正确的,但是,似乎首先创建一个世界矩阵(因此每个顶点现在都在世界空间中),然后应用“围绕局部 y 轴”变换。 IMO,您应该首先将 XMMatrixRotationY( XMConvertToRadians( angle ) ); 应用于模型空间中的顶点,然后构建世界矩阵。

关于c++ - 如何在 DirectX11 中围绕其局部轴之一旋转对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36896607/

相关文章:

c++ - Dalvik虚拟机源码开发方法

c# - C++/WinRT UWP FileOpenPicker 缺失

android - 当我需要使用 scaleType 矩阵时如何在 onCreate 中将图像缩放到 imageview

r - 在有约束的情况下扩展电网(或电源组)

math - 使用四元数绕轴旋转多个点

c++ - 如何在同时使用 Intel C++ 和 CUDA C++ 的 Eclipse-nsight 中创建项目?

c++ - 为什么在比较字符串时出现错误 "no match for ' operator= =' "?

matlab - 矩阵列的逻辑运算。

c++ - OpenGL - 旋转播放器位置以面对鼠标指针

c++ - 手动旋转 vector