Track Mouse Position & Rotate Model To Angle?

Ok, I am using Win32 and programming in C++, no other API’s like GLUT/SDL is being used, only OpenGL and Win32 programming.

I am having a bit difficult time trying to sort out this problem, I am just learning Algebra basic, its not like I am in middle school, its just I was never thought how too do Algebra in my life…

What I am doing is trying to rotate a model too the position of the mouse cursor on the window.

What I have now is, that the model rotates back and forth 180 degrees when the mouse moves around it. So what I am thinking is that I mite be missing a ‘projection’ value from converting 3D cords to 2D.

This is my code:


POINT mousePosition;
		GetCursorPos(&mousePosition);

		float rotate = abs((GLfloat)atan2((float)mousePosition.y-((float)m_iHeight/2),(float)mousePosition.x-((float)m_iWidth/2)))/Math::PI*180.0f; //ROTATE TO MOUSE
		
	m_Player.SetRotation(rotate);

BTW Just a quick question about OpenGL and DirectX, I heard it’s bad to mix DirectX and OpenGL together, forgot why, but I was wondering if someone can tell me that it is or not. I just want to use DirectInput for OpenGL too use a Xbox controller.

Thanks, Andrew.

If I understood what you want to do, this needs gluUnproject to find the 3D ray matching the 2D mouse position, then interserct this ray with the sphere, then use this point as a quaternion source angle. Next mouse position, do the same, then rotate between these 2 quaternion angles. There are tutorials on the web for each of these steps so it is not as complex as it sounds.

About mixing DirectInput and OpenGL, it is perfectly possible, that is what idsoftware is using since a decade on windows. The downside is that this code is tied to windows, and often people using OpenGL do it for the crossplatform benefit.

If there are tutorials for this function there sure isn’t a lot of them.

I created this function:


void ScreenToWorld(GLdouble screen_x, GLdouble screen_y, GLdouble nominated_screen_z, GLdouble *world_x, GLdouble *world_y, GLdouble *world_z)
{
   GLdouble ModelView[16];
   GLdouble Projection[16];
   GLint Viewport[4];

   glGetDoublev(GL_MODELVIEW_MATRIX, ModelView);
   glGetDoublev(GL_PROJECTION_MATRIX, Projection);
   glGetIntegerv(GL_VIEWPORT, Viewport);

   gluUnProject(screen_x, screen_y, nominated_screen_z, ModelView, Projection, Viewport, world_x, world_y, world_z);

After the 3rd argument I am lost of what too enter in the function, I got it off a forum someone posted, they where not too clear how to use it. Can you maybe point out how too use it and if this is what I am looking for and how to use it?

Thanks about the DirectInput question.

This should help :
http://www.opengl.org/resources/faq/technical/glu.htm
http://nehe.gamedev.net/data/articles/article.asp?article=13
http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glu/unproject.html

I seen them and it looks that they work, but my rotation is off still:

All my rotation does is rotate around in circles now when I move the mouse:


POINT mouse;						// Stores The X And Y Coords For The Current Mouse Position
GetCursorPos(&mouse);					// Gets The Current Cursor Coordinates (Mouse Coordinates)
ScreenToClient(hWnd, &mouse);

int x = mouse.x;
int y = mouse.y;

GLint viewport[4];
	GLdouble modelview[16];
	GLdouble projection[16];
	GLfloat winX, winY, winZ;
	GLdouble posX, posY, posZ;

	glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
	glGetDoublev( GL_PROJECTION_MATRIX, projection );
	glGetIntegerv( GL_VIEWPORT, viewport );

	winX = (float)x;
	winY = (float)viewport[3] - (float)y;
	glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

	gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);


	float DeltaY = posY - v3Position.m_fY;
	float DeltaX = posX - v3Position.m_fX;

		float rotate = (GLfloat)atan2(posY,posX)/Math::PI*180.0f; //ROTATE TO MOUSE
			
		rotate = Math::radian2Degree(rotate);
			m_Player.SetRotation(-rotate);

If I May Go Off Topic A Minute
BTW, I am getting this ‘jumpy’ effect when I move my character around by translating. I am not sure what the problem is, but I was wondering if someone can help. Since I am lost on what the issue is with it.

How the object is set up


glPushMatrix();
		
		glTranslatef(v3Position.m_fX, 0, v3Position.m_fY);

		
		glRotatef(-90, 4.0f, 1.0f, 0.0f);
		glRotatef(m_Player.GetAngle(), 0.0f, 0.0f, 1.0f);
		
		glScalef(0.5f, 0.5f, 0.5f);
		//Draw Model

How I add up the position:
m_v3Position.m_fX += fDeltaTime*m_fLinearSpeed;

Delta float value: 0.018984120
LinearSpeed: 4.0000000

Even a guest what the problem is would be appreciated.

I will make a guess here. When you call glTranslatef, glRotatef … etc, these functions multiply the resulting matrix with the matrix at the top of stack. If each time you redraw you forget to call glLoadIdentity() at the beginning of the loop then your model will not addvance fDeltaTimem_fLinearSpeed at each frame but will advance m_v3Position + fDeltaTimem_fLinearSpeed. Is that the jumpy effect you wrote above?
Do your entire rendering loop look like this:


glClear(...)
glLoadIdentity();
....
glPushMatrix()
m_v3Position.m_fX += fDeltaTime*m_fLinearSpeed; //called somewhere before the following
glTranslatef(v3Position.m_fX, 0, v3Position.m_fY);

glRotatef(-90, 4.0f, 1.0f, 0.0f);
glRotatef(m_Player.GetAngle(), 0.0f, 0.0f, 1.0f);
glScalef(0.5f, 0.5f, 0.5f);
//Draw model 
....
glPopMatrix();

SwapBuffers

My code is set up like that and the line your asking about if it’s doing the jumpiness. No it’s not, even if I move the mouse around the screen my model’s animation goes faster then normal and I don’t have a WM_MOUSEMOVE case.

OpenGL is acting very odd for me lately.

Here is the hole Render function if I must have over looked something then, I have a post render function that does the swapbuffers and glFlush when Render function is ended.


glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();


			m_Camera.RenderOGL();

			static Vector3 v3Position;
			v3Position = m_Player.GetPosition();

		m_Camera.Set(Vector3(v3Position.m_fX, 30.0, v3Position.m_fY), Vector3(v3Position.m_fX,-10.0f,v3Position.m_fY), Vector3(-1.0f, 1.0f, 0.0f));
		
			
			glNormal3f(1.0f,1.0f,1.0f);

			HudMode(true);
			glEnable(GL_COLOR);
			glColor3f(0.0f, 256.0f, 0.0f);
			font.PrintText(30.00f, 960.00f,"HEALTH:"); font.PrintText(200.00f, 960.00f,"100");

			HudMode(false);

			glDisable(GL_COLOR);

			glEnable(GL_BLEND);
			glNormal3f(1.0f,1.0f,1.0f);
			glColor3f(4,4,3);
			glPointSize(10.0);
			glBegin(GL_POINTS);
			glVertex2f(0.00f, 0.00f);
			glEnd();
			
			glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);	
		glBindTexture(GL_TEXTURE_2D, texture[0].texID);

glPushMatrix();

	glTranslatef(v3Position.m_fX, 0, v3Position.m_fY);

	glRotatef(-90, 4.0f, 1.0f, 0.0f);
	glRotatef(m_Player.GetAngle(), 0.0f, 0.0f, 1.0f);
	glScalef(0.5f, 0.5f, 0.5f);

		ModelMod.draw(&object2);

		if(m_Player.ActionMov == PY_RUN){
		ModelMod.setAnimation(&object2, "run");
		}else{
		ModelMod.setAnimation(&object2, "stand");
		}

		glPopMatrix();
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_BLEND);
	
	glColor3f(3,3,3);

} //Render