如何在Directx中使用弧形球移动物体时保持旋转中心静止?

时间:2014-12-23 19:32:03

标签: c++ visual-studio directx arcball

互联网上有一些关于在OpenGL中使用arcball的信息,但对DirectX来说并不多。我正在使用Microsoft DirectX SDK中的arcball函数版本。它通过改变鼠标移动(fDeltaX和fDeltaY)改变其平移矩阵来改变对象的位置:

D3DXMatrixTranslation( &arcBall.mTranslationDelta, -fDeltaX, fDeltaY, 0.0f );
D3DXMatrixMultiply( &arcBall.mTranslation, &arcBall.mTranslation, &arcBall.mTranslationDelta );

问题是旋转中心与物体中心相同,因此旋转中心随物体移动。如何保持旋转中心静止?

要在屏幕上绘制对象,我使用对象的中心位置创建一个世界矩阵,然后将其乘以旋转矩阵,然后乘以平移矩阵:

D3DXMatrixTranslation( (D3DXMATRIX*)&g_World_drawing, -g_vObjectCenterPtr.x, -g_vObjectCenterPtr.y,  -g_vObjectCenterPtr.z );
D3DXMatrixMultiply( (D3DXMATRIX*)&g_World_drawing, (D3DXMATRIX*)&g_World_drawing, ArcBall_GetRotationMatrix() );
D3DXMatrixMultiply( (D3DXMATRIX*)&g_World_drawing, (D3DXMATRIX*)&g_World_drawing, &arcBall.mTranslation );

然后我指定绘图的世界矩阵:

d3dDevice->SetTransform(D3DTS_WORLD, &g_World_drawing);

我是否需要一个单独的旋转中心,如果需要,我该如何使用它?或者有没有办法补偿移动物体?

我在Visual Studio 2012中创建了一个非常简单的程序来显示这个问题。我在gametutorials.com的旋转立方体教程中添加了一个弧形球,压缩文件夹,并将其here与问题描述和一些屏幕图像一起发布。

我可以通过根据鼠标移动了多少设置一个平移矩阵,然后将其乘以旋转矩阵,然后将其两个值添加到到旋转中心:

D3DXMatrixTranslation( &translationDelta, dPix->x * xfactor, dPix->y * yfactor, 0.0f );
D3DXMatrixMultiply( (D3DXMATRIX*)&translationDelta, (D3DXMATRIX*)&translationDelta, ArcBall_GetRotationMatrix(abPtr) );
g_vObjectCenterPtr->x += translationDelta._41;
g_vObjectCenterPtr->y -= translationDelta._42;

然后我必须通过改变弧形球的平移矩阵来补偿移动旋转中心:

// now compensate for moving the object so that the object remains as motionless
D3DXMatrixTranslation( &translationDelta, translationDelta._41, -translationDelta._42, 0.0f );
D3DXMatrixMultiply( (D3DXMATRIX*)&translationDelta, (D3DXMATRIX*)&translationDelta, ArcBall_GetRotationMatrix(abPtr) );

D3DXMatrixTranslation( &arcBall.mTranslationDelta, translationDelta._41, translationDelta._42, 0);
D3DXMatrixMultiply( &arcBall.mTranslation, &arcBall.mTranslation, &arcBall.mTranslationDelta );

但是,我还没弄清楚如何将物体的移动与旋转中心的相应移动相结合,以便在旋转中心保持静止时物体移动。有人知道怎么做吗?

1 个答案:

答案 0 :(得分:0)

我没有尝试过您的代码或直接在DirectX中工作,但是翻译然后旋转将始终旋转您翻译的点,而旋转然后翻译将不会(或等效地,使用包含两者的矩阵)变换)。

如果您想为此编写自己的代码,可以使用四元数NLERP。这很简单,但要做得对,有点棘手。