   Moving and rotating object
  Hello everybody! I am a new guy in this forum. I am studying about directx and writing like a game program using directX. My program is about moving ship. I've a problem in this part. I can make to move ship forward and backward. But when rotate my ship it not works correctly. The problem is it rotates left or right , and then it don't move along new direction. My ship moves with it's old direction. So somebody help me please. How can I write my ship to get new direction and move correctly. Please tell me some codes or the theory using for object movement. In my program this part is so hard for me.I used C++ for my program. Thank you.   
  Seems like this is an issue of local space vs world space.  Please provide more details on your implementation, it is difficult to help without knowing more about what you are doing.   ;  Thank you for reply.Yes, I think about local space and world space problem. But I've no idea about what to do. I should study more harder. I wish you could help me with this problem. Here is code about my object.Please advice me what I made wrong in my program. Thank you./////////////////////////////////////////////////////////////////////////////#include "Object.h"extern LPDIRECT3DDEVICE9 d3ddev;#pragma comment (lib, "d3d9.lib")#pragma comment (lib, "d3dx9.lib")Object::Object(void){MoveDirection = D3DXVECTOR3(0, 0, 1);objectscale = D3DXVECTOR3 (0.0f, 1.0f, 0.0f);myMesh=NULL;myMat=NULL;myTexture=NULL;numMat=NULL;}Object::~Object(void){}D3DXVECTOR3 & Object::GetMoveDirection(D3DXVECTOR3 *direction){*direction = MoveDirection;return MoveDirection;}D3DXVECTOR3 & Object::GetPosition(D3DXVECTOR3 *position){*position = Position;return Position;}VOID Object::SetPosition(float x, float y, float z){Position = D3DXVECTOR3(x, y, z);}VOID Object::Move(float spd){Position += MoveDirection;D3DXMatrixTranslation(&mymat,Position.x*spd,0.f,Position.z*spd);mat=mat*mymat;}VOID Object::Rotate(float angle){m_fYaw += angle;   D3DXVECTOR3 vec(0, 1, 0);D3DXMatrixRotationAxis(&mymat, &vec, D3DXToRadian(angle));D3DXVec3TransformNormal(&MoveDirection, &MoveDirection, &mymat);mat=mat*mymat;}void Object::Loadobject(Object* mobject,LPCWSTR filename){LPD3DXBUFFER myBuffer;    D3DXLoadMeshFromX(filename,D3DXMESH_SYSTEMMEM, d3ddev,NULL,&myBuffer,NULL,&numMat, &myMesh); D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)myBuffer-&gt;GetBufferPointer();  myMat = new D3DMATERIAL9[numMat];   myTexture=new LPDIRECT3DTEXTURE9[numMat];    for(DWORD i = 0; i &lt; numMat; i++)   {  myMat = tempMaterials.MatD3D;  myMat.Ambient = myMat.Diffuse; if(FAILED(D3DXCreateTextureFromFileA(d3ddev,(tempMaterials.pTextureFilename),&myTexture)))myTexture=NULL;    }D3DXMatrixIdentity(&mat);D3DXMatrixIdentity(&mymat);    return; }void Object::Drawobject(){D3DXMATRIX matmy;d3ddev-&gt;GetTransform(D3DTS_WORLD, &matmy);d3ddev-&gt;SetTransform(D3DTS_WORLD, &mat); for(DWORD i = 0; i &lt; numMat; i++)   {   d3ddev-&gt;SetMaterial(&myMat);  if(myTexture!=NULL)d3ddev-&gt;SetTexture(0,myTexture);   myMesh-&gt;DrawSubset(i);   }  d3ddev-&gt;SetTransform(D3DTS_WORLD, &matmy);}void Object::Scale(float size){D3DXMATRIX mat1;objectscale.x=size,objectscale.y=size,objectscale.z=size;D3DXMatrixScaling(&mat1,objectscale.x,objectscale.y,objectscale.z); mat=mat*mat1;}void Object::Cleand3d(){myMesh-&gt;Release();}///////////////////////////////////////////////////////////////////////////////------------------------------------------------------------------------------ void objectmovement() { speed=0.0005f; course=0.5f; if (dinput.keystate[DIK_UP]){ship.Move(speed);}if (dinput.keystate[DIK_DOWN]){ship.Move(-speed);}if (dinput.keystate[DIK_LEFT]){ship.Rotate(-course);}if (dinput.keystate[DIK_RIGHT]){ship.Rotate(course);} }-------------------------------------------------------------------------------I think you mean like this. If it's not i'll edit again.[Edited by - tnaz on April 21, 2010 5:03:47 PM];  Can you repost your code using [ source ] tags? (With no spaces...)   ;  I don't see anything wrong with your code, I think it should work correctly.  Unless the D3DXMatrixTranslation function does not completely overwrite the input matrix, in which case you would probably not get the results you want.Use the debugger to step through the code and check the values of mat and MoveDirection to make sure they are what you expect all the time.   ;  Thank you for your reply. I think the way I used was not correctly. I think using same matrix (mat) in Translation and Rotation makes  me trouble. It seems hard to change local space to world space.So if you know some better methods to make  correct movement or tutorials , please let me know. Thank you.   ;  If you are trying to make something move in 2D and you are wanting it to move in the direction that it is facing try researching the topic "Polar Coordinate Systems" this uses cosine and sine to calculate a movement vector that can then be applied to the object that you wish to move.   ;  Thanks for your advice. But I m trying to make object movement in 3d. :) I hope somebody in here can help and guide me. And I want to know one thing. Can I write my object movement like Camera movement? I've done with Camera. It works nicely . If it can be used, I should make a new start for my program.   ;  Well of course not, your camera is not an object is it? it doesn't have a position or an orientation does it?What's that? It does have a position, and an orientation?In case you can't detect the sarcasm it the above, read again until it comes through. Any object in your world, whether camera, object, car, or character will have the same properties, position and orientation. So if you can move your camera, you can move your object. lets look at what's happening in your code:VOID Object::Move(float spd){Position += MoveDirection;D3DXMatrixTranslation(&mymat,Position.x*spd,0.f,Position.z*spd);mat=mat*mymat;}what is mat and where does it come from? same for mymat? is one of these  the objects world matrix?VOID Object::Rotate(float angle){m_fYaw += angle;   D3DXVECTOR3 vec(0, 1, 0);D3DXMatrixRotationAxis(&mymat, &vec, D3DXToRadian(angle));D3DXVec3TransformNormal(&MoveDirection, &MoveDirection, &mymat);mat=mat*mymat;}If you have moved from origin(translated) and now rotate, what is happening to mat? remember that the order transformations are done in can have a drastic effect on what the final matrix looks like.Try:VOID Object::Move(float spd) {   // when object is moved, move it   Position += MoveDirection * spd;}VOID Object::Rotate(float angle) {   D3DXMATRIX mat;D3DXVECTOR3 vec(0, 1, 0);    D3DXMatrixRotationAxis(&mat, &vec, D3DXToRadian(angle));// adjust the yaw scalar   m_fYaw += angle;    // rotate the move vector   D3DXVec3TransformNormal(&MoveDirection, &MoveDirection, &mat);}VOID Object::Scale(float scale) {   // NOTE: since you scale the same on each axis, use a float for myscale   myscale *= scale;}  // NEW FUNCTIONVOID Object::GetWorldTransform(D3DXMATRIX* mat);   D3DXMatrix scaling, rotation, translation;   D3DXVECTOR3 vec(0, 1, 0);   // create Scaling Matrix   D3DXMatrixScaling(&scaling, myscale,myscale,myscale);   // create the rotation matrix   D3DXMatrixRotationAxis(&rotation, &vec, D3DXToRadian(m_fYaw));   // create the translation matrix   D3DXMatrixTranslation(&translation,Position.x,Position.y,Position.z); // output the final matrix   mat = scaling * rotation * translation;}   // why ::DrawObject, if the object only draws itselfVOID Object::Draw() {   D3DXMATRIX temp, mymat;   GetWorldTransform(&mymat); // NEW function which creates scale rotation and// translation each time it is called.   d3ddev->GetTransform(D3DTS_WORLD, &temp); // save current world to temp   d3ddev->SetTransform(D3DTS_WORLD, mymat); // assign mymat to world    for(DWORD i = 0; i < numMat; i++)   {  d3ddev->SetMaterial(&myMat);    if(myTexture!=NULL)d3ddev->SetTexture(0,myTexture);  myMesh->DrawSubset(i);  }d3ddev->SetTransform(D3DTS_WORLD, &temp); // reset world to previous}I Realize that there are always better ways, but that should work without a hitch, read through it as it will require some changes to your existing code.   ;  Thanks Burnt_Fyr for your help. I tried to write as your code and I changed my existing codes a little bit. Now,My object moves as its direction. But I still have a problem, which is something wrong in rotation. When it rotates, its local space does not change. I mean it rotates from the original points (position) of the object. http://img52.imageshack.us/img52/2742/rotqk.png  <- Here is the picture of my problem (B). How can I make to rotate my object correctly? I really want to know what I made wrong in this program.Here are the new codes I'd changed.#include "Object.h"extern LPDIRECT3DDEVICE9 d3ddev;#pragma comment (lib, "d3d9.lib")#pragma comment (lib, "d3dx9.lib")Object::Object(void){MoveDirection = D3DXVECTOR3(0, 0, 1);objectscale = D3DXVECTOR3 (0.0f, 1.0f, 0.0f);myMesh=NULL;myMat=NULL;myTexture=NULL;numMat=NULL;}Object::~Object(void){}D3DXVECTOR3 & Object::GetMoveDirection(D3DXVECTOR3 *direction){*direction = MoveDirection;return MoveDirection;}D3DXVECTOR3 & Object::GetPosition(D3DXVECTOR3 *position){*position = Position;return Position;}VOID Object::SetPosition(float x, float y, float z){D3DXMATRIX pos;D3DXMatrixTranslation(&pos,x,y,z);d3ddev->SetTransform(D3DTS_WORLD,&pos);}VOID Object::Move(float spd){Position += MoveDirection;vel+=spd*0.05f;}VOID Object::Rotate(float angle){m_fYaw+=angle;}VOID Object::GetWorldTransform(D3DXMATRIX *mat){D3DXVECTOR3 vec(0.f,1.f,0.f);D3DXMatrixScaling(&scale,objectscale.x,objectscale.y,objectscale.z); D3DXMatrixTranslation(&move,Position.x*vel,0.f,Position.z*vel);D3DXMatrixRotationAxis(&rotate,&vec,D3DXToRadian(m_fYaw));*mat=scale*move*rotate;}void Object::Loadobject(Object* mobject,LPCWSTR filename){LPD3DXBUFFER myBuffer;    D3DXLoadMeshFromX(filename,D3DXMESH_SYSTEMMEM, d3ddev,NULL,&myBuffer,NULL,&numMat, &myMesh); D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)myBuffer->GetBufferPointer();  myMat = new D3DMATERIAL9[numMat];   myTexture=new LPDIRECT3DTEXTURE9[numMat];    for(DWORD i = 0; i < numMat; i++)   {  myMat = tempMaterials.MatD3D;  myMat.Ambient = myMat.Diffuse; if(FAILED(D3DXCreateTextureFromFileA(d3ddev,(tempMaterials.pTextureFilename),&myTexture)))myTexture=NULL;    }D3DXMatrixIdentity(&Worldmatrix);    return; }void Object::Drawobject(){D3DXMATRIX temp;SetPosition(0.f,-2.f,0.f);GetWorldTransform(&Worldmatrix);d3ddev->GetTransform(D3DTS_WORLD, &temp);d3ddev->SetTransform(D3DTS_WORLD, &Worldmatrix); for(DWORD i = 0; i < numMat; i++)   {   d3ddev->SetMaterial(&myMat);  if(myTexture!=NULL)d3ddev->SetTexture(0,myTexture);   myMesh->DrawSubset(i);   }  d3ddev->SetTransform(D3DTS_WORLD, &temp);}void Object::Scale(float size){objectscale.x=size,objectscale.y=size,objectscale.z=size;}void Object::Cleand3d(){myMesh->Release();}For more details, here is archive of my original source codes.Quote:http://www.mediafire.com/?kqmzgdqyjwjI've tried many times and it doesn't work correctly yet. I really need some help and advices for  this step. Thank you.   