detect mouse over 3d model

Started by
18 comments, last by Waterwalker 15 years ago
I am programming wheel of fortune.You know that user select letter to solve puzzle.My problem is to detect which letter is clicked.I generate Ray with mouse corrdinates.Then for 26 letters,I tried to detect collision using BoundingSphere. this is the piece of code.Please help. private bool mouseOverModel(MouseState mouseState) { Vector3 nearScreenPoint = new Vector3(mouseState.X, mouseState.Y, 0); Vector3 farScreenPoint = new Vector3(mouseState.X, mouseState.Y, 1); Vector3 near3DWorldPoint = graphics.GraphicsDevice.Viewport.Unproject(nearScreenPoint, cameraProjectionMatrix, cameraViewMatrix, Matrix.Identity); Vector3 far3DWorldPoint = graphics.GraphicsDevice.Viewport.Unproject(farScreenPoint, cameraProjectionMatrix, cameraViewMatrix, Matrix.Identity); Vector3 pointerRayDirection = far3DWorldPoint - near3DWorldPoint; pointerRayDirection.Normalize(); Ray pointerRay = new Ray(near3DWorldPoint, pointerRayDirection); for(int i=0;i<alphabet.Length;i++) { BoundingSphere collision = new BoundingSphere(); collision.Radius = alphabet.scale; collision.Center = alphabet.position; Nullable<float> dist = pointerRay.Intersects(collision); if (!dist.HasValue) { return false; } if (dist.Value <= pointerRayDirection.Length())//check whether it is the closest object intersected so far. { selectedLetterIndex = i; alphabet.isclicked = true; Console.WriteLine(selectedLetterIndex); return true; } } return false; }
Advertisement
What exactly is your problem? For letters it would probably be better to use a bounding box the size of your characters. Spheres may intersect with eachother.
Portfolio & Blog:http://scgamedev.tumblr.com/
you are right.I use BoundingSphere.I don't know how to use BoundingBox.I want to find which letter is clicked.Can you see any fault in my code.
if (dist.Value <= pointerRayDirection.Length())//check whether it is the closest object intersected so far. 

Nope. The only thing you are checking with this test is whether the intersection point is closer to the viewer than the length of the ray. Since you normalized the ray this distance is 1.0 in world space. Do not confuse this with the depth ranging from 0.0 to 1.0 of the 2d points you unproject.

You have to store the first dist that has a value and compare all following valid distances against that one distance. Each time you have a closer distance then store that one. Assuming that all of your letters are next to each other it is valid to return true upon the first hit because it will then be the only one possible:

float best_hit = MAX_FLOAT;for(int i=0;i<alphabet.Length;i++){BoundingSphere collision = new BoundingSphere();collision.Radius = alphabet.scale;collision.Center = alphabet.position;Nullable<float> dist = pointerRay.Intersects(collision);if (dist.HasValue && dist.Value <= best_hit)//check whether it is the closest object intersected so far. {selectedLetterIndex = i;alphabet.isclicked = true;Console.WriteLine(selectedLetterIndex);best_hit = dist.Value; // if you do not want to return upon first hit this is requiredreturn true;}
------------------------------------I always enjoy being rated up by you ...
Waterwalker your answer is logical.It can work.But I could't understand what can I wrote for MAX_FLOAT value.Can you help.
Um ... sorry that is actually FLOAT_MAX as defined in <limits> that you need to include. This represents infinity in this case and stands for "I have not found any intersection yet".
------------------------------------I always enjoy being rated up by you ...
I don't want to seem lazy.But I am searching for FLOAT_MAX in XNA and <limits>.But I couldn't related things.Can these library can be c++ or anything else.I couldnt find in XNA.
Assuming you're using C# you can use Single.MaxValue to get the maximum value a float can hold. If not using C#, please mention what language you are using.
I am using c# and discovered float.MaxValue.I ran the code after applying changes.Bıt it doesn't work.
How do you render the letters?

If they are textured quads then it should be strait forward: as you print the letters just store coordinates for each quad in a array and then use that array to search for the quad mouse cursor is inside (in screen space).
Crush your enemies, see them driven before you, and hear the lamentations of their women!

This topic is closed to new replies.

Advertisement