Проблемы с вращением камеры в OpenGL4

Я новичок, использующий современный OpenGL с библиотеками glm, и я попытался создать движение клавиатуры с движением камеры (WSAD для движения вперед, назад, влево, вправо) и Q & E (по часовой стрелке и против часовой стрелки).

Когда я пытаюсь сделать полный оборот по оси Y, кажется, что он делает половину оборота, а затем возвращается к началу (представьте, что дуга составляет 180 градусов). При возникновении проблем с вращением возникают проблемы с направлением вперед, оно меняется, вместо того, чтобы двигаться вперед прямо вперед, движение вперед смещается влево или вправо, когда мы меняем вращение.

    glm::vec3 eyepos = glm::vec3(-0.6f, -0.4f, 31.1f);
    glm::vec3 frontvector = glm::vec3(0.0f, 0.0f, -1.0f);//looking         pointing vector
    glm::vec3 lookvector = glm::vec3(0.0f, 0.0f, -1.0f);
    glm::vec3 flatupvec = glm::vec3(0.0f, 1.0f, 0.0f);
    glm::vec3 upvec = glm::vec3(0.0f, 1.0f, 0.0f);

    glm::mat4 viewmatrix;
    glm::mat4 projectionmatrix;//camera lens, projection matrix, need an                 aspect ratio function here /3D FOV

    GLfloat movespeed = 0.1f;
    GLfloat turnspeed = 1.0f;

    //********************MOVEMENT_TRANSFORMS***********************************
        if (kb.w == true) { eyepos += frontvector *  movespeed;         }   //move up
        if (kb.s == true) { eyepos -= frontvector *  movespeed; }   //move down
        if (kb.q == true) { glm::quat q =         glm::angleAxis(glm::radians(turnspeed),
            glm::vec3(0, 1, 0)); frontvector = (frontvector * q);         }//turn left (yaw)
        if (kb.e == true) { glm::quat q =         glm::angleAxis(glm::radians(-turnspeed), 
            glm::vec3(0, 1, 0)); frontvector = (frontvector * q);         }//turn right (yaw)
        if (kb.a == true) { eyepos -=         glm::normalize(glm::cross(frontvector, flatupvec)) * movespeed; }         //strafe left
        if (kb.d == true) { eyepos +=         glm::normalize(glm::cross(frontvector, flatupvec)) * movespeed; }         //strafe right
        if (kb.r == true) { eyepos += flatupvec * movespeed; }  //move         up
        if (kb.f == true) { eyepos -= flatupvec * movespeed; }  //move         down
                //********************ROTATIONS_EYEPOINT************************************
        if (kb.t == true) { glm::quat q = glm::angleAxis(turnspeed,         glm::vec3(1, 0, 0)); lookvector = q * lookvector; } //pitch up
        if (kb.g == true) { glm::quat q = glm::angleAxis(-turnspeed,         glm::vec3(1, 0, 0)); lookvector = q * lookvector; }//pitch down
        if (kb.z == true) { glm::quat q = glm::angleAxis(-turnspeed,         glm::vec3(0, 0, 1)); upvec = q * upvec; }  //roll left
        if (kb.x == true) { glm::quat q = glm::angleAxis(turnspeed,         glm::vec3(0, 0, 1)); upvec = q * upvec; }   //roll right
        if (kb.c == true) { glm::quat q = glm::angleAxis(turnspeed,         glm::vec3(0, 1, 0)); lookvector = q * lookvector; } //yaw left
        if (kb.v == true) { glm::quat q = glm::angleAxis(-turnspeed,         glm::vec3(0, 1, 0)); lookvector = q * lookvector; }//yaw right

        viewmatrix = glm::lookAt( eyepos, eyepos + frontvector + lookvector, upvec);
        projectionmatrix = glm::perspective(45.0f, 1.8f, 0.0001f, 500.0f);

Почему вы держите frontvector и lookvector? Разве они не должны быть одинаковыми?

Nico Schertler 11.04.2019 17:51

Это должно быть обработано с помощью eyepos. В любом случае, инициализировать движение к (0, 0, 1) кажется неправильным.

Nico Schertler 11.04.2019 18:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
98
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в вашем векторе взгляда. Ваша функция работает, говоря, что вы, скажем, (10,0,10), и вы смотрите на ((10,0,10)+(0,0,-1)+(0,0,-1)), что равно (10,0,8) или прямо. Допустим, вы выглядите правильно ((10,0,10)+(0,9,0,-0,1)+(0,0,-1)), что равно (10,9,0,8,9), и все примерно по-прежнему хорошо. Но скажем, вы поворачиваете его почти до максимума ((10,0,10)+(0,1,0,0,9)+(0,0,-1)), что равно (10,1,0,9,9), сравнивая (10,1,0 ,9.9) и от (10,0,8) до (10,0,10) по-прежнему тот же вектор (который объясняет дугу 180 градусов) и (10,0,10) точка зрения и (10,0,10) lookat будет неоднозначным, поэтому ваша проблема заключается в «viewmatrix = glm::lookAt(eypos, eyepos + frontvector + lookvector, upvec);» call и одновременное включение как frontvector, так и lookvector, и с программой, как она есть, вы можете удалить часть frontvector этого вызова, но хороший кусок кода;)

Другие вопросы по теме