PDA

View Full Version : How to rotate object around screen coordinates?

yesint
04-12-2009, 02:32 AM
Dear All,
I can't figure out how to rotate the object around the coordinates of physical screen, not around internal coordinates. I have to rotate an object first around X axis of the physical screen by angleX, then around the Y axis of the physical screen by angleY. However, after
glRotatef(angleX, 1.0, 0.0, 0.0);
the Y axis of the object is no longer aligned with Y of the screen, so I don't know what rotation vector to use. Even if figure this out and rotate around Y correctly then X become misaligned and the complete mess begins.
I googled a lot, but didn't find any solution. Any suggestions?

scratt
04-12-2009, 05:13 AM
Not quite sure what you doing exactly.. But things you may want to read about are GImbal Lock, and then perhaps look at Quaternions. These may help you understand some of the problems you are describing.

Also take a look at the significance of the order of your translations and rotations. Which comes first has a huge bearing on what the end result is.

yesint
04-12-2009, 07:12 AM
Ok, let me be more specific. I have an object, which I want to rotate using the mouse. If mouse moves from left to right the object should rotate around Y of the physical screen. If the mouse moves from top to bottom the object should rotate around X of the physical screen. I don't care about instantaneous positions of internal axes of the object. I should always rotate around axes of global "external" coordinate system. So, the problem is how to express such rotation in OpenGL.

franchela
04-12-2009, 08:19 AM
LRESULT CALLBACK WindowProc(HWND g_hWnd,UINT msg,WPARAM wParam, LPARAM lParam )
{

static POINT ptLastMousePosit;
static POINT ptCurrentMousePosit;
static bool bMousing;

switch( msg )
{
case WM_LBUTTONDOWN:
ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD( lParam );
ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD( lParam );
bMousing = true;
break;

case WM_LBUTTONUP:
bMousing = false;
break;

case WM_MOUSEMOVE:
ptCurrentMousePosit.x = LOWORD( lParam );
ptCurrentMousePosit.y = HIWORD( lParam );
if( bMousing )
{
g_fRot[1] += ptCurrentMousePosit.x - ptLastMousePosit.x;
g_fRot[0] += ptCurrentMousePosit.y - ptLastMousePosit.y;
}
ptLastMousePosit.x = ptCurrentMousePosit.x;
ptLastMousePosit.y = ptCurrentMousePosit.y;
break;
}

void Render( void )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );

// Translate view
glTranslatef ( -g_fEye[0], -g_fEye[1], -g_fEye[2] );

// Rotates the screen by the angles

glRotatef( g_fRot[0], 1.0f, 0.0f, 0.0f );
glRotatef( g_fRot[1], 0.0f, 1.0f, 0.0f );
glRotatef( g_fRot[2], 0.0f, 0.0f, 1.0f );

// Draw Things.

SwapBuffers( g_hDC );
}

yesint
04-12-2009, 10:09 AM
franchela, this is how I did it initially. Of course it does not work.
After
glRotatef( g_fRot[0], 1.0f, 0.0f, 0.0f );
the Y and Z axes rotate and the second call to glRotate rotates in local object coordinates, while I have to rotate in screen coordinates.

Dave Driesen
04-13-2009, 02:13 AM
I know this was posted in the beginner area but you seem familiar with the math involved so I just want to note that you could do this by providing a position, up- and forwardvector for each object and then performing a (possibly tweaked) gluLookAt with these vectors for each object when it's time to draw them.

This method is similar to how camera classes tend to work. It's a somewhat different and more involved approach but it gives you a lot of freedom seeing as you can rotate and translate those vectors with the greatest of ease and not worry about the order in which you do it etc.

In this case you would just have to rotate around a screen axis which you probably have, or that you can calculate by unprojection.

yesint
04-13-2009, 03:09 AM
Ok, I figured out how to do this. The solution is quite non-trivial and involves pre-multiplying the rotation matrix instead of post-multiplying: http://www.opengl.org/resources/faq/technical/transformations.htm, question 9.070.

MaxH
04-13-2009, 03:24 PM
Ok, I figured out how to do this. The solution is quite non-trivial and involves pre-multiplying the rotation matrix instead of post-multiplying: http://www.opengl.org/resources/faq/technical/transformations.htm, question 9.070. So do you have it working yet?

yesint
04-14-2009, 12:27 AM
Now it works for me.

ccl3641
04-15-2012, 01:22 PM
I've been facing a similar issue, but can't resolve it... could you post some example code?