1
votes

I'm trying to create mini application which rotates camera around a cube with movement of mouse. It works perfectly on Rotating around Y axis, but I have a problem with rotating around X axis. When I continuously move my mouse upwards, cube starts to rotate on positive X direction. After some time, it reverses it's rotation direction and starts rotating on negative X direction, then after some time, again rotates on positive X direction. I want to make it rotate around Positive X as far as I move my mouse upwards. What is the problem here?

Cube is positioned on the center of coordinate system. Projection is perspective:

Edit: Here is the video related to problem: https://youtu.be/997ZdUM8fcQ

vec4 eye;
vec4 at;
vec4 up;
GLfloat mouseX = -1;
GLfloat mouseY = -1;

// Bound to glutPassiveMotionFunc
void mouse(int x, int y) {
    // This rotation works perfect, cube rotates on same direction continuously as far as I move the mouse left or right 
    GLfloat acceleration_x = mouseX - x;
    eye = RotateY(acceleration_x / 10.f) * eye;
    mouseX = x;


    // This rotation doesn't work properly, after some time, cube's rotation direction inverses
    GLfloat acceleration_y = mouseY - y;
    eye = RotateX(acceleration_y / 10.f) * eye;
    mouseY = y;


    // This part teleports pointer to opposite side of window after reaching window bounds
    if (x >= 1364) {
        glutWarpPointer(1, y);
        mouseX = 1;
    } 
    else if (x <= 0) {
        glutWarpPointer(1363, y);
        mouseX = 1363;
    }

    if (y >= 751) {
        glutWarpPointer(x, 3);
        mouseY = 3;
    }
    else if (y <= 2) {
        glutWarpPointer(x, 750);
        mouseY = 750;
    }
}


void display( void )
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    vec4   up( 0.0, 1.0, 0.0, 0.0 );

    mat4 model_view = LookAt( eye, at, up );
    glUniformMatrix4fv( ModelView, 1, GL_TRUE, model_view );

    glDrawArrays( GL_TRIANGLES, 0, NumVertices );
    glutSwapBuffers();
}

// Bound to glutTimerFunc
void timer( int id )
{    
    glutPostRedisplay();
    glutTimerFunc(1000.f/60.f, timer, 0);
}

int main( int argc, char **argv )
{
    ......
    ......

    eye = vec4(0, 0, 2, 0);
    at = vec4(0, 0, 0, 0);
    up = vec4(0.0, 1.0, 0.0, 0.0);

    .....
    .....
}
1

1 Answers

1
votes

It is because the camera gets flipped. Use your hand like this: let the index finger be the dir, and your thumb is up (thumb=(0, 1, 0)). Direct your index finder forwards, and your thumb upwards. Now, start rotating your hand around X: your index finger starts to point downwards, while your thumb forwards (during this, thumb.y is positive). When you rotated your hand 90 degrees, index finger points downwards, and thumb points forwards (thumb.y is 0). When you continue rotating, your thumb starts to point forwards+downwards (thumb.y becomes negative).

At this moment, the LookAt function will not calculate the matrix you wanted, because you want the up vector to point downwards (as we said, thumb.y is negative), but in the code, up vector is a constant (0, 1, 0), so LookAt will calculate a matrix which has a positive up.y: The camera gets flipped.

A solution could be that you register the needed rotation angles, and rotate camera matrix (instead of dir) with these angles