Проблемы с движением камеры от первого лица


Я реализовываю камеру от первого лица, используя библиотеку GLM, которая предоставляет мне некоторые полезные функции, которые вычисляют перспективу и матрицы "lookAt". Я также использую OpenGL, но это не должно иметь значения в этом коде.

В основном, то, что я испытываю, - это то, что я могу смотреть вокруг, как в обычном FPS, и двигаться. Но движение ограничено тремя осями таким образом, что если бы я повернул камеру, я все равно двигался бы в том же направлении, как если бы я этого не делал. повернуть его... Позвольте мне проиллюстрировать (в 2D, чтобы упростить вещи).Введите описание изображения здесь

На этом изображении вы можете видеть четыре положения камеры. Отмеченные единицей - до движения, отмеченные двойкой-после движения. Красные треугольники представляют собой камеру, которая ориентирована прямо вперед вдоль оси Z. Синие треугольники представляют собой камеру, которая была повернута назад вдоль оси x (влево). Когда я нажимаю "клавишу движения вперед", камера перемещается вперед по оси z в в обоих случаях, не обращая внимания на ориентацию камеры.

Чего я хочу, так это более похожего на FPS поведения,когда нажатие вперед перемещает меня в направлении камеры. Я думал, что с аргументами, которые я передаю glm::lookAt, это будет достигнуто. Очевидно, нет.

Что не так с моими расчетами?

// Calculate the camera's orientation
float angleHori = -mMouseSpeed * Mouse::x; // Note that (0, 0) is the center of the screen
float angleVert = -mMouseSpeed * Mouse::y;

glm::vec3 dir(
    cos(angleVert) * sin(angleHori),
    sin(angleVert),
    cos(angleVert) * cos(angleHori)
);

glm::vec3 right(
    sin(angleHori - M_PI / 2.0f),
    0.0f,
    cos(angleHori - M_PI / 2.0f)
);

glm::vec3 up = glm::cross(right, dir);

// Calculate projection and view matrix
glm::mat4 projMatrix = glm::perspective(mFOV, mViewPortSizeX / (float)mViewPortSizeY, mZNear, mZFar);
glm::mat4 viewMatrix = glm::lookAt(mPosition, mPosition + dir, up);
2 2

2 ответа:

gluLookAt принимает 3 параметра: глаз, центр и вверх. Первые две-это позиции, а последняя-вектор. Если вы планируете использовать эту функцию, то лучше последовательно поддерживать только эти три параметра.

Переходим к вопросу с расчетом. Я вижу, что переменная position остается неизменной на протяжении всего кода. Все, что меняется, - это взгляд только на точку I. e. centre. Правильно будет сначала сделать position += dir, что позволит переместить камеру (положение) вдоль направления движения. на что указывает dir. Теперь, чтобы обновить centre, второй параметр можно оставить как есть: position + dir; это будет работать, так как позиция уже была обновлена до новой позиции, и оттуда у нас есть точка дальше в направлении dir, чтобы посмотреть.

На самом деле проблема была в другом методе. При перемещении камеры мне нужно было сделать следующее:

void Camera::moveX(char s)
{
    mPosition += s * mSpeed * mRight;
}

void Camera::moveY(char s)
{
    mPosition += s * mSpeed * mUp;
}

void Camera::moveZ(chars)
{
    mPosition += s * mSpeed * mDirection;
}

Чтобы заставить камеру двигаться по правильным осям.