2
\$\begingroup\$

I'm working on a XNA project (not really a game) and I'm having some trouble with picking algorithm. I have a few types of 3D models that I draw to the screen, and one of them is a switch. So I'm trying to make a picking algorithm that would enable the user to click on the switch and that would trigger some other function. The problem is that the BoundingSphere.Intersect() method always returns null as result. This is the code I'm using:

In the declaration section: `

//Basic matrices
private Matrix world = Matrix.CreateTranslation(new Vector3(0, 0, 0));
private Matrix view = Matrix.CreateLookAt(new Vector3(10, 10, 10), new Vector3(0, 0, 0), Vector3.UnitY);
private Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 600f, 0.01f, 100f);

//Collision detection variables
Viewport mainViewport;
List<BoundingSphere> spheres = new List<BoundingSphere>();
Ray ControlRay;
Vector3 nearPoint, farPoint, nearPlane, farPlane, direction;

`

And then in the Update method: `

nearPlane = new Vector3((float)Mouse.GetState().X, (float)Mouse.GetState().Y, 0.0f);
farPlane = new Vector3((float)Mouse.GetState().X, (float)Mouse.GetState().Y, 10.0f);

nearPoint = GraphicsDevice.Viewport.Unproject(nearPlane, projection, view, world);
farPoint = GraphicsDevice.Viewport.Unproject(farPlane, projection, view, world);

direction = farPoint - nearPoint;
            direction.Normalize();
            ControlRay = new Ray(nearPoint, direction);                      
            if (spheres.Count != 0)
            {
                for (int i = 0; i < spheres.Count; i++)
                {
                    if (spheres[i].Intersects(ControlRay) != null)
                    {
                        Window.Title = spheres[i].Center.ToString();
                    }
                    else
                    {
                        Window.Title = "Empty";
                    }
                }

`

The "spheres" list gets filled when the 3D object data gets loaded (I read it from a .txt file). For every object marked as switch (I use simple numbers to determine which object is to be drawn), a BoundingSphere is created (center is on the coordinates of the 3D object, and the diameter is always the same), and added to the list. The objects are drawn normally (and spheres.Count is not 0), I can see them on the screen, but the Window title always says "Empty" (of course this is just for testing purposes, I will add the real function when I get positive results) meaning that there is no intersection between the ControlRay and any of the bounding spheres. I think that my basic matrices (world, view and projection) are making some problems, but I cant figure out what. Please help.

\$\endgroup\$
3
  • \$\begingroup\$ Try to use this: farPlane = new Vector3((float)Mouse.GetState().X, (float)Mouse.GetState().Y, 0.99f); \$\endgroup\$
    – Vodáček
    Jun 28, 2012 at 11:05
  • \$\begingroup\$ Yes that worked, thanks. Could you please explain to me why this works and my version does not (this is a part of a school project so I need to be able to explain every detail of the program) \$\endgroup\$
    – NDraskovic
    Jun 28, 2012 at 11:13
  • \$\begingroup\$ ok, I will write answer \$\endgroup\$
    – Vodáček
    Jun 28, 2012 at 11:14

1 Answer 1

1
\$\begingroup\$

Your mistake is hidden in this line:

farPlane = new Vector3((float)Mouse.GetState().X, (float)Mouse.GetState().Y, 10.0f);

this vector represents position in screen space. 0,0 is on upper left corner. Z here represents depth in range from 0 to 1. So value 10 is not correct. You must use this:

farPlane = new Vector3((float)Mouse.GetState().X, (float)Mouse.GetState().Y, 0.99f);

Something more about ray picking can be found here: http://www.innovativegames.net/blog/blog/2009/03/17/picking/

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I added link to Sean James blog, perhaps it will help you. \$\endgroup\$
    – Vodáček
    Jun 28, 2012 at 11:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .