直接相机旋转的错误控制



我使用鼠标在我的程序中控制相机旋转(使用 Directx 9.0c)。鼠标 X 控制相机围绕向上矢量旋转,鼠标 Y 控制围绕右矢量旋转。旋转计算如下: void Camera::RotateCameraUp(float angle) { D3DXMATRIX RoMatrix; D3DXMatrixRotationAxis(&RoMatrix, &vUp, angle); D3DXVec3TransformCoord(&vLook, &vLook, &RoMatrix); D3DXVec3TransformCoord(&vRight, &vRight, &RoMatrix); } void Camera::RotateCameraRight(float angle) { D3DXMATRIX RoMatrix; D3DXMatrixRotationAxis(&RoMatrix, &vRight, angle); D3DXVec3TransformCoord(&vLook, &vLook, &RoMatrix); D3DXVec3TransformCoord(&vUp, &vUp, &RoMatrix); } 假设围绕向上或向右向量的旋转不应导致围绕"LookAt"向量的旋转,但是如果我将鼠标绕圈一会儿并在起点停止它,则围绕"LookAt"向量的旋转已经发生。我认为这是因为计算时的错误,但我不知道如何消除或控制它。知道吗?

这是一个常见问题。您应用了许多旋转,随着时间的推移,舍入误差会相加。一段时间后,三个向量vUpvLookvRight不再归一化和正交。我会使用以下两个选项之一:

1.不要存放vLookvRight;相反,只需存储 2 个角度。假设 x 为右,y 为顶部,z 为后,存储 a) 视图轴与 xz 平面之间的角度,以及 b) 视图轴在 xz 平面上与 z 轴或 x 轴上的投影之间的角度。根据鼠标移动更新这些角度,并从中计算vLookvRight

阿拉伯数字。将 vRight 的 y 分量设置为 0,因为vRight应该在 xz 平面中。然后重新正交归一化向量(您知道向量应该彼此垂直并且长度为 1)。因此,在计算新的vLookvRight之后,应用以下更正:

vRight.y = 0
vRight = Normalize(vRight)
vUp = Normalize(Cross(vLook, vRight))
vLook = Normalize(Cross(vRight, vUp))

最新更新