旋转矩阵的奇怪行为 [英] Strange behavior with rotation matrices

查看:198
本文介绍了旋转矩阵的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在相机前直接渲染太空船,模型随相机视图旋转。这工作,只要玩家只有雅司或辊。如果他这两个,它进入一个翻滚。问题的视频在这里: http://youtu.be/voKTsdy5TFY

I am trying to render a spaceship directly in front of a camera, with the model rotating with the camera's view. This works, as long as the player only yaws or rolls. If he does both, it goes into a tumble. A video of the problem is here: http://youtu.be/voKTsdy5TFY

相关代码如下,为清楚起见进行编辑:

The relevant code follows, edited for clarity:

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 Team的要求扩展代码。

Expanded code at the behest of Optillect Team.

推荐答案

Na7coldwater可能正确的万向节锁。您使用的2个角度,yawangle和pitchangle是欧拉角,因此容易受到gimble锁定。

Na7coldwater may be right on the gimbal lock. The 2 angles you use, yawangle and pitchangle are euler angles and hence susceptible to gimble lock.

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

You could avoid gimbal lock by either using quaternions or by storing the current rotation and then build a delta rotation matrix and multiply to the previous rotation matrix.

即在建立旋转矩阵时,您将存储前一个旋转的增量,而不是来自模型原点状态的absoloute旋转。

ie where you build your rotation matrix you will be storing the delta from the previous rotation rather than the absoloute rotation from the model's origin state.

例如

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是逐帧存储的。

where playerrot is stored from frame to frame.

这篇关于旋转矩阵的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆