0

[C++] {DirectX 9}

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

所以我正在编写一个小游戏,其中玩家被表示为一个斧头网格。玩家的视图随着鼠标的移动水平旋转(围绕 Y 轴)。[这里]是一个截图,以获得更好的想法。

所以我试图让斧头在按住鼠标时来回摆动。目前,我在 Player 类中将玩家的全局位置和旋转存储为变量(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 建议的那样,我想我会尝试仅使用矩阵来实现它。

4

1 回答 1

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数学运算或者搜索其他教程,真的很容易学如何处理它们。

如果您想了解有关特定数学或其他游戏相关主题的一些信息,我建议您阅读 Jason Gregory 的“游戏引擎架构”

于 2013-10-28T14:29:44.030 回答