Jump to content

  • Log In with Google      Sign In   
  • Create Account

Getting a mouse position in 3D


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 18 June 2013 - 09:31 PM

I've looked at a few tutorials on picking and the Unproject method, so I have an idea of how this is supposed to work. My method does give me back a mouse position, it's just incredibly wrong. A position at 0, 0, 0 would end up to be something like 36, -1, 65. 

 public Vector3 FindWhereClicked(MouseState ms)
    {
        Vector3 nearScreen = new Vector3(ms.X, ms.Y, 0);
        Vector3 farScreen = new Vector3(ms.X, ms.Y, 1);
        Vector3 nearWorld = device.Viewport.Unproject(nearScreen, cam.proj, cam.view, Matrix.Identity);
        Vector3 farWorld = device.Viewport.Unproject(farScreen, cam.proj, cam.view, Matrix.Identity);

        Vector3 direction = farWorld - nearWorld;

        float zFactor = -nearWorld.Y / direction.Y;

        Vector3 zeroWorldPoint = nearWorld + direction * zFactor;

        return zeroWorldPoint;
    }



Variables grabbed from the camera method


  public ThirdPersonCam()
    {
        proj = Matrix.CreatePerspectiveFieldOfView(0.78f, 1.7777f, 1f, 10000f);
    }

    public void CameraUpdate(Matrix objectToFollow)
    {
        Vector3 camPosition = objectToFollow.Translation + (objectToFollow.Backward * 10) + (objectToFollow.Up * 2);
        Vector3 camTarget = objectToFollow.Translation;

        view = Matrix.CreateLookAt(camPosition, camTarget, Vector3.Up);
    }

Is the problem coming from my camera? Or from my FindWhereClicked method?


If you see a post from me, you can safely assume its C# and XNA :)


Sponsor:

#2 frob   Moderators   -  Reputation: 22732

Like
0Likes
Like

Posted 18 June 2013 - 10:59 PM

Finding out where a mouse clicked is not a Vector3 result.

The best mouse result is a volume. Imagine four rays, one at each corner of the pixel, being projected to infinity. Or at least projected to your near and far planes.

An alternative mouse result is a ray through the middle of the pixel, or a line between the near and far plane. You basically have that in your code snippit above. It looks like you correctly computed the two intersections of the mouse point with the near and far plane. I'm not sure why you want to have near and far planes at z=0 and z=1. Seems like a mighty shallow world, but that's your call.

As soon as you computed nearWorld and farWorld your work is done. That is your line. That is the result. Yay!


After that, though, your code drifts to dangerous territory, with divide-by-zeros and INF/NAN propagation when direction.Y == 0. At that point it looks like you are trying to project on to a point on that line, but I'm not really sure why you would want to be doing that.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I write about assorted stuff.


#3 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 18 June 2013 - 11:04 PM

The code I have was taken from a tutorial I found lol. It looked alright in theory... So with my method I should be returning a ray instead of a Vector3?


If you see a post from me, you can safely assume its C# and XNA :)


#4 Endurion   Crossbones+   -  Reputation: 3685

Like
0Likes
Like

Posted 18 June 2013 - 11:27 PM

Yes. When your mouse points at one pixel, in the 3d world it's pointing at it actually covers a line (or ray).

 

With the ray you received you can now calculate intersections with objects or planes to achieve what you probably really want: The first solid object under the mouse.


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

#5 frob   Moderators   -  Reputation: 22732

Like
2Likes
Like

Posted 18 June 2013 - 11:38 PM

The code I have was taken from a tutorial I found lol. It looked alright in theory... So with my method I should be returning a ray instead of a Vector3?

It can be, if that is what you need.

The point I was trying to make is that a mouse in 3D is not a point in space. A mouse in 3D is either a line or a volume.

That leads directly to a question: What are you going to do with the results?

Right now nearWorld and farWorld are at the projected origin and a point just past the projected origin. Does that meet your needs?


If you are going to use the results for a bunch of ray-volume intersection tests, then the pair of points will probably work for you. You can use them in conjunction with a spatial tree and mesh volume tests for an object picker, for example. It can get into expensive tests against meshes if you are looking for a first-hit case and objects can have holes. (Also this method of picking won't work too well when vertex and geometry shaders are in use, but that is beyond For Beginners.) So it may or may not be a good solution if that is your usage.

If you are going to use the results for a bunch of line-line intersection tests, that is probably bad because there is a slim chance they will overlap. In that case you probably want the volume that the pixel covers, and you will probably want to use the actual near and far planes rather than 0 and 1 past the mouse.

If your purpose is something else entirely, the results may or may not be adequate.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I write about assorted stuff.


#6 burnt_casadilla   Members   -  Reputation: 443

Like
0Likes
Like

Posted 18 June 2013 - 11:53 PM

There's going to be a lot of things done eventually. Right now, I'm just trying to place blocks like you would in Minecraft, having them snap to a grid somehow on top of other blocks. But eventually the mouse will be used for a user interface and for the player. The player will be able to choose a spot on the map in front of them and fire a bolt or some kind of projectile. These all seem like things that could be done with a simple ray though. There won't be any clicking and dragging to select more than one object or anything like that. I think I'm pretty much just having the mouse intersect with points on the map is what I'm trying to get at. At those points, something will happen once the mouse has been clicked 


Edited by burnt_casadilla, 18 June 2013 - 11:55 PM.

If you see a post from me, you can safely assume its C# and XNA :)





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS