Skip to main content
GameDev.net gamedev.net
🔒 Locked

Matrice Rotation

Started by pebben May 6, 2004 at 7:39 AM 18 replies 2.6k views
Original Post
pebben
pebben
Hi There! I´m having a problem with my rotation. I have created an aircraft that I steer with "mousevalues" that are set into m_vRot.y and m_vRot.x. And now to the problem, I want the aircraft to roll? I can´t use the fourth value in the D3DXMatrixRotationYawPitchRoll function, because it will destroy my steering with the mouse. How can solve this problem? Please finsih my code... D3DXMATRIX mTmp; D3DXMatrixRotationYawPitchRoll(&m_toWorld, m_vRot.y, m_vRot.x, 0.0f); D3DXMatrixTranslation(&mTmp, m_vPos.x, m_vPos.y, m_vPos.z); D3DXMatrixMultiply(&m_toWorld, &m_toWorld, &mTmp); D3DXMatrixScaling(&mTmp, m_vScale.x, m_vScale.y, m_vScale.z); D3DXMatrixMultiply(&m_toWorld, &m_toWorld, &mTmp); /Have A Nice Day -Patrick
/Have A Nice Day -Patrick
Pipo DeClown
Pipo DeClown
Hmm.. I guess your aircraft can move in 360º(XZ). So what you want is to record the direction it's heading to. Then I'd calculate the yaw, pitch, roll in that direction (instead of straightforward).

--
You're Welcome,
Rick Wong

- sitting in his chair doing the most time-consuming thing..

[edited by - Pipo DeClown on May 6, 2004 8:54:51 AM]
pebben
pebben
Hi Again!
If I understand you right I must convert the D3DXMatrixRotationYawPitchRoll with D3DXMatrixRotationAxis.
For Example.

D3DXMatrixRotationAxis(m_matToWorld, vUp, m_vRot.y);
D3DXMatrixRotationAxis(m_matToWorld, vRight, m_vRot.x);
D3DXMatrixRotationAxis(m_matToWorld, vAheadZ, RollValue);

Well, I´ve tried that, and I cant get it to work?
/Have A Nice Day -Patrick
Pipo DeClown
Pipo DeClown
I''m not sure about it, AT ALL. But maybe you can try to swap:

D3DXMatrixRotationAxis(m_matToWorld, vUp, m_vRot.y); // use m_vRot.x
D3DXMatrixRotationAxis(m_matToWorld, vRight, m_vRot.x); // use m_vRot.y
D3DXMatrixRotationAxis(m_matToWorld, vAheadZ, RollValue);

--
You''re Welcome,
Rick Wong

- sitting in his chair doing the most time-consuming thing..
pebben
pebben
Hi!
I´ve tried it, and it doesn´t work becuase the world matrix are overrided every time the D3DXMatrixRotationAxis function are called.
It´s just the last rotation that succeeds, so in this case Roll over Z-axis is the only one that is working. Hmmm, how can I solve it?

/Have A Nice Day -Patrick
/Have A Nice Day -Patrick
Pipo DeClown
Pipo DeClown
You did use the reference right? (&)
I'm almost sure you did.. but I can't find a solution..

[Edit: the function does not work this way! I'm looking for a tutorial on the web that shows how to use it.. ]


--
You're Welcome,
Rick Wong

- sitting in his chair doing the most time-consuming thing..

[edited by - Pipo DeClown on May 6, 2004 9:44:02 AM]
pebben
pebben
D3DXMatrixRotationAxis(&m_matToWorld, &vUp, m_vRot.y); // use m_vRot.x
D3DXMatrixRotationAxis(&m_matToWorld, &vRight, m_vRot.x); // use m_vRot.y
D3DXMatrixRotationAxis(&m_matToWorld, &vAheadZ, RollValue);

well, yes I did, please help somebody? How can I make the aircraft roll without destroying the mouse steering?
/Have A Nice Day -Patrick
Zavie
Zavie
Hello,

Could you describe much more precisely what behaviour you are expecting, and what behaviour you are getting?


--
Zavie
-- Zavie
Pipo DeClown
Pipo DeClown
Err.. in this hopeless situation, where no one else saves the day..
Can you try to use 3 different matrices (for each of the function-calls), and then multiply them?

And btw, maybe this is not the right way, at all.


--
You're Welcome,
Rick Wong

- sitting in his chair doing the most time-consuming thing..

[edited by - Pipo DeClown on May 6, 2004 10:01:26 AM]
Pipo DeClown
Pipo DeClown
Are the up, right and ahead vectors of the camera or of the aircraft?

--
You''re Welcome,
Rick Wong

- sitting in his chair doing the most time-consuming thing..
pebben
pebben
Here Come´s a Master Explanation!
I have an aircraft that I rotate to look at different points with the D3DXMatrixRotationYawPitchRoll(&m_toWorld, RotY, RotX, 0.0f);
RotY and RotX are values that comes from the mouse. They are the rotation i radians, Like in a ordinary first person shooter game.
Now comes the problem.
I want the aircraft to roll around the axis that is straight ahead of the aircraft?
I´ve tried too use
D3DXMatrixRotationAxis(&m_toWorld, vAircraftDirection, RollValue); .... well maybe that´s the solution for the problem,? but than I can´t get the mouse rotation right. I must use D3DXMatrixRotationAxis with the mouse steerings values too, but how?


/Have A Nice Day -Patrick
/Have A Nice Day -Patrick
Pipo DeClown
Pipo DeClown
Sorry, I asked ''of the camera or of the aircraft''.
So I''m not really expecting a ''yes'' or ''no''.

--
You''re Welcome,
Rick Wong

- sitting in his chair doing the most time-consuming thing..
Zavie
Zavie
Ok I think I see what is your problem.


I haven''t made such things for a while, so I don''t remember exactly the stuff (and in fact, it''s so booooring to do that when you have a model working correctly, you KEEP it).

I don''t know how exactly does the RotateYawPitchRoll function works (I suppose it is just three rotation matrices multiplied), but your problem certainly comes from your axis which are wrong.

Think of a Quake-like game : in fact, you''re always moving in a 2D space. If you look up then turn, you will still have an horizontal horizon. Now think of a fly game : if you look up then turn, then horizon won''t be horizontal at all.

First you have to choose wich behaviour you want exactly. Then, think of your axis: are your rotation matrices computed thanks to the right x, y and z axis?


I hope this will help you ^_^
If not, I have an example, but it''s using OpenGL.


--
Zavie
-- Zavie
pebben
pebben
Hi There!
Maybe I´ll understand, but please paste your open gl code here so might it get easier for me.


/Have A Nice Day -Patrick
/Have A Nice Day -Patrick
pebben
pebben
Hi Again!
Or maybe someone else can give me a good example in directx?

/Have A Nice Day -Patrick
/Have A Nice Day -Patrick
Supernat02
Supernat02
Try this:


D3DXMATRIX XRot, YRot, ZRot, FinalRot;

D3DXMatrixRotationZ(&ZRot, Somevalue);
D3DXMatrixRotationY(&YRot, Mouse.y);
D3DXMatrixRotationX(&XRot, Mouse.x);

FinalRot = ZRot*YRot*XRot;
D3DDevice->SetTransform(D3DTS_WORLD, &FinalRot);


I''m not really clear on the problem, but maybe this is what you''re looking for? The order of multiplication of rotations matters in this case. Yaw, Pitch, Roll are going to be handled differently with the YawPitchRoll function than doing it this way. You want the Z axis roll to be the first matrix affected (that''s why I put it on the left of the multiplication stack). I haven''t tried this, so I don''t know if it is what you need. You may have to switch YRot and XRot in the FinalRot multiplication, but keep ZRot first. You may also have to use D3DXMatrixRotationAxis now that I think about it. It''s something to play with anyway.

Good luck,
Chris
Chris ByersMicrosoft DirectX MVP - 2005
pebben
pebben
Hi!
Thanx for the tip, but I´m still having problem. This is how I wrote the code. Can anyone see what´s wrong? Look at the explanation below if you don´t know what the problem is.

D3DXVec3Normalize(&vRight,&D3DXVECTOR3( m_toWorld(0,0), m_toWorld(0,1), m_toWorld(0,2) ));
D3DXVec3Normalize(&vUp , &D3DXVECTOR3( m_toWorld(1,0), m_toWorld(1,1), m_toWorld(1,2) ));
D3DXVec3Normalize(&vAhead , &D3DXVECTOR3( m_toWorld(2,0), m_toWorld(2,1), m_toWorld(2,2) ));

D3DXMATRIX XRot, YRot, ZRot;
D3DXMatrixRotationAxis(&ZRot, &vAhead, timeGetTime()/1000.0f);
D3DXMatrixRotationAxis(&YRot, &vUp, m_vRot.y); // use m_vRot.x
D3DXMatrixRotationAxis(&XRot, &vRight, m_vRot.x); // use m_vRot.y
m_toWorld = ZRot * YRot * XRot;

Here Come´s a Master Explanation!
I have an aircraft that I rotate to look at different points with the D3DXMatrixRotationYawPitchRoll(&m_toWorld, RotY, RotX, 0.0f);
RotY and RotX are values that comes from the mouse. They are the rotation i radians, Like in a ordinary first person shooter game.
Now comes the problem.
I want the aircraft to roll around the axis that is straight ahead of the aircraft?
I´ve tried too use
D3DXMatrixRotationAxis(&m_toWorld, vAircraftDirection, RollValue); .... well maybe that´s the solution for the problem,? but than I can´t get the mouse rotation right. I must use D3DXMatrixRotationAxis with the mouse steerings values too, but how?





/Have A Nice Day -Patrick
/Have A Nice Day -Patrick
Sonicmage
Sonicmage
I''m sure you could''ve found the answer you were looking for just by doing a search on these forums. This question seems to come up pretty frequently.

Anyways, there are a couple of problems I see going on here. First of all, you need to be very clear about which mouse direction is going to perform which action. From the code I see, it looks like you are trying to perform yaw (rotating "left and right") by moving the mouse up and down and perform pitch (rotating "up and down") by moving the mouse side-to-side. Obviously, this is counter-intuitive. You want moving the mouse up and down to affect pitch and side-to-side to affect roll (not yaw, roll) because this is the natural way to fly aircraft. You might try to use alternate keys to affect rudder controls (yaw).
Also, you might want to look into integrating joystick support for aircraft control because anybody who has played Battlefield 1942 will tell you that mouse control for aircraft is not very comfortable.

The second problem you have is in the order in which you multiply your matrices. There is a reason that D3DXMatrixRotationYawPitchRoll is called what it is, because the order you want is to rotate for is first for yaw, then for pitch, then for roll. Of course, this means you need to multiply your matrices in the reverse order of this.

So, what you want is...

D3DXVec3Normalize(&vRight,&D3DXVECTOR3( m_toWorld(0,0), m_toWorld(0,1), m_toWorld(0,2) ));
D3DXVec3Normalize(&vUp , &D3DXVECTOR3( m_toWorld(1,0), m_toWorld(1,1), m_toWorld(1,2) ));
D3DXVec3Normalize(&vAhead , &D3DXVECTOR3( m_toWorld(2,0), m_toWorld(2,1), m_toWorld(2,2) ));

D3DXMATRIX XRot, YRot, ZRot;
D3DXMatrixRotationAxis(&ZRot, &vAhead, m_vRot.x); //this is roll
D3DXMatrixRotationAxis(&YRot, &vUp, 0.0f); //this is yaw
D3DXMatrixRotationAxis(&XRot, &vRight, m_vRot.y); //this is pitch
m_toWorld = ZRot * XRot * YRot;

(Note: Your right vector will always be the cross product of your up vector and ahead vector, and there will be no need to normalize it if your up vector and ahead vector are already normalized)

You are not done here though. Evaluating each Euler angle separately and then multiplying the matrices together introduces a common pesky problem known as gimbal lock. I am not going to go into too much detail because information about it can be easily found if you search on the Web, but basically, gimbal lock means you lose a degree of freedom if you end up rotating into certain configurations (three spatial axes become two, nice huh?) and then youll find you can no longer rotate your aircraft effectively.

To solve the situation, there is one of two ways you can take. You can either use rotation around a SINGLE arbitrary axis or you can use quaternions. I prefer quaternions myself. Luckily, both methods have full support within Direct3D so you will be able to find what you need.
pebben
pebben
Thanx for all help friends, but I ain´t done yet..
I tested to write the code like you said, and my camera starts to flimmer sometimes. Or very often..
Is it because of Gimpal Lock ??? I read about it´s and it seems to accure when two axis are identical. Or can it be something else that are wrong in my code?
/Have A Nice Day -Patrick

Topic Locked

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

Sign in to reply to this topic.