旋转矩阵的奇怪行为

时间:2011-07-14 19:55:16

标签: c++ matrix directx rotation

我正试图直接在相机前面渲染一艘宇宙飞船,模型随着相机的视野旋转。这是有效的,只要玩家只有偏航或滚动。如果他同时做到这两件事,那就会陷入困境。问题的视频在这里:http://youtu.be/voKTsdy5TFY

以下是相关代码,为清晰起见进行了编辑:

D3DXMatrixRotationAxis(&playeryaw, &up, yawangle);
D3DXMatrixRotationAxis(&playerpitch, &right, pitchangle);

playerrot =  playeryaw * playerpitch;
D3DXMatrixTranslation(&playertrans, pos.x, pos.y, pos.z);
D3DXMatrixScaling(&playerscale, 0.05 / ((float)i + 1),  0.05 / ((float)i + 1),  0.05 / ((float)i + 1));
playercom = playerscale * playerrot *  playertrans;
device->SetTransform(D3DTS_WORLD, &playercom);
playermesh.render();

编辑:根据Optillect团队的要求扩展代码。

3 个答案:

答案 0 :(得分:2)

似乎你对宇宙飞船应用了相同的变换。你应该:

  1. 将旋转基质应用于宇宙飞船,然后应用平移矩阵(宇宙飞船的位置)。
  2. 将这些matricies应用于向上和向右的向量。
  3. 根据向上和向右矢量构建视图(相机)矩阵(首先翻转飞船后部,然后旋转,然后转换到飞船的位置)
  4. 这样的事情:

        D3DXMatrixRotationAxis(&shipyaw, &up, yawangle);
        D3DXMatrixRotationAxis(&shippitch, &right, pitchangle);
        D3DXMatrixTranslate(&shippos, x, y, z);
        shipmatrix = shippitch * shipyaw * shippos;
    
        D3DXMatrixTranslate(&viewoffset, 0, 0, -10);
        D3DXMatrixRotationAxis(&viewyaw, &up, -yawangle);
        D3DXMatrixRotationAxis(&viewpitch, &right, -pitchangle);
        D3DXMatrixTranslate(&viewpos, -x, -y, -z);
        viewmatrix = viewoffset * viewpitch * viewyaw * viewpos;
    

答案 1 :(得分:2)

Na7coldwater可能正好在万向节锁上。你使用的两个角度,yawangle和pitchangle是欧拉角,因此容易受到万向节的影响。

您可以通过使用四元数或存储当前旋转来避免万向节锁定,然后构建增量旋转矩阵并乘以前一个旋转矩阵。

即,在构建旋转矩阵的位置,您将存储前一旋转的增量而不是模型原点状态的绝对旋转。

e.g

D3DXMatrixRotationAxis(&playeryaw, &up, yawanglethisframe);
D3DXMatrixRotationAxis(&playerpitch, &right, pitchanglethisframe);

playerrot =  playerrot * (playeryaw * playerpitch); // This line has changed!!
D3DXMatrixTranslation(&playertrans, pos.x, pos.y, pos.z);
D3DXMatrixScaling(&playerscale, 0.05 / ((float)i + 1),  0.05 / ((float)i + 1),  0.05 / ((float)i + 1));
playercom = playerscale * playerrot *  playertrans;
device->SetTransform(D3DTS_WORLD, &playercom);
playermesh.render();

其中playerrot是逐帧存储的。

答案 2 :(得分:1)

看起来像Gimbol lock,这是使用Euler angles表示三维旋转的已知限制。您可能希望使用matricesquaternions来代表您的宇宙飞船的旋转。