Проблемы с движением камеры от первого лица
Я реализовываю камеру от первого лица, используя библиотеку 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 ответа:
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; }
Чтобы заставить камеру двигаться по правильным осям.