Convert mouse 2d to 3d, DirectX C#

Started by
4 comments, last by DX_test000 17 years, 10 months ago
How do you convert the mouse 2d screen coordinates to 3d coordinates? I have the code to calculate a ray to find the intersect an object which works fine, after I have selected an object, I want to move the object to the position that the user has clicked. I want to use the same Z coordinate of the selected object but then translate the object to the mouse positon. Any ideas? The pick code I am using is: near = new Vector3(mouseX, mouseY, 0); far = new Vector3(mouseX, mouseY, 1); near.Unproject(_device.Viewport, _camera.Projection, _camera.View, World); far.Unproject(_device.Viewport, _camera.Projection, _camera.View, World); far.Subtract(near); // Retrieve intersection information IntersectInformation closestIntersection; intersects = Test.mesh.Intersect(near, far, out closestIntersection);
Advertisement
Also I have seen the use of GLUUNPROJECT in open GL to do this, is there a directX funtion to do the same?
So you've picked your object, and then the user clicks somewhere else and you want to move it under their mouse, so that it seems to be at the same distance ?

If so ...

you need to work out the distance of the object from the screen when you pick it, then move it along the new positions' ray that distance ...

once you know which mesh was picked, you can work out the distance using:
float length = Vector3.Length(meshPosition - near);

then, when you have your new ray (formed the same way as the original picking ray), you can work out where along it to place the mesh:
Vector3 newPosition = near + length * (far - near);

Hope thats what you were asking.


Wyzfen
oh - and been in Adelaide long ? I finally escaped last year :)

I have tried what you sugested but this did not work.

in my code the last parameter "world" is the position of the object that the user has clicked on.

if the object is at 10,10,0 and the camera is at 0,0,-100.
If I calculate the lenght I get 23.

When I calculate the near and far for where the mouse has been clicked I use the world as the identity.

Therefore I get a very large far point. Then when I * that with the lenght I get very large numbers. This does not look correct to me.

This must be very common code for many games but I can't find an example.

Yep, been living in Adelaide all of my life. :)
Any help is appreciated.


THIS IS THE PICK CODE:
World = object.World;
near = new Vector3(mouseX, mouseY, 0);
far = new Vector3(mouseX, mouseY, 1);

near.Unproject(_device.Viewport, _camera.Projection, _camera.View, World);
far.Unproject(_device.Viewport, _camera.Projection, _camera.View, World);
far.Subtract(near);

// Retrieve intersection information
IntersectInformation closestIntersection;
intersects = Test.mesh.Intersect(near, far, out closestIntersection);

if (intersects)
_length = Vector3.Length(object.Position - near);


THIS IS THE CODE I USE WHEN THE USER CLICK ON ANOTHER POINT.
near = new Vector3(MousePosition.X, MousePosition.Y, 0);
far = new Vector3(MousePosition.X, MousePosition.Y, 1);

World = Matrix.Identity;
near.Unproject(_device.Viewport, _camera.Projection, _camera.View, World);
far.Unproject(_device.Viewport, _camera.Projection, _camera.View, World);
far.Subtract(near);

Vector3 newPosition = near + _length * (far - near); ;
_clicked.X = newPosition.X;
_clicked.Y = newPosition.Y;



Thanks
Aha. I thought there might be a use for Vector3.Project. Found this solution somewhere else, but havent tried it myself yet.

So, once you've tested for intersection, you use:

Vector3 position = object.Position;
position.Project(_device.Viewport, _camera.Projection, _camera.View, World);

That gives the screen coordinates for your object at its original position.

Now, to set that to the new mouse location;

position.X = newScreenPosition.X;
position.Y = newScreenPosition.Y;
(the z stays the same - thats the trick)

And finally, re-unproject it back into 3d space:

position.Unproject(_device.Viewport, _camera.Projection, _camera.View, World);

and theres your new position.
object.Position = position;

of course, that centres the object on the new position, if you want it to have the same offset as when you clicked it, you need to take that into account.

let me know if that works - i'll be needing it myself in a few days :)

Wyzfen

Excellent, Works fine, thanks for your help.

Couldn't have worked that out myself.

Thanks.

This topic is closed to new replies.

Advertisement