Thursday, June 29, 2017

c++ - Camera rotation - First Person Camera using GLM



I've just switched from deprecated opengl functions to using shaders and GLM math library and i'm having a few problems setting up my camera rotations (first person camera). I'll show what i've got setup so far.


I'm setting up my ViewMatrix using the glm::lookAt function which takes an eye position, target and up vector


// arbitrary pos and target values
pos = glm::vec3(0.0f, 0.0f, 10.0f);
target = glm::vec3(0.0f, 0.0f, 0.0f);
up = glm::vec3(0.0f, 1.0f, 0.0f);

m_view = glm::lookAt(pos, target, up);

i'm using glm::perspective for my projection and the model matrix is just identity



m_projection = glm::perspective(m_fov, m_aspectRatio, m_near, m_far);

model = glm::mat4(1.0);

I send the MVP matrix to my shader to multiply the vertex position


glm::mat4 MVP = camera->getProjection() * camera->getView() * model;
// in shader
gl_Position = MVP * vec4(vertexPos, 1.0);

My camera class has standard rotate and translate functions which call glm::rotate and glm::translate respectively



void camera::rotate(float amount, glm::vec3 axis)
{
m_view = glm::rotate(m_view, amount, axis);
}
void camera::translate(glm::vec3 dir)
{
m_view = glm::translate(m_view, dir);
}

and i usually just use the mouse delta position as the amount for rotation



Now normally in my previous opengl applications i'd just setup the yaw and pitch angles and have a sin and cos to change the direction vector using (gluLookAt) but i'd like to be able to do this using GLM and matrices.


So at the moment i have my camera set 10 units away from the origin facing that direction. I can see my geometry fine, it renders perfectly. When i use my rotation function...


camera->rotate(mouseDeltaX, glm::vec3(0, 1, 0));

What i want is for me to look to the right and left (like i would with manipulating the lookAt vector with gluLookAt) but what's happening is It just rotates the model i'm looking at around the origin, like im just doing a full circle around it. Because i've translated my view matrix, shouldn't i need to translate it to the centre, do the rotation then translate back away for it to be rotating around the origin? Also, i've tried using the rotate function around the x axis to get pitch working, but as soon as i rotate the model about 90 degrees, it starts to roll instead of pitch (gimbal lock?).


Thanks for your help guys,


and if i've not explained it well, basically i'm trying to get a first person camera working with matrix multiplication and rotating my view matrix is just rotating the model around the origin.



Answer



Answer:


Thanks for your help guys.



I just kept track and updated the position and heading variable separately from the view matrix.


glm::vec3 m_position;
glm::vec3 m_direction;

...

// speed is usually 0.1f or something small like that
void camera::rotate(float amount, glm::vec3& axis)
{
m_direction = glm::rotate(m_direction, amount * m_speed, axis);

}

void camera::translate(glm::vec3& direction)
{
m_position += direction;
}

// call this once per loop
// m_up is glm::vec3(0, 1, 0) for a first person camera
void camera::update()

{
m_view = glm::lookAt(m_position, m_position + m_direction, m_up);
}

and just if anyone is curious about strafing of the camera i'll add that code in


enum MovementType {FORWARD, BACKWARD, STRAFE_L, STRAFE_R};

void camera::applyMovement(MovementType movement)
{
switch (movement)

{
case FORWARD:
m_position += m_direction;
break;
case BACKWARD:
m_position -= m_direction;
break;
case STRAFE_LEFT:
m_position += glm::cross(m_direction, m_up);
break;

case STRAFE_RIGHT:
m_position -= glm::cross(m_direction, m_up);
break;
}
}

No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...