Я работаю над шахматной игрой в 3D-пространстве. Я пытаюсь понять, как я могу перемещать фигуры, но камера и различные режимы мыши вызывают у меня головную боль.
Идея:
Есть 2 режима ввода камеры/мыши, один позволяет мне свободно перемещаться в пространстве и осматриваться (короче говоря, разблокирована камера/камера fps), а другой блокирует экран, я не могу двигаться, а движение мыши не поворачивает вид ( заблокированная камера/своего рода камера с меню без меню). В заблокированном режиме я мог бы выбрать квадрат под фигурами и переместить их на другой с помощью луча, который я бросаю на сцену в позицию моего курсора.
Что у меня есть:
Класс камеры, который работает должным образом и создан в соответствии с этим кодом с сайта Learnopengl.com https://learnopengl.com/code_viewer_gh.php?code=includes/learnopengl/camera.h
Класс лучей мыши, созданный в соответствии с этим руководством: https://antongerdelan.net/opengl/raycasting.html
Вычисление направления мыши помещено в код (последняя функция правильно возвращает направление, так как я тестировал ее с заблокированной камерой) (обновляется при каждом рендере):
glm::vec3 NormalizedDeviceCoordinates() {
float x = (2.f * this->mouseX) / this->frameBufferWidth - 1.0f;
float y = 1.0f - (2.0f * this->mouseY) / this->frameBufferHeight;
float z = 1.0f;
return glm::vec3(x, y, z);
}
glm::vec4 HomogeneousClipCoordinates(glm::vec3 NormalizedDeviceCoords) {
return glm::vec4(NormalizedDeviceCoords.x, NormalizedDeviceCoords.y, -1.f, 1.f);
}
glm::vec4 EyeCoordinates(glm::vec4 HomogenousClipCoords) {
glm::vec4 ray_eye = glm::inverse(projectionMatrix) * HomogenousClipCoords;
return glm::vec4(ray_eye.x, ray_eye.y, -1.f, 0.f);
}
glm::vec3 WorldCoordinates(glm::vec4 EyeCoords) {
glm::vec3 ray_wor = (glm::inverse(viewMatrix) * EyeCoords);
ray_wor = glm::normalize(ray_wor);
return ray_wor;
}
glm::vec3 calculateMouseRay() {
return WorldCoordinates(EyeCoordinates(HomogeneousClipCoordinates(NormalizedDeviceCoordinates())));
}
У меня также есть функция ввода с клавиатуры, с помощью которой я могу переключаться между двумя режимами при нажатии клавиши M. Различия между разблокированным и заблокированным режимом:
glfwSetInputMode(this->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
/glfwSetInputMode(this->window, GLFW_CURSOR, GLFW_CURSOR_NORMAL)
- разрешает движение и вращение камеры / не разрешает движение или вращение камеры
Проблема:
Я действительно не знаю, как это описать, поэтому я сделал видео и загрузил его на YouTube.
Вот ссылка: https://youtu.be/4s-M6vHxvCc
А теперь время пояснений:
- Черно-белый куб, который вы видите, — это моя попытка отследить направление луча (проще говоря, я рисую куб и отправляю матрицу преобразования в шейдер, который преобразует его в местоположение камеры + вектор направления луча), пока куб отображается в обоих режимы (разблокированный и заблокированный).
- В первой половине видео я в разблокированном режиме. Вы можете видеть, как я пытаюсь вращаться влево и вправо, пытаясь показать, что куб несколько застрял в этом углу и не будет двигаться дальше него.
- Во второй половине видео (после того, как куб встанет на место) я переключаюсь в заблокированный режим. Вы также можете видеть мой курсор, а также куб. Они не выровнены, но куб фактически воспроизводит движение курсора. (Также стоит отметить, что между курсором и позицией есть смещение, вероятно, из-за предыдущего вращения мыши из разблокированного режима, не знаю, как это учитывать)
Возможные решения/причины/идеи:
Я не совсем уверен в этом, но я думаю, что есть несколько пересекающихся проблем.
Во-первых, я думаю, что куб каким-то образом привязан к горизонтальной плоскости (непреднамеренно). Если я двигаюсь с помощью клавиш перемещения, куб движется вместе со мной, но всякий раз, когда я двигаю мышь, он всегда движется вдоль этой одной плоскости.
Во-вторых, по логике вещей это должна быть не горизонтальная плоскость, а плоскость, на которую отрисовывался первый экран (английский язык не мой родной).
В-третьих, если второе предположение верно, мне нужно каким-то образом переместить эту плоскость в соответствии с вращением мыши (может быть, лучше сказать направление камеры), что я не знаю, как это сделать (или в какой момент я должен добавить это к уравнению вообще в факт).
Послесловие:
Возможно, вы заметили проблему с первой половиной видео (разблокированный режим). Если говорить в терминах видеоигр (это предположение), у меня одновременно работает камера fps (курсор которой обычно находится в середине экрана) и какая-то камера меню (которая отслеживает реальное положение курсора), что это плохо, потому что я бы хотел, чтобы куб рисовался в центре экрана (направление камеры), И только когда я переключаюсь в (заблокированный режим), куб начинает двигаться в зависимости от положения курсора. Но для примера вы должны увидеть, что существует другая проблема, упомянутая выше.
Буду признателен всем, кто сможет ответить на вопрос или направить меня в нужное русло, если нужна дополнительная информация, спрашивайте.