将局部旋转转换为全局旋转(矩阵)

时间:2013-10-28 13:53:00

标签: c++ matrix game-engine directx-9 rotational-matrices

[C ++] {DirectX 9}

TL; DR:如何使用矩阵将表示X轴局部旋转的浮点数转换为全局偏航/俯仰/滚转?

所以我正在写一个小游戏,玩家被表示为一个斧头网格。通过鼠标移动,播放器的视图水平旋转(围绕Y轴)。 [Here]是获取更好主意的屏幕截图。

因此,当我按住鼠标时,我正试图让斧头来回摆动。目前,我将播放器类的播放器的全局位置和旋转存储为变量(m_x,m_y,m_z,m_rotationX,m_rotationY,m_rotationZ)。

当我绘制对象时,我将所有这些坐标转换为全局空间以创建世界矩阵。所以是的,这些是全球坐标。 m_rotationY根据鼠标移动而改变。

这意味着如果我增加m_rotationX(即通过某个动画增量的sin值),对象将全局旋转,这意味着如果我向左或向右看,则斧头在屏幕上摆动而不是远离屏幕它

我的问题:我需要做什么样的矩阵变换才能将一些“局部”x旋转值转换为“全局”x,y和z旋转值。

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
}

到目前为止,我的想法是创建一个X旋转矩阵,然后使用它来转换某种向量,但是我对它的所有实验都非常不成功。

感谢您的时间:D

修改

更多图表!

当我m_rotationX = rotationAmount;

时会发生这种情况

http://imgur.com/a/yZqzx

编辑2:

基于Federico的回答,我设置了以下代码:

// 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);

这应该给我一个表示X轴局部旋转的旋转矩阵。但是我可能完全错了。

无论如何,如何将其恢复为全局rotationX,rotationY和rotationZ浮点数

* 编辑3:*

这是我尝试从矩阵中提取旋转角度。不幸的是,结果完全没了。斧头从视野中消失,角色随机移动。

    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;

数学上这对我来说听起来很合理。不知道从哪里开始。

猜猜我只会尝试使用矩阵来实现它,正如Frederico建议的那样。

1 个答案:

答案 0 :(得分:0)

如果我理解你要做什么,这将创建一个围绕任意轴旋转的矩阵,在这种情况下,轴是方向和向上矢量之间的交叉积,这是指向右边的轴(或左,取决于坐标系和产品订单)。交叉积总是返回与另外两个垂直的向量。

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

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

生成的矩阵应该是您的旋转矩阵。

如果想要回转旋转角度,请查看“旋转矩阵XYZ”部分中的http://en.wikipedia.org/wiki/Euler_angles,但我建议您使用directx给出的内置矩阵和向量运算来存储您的位置和旋转。

它允许您使用矩阵轻松旋转,平移和缩放位置和方向,而无需在每个操作下处理数学,并且不会导致gimabl锁定(http://en.wikipedia.org/wiki/Gimbal_lock)。看看http://msdn.microsoft.com/en-us/library/windows/desktop/bb205164(v=vs.85).aspx的directx数学运算或搜索其他教程,学习如何处理它们真的很容易。

如果你想要一些关于特定数学或其他游戏相关主题的信息,我建议你阅读杰森格雷戈里的“游戏引擎架构”