Skip to main content
gamedev.net
🔒 Locked

Car movement

Started by NucleA Apr 26, 2011 at 12:53 PM 11 replies 3k views
Original Post
NucleA
NucleA
So, basically for moving a car, here is part of my coding:



D3DXMATRIX worldMatrix;
D3DXMatrixIdentity(&worldMatrix);

D3DXMatrixTranslation(&worldMatrix, 0, 0, tz);

D3DXMATRIX tempMatrix;

D3DXMatrixRotationY(&tempMatrix, ry);
D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &tempMatrix);

d3d_dev->SetTransform(D3DTS_WORLD, &worldMatrix);


Note: tz is a variable which value increases when up arrow key is pressed and decreases when down arrow key is pressed. Same for ry, when left arrow key is pressed, its value decreases and when right arrow key is pressed its value increases.

The Problem: The car is always rotated around the origin, which makes the movement unrealistic. So, if the car is like far away from the origin, it is not rotated around itself but around the origin.

I have tried with D3DXMatrixRotationAxis() function but with no success..

Another thing, if i do the rotation first and then the translation, the car rotate around itself anywhere it is, even far from the origin. BUT, the translation of the car is messed up!

Any1 can help please?
Zakwayda
Zakwayda
This:


Another thing, if i do the rotation first and then the translation, the car rotate around itself anywhere it is, even far from the origin.

Is what you want. However, you'll also need to change this:

D3DXMatrixTranslation(&worldMatrix, 0, 0, tz);
Specifically, you'll need to track and update the car's position in world space, and then submit the car's world-space position in the above line of code.
NucleA
NucleA
@jyk, another problem crops up with the translation as i said..I can't do both the translation and the rotation without any problem.
Juliean
Juliean
I can't do both the translation and the rotation without any problem. [/quote]

As you said, the car is always rotated around its origin. You can't change this behavior, you have to change the order to rotation->translation, this will rotate the car in the origin (=rotation around itself) and then translate it to wherever you want.
NucleA
NucleA
Rotation First, then Translation:

Problem: Car rotation OK But when i press up or down, the car will NOT move in the direction it is facing.

Translation First, then Rotation:

Problem:
When pressing Up or down, the car will move according to the direction it is facing, but the when pressing right/left, the rotation will be around the origin.

I don't know if you guys get my point, i will try to upload a video on youtube if i can to show you the problem!
Zakwayda
Zakwayda

I don't know if you guys get my point

We understand what you're saying :) As I said above though, you'll need to apply the transforms in the order rotation->translation, and track and update the world position of the object in world space (which you don't appear to be doing currently).
Juliean
Juliean
Yes I get it. Well I was facing the same problem at first. I'm not so sure how I solved it, but does you code for translation/rotation looks something like this:

void CPrimitive::SetWorldTransformation(D3DXVECTOR3 Position, D3DXVECTOR3 Rotation, D3DXVECTOR3 Scale)
{
D3DXMATRIX WorldMatrix, RotationMatrixX, RotationMatrixY, RotationMatrixZ, TranslationMatrix, ScaleMatrix;

//set rotation matrices
D3DXMatrixRotationX(&RotationMatrixX, Rotation.x);
D3DXMatrixRotationY(&RotationMatrixY, Rotation.y);
D3DXMatrixRotationZ(&RotationMatrixZ, Rotation.z);

//set scalation matrix
D3DXMatrixScaling(&ScaleMatrix, Scale.x, Scale.y, Scale.z);

//set center of the mesh to origin
D3DXMatrixTranslation(&TranslationMatrix, 0.0f, 0.0f, 0.0f);
D3DXMatrixMultiply(&WorldMatrix, &ScaleMatrix, &TranslationMatrix);

//apply rotation
D3DXMatrixMultiply(&WorldMatrix, &WorldMatrix, &RotationMatrixZ);
D3DXMatrixMultiply(&WorldMatrix, &WorldMatrix, &RotationMatrixX);
D3DXMatrixMultiply(&WorldMatrix, &WorldMatrix, &RotationMatrixY);

//set center of the mesh to its world position
D3DXMatrixTranslation(&TranslationMatrix, Position.x, Position.y, Position.z);
D3DXMatrixMultiply(&WorldMatrix, &WorldMatrix, &TranslationMatrix);

//set transform
m_lpDevice->SetTransform(D3DTS_WORLD, &WorldMatrix);
}


Thats the way I'm doing it, and so it should work. Only difference is that I'm calculating the position elsewhere in the code so you might want to change that. Hope that helps.
NucleA
NucleA
Translation Then Rotation:


Rotation Then Translation:
NucleA
NucleA
@The King2, How do i track the car position then?
Zakwayda
Zakwayda
Nice example videos :) But yeah, what you're seeing in the second video is exactly what you should expect.

I explained what the problem is a couple of times previously (and I think The King2 did as well), but perhaps it was lacking context. If there's anything about those answers that was unclear, feel free to ask and I'm sure we can get it cleared up.
NucleA
NucleA
If am not mistaken, If i use the code which The King posted, i will have to track down the position of the car. So, another problem crops up.

To track down the car position, i will have to update the position vector each time i press up and down key. If the car is simply moving forward and backward, no problem. BUT when i press left/right, the orientation of the car will change, and the car will have to move forward/backward relative to the orientation of the car. Now, i will have to track both the X & Y Coordinates of the car's position. Here is another problem now!
Zakwayda
Zakwayda

To track down the car position, i will have to update the position vector each time i press up and down key. If the car is simply moving forward and backward, no problem. BUT when i press left/right, the orientation of the car will change, and the car will have to move forward/backward relative to the orientation of the car. Now, i will have to track both the X & Y Coordinates of the car's position. Here is another problem now!

Yup, that's what you have to do :)

You can store the position of the car as a vector. When it comes time to move the car (linearly), you'll need a vector representing the current forward direction of the car; then, you would add this vector (scaled by the speed and the time step) to the position vector.

There's a few different ways to compute the direction vector. If the car only rotates about its up axis, you can compute the direction vector using a little trig. Another option is to extract the forward direction vector directly from the transform matrix.
Juliean
Juliean
To track down the car position, i will have to update the position vector each time i press up and down key. If the car is simply moving forward and backward, no problem. BUT when i press left/right, the orientation of the car will change, and the car will have to move forward/backward relative to the orientation of the car. Now, i will have to track both the X & Y Coordinates of the car's position. Here is another problem now! [/quote]

Yes, as jyk said, thats the way you do it. It's not that hard if you got the basic implementation. If you have the rotation, like you do, you could do it like me:

void CControl::Update(void)
{
float MoveX, MoveY, Angle;
Angle = m_Camera->GetAngleY();

MoveX = m_MoveSpeed * sin(DEGTORAD(90 - Angle));
MoveY = m_MoveSpeed * sin(DEGTORAD(Angle));
if(m_Keys[K_FORWARD])
{
m_Object->SetRotation(0.0f, -Angle, 0.0f);
m_Object->Move(-MoveX, 0.0f, -MoveY);
}
else if(m_Keys[K_BACKWARD])
{
m_Object->SetRotation(0.0f, -Angle, 0.0f);
m_Object->Move(MoveX, 0.0f, MoveY);
}

}

My code moves a object based on a 3rd-person cameras position. You can take the cars y-angle instead of the camers angle, just ignore the m_Object->SetRotation-calls and you have to use the negative angle.

MoveX = m_MoveSpeed * sin(DEGTORAD(90 + ry));
MoveY = m_MoveSpeed * sin(DEGTORAD(-ry));
if(m_Keys[K_FORWARD])
{
m_Object->Move(-MoveX, 0.0f, -MoveY);
}
else if(m_Keys[K_BACKWARD])
{
m_Object->Move(MoveX, 0.0f, MoveY);
}


This should do it, if I'm not mistaken.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.