Sign in to follow this  
Zerocyde

Rotation around maintained arbitrary axis.

Recommended Posts

Zerocyde    116
[color=#000000][font=verdana, geneva, lucida,]I've been racking my brain for days now and can't find the answer. I'm using C++ and DirectX but I figure that this is more of a math problem that can relate to all languages trying to work in 3D.[/font][/color]

[color=#000000][font=verdana, geneva, lucida,]Basically, to rotate a flying vehicle (spaceship, airplane, whatever) I am using this system that I found for FPS camera control:[/font][/color]

[color=#000000][font=verdana, geneva, lucida,][CODE]
up=D3DXVECTOR3(0.0f, 1.0f, 0.0f);
look=D3DXVECTOR3(0.0f, 0.0f, 1.0f);
right=D3DXVECTOR3(1.0f, 0.0f, 0.0f);

D3DXMATRIX yawMatrix;
D3DXMatrixRotationAxis(&yawMatrix, &up, yaw);
D3DXVec3TransformCoord(&look, &look, &yawMatrix);
D3DXVec3TransformCoord(&right, &right, &yawMatrix);

D3DXMATRIX pitchMatrix;
D3DXMatrixRotationAxis(&pitchMatrix, &right, pitch);
D3DXVec3TransformCoord(&look, &look, &pitchMatrix);
D3DXVec3TransformCoord(&up, &up, &pitchMatrix);

D3DXMATRIX rollMatrix;
D3DXMatrixRotationAxis(&rollMatrix, &look, roll);
D3DXVec3TransformCoord(&right, &right, &rollMatrix);
D3DXVec3TransformCoord(&up, &up, &rollMatrix);

rotMatrix = yawMatrix*pitchMatrix*rollMatrix;
[/CODE][/font][/color]

[color=#000000][font=verdana, geneva, lucida,][background=rgb(251, 251, 251)]And you rotate by adjusting the yaw, pitch, and roll float values. The problem is that this code only seems to rotate around the default axis. For instance, if I make my little ship pitch down (lower the nose to fly downwards) and then wish to "roll" left or right, I want to rotate the ship around the look axis of the ship itself, but with this method it will only rotate around (0, 0, 1).[/background][/font][/color]

[color=#000000][font=verdana, geneva, lucida,]Basically, what methods can I use to maintain a look, right, and up axis that stay aligned with the object in question and never revert to default so that I can rotate around them at will?[/font][/color]

[color=#000000][font=verdana, geneva, lucida,]EDIT: Actually, to be more precise, this method will rotate properly around the look axis I want, but only because it does roll last after the look axis is already fully finished by the yaw and pitch rotations. Pitch rotates around a half formed right axis, and yaw rotates around the default (0, 1, 0) up axis.[/font][/color] Edited by Zerocyde

Share this post


Link to post
Share on other sites
codeToad    142
[quote name='Zerocyde' timestamp='1337278512' post='4940995']
[color=#000000]Basically, what methods can I use to maintain a look, right, and up axis that stay aligned with the object in question and never revert to default so that I can rotate around them at will?[/color]
[/quote]

Why not just apply a cumulative rotation on every frame? (i.e., at the beginning of the game, the player has rotated 0 degrees about the Y axis. At some point, the player rotates 3 degrees on the Y axis. You need to save that state in some variable that persists throughout the game. Later, the player rotates another 2 degrees around the Y axis. Since you are keeping track of the rotation state, you can apply a rotation of the cumulative 5 degrees, rather than just 2 degrees).

Share this post


Link to post
Share on other sites
Zerocyde    116
I found a solution. This is what ended up working for me:

[CODE]
D3DXMATRIX yawMatrix, pitchMatrix, rollMatrix, combined;

// rotate around your 3 maintained axis
D3DXMatrixRotationAxis(&yawMatrix, &up, yaw);
D3DXMatrixRotationAxis(&pitchMatrix, &right, pitch);
D3DXMatrixRotationAxis(&rollMatrix, &look, roll);

// combined them into one rotation matrix
D3DXMatrixMultiply(&combined, &yawMatrix, &pitchMatrix);
D3DXMatrixMultiply(&combined, &rollMatrix, &combined);

// rotate 2 of the axis by the combined rotation matrix and build the third using cross product
D3DXVec3TransformCoord(&right, &right, &combined);
D3DXVec3TransformCoord(&up, &up, &combined);
D3DXVec3Cross(&look, &right, &up);

// normalize all 3 axis
D3DXVec3Normalize(&right, &right);
D3DXVec3Normalize(&up, &up);
D3DXVec3Normalize(&look, &look);

// build the final matrix like this
rotMatrix = D3DXMATRIX
(
right.x, right.y, right.z, 0.0f,
up.x, up.y, up.z, 0.0f,
look.x, look.y, look.z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
);
[/CODE] Edited by Zerocyde

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this