Converting Mouse Coords to World Space coords

Started by
10 comments, last by pemjahat 19 years, 3 months ago
Hi I have a 800 x 600 window, and a quad thats 2000 x 2000 x 2000 in the center of the screen. I have the x file tiny.x and I want to move it based on what the user clicks with the mouse. I don't want it to walk there or anything yet I just want to send the position in world space from the mouse coords. So it would be like teleportation.
Advertisement
Check out the D3DXVec3Unproject() function. It takes a vector from screen space (your mouse click) and gives you back the object-space vector (your insertion point). If you ever need it, D33DVec3Project() takes an object space vector and gives you back the screen space vector.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
Hi, I am using managed dx9 with c# but I looked up that function and got what is was in c#.
I have a vector3 that I pass my mouse coords in the first param, and all the others I just pass my device stuff. But when I output the the vector the increment is really small, so my guy just move a couple pixels when I point to the other side of the screen. Am I using this right?

m_ObjectSpace = Vector3.Unproject(				new Vector3(m_XPos, m_YPos, 0f),				d3ddevice.Viewport, d3ddevice.Transform.Projection,				d3ddevice.Transform.View, d3ddevice.Transform.World);
Actually you need to call Vector3.Unproject two times, both with x,y set to mouse pos but different z value (0 and 1 should be ok).

Since transforming from 2d (screen) to 3d (the world) you cannot tell how "far" into the 3d screne you are pointing. One 2d point is actually a whole line of 3d points.

By calling two times with different z values you get two different points on that line. Now you can use that points as a ray to do intersection tests. You have to calculate where that line intersects your quad (box?). The intersection point will give you the real position where your model needs to move to.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Yah I dont know math very well. So I dont know what your saying about intersection tests. Can't I use the two points to come up with the real points the mouse is pointing to?
Yes, that's what's intersection test is for.

Imagine a line between the two points. The real point you want to find is somewhere on that line. So you have to calculate an intersection between the quad and the line. If it's a quad you can use three corner points and construct a plane from it (in C++ it's D3DXPlaneFromPoints).
Then there's a function called D3DXPlaneIntersectLine, where you simply insert the two points and the plane, and get a resulting vector. This is the exact point under the mouse on the surface of the quad.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

I would recommend reading some tutorials or a book that covers picking or ray intersections. You really need to understand what's going on before you can do what you need to do, i.e. you may have to learn the math. It's not as hard as it sounds though. The point where the mouse is on the monitor is dependant on several things: 1) Your view point (i.e. the direction and angle of your camera), 2) The projection matrix, and 3) the depth you are pointing at. Let's minimize a lot of these effects by setting up a 90 degree FOV projection and placing the camera at 0,1,0 looking in the 0,1,1 direction. You're looking straight down the z axis just 1 unit above the xz plane. Let's say there are 20 objects in front of you, one right behind the next. You click on the front-most object...but which one did you really click on? The front one? But the mouse cursor is also over the very last object...this is why you must test for the first object you hit (if that's what you want to do).

It's also why your 2D point on the screen is a 3D line (pointing straight down the z axis right through the middle of all 20 objects). You can define this line with 2 points. You call the unproject function at (z=0 and z=4) or (z=0 and z=20), just as long as the z value changes and it's in front of the camera. The two points you get from doing that can then be used to create a directional vector, which will be used to do intersection tests (that is, see if the vector intersects with an object).
Chris ByersMicrosoft DirectX MVP - 2005
Thanks for the help but It is moving too much and not exactly where the mouse is at

m_ObjectSpace = Vector3.Unproject(				new Vector3(m_XPos, m_YPos, 0f),				d3ddevice.Viewport, d3ddevice.Transform.Projection,				d3ddevice.Transform.View, d3ddevice.Transform.World);m_ObjectSpace2 = Vector3.Unproject(				new Vector3(m_XPos, m_YPos, 1f),				d3ddevice.Viewport, d3ddevice.Transform.Projection,				d3ddevice.Transform.View, d3ddevice.Transform.World);Plane plane = Plane.FromPoints(					new Vector3(-1000f, -50f, -1000f),					new Vector3( 1000f, -50f, -1000f),					new Vector3( 1000f, -50f,  1000f));								Vector3 tmpVec = Plane.IntersectLine(plane,					m_mouse.ObjectPos, m_mouse.ObjectPos2);				person.Move(tmpVec.X, 0f, tmpVec.Z);
Do you guys know if theres a math book that goes over some of these advanced topics.
You need to understand more than the math. You need to understand the reason for transformations, how the projection, camera, world, and local coordinates all come together to get a point on a view plane to see the image that you want. Some good beginner gaming books will have that. I think there's one in the Andre LaMothe series called Tips and Tricks of the Gaming Gurus or something to that nature. It covers a lot of that in detail. There are others as well. I'll take a look in my library when I get home and try to post some others tonight.

Chris
Chris ByersMicrosoft DirectX MVP - 2005

This topic is closed to new replies.

Advertisement