Frage

[C++] {DirectX 9}

TL;DR: How do I convert a float representing local Rotation in the X axis into global yaw/pitch/roll using Matrices?

So I'm writing a little game in which the player is represented as an axe mesh. The player's view rotates horizontally (around the Y axis) with mouse movement. [Here] is a screenshot to get a better idea.

So I'm trying to animate the axe swinging back and forth when holding down the mouse. At the moment, I'm storing the global position and rotation of the player within the Player class as variables (m_x, m_y, m_z, m_rotationX, m_rotationY, m_rotationZ).

When I draw the object, I transform all these coordinates into global space to create a world matrix. So yeah, these are global coordinates. m_rotationY gets changed based on mouse movement.

What this means is that if I increment m_rotationX (i.e. by a sin value of some animation increment), the object gets rotated GLOBALLY, which means if I look left or right, the axe is swinging across the screen instead of away from it.

My question: What kind of matrix transformations will I have to do to convert some "local" x rotation value into "global" x, y, and z rotation values.

if(m_attacking)
{
    m_attackAnimation += 0.1f;
    float rotationAmount = sin(m_attackAnimation) * 0.1;

    // How do I figure out m_rotationX, m_rotationY and m_rotationZ 
    // from rotationAmount here? :c
}

My thoughts so far have been to create an X Rotation Matrix, then transform some kind of vector using that, but all of my experimentation with that has been pretty unsuccessful.

Thanks for your time :D

EDIT:

More diagrams!

This is what happens when I do m_rotationX = rotationAmount;

http://imgur.com/a/yZqzx

EDIT 2:

So based on Federico's answer, I have the following code set up:

// Get the local "right" vector
D3DXVECTOR3 right(1, 0, 0);
D3DXMATRIX rotationY;
D3DXMatrixRotationY(&rotationY, m_rotationY);
D3DXVec3TransformCoord(&right, &right, &rotationY);

// Calculate the theta value we want to rotate by
m_attackAnimation += 0.1f;
float rotationAmount = sin(m_attackAnimation) * 0.1;

//Cross product
D3DXVECTOR3 axis;
D3DXVECTOR3 up(0, 1, 0);
D3DXVec3Cross(&axis, &right, &up);

//Rotation matrix
D3DXMATRIX matrix;
D3DXMatrixRotationAxis(&matrix, &axis, rotationAmount);

This SHOULD give me a rotation matrix representing a local rotation in the X axis. However I've probably got it totally wrong.

Regardless, how do I get this back into global rotationX, rotationY, and rotationZ floats

*Edit 3: *

This is my attempt at extracting the rotation angles from the matrix. Unfortunately, the result is completely off. The axe just disappears from view and the character moves around randomly.

    float rotY = acosf(matrix._11);
float rotX = asinf(matrix._13 / sin(rotY));
float rotZ = acosf(matrix._21 / sin(rotX));

m_rotationX += rotX;
m_rotationY += rotY;
m_rotationZ += rotZ;

Mathematically this seems sound to me. Not sure where to go from here.

Guess I'll just try to implement it using only matrices, as Frederico suggested.

War es hilfreich?

Lösung

If I understood what you are trying to do, this will create a matrix which will rotate around an arbitrary axis, in your case the axis is the cross product between the direction and up vector, which is the axis pointing to your right (or left, depends on the coordinate system and product order). Cross product always return a vector perpendicular to the other two.

//Cross product
D3DXVECTOR3 axis;
D3DXVec3Cross(&axis, &direction, &up);

//Rotation matrix
D3DXMATRIX matrix;
D3DXMatrixRotationAxis(&matrix, &axis, rotationAmount);

The resulting matrix should be your rotation matrix.

Have a look at http://en.wikipedia.org/wiki/Euler_angles in the section "rotation matrix XYZ" if you want to get the rotation angles back, but I suggest you to use built-in matrix and vector operation given by directx to store your position and rotation.

It will allow you to easily rotate, translate and scale positions and directions using matrices withouth taking care of maths under every operation, and withouth causing gimabl lock (http://en.wikipedia.org/wiki/Gimbal_lock). Have a look at http://msdn.microsoft.com/en-us/library/windows/desktop/bb205164(v=vs.85).aspx for directx maths operations or search for other tutorials, it is really easy to learn how to handle them.

If you want some infos on specific math or other game-related topics I suggest you to read "game engine architecture" by Jason Gregory

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top