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