Проблемы с вращением камеры в OpenGL4 - PullRequest
2 голосов
/ 11 апреля 2019

Я новичок, использующий современный 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);

1 Ответ

1 голос
/ 11 апреля 2019

Проблема в вашем внешнем виде. Ваша функция работает, говоря, что вы говорите (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 (eyepos, eyepos + frontvector + lookvector, upvec);" вызов и включение одновременно frontvector и lookvector, а также с программой, какой она есть, вы можете удалить часть frontvector этого вызова, но неплохой код;)

...