【发布时间】:2013-10-28 23:37:34
【问题描述】:
[C++] {DirectX 9}
TL;DR:如何使用矩阵将表示 X 轴上局部旋转的浮点数转换为全局偏航/俯仰/滚动?
所以我正在编写一个小游戏,其中玩家被表示为一个斧头网格。玩家的视图随着鼠标的移动水平旋转(围绕 Y 轴)。 [Here] 是一个截图,以获得更好的想法。
所以我试图在按住鼠标时让斧头来回摆动。目前,我在 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;时发生的事情
编辑 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 的建议尝试仅使用矩阵来实现它。
【问题讨论】:
-
是的,这似乎是正确的,要获取全局旋转值,您应该从矩阵值中执行逆正弦和余弦,看看我的维基百科帖子,但如果您不需要这样做你总是使用 d3dx 矩阵和向量
-
嗯,看那个维基百科链接,似乎我只能得到 yRotation 值。坐标矩阵[0][0] 就是 cos(yRotation),所以我可以很容易地得到它。所有其他的都是从多个其他角度复合的。是的,我最终需要这样做。目前欧拉锁不是问题,因为我只是沿 Y 轴旋转相机。
-
没关系,想通了:Y = invCos(matrix[0][0]); X = invSin(矩阵[0][2] / sin(Y)); Z = invCos(矩阵[1][0] / sin(X));现在来实现它。
标签: c++ matrix game-engine directx-9 rotational-matrices