0

Internet 上有一些关于在 OpenGL 中使用轨迹球的信息,但对于 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 上的 Rotating Cube 教程中添加了一个轨迹球,压缩了文件夹,并将它与问题描述和一些屏幕图像一起发布到这里。

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

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 );

但是,我无法弄清楚如何将对象的移动与旋转中心的相应移动相结合,以便在旋转中心保持静止的同时对象移动。有人知道怎么做这个吗?

4

1 回答 1

0

我没有尝试过您的代码或直接在 DirectX 中进行了很多工作,但是平移然后旋转将始终旋转您平移到的点,而旋转然后平移则不会(或等效地,使用包含两个变换的矩阵)。

如果您想为此编写自己的代码,可以使用四元数 NLERP 来完成。这很简单,但要正确处理它有点棘手。

于 2014-12-23T22:43:33.477 回答