Как сохранить центр вращения неподвижным при перемещении объектов с помощью аркбола в Directx?

В Интернете есть некоторая информация об использовании arcballs с OpenGL, но не так много для DirectX. Я использую версию функции arcball из Microsoft DirectX SDK. Он меняет положение объектов, изменяя свою матрицу перевода путем изменения движения мыши (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, заархивировал папку и опубликовал ее Вот вместе с описанием проблемы и некоторыми изображениями на экране.

Я могу переместить центр вращения сам по себе без перемещения объектов, настроив матрицу перевода в соответствии с тем, насколько сильно двигалась мышь, а затем умножив ее на матрицу вращения, а затем добавив два ее значения к центр вращения:

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

Однако я не смог понять, как совместить перемещение объектов с соответствующим движением центра вращения, чтобы объекты двигались, пока центр вращения остается неподвижным. Кто-нибудь знает, как это сделать?

0

Решение

Я не пробовал ваш код или много работал непосредственно в DirectX, но перевод и вращение всегда будут вращать точку, в которую вы переводили, тогда как вращение и последующий перевод не будут (или эквивалентно, с использованием матрицы, содержащей оба преобразования).

Если вы хотите написать свой собственный код для этого, вы можете сделать это с помощью quaternion NLERP. Это просто, но немного сложно понять это правильно.

0

Другие решения