旋转相机沿一个轴失效

时间:2011-01-07 17:55:53

标签: 3d matrix c++11

编辑:我已经解决了这个具体问题,但创建了一个具有相似基本描述的新问题。相机旋转多次后,它开始不应该滚动。我有偏航和音调绑定到鼠标,所以我知道0传递滚动。麻烦的是,我实际上并没有任何算法来知道这是否正在发生,更不用说纠正问题。

这是我现有的代码:

D3DXMATRIX CameraRotationMatrix;
D3DXVECTOR3 CameraPosition;
//D3DXVECTOR3 CameraRotation;

inline D3DXMATRIX GetRotationMatrix() {
    return CameraRotationMatrix;
}
inline void TranslateCamera(float x, float y, float z) {
    D3DXVECTOR3 rvec, vec(x, y, z);
    #pragma warning(disable : 4238)
    D3DXVec3TransformNormal(&rvec, &vec, &GetRotationMatrix());
    #pragma warning(default : 4238)
    CameraPosition += rvec;
    RecomputeVPMatrix();
}
inline void RotateCamera(float x, float y, float z) {
    D3DXVECTOR3 RotationRequested(x, y, z);
    D3DXVECTOR3 XAxis, YAxis, ZAxis;
    D3DXMATRIX rotationx, rotationy, rotationz;
    XAxis = D3DXVECTOR3(1, 0, 0);
    YAxis = D3DXVECTOR3(0, 1, 0);
    ZAxis = D3DXVECTOR3(0, 0, 1);

    #pragma warning(disable : 4238)
    D3DXVec3TransformNormal(&XAxis, &XAxis, &GetRotationMatrix());
    D3DXVec3TransformNormal(&YAxis, &YAxis, &GetRotationMatrix());
    D3DXVec3TransformNormal(&ZAxis, &ZAxis, &GetRotationMatrix());
    #pragma warning(default : 4238)
    D3DXMatrixIdentity(&rotationx);
    D3DXMatrixIdentity(&rotationy);
    D3DXMatrixIdentity(&rotationz);
    D3DXMatrixRotationAxis(&rotationx, &XAxis, RotationRequested.x);
    D3DXMatrixRotationAxis(&rotationy, &YAxis, RotationRequested.y);
    D3DXMatrixRotationAxis(&rotationz, &ZAxis, RotationRequested.z);
    CameraRotationMatrix *= rotationx;
    CameraRotationMatrix *= rotationy;
    CameraRotationMatrix *= rotationz;
    RecomputeVPMatrix();
}

2 个答案:

答案 0 :(得分:1)

如果你使用欧拉角进行了大量的旋转,你可能会陷入万向节锁。

Wikipedia page on Gimbal lock

答案 1 :(得分:0)

你究竟是如何编写旋转的?如果你只需要偏航和俯仰,可以通过组合不同侧面的旋转来轻松避免不必要的旋转。

例如,如果您有一个新的鼠标输入,可以为您提供pitch_diffyaw_diff四元数,则可以执行:my_rotation = yaw_diff * my_rotation * pitch_diff。这样,my_rotation的“左半部分”将永远是偏航,而“右半部分”将始终是俯仰。你永远不会得到一个滚动组件!