1
$\begingroup$

Currently for a university assignment I have been given a 3D rendering engine, capable of rendering a 3D world. One task is to create a first person camera for it (I know with OpenGL you don't have a camera, you have to effect the modelview).

Anyway, I have managed to get a first person camera working, however rotation is becoming a bit of a problem. I have spent a good few hours trying to fix the problem, but can't seem to find a solution.

Rotation works perfectly, until you move forward about -10 into the z axis. When you do, the camera rotation seemingly rotates around a set point, so it orbits the actual model, rather than just changing the direction the camera is looking at.

So if you move out, then rotate, the camera will move around the object, not just move the object out of sight.

Not sure what code you'll need to see to help, but here's some:

Camera Rotation:

void Camera::RotateCamera(float yaw, float pitch, float roll)
{
//left and right rotation
Quaternion a;
Quaternion b;
Quaternion c;
Quaternion up;
Quaternion right;
Quaternion temp;
float s;
float vx;
float vy;
float vz;

if (yaw != 0)
{
    s = cos(yaw / 2);
    c.SetQuaternion(m_direction, s);
    vx = m_upVector[0] * sin(yaw / 2);
    vy = m_upVector[1] * sin(yaw / 2);
    vz = m_upVector[2] * sin(yaw / 2);
    a.SetQuaternion(vx, vy, vz, s);
    b.SetQuaternion(vx, -vy, -vz, s);

    up = a*c*b;

    m_direction.SetVector(up[0], up[1], up[2]);
}

//up and down rotation
if (pitch != 0 && curDown < maxDown && curDown > -maxDown)
{
    curDown += pitch;
    s = cos(pitch / 2);

    a.SetQuaternion(m_direction, s);
    vx = m_rightVector[0] * sin(pitch / 2);
    vy = m_rightVector[1] * sin(pitch / 2);
    vz = m_rightVector[2] * sin(pitch / 2);
    b.SetQuaternion(vx, vy, vz, s);
    c.SetQuaternion(-vx, -vy, -vz, s);

    right;
    temp;
    right = b * a * c;
    m_direction.SetVector(right[0], right[1], right[2]);
}
m_direction.Normalise();
m_rightVector = m_direction.CrossProduct(m_upVector);
m_upVector = m_rightVector.CrossProduct(m_direction);

m_rightVector.Normalise();
m_upVector.Normalise();
UpdateViewMatrix();
}

The quaternion class is correct (so I'm assuming as it was already created for us).

Camera rotation code

if (x - ox > 0)
{
    cam_pos->RotateCamera(0.05, 0, 0);
}
else if (x - ox < 0)
{
    cam_pos->RotateCamera(-0.05, 0, 0);
}

ox = x;
oy = y;

Applying the camera

modelview = (*cam_pos->GetViewMatrix()) * modelview;
modelview = modelview*translation;

float aspect_ratio = (float)m_width / (float)m_height;
projection.SetPerspective(60.0f, aspect_ratio, 1.0f, 1000.0f);

glUniformMatrix4fv( m_uniform_projection, 1, GL_FALSE, projection.ToPtr() );
glBindSampler(0, m_texDefaultSampler);

Where *cam_pos is the actual camera.

The code works, just rotation goes off.

This is what currently happens on rotation: weird rotation effect

$\endgroup$
1
$\begingroup$

A common mistake that causes this behavior is to first apply the translation and then the rotation when rendering the scene. I think that's what's happening. If you apply the rotation first and then the translation it should behave as expected. Give that a try

$\endgroup$
  • $\begingroup$ Did you get to try this? Did it work? $\endgroup$ – Leon Apr 10 '16 at 7:33
  • $\begingroup$ I just did it now. I originally had the pos defined in the 4x4 view matrix, but i took it out and did it at the end, and it worked! Thankyou! $\endgroup$ – iBaconButty Apr 10 '16 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.