Jump to content
  • Advertisement
Sign in to follow this  
Shadekf

Screen to wolrd conversion issue

This topic is 3413 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys, I'm thinking this is pretty common problem. Below is a code snippet for a screen to world point conversion method. Coord is just an object I use to store the coordinates through out my game so I don't have to declare windows.h all over the place. Logger just writes the message to a log file. screenPoint, viewport, matProjection, matView, matWorld are all global variables (for the moment) and are set up before this method is called.
Coord screen_to_world(float x, float y, float z)
{
	string str;

	D3DXVECTOR3 result;

	D3DXVECTOR3 screenPoint; // set screen vector
	screenPoint.x = x;
	screenPoint.y = y;
	screenPoint.z = z;

	ostringstream buffer;
	buffer << "before x: " << screenPoint.x << " y: " << screenPoint.y << " z: " << screenPoint.z << endl;
	buffer.flush();
	str = buffer.str();
	logger->Note(str);
	
	//transform the mouse clicked location
	D3DXVec3Unproject( &result, &screenPoint, &viewport, &matProjection, &matView, &matWorld );

	ostringstream buffer2;
	buffer2 << "after x: " << result.x << " y: " << result.y << " z: " << result.z << endl;
	buffer2.flush();
	str = buffer2.str();
	logger->Note(str);

	Coord loc = Coord( result.x, result.y, result.z);

	return loc;
}

The issue is that I'm getting slightly odd results. if the method call is: screen_to_world(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, 1) It will return the output of: before x: 400 y: 300 z: 1 after x: 0 y: 0 z: -0.000762945 Which is perfect as that is the center of the screen. But if the method call is for example: screen_to_world(656, 89, 1) Which is in the top corner of the screen I get the output of: before x: 656 y: 89 z: 1 after x: -35.3465 y: 29.133 z: -0.000762945 The issue with this being that that is not the location I clicked, the Y value is a little too high. So the issue is either I'm missing something in the method or something is wrong with the mouse call. I don't see the mouse being the issue but just to make sure here's my process message method as well.
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	string str;

    switch(message)
    {
		case WM_LBUTTONDOWN:
			{
				if (!m_left_mouse)
				{
					Coord loc = screen_to_world(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 1);
					s_loc->m_x = loc.m_x; 
					s_loc->m_y = loc.m_y; 
					s_loc->m_z = loc.m_z;
					logger->Note("LEFT MOUSE DOWN\n");
					m_left_mouse = true;
				}
			} break;
		case WM_LBUTTONUP:
			{
				if (m_left_mouse)
				{
					Coord loc = screen_to_world(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 1);
					e_loc->m_x = loc.m_x; 
					e_loc->m_y = loc.m_y;
					e_loc->m_z = loc.m_z;
					logger->Note("LEFT MOUSE UP\n");
					m_left_mouse = false;
				}

				manager->left_click(*s_loc, *e_loc);
			} break;
		case WM_RBUTTONDOWN:
			{
				if (!m_right_mouse)
				{
					Coord loc = screen_to_world(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 1);
					s_loc->m_x = loc.m_x; 
					s_loc->m_y = loc.m_y; 
					s_loc->m_z = loc.m_z;
					logger->Note("RIGHT MOUSE DOWN\n");
					m_right_mouse = true;
				}
			} break;
		case WM_RBUTTONUP:
			{
				if (m_right_mouse)
				{
					Coord loc = screen_to_world(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 1);
					e_loc->m_x = loc.m_x; 
					e_loc->m_y  = loc.m_y; 
					e_loc->m_z = loc.m_z;
					logger->Note("RIGHT MOUSE UP\n");

					manager->right_click(*e_loc);
					m_right_mouse = false;
				}
			} break;
		case WM_MOUSEMOVE:
			{
			} break;
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            } break;
    }

    return DefWindowProc (hWnd, message, wParam, lParam);
}

I feel I'm at the point where I'm starting to get all this new stuff (this is my first game made from scratch), but this issue is giving me the run around. Can anyone point me in the right direction?

Share this post


Link to post
Share on other sites
Advertisement
Okay this is strange.

I did some more checking and I tried a different method for obtaining the mouse coordinates (GetCursorPos()). And it gave a different result:

GetCursPos method: x = 104, y = 134

Other method: x = 100, y = 100

I amended my current method to add on 4 to x and 34 to y and now the screen_to_world conversion is spot on and things are moving around correctly. The question I have to ask is why did this occur? Why are the results of the two methods different and why are they different by the exact some amount every time?

Can anyone answer this for me?

[Edited by - Shadekf on May 18, 2009 11:38:21 PM]

Share this post


Link to post
Share on other sites
The difference is that GetCursorPos returns the mouse coordinates in screen coordinates (that is 0,0 is the top left corner of the screen).

The other method (I presume WM_LBUTTONDOWN/WM_MOUSEMOVE etc.) returns the mouse coordinates in client coordinates (0,0 is the top left corner of your Windows' client area).

You can use either function but you absolutely MUST not subtract magic numbers (4 and 34 in your case). These are the sizes of your window border and the caption on top. These sizes vary with the users settings and enabled themes.

You can use ScreenToClient to transform screen coordinates to client coordinates.

Share this post


Link to post
Share on other sites
Oh that makes a degree of sense. It never occurred to me as I am using full screen mode.

Oh and for the record I had no intention of leaving it as magic numbers that was just a quick test to work out what was wrong. :)

Thanks for your help.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!