ssell
ssell

Reputation: 6597

OpenGL Camera Rotation Not Working

I know this is a common question (as I have read many threads on here and other forums about it) but for the life of me I can not get the camera rotation that I desire. I want the camera to be able to 'look around' and not for it to 'orbit' around a point, this point being the OpenGL origin.

I am aware that 'there is no camera in OpenGL', the terrain moves and not the viewpoint, etc. and all of those similar concepts but it has not helped me in solving this.

Unfortunately I am stubborn and want to write my code with no deprecated features and so this eliminates 99% of the similar situations I have read about since most of those solutions were with gluLook and similar functions.

The matrix class I am using is similar to the one that is used by the OpenGL SuperBible 5th Edition ( source, GLFrame.h is the main file of interest) but have adapted it to use the OpenGL Mathematics Library.

The typical response to this question is to translate to the origin, rotate, then translate back, but this does nothing for me.

Some code:

void rotateLocalX( GLfloat p_Angle )
{
    if( ( m_Roll < m_RollLimit ) && ( m_Roll > ( -m_RollLimit ) ) )
    {
        //store away the current location so I can translate back to it
        glm::vec3 tempOrigin = getOrigin( );

        m_Roll += p_Angle;

        // Go to the Origin

        //you can also subtract the current location to get to 0.f

        //also doing glm::translate( m_Matrix, -( tempOrigin ) ); -> rotate -> 
        //glm::translate( m_Matrix, tempOrigin ) has the same result
        m_Matrix[ 3 ][ 0 ] = 0.f;
        m_Matrix[ 3 ][ 1 ] = 0.f;
        m_Matrix[ 3 ][ 2 ] = 0.f;
        m_Matrix[ 3 ][ 3 ] = 1.f;

        // Rotate the matrix
        m_Matrix = glm::rotate( m_Matrix, p_Angle, glm::vec3( 1.f, 0.f, 0.f ) );

        // Go back to the original location
        m_Matrix[ 3 ][ 0 ] = tempOrigin.x;
        m_Matrix[ 3 ][ 1 ] = tempOrigin.y;
        m_Matrix[ 3 ][ 2 ] = tempOrigin.z;
        m_Matrix[ 3 ][ 3 ] = 1.f;

        normalize( );
    }
}

And if it is of any consequence, I am treating the camera matrix as the view matrix (with a separate model matrix [view*model=modelview] and a perspective projection matrix).

Finally a typical frame goes like this: check for input (move/rotate camera as appropriate), render skybox (ignoring the origin/location column of the view/camera matrix), draw everything else (taking into account the entire view matrix).

I apologize for asking such a common question but two days of searching and trying various different solutions has yielded no positive results.

Thank you.

Upvotes: 0

Views: 2028

Answers (3)

J&#244;s&#249;&#229;
J&#244;s&#249;&#229;

Reputation: 21

while building your view matrix make sure you are doing the multiplication in order

rotation * translation

and not

translation * rotation

this was the way I solved this problem that where happening to me

Upvotes: 0

JCooper
JCooper

Reputation: 6535

Moving a 'camera' is equivalent to applying the inverse transformation to the model.

Let's say you have an object centered at point x in your world, oriented with rotation matrix R. You also have a camera at point y in your world, oriented with rotation matrix S. To get what I believe is your desired result when rendering the object, you need a transformation matrix that looks like this:

S^-1*T(-y)*T(x)*R

That is, you orient the object around the origin in object coordinates, you translate it to its location in world coordinates. You then translate it so that the camera is at the origin, and finally rotate the object so that the camera is looking down the -z axis. Fortunately, inverting a rotation matrix is the same thing as taking the transpose.

If you want to translate the camera by c in camera-centered coordinates then you get x' = x + Sc. The translations are rotated by the forward camera rotation. If you want to rotate by Q in camera coordinates, then you post-multiply: S' = S*Q.

If c and Q are in world coordinates then x' = x + c and S' = Q*S.


By your answer to my comment, it sort of sounds like you might just be manipulating the wrong numbers in the matrix. Is it possible that your rows and columns are swapped; so you're always getting [0,0,0] as the origin? And then setting those values back to zero (although they're unchanged).


Edit 2:

Perhaps you're not inverting m_Matrix before applying it to the transformation matrix? I think that would create the effect you're describing. To create the inverse matrix, you will take the transpose of the rotation component, negate the translation component, and rotate the translation component by the rotation component.

Upvotes: 1

Gabriele Petrioli
Gabriele Petrioli

Reputation: 196256

You should have a direction vector somewhere in your code in addition to the position of the camera.

That is what you need to rotate.

You might want to look at the matrix transform extensions and in particular the lookAt

Upvotes: 1

Related Questions