Я использую мышь для управления поворотом камеры в моей программе (с использованием DirectX 9.0c). Мышь X управляет камерой для поворота вокруг вектора Up, а Y 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); }
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); }
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". Я думаю, что это из-за ошибки во время сглаживания, но я не знаю, как ее устранить или контролировать. Есть идеи?
Это распространенная проблема. Вы применяете много оборотов, и со временем погрешности округления суммируются. Через некоторое время три вектора vUp
, vLook
и vRight
больше не нормализуются и ортогональны. Я бы использовал один из двух вариантов:
1. Не храните vLook
и vRight
; вместо этого просто сохраните 2 угла. Предполагая, что x правильно, y вершина, z вернулась, сохраните a) угол между вашей осью обзора и xz-плоскостью и b) угол между проекцией вашей оси обзора на xz-плоскость и ось z или x-Axis. Обновите эти углы в соответствии с движением мыши и вычислите vLook
и vRight
от них.
2. Установите y-компонент vRight
0, так как vRight
должен находиться на xz-плоскости. Затем повторите ортонормировку векторов (вы знаете, что векторы должны быть перпендикулярны друг другу и иметь длину 1). Поэтому, после вычисления новых vLook
и vRight
, примените следующие исправления:
vRight.y = 0
vRight = Normalize(vRight)
vUp = Normalize(Cross(vLook, vRight))
vLook = Normalize(Cross(vRight, vUp))
(0, 1, 0)
в первом методе.