Reputation: 422
I am a beginner using modern OpenGL with the glm libraries, and I tried to create keyboard movement with movement for the camera(WSAD for forward backward left right) and Q & E( clockwise and counter-clockwise).
When I try to do a full rotation on the Y axis it seems to do a half rotation and then skip back to the beginning (think a 180 degree arc). While having issues with rotation there comes issues with the forward direction, it gets changed, instead of moving forward straight ahead, moving forward is offset by left or right when we change the rotation.
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);
Upvotes: 2
Views: 135
Reputation: 44
The problem is your look vector. Your function works by saying you are at say (10,0,10) and you are looking at ((10,0,10)+(0,0,-1)+(0,0,-1)) which equals (10,0,8) or straight ahead. So say you look right ((10,0,10)+(0.9,0,-0.1)+(0,0,-1)) which equals (10.9,0,8.9) and all is roughly still good. But say you turn it almost to the max ((10,0,10)+(0.1,0,0.9)+(0,0,-1)) which equals (10.1,0,9.9), comparing (10.1,0,9.9) and (10,0,8) to (10,0,10) is still the same vector (that would explain the 180 degree arc) and (10,0,10) eyepoint and (10,0,10) lookat would be ambiguous therefore your problem is the "viewmatrix = glm::lookAt( eyepos, eyepos + frontvector + lookvector, upvec);" call and the inclusion of both the frontvector and lookvector at the same time and with the program as it is you may wish to remove the frontvector portion of that call, but nice bit of code ;)
Upvotes: 1