Трудности с камерой и мышью

Я работаю над шахматной игрой в 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 (курсор которой обычно находится в середине экрана) и какая-то камера меню (которая отслеживает реальное положение курсора), что это плохо, потому что я бы хотел, чтобы куб рисовался в центре экрана (направление камеры), И только когда я переключаюсь в (заблокированный режим), куб начинает двигаться в зависимости от положения курсора. Но для примера вы должны увидеть, что существует другая проблема, упомянутая выше.

Буду признателен всем, кто сможет ответить на вопрос или направить меня в нужное русло, если нужна дополнительная информация, спрашивайте.


person Hinterino Salterino    schedule 11.01.2021    source источник
comment
хм, до сих пор нет ответа ... Возможно, добавление MCVE поможет, поскольку сейчас никто не может воспроизвести вашу проблему, поэтому любой ответ будет просто теоретическим, полным догадок и абсолютно непригодным для вас, и наверняка есть много руководств по подобным вещам. .. так что никто не удосужился добавить ответ. Добавьте также важные вещи, такие как то, как вы представляете доску, фигуры ... как вы хотите двигаться (относительно доски или экрана или с помощью навигационных элементов, таких как стрелки и области слайдов) и т. д. ... Я бы забыл о вашей коробке и 1 . сначала кодируйте выбирая фрагменты   -  person Spektre    schedule 13.01.2021
comment
и только потом поиграйте с перетаскиванием... Это может помочь Вычислить объекты, движущиеся с помощью стрелок и мыши (стрелка может быть непосредственно вашей частью), и вам, скорее всего, потребуется понять матрицы однородного преобразования 4x4 для всего этого.   -  person Spektre    schedule 13.01.2021
comment
@Spektre На данный момент я как бы отказался от этой идеи, и, как вы сказали, я больше сосредоточен на перетаскивании объекта. Я отказался от использования простой камеры fps (вектор фронта/направления камеры) — это вектор, для которого я вычисляю пересечения, и на данный момент он работает нормально. А что касается MCVE, это может звучать супер-эгоистично, но я даже не знаю, как я буду его создавать, это займет слишком много времени (которого мне как бы не хватает). В любом случае спасибо за комментарий   -  person Hinterino Salterino    schedule 13.01.2021
comment
да, создание MCVE из большего кода/движка всегда проблема... поэтому я создал этот полный GL+GLSL+VAO/VBO C++ пример, который я использую для MCVE в своих ответах, поскольку мой движок GL не будет работать без большого количества кода, который он содержит... и разделение только необходимого кода было бы слишком трудоемким.   -  person Spektre    schedule 13.01.2021