如何在DirectX11中围绕其本地轴之一旋转对象

时间:2016-04-27 17:16:37

标签: 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 );

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

有“数学沉重”的背景,所以请耐心等待。 我很熟悉乘法矩阵时的顺序的重要性(Scale * Rotation * Translation)。我尝试了几种方法,但都失败了。

第一种方法

// 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

     

这里,A行的前三个值是您的局部X轴=(1,0,0)
  B行中的前三个值是您的局部Y轴=(0,1,0)
  行C中的前三个值是本地z轴=(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的结果是旋转的对象和从世界原点到指定向量的轴。

第3种方法

然后我认为我可以使用与初始化矩阵相同的技术来执行旋转!这意味着我仍然需要从对象世界矩阵中提取一些当前数据。我找到了这个: 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 ..那里的任何人有一些洞察力分享?谢谢!

1 个答案:

答案 0 :(得分:1)

AFAIU,第一种方法是正确的,但是,似乎首先你创建一个世界矩阵(因此你的每个顶点现在都在世界空间中),然后你应用'around-local-y-axis'转换。 IMO,您应首先将 XMMatrixRotationY(XMConvertToRadians(angle)); 应用于模型空间中的顶点,然后构建World Matrix。