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

1. Originally Posted by rakeshthp
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. 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

3. Originally Posted by rakeshthp
OnMouseDown event:
Code :
`firstVector = ScreenToWorld(event.GetX(), event.GetY());`
Where does ScreenToWorld() get its Z coordinate from?

Originally Posted by rakeshthp
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. Originally Posted by GClements
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. Originally Posted by rakeshthp
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. Originally Posted by GClements
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
•