Rotate and then translate

Started by
3 comments, last by Skeleton_V@T 18 years, 3 months ago
Hello, I'm a beginner. I have a problem about Matrix. I want to move and rotate a object e.g. car. How can i translate it in right direction after it rotated. I have read the post before which is asking the same problem. The answer is translate the object back to (0,0,0), then rotate it, then translate back to before coordinates. D3DXMATRIX matIdentity; D3DXMatrixIdentity(matIdentity); // set object back to (0,0,0) m_pD3DDevice->SetTransform(D3DTS_WORLD, &matIdentity); // rotate oject D3DXMatrixMultiply(&matWorld, &matRotation, &matScale); m_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld); // set oject before translation D3DXMatrixMultiply(&matWorld, &matTranslation, &matRotation); m_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld); The result is the car still rotate in world coordinates, not local coordinates. Is that my concept totally wrong? Pls help...Thanks for reading~
Advertisement
You don't need to SetTransform () each time you modify the matrix. The idea is that from the Identity matrix, you multiply with Scale and Translation matrix, then Rotate it to the car's postition. The code will look like this:
D3DXMATRIX matWorld ;D3DXMatrixIdentity(matWorld);//Scale, Translate, then Rotate objectD3DXMatrixMultiply (&matWorld, &matScale, &matTranslation) ;D3DXMatrixMultiply (&matWorld, &matWorld, &matRotation) ;//Set DirectX's World matrixm_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);


You may follow this link if there're any matrix problems remain.
--> The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones <--
thank you...Skeleton_V@T

I have read andypike's tutorial which is very good, and i got more understand about matrix...

And i implement the code...

// Save Translation
D3DXMATRIX matTemp = matTranslation;

// Set to (0,0,0)
D3DXMATRIX matInverse;
D3DXMatrixInverse(&matInverse, NULL, &matTranslation);
D3DXMatrixMultiply(&matWorld, &matTranslation, &matInverse);

// rotate object and then restore Translation
D3DXMatrixMultiply(&matWorld, &matWorld, &matRotation);
D3DXMatrixMultiply(&matWorld, &matTemp, &matWorld );

But now i am facing the problem is the car will rotate at world coordinates(0,0,0) when it's not at the world coordinates(0,0,0)...

http://hk.geocities.com/ktfsince1981/pic.jpg

please Help again.
Normally one first scales the model (if needed), then rotates it into the correct orientation, then translates it to the correct position. This actually means to scale about the world center, and to rotate around the world center. If you e.g. first translate and then rotate, you simultanously do a translation (on an arc) with the rotation, what isn't what you want normally.

Your model is (hopefully) defined in its own local co-ordinate system. So you don't need to do the inverse translation I've seen from your code snippet. Instead, set-up a fresh matrix from the car's parameters, and set the transform to it:
D3DXMATRIX matrix, orientation;D3DXMatrixRotateY(&orientation, car->heading); // assuming you need heading onlyD3DXMatrixTranslation(&matrix, car->location.x, car->location.y, car->location.z);D3DXMatrixMultiply(&matrix, &orientation, &matrix) ;m_pD3DDevice->SetTransform(D3DTS_WORLD, &matrix);

Say, the origin of your model is left at the world's origin for rotation, and is translated after that to the target position.

EDIT: If you look at the code snippet above, you'll see this scheme (look especially at the MatrixMultiply):
M := R * T
where M denotes the resulting transformation matrix, R denotes the rotation matrix, and T denotes the translation matrix. D3D applies the transformation so that a new vertex position is computed by
v' := v * M = v * R * T
This could be read as follows: First R ist applied, then T is applied. Exactly what normally is wanted.
[Edit]: I noticed that, the code below is for Model View matrix. Yours is World matrix, so the inverse is correct.

Quote:// Set to (0,0,0)
D3DXMATRIX matInverse;
D3DXMatrixInverse(&matInverse, NULL, &matTranslation);
D3DXMatrixMultiply(&matWorld, &matTranslation, &matInverse);

When you perform a multiplication of a matrix with it's inverse, the result will be an Identity matrix, so matTranslation * matInverse (of matTranslation before) = I. This is equivalent to:
D3DXMATRIX matWorld ;D3DXMatrixIdentity(matWorld);


For Model View matrix:
  • If you rotate the world coordinate then translate along that rotated coordinate, you will have an object rotates around the origin.
  • If you translate the world coordinate then rotate around the translated coordinate, you will have an object rotates around the new translated position.

    Your code does the latter correctly, translate then rotate. What happens when you reverse the code like this, did the car rotates correctly ?:
    D3DXMATRIX matWorld ;D3DXMatrixIdentity(matWorld);// rotate object and then restore TranslationD3DXMatrixMultiply(&matWorld, &matWorld, &matRotation);D3DXMatrixMultiply(&matWorld, &matTranslation, &matWorld );
  • --> The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones <--

    This topic is closed to new replies.

    Advertisement