Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 2 FirstFirst 12
Results 11 to 16 of 16

Thread: How to rotate entire scene based on mouse events?

  1. #11
    Senior Member OpenGL Pro Aleksandar's Avatar
    Join Date
    Jul 2009
    Posts
    1,160
    Quote Originally Posted by rakeshthp View Post
    How to compute the angle of rotation from the mouse events?
    Mouse gestures can be interpreted according to needs of your application.
    If you know the orientation of lookAt vector at the time gesture starts (V1), and you know its orientation after gesture (V2), then you should rotate around vector V = V1 x V2, and the angle is ang = arccos((V1.V2)/|V1.V2|), where x is vector product, . - scalar (dot) product, || - norma (length).

    With quaternions, if qc ia a quaternion that represents orientation of the camera, and qr is a quaternion that represents desired rotation, then
    qc = qc * qr

    The problem is to define quaternion that represents rotation. If you know the axis around which you want to rotate and the angle, then:
    Code :
    void Quaternion::fromAxis(const vec &axis, double angle)
    {
      double sinAngle;
      angle *= 0.5;
      vect vn(v);
      vn.normalize();
     
      sinAngle = sin(angle);
     
      x = (vn.x * sinAngle);
      y = (vn.y * sinAngle);
      z = (vn.z * sinAngle); 
      w = cos(angle);
    }

  2. #12
    Intern Contributor
    Join Date
    Jun 2009
    Posts
    91
    Hi,

    Sorry for the late reply. I was stuck up with some other work and so this project was kept on hold. Coming to the point, this is what I did:

    OnMouseDown event:
    Code :
    firstVector = ScreenToWorld(event.GetX(), event.GetY());

    OnMouseDown & OnMouseDrag event:
    Code :
    secondVector = ScreenToWorld(event.GetX(), event.GetY());
    rotAxis = EVector3::CrossProduct(firstVector, secondVector);
    double ag = EVector3::DotProduct(firstVector, secondVector);
    rotAngle += ag;

    OnMouseUp event:
    Code :
    secondVector = ScreenToWorld(event.GetX(), event.GetY());
    rotAxis = EVector3::CrossProduct(firstVector, secondVector);
    double ag = EVector3::DotProduct(firstVector, secondVector);
    rotAngle += ag;

    OnPaintEvent
    Code :
    glViewPort(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(centerp.x-screenwidth/2, centerp.x+screenwidth/2, 
             centerp.y-screenheight/2, centerp.y+screenheight/2, 1.0, 10000.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glRotatef(rotAngle * 180/PI, rotAxis.x, rotAxis.y, rotAxis.z);


    With this setup, I do get rotation and model get rotated in single direction, irrespective of the direction of the mouse movement. I mean if the mouse is moved from left to right, then the scene should get rotated around y-axis isn't it? But here I am getting rotation in single direction. I am sure I am missing something or I might be doing something wrong. First of all, is the logic correct what I am doing? Please guide me what is my mistake?

    Thanks
    Last edited by rakeshthp; 10-19-2013 at 10:30 AM. Reason: formatted

  3. #13
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    495
    Quote Originally Posted by rakeshthp View Post
    OnMouseDown event:
    Code :
    firstVector = ScreenToWorld(event.GetX(), event.GetY());
    Where does ScreenToWorld() get its Z coordinate from?

    Quote Originally Posted by rakeshthp View Post
    OnMouseDown & OnMouseDrag event:
    Code :
    secondVector = ScreenToWorld(event.GetX(), event.GetY());
    rotAxis = EVector3::CrossProduct(firstVector, secondVector);
    double ag = EVector3::DotProduct(firstVector, secondVector);
    rotAngle += ag;
    If the world Z coordinate is a constant, firstVector and secondVector will both be parallel to the screen, and rotAxis will always be the Z axis.

    If you want trackball like behaviour, the rotation axis should be the cross product of the Z axis and the relative mouse motion (i.e. the current position minus the mouse-down position).

  4. #14
    Intern Contributor
    Join Date
    Jun 2009
    Posts
    91
    Quote Originally Posted by GClements View Post
    Where does ScreenToWorld() get its Z coordinate from?


    If the world Z coordinate is a constant, firstVector and secondVector will both be parallel to the screen, and rotAxis will always be the Z axis.

    If you want trackball like behaviour, the rotation axis should be the cross product of the Z axis and the relative mouse motion (i.e. the current position minus the mouse-down position).
    I'm using gluUnproject to convert screen coordinate to world coordinate.. z value is coming from unproject function..

  5. #15
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    495
    Quote Originally Posted by rakeshthp View Post
    I'm using gluUnproject to convert screen coordinate to world coordinate.. z value is coming from unproject function..
    gluUnProject() takes a Z coordinate as its parameter. Where is it getting it from? If it's constant, then everything in my previous post still applies.

  6. #16
    Intern Contributor
    Join Date
    Jun 2009
    Posts
    91
    Quote Originally Posted by GClements View Post
    gluUnProject() takes a Z coordinate as its parameter. Where is it getting it from? If it's constant, then everything in my previous post still applies.
    Below is my code for screentoworld function

    Code :
    EVector3 ScreenToWorld(int mouseX, int mouseY)
    {
       glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
       glGetDoublev(GL_PROJECTION_MATRIX, projection);
       glGetIntegerv(GL_VIEWPORT, viewport);
     
       posx = (double)mouseX;
       posy = (double)mouseY;
       glReadPixels(mousex, mousey, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &posz);
     
       gluUnproject(posx, posy, posz, modelview, projection, viewport, &worldx, &worldy, &worldz);
       return EVector3(worldx, worldy, worldz);
    }

    So the z value is taken from the depth component, which is read using glReadPixel function. Actually, I need to make to more general form so that rotation works for both: constant z, and varying z values.

    Thanks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •