Translate & Rotate a 3D model

Started by
7 comments, last by jo_birdi 16 years, 10 months ago
Hi there, I'm new to DirectX and this forum. Am having trouble with transformation of a 3D model. I have this 3D model placed at world origin, and the camera looks directly at the origin. The user can translate the object in +X or -X and +Y or -Y directions. If the user rotates the object (clockwise or anti-clockwise about the Z-aixs), then it should revolve around the world origin, using its translated position as the radius. But if the user translates the object again, it should move in the vertical or horizontal direction (along +X or -X and +Y or -Y axes). The problem is that, when i translate after rotation, the translation seems to happen along the rotated X and Y axes. It is not a vertical or horizontal translation anymore. How can I fix this? I tried translating with the previous value, rotation, and then translating by the new value, but the same effect is seen. If anyone can make sense out of what I'm trying to say here, PLEASE HELP!!! Thanks in advance!
Advertisement
Instead of just plain translating, you need to rotate your translation through the inverse of the models rotation first. Translate with the result.

I think that should work...
Hey RabidDog,

Thanks for your reply!
But I dont understand it!

Let me explain my problem with an example:
Say there is this model at the world origin. (0, 0)
Now I translate it by 10 units along the x-axis. (10, 0)
Then I rotate it in the anti-clockwise direction by some angle. (9, 5)
Now if I translate again along the X-axis by 3 units, the position should be (12, 5).
And if I rotate it again in the anti-clockwise direction , it has to rotate with the effective radius from the origin which is 13, so let's say the object moves to (10, 7).
And if I again translate it by 5 units in the X-direction, the position should be (15, 7).
And so on...

Basically, the translation must always be horizontal/vertical, but the object must rotate about the origin(along the Z-axis) using the effective radius from the origin.

Does your solution handle this problem?
If it does, then can you please explain it to me?
The way I do this is to store rotations in a local matrix for the mesh, and multiply that by the world, view, and projection matrices for rendering.
Try first rotating in the opposite direction, then translate and then rotate in the right direction. If this still doesn't work, post the code that does the transformations (maybe you're setting up/multiplying the matrices incorrectly).
Hey there,

Have tried the approaches sent by you, but it's not working, maybe because I'm not able to code it the right way.

This is the code that I've written:

D3DXMATRIXA16 matWorld,matScale;
D3DXMatrixIdentity( &matWorld );
D3DXMATRIX matRotate,matRotateX,matRotateY,matTranslate;

//This is quartenion rotation
//This sets the default X,Y,Z rotation
D3DXMatrixMultiply (&matWorld, &matWorld,
&d3dRotationMatrix);

//This is orbit
D3DXMatrixRotationX(&matRotateX, fOrbitY );
D3DXMatrixRotationY(&matRotateY, fOrbitX );
D3DXMatrixMultiply (&matWorld, &matWorld, &matRotateX);
D3DXMatrixMultiply (&matWorld, &matWorld, &matRotateY);

//If rotate has been called, then get the effective pan
// and pan before rotating the object
if (bRotateMessage)
{
float fEffectiveX, fEffectiveY;
float fRadius;

if ( FloatEqual(fOriginalPanX, 0.0f)
&& FloatEqual(fOriginalPanY, 0.0f) )
{
// Translate by the additional pan
fEffectiveX = fAdditionalPanX;
fEffectiveY = fAdditionalPanY;
}
else
{
fRadius = sqrt( (fOriginalPanX * fOriginalPanX)
+ (fOriginalPanY * fOriginalPanY) );

// Rotate the original pan by the given angle
fEffectiveX = fRadius * cos(fRotateAngle);
fEffectiveY = fRadius * sin(fRotateAngle);

// Translate by the additional pan
fEffectiveX += fAdditionalPanX;
fEffectiveY += fAdditionalPanY;
}

fOriginalPanX = fEffectiveX;
fOriginalPanY = fEffectiveY;

D3DXMatrixTranslation(&matTranslate,
fOriginalPanX,
fOriginalPanY, 0.0f);
D3DXMatrixMultiply (&matWorld, &matWorld, &matTranslate);

// Reset the additional pan value
fAdditionalPanX = 0;
fAdditionalPanY = 0;

bRotateMessage = FALSE ;
}

//This is rotation about Z axis
D3DXMatrixRotationZ( &matRotate, fRotateAngle );
D3DXMatrixMultiply (&matWorld, &matWorld, &matRotate);

//3D Object corners initialization
FindSampleRange(matWorld);

//Set the View Matrix
D3DXMATRIXA16 matView;
D3DXVECTOR3 vFromPt = D3DXVECTOR3( 0.0f, 0.0f, -3.0f );
D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );

D3DXMatrixLookAtLH( &matView, &vFromPt, &vLookatPt, &vUpVec );

// If NavigatePan has been called, then do the pan in view coords
// using the additional pan values
if (bPanMessage)
{
D3DXMatrixTranslation(&matTranslate,
-fAdditionalPanX,
fAdditionalPanY, 0.0f);
D3DXMatrixMultiply (&matView, &matView, &matTranslate);

m_bPanMessage = FALSE;
}

//This is Zoom
D3DXMatrixScaling( &matScale, m_fScale, m_fScale, m_fScale);
D3DXMatrixMultiply( &matView, &matView, &matScale );

m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );



!!! SOS !!!
What is d3dRotationMatrix? what do you initialize it to?
Your code also rotates around the X and Y axes, which you didn't mention. Maybe try to remove that temporarily and just rotate around Z.

EDIT: Deleted the code I posted, it wasn't working.

[Edited by - Gage64 on June 14, 2007 2:56:15 AM]
Like Gage64 said - I'm curious about that initial rotation matrix(because if there are any initial rotations before the first translation - translations will occur along the first rotation). If I understand what you're trying to do correctly, I'd translate first, then add my rotation matrix to it and keep an accumulative matrix to build apon the results of each prior operation. If you translate, then rotate - it should rotate about the origin automatically keeping the it's new distance from the origin into account.
That way you could translate to say 10,4 and rotate around the origin from position, and then add another translation matrix to offset yet again, and then simply rotate by whatever desired angle to rotate around the origin from its new location.
If I understand correctly, I'd imagine that should work.
Hopefully that was helpful. Good luck! :)
Boy am I glad to get so many replies! :)

The initial rotation was done so that the model's front always faces the user.
But that's ok. Even when I remove that rotation, it doesn't make any difference :(

I have actually tried to use both the world and view transforms.
Until the user clicks on rotate, all the translate values will be put in additionalPan, and used to move the camera in the opposite direction.
When the user clicks on rotate, the additional pan is transferred to original pan, and then the object is translated and rotated using world transforms. And the camera is moved back by the additionalPan, whose value is then reset.

In case if I dont use the world and view transforms, after rotating the object, the translate will appear to happen along the rotated X-Y axes (diagonal to the screen).

I really dont see how to achieve the Z-axis rotation while having a horizontal/vertical translate. It's just not working... Boo hoo...

This topic is closed to new replies.

Advertisement