Hufschmid's main page
Software index

 
How can I keep the rotation center stationary with an arcball?

Are you familiar with C, DirectX, and arcballs? If so, do you know how to use the panning feature of the arcball function while keeping the center of rotation at the center of the screen? When I pan with the right mouse button, the center of rotation moves along with the objects.

The arcball shifts the position of objects by altering its translation matrix by the change in mouse movement (fDeltaX and fDeltaY):

   D3DXMatrixTranslation( &arcBall.mTranslationDelta, -fDeltaX, fDeltaY, 0.0f );
   D3DXMatrixMultiply( &arcBall.mTranslation, &arcBall.mTranslation, &arcBall.mTranslationDelta );
 
To draw objects on the screen, I create a world matrix using the object's center location, and then I multiply it by the rotation matrix, and then by the translation matrix:
 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);
 
 Then I specify that world matrix for the drawing:
   d3dDevice->SetTransform(D3DTS_WORLD, &g_World_drawing);

The problem is that the rotation center moves along with the objects. Do I need a separate rotation center, and if so, how do I incorporate that into these functions? Or is there some way to compensate for moving the objects?

I created a simple Visual Studio 2012 project to show the problem. I downloaded the source code for the Rotating Cube at gametutorials.com and added a simplified version of the arcball function that is part of the Microsoft DirectX SDK. The resulting program is small and easy to understand. I zipped up the folder and put it here:
   rotatingcube.zip   15 kb 

The screen image below shows the cube. The center of rotation is at the intersection of the four lines. Initially the center of rotation and the center of the cube is at x0 y0 z0.


 
In the image below, I show what should happen when the cube is shifted with the right mouse button. The center of rotation should remain in the center of the screen and only the cube should move.


 
 
I created the function AddTranslationDeltaTo_ObjectCenter for arcball.cpp in order to experiment with keeping the center of rotation stationary.

The following version works as it should, but only when looking at the cube in a "top view"; ie, when the view is down the Z-axis, with Y-axis up and down, X-axis left and right:

void AddTranslationDeltaTo_ObjectCenter ( D3DXVECTOR3 *vObjectCenterPtr  )
{
// Put the rotation center back to the center of the screen
vObjectCenterPtr->x -= arcBall.mTranslationDelta._41;
vObjectCenterPtr->y -= arcBall.mTranslationDelta._42;

// compensate for moving the part by moving the eye location so that the part remains motionless
D3DXMatrixTranslation( &arcBall.mTranslationDelta,
          -arcBall.mTranslationDelta._41,
          -arcBall.mTranslationDelta._42,
           0);
D3DXMatrixMultiply( &arcBall.mTranslation, &arcBall.mTranslation, &arcBall.mTranslationDelta );
}
 
When the cube is in some other orientation,  moving the mouse "upwards" or "downwards" on the screen will cause the objects to move along the  y-axis regardless of the orientation of the y-axis, and moving the mouse to the left or right will cause the objects to move along the x-axis regardless of where the X axis is pointing.

If anybody knows the solution to this problem, please email me the answer. 

I will update this page with the source code with the solution, and leave it posted as a tutorial on how to keep the rotation center stationary with an arcball. So, until you see this page change, that means I still do not have the answer.

Eric

erichuf@aol.com

23 December 2014