On picking an object...

Oct 21, 2011 at 2:17 AM

Picking works beautifully! I have a few hundred cloned models and I can construct a ray from the mouse coordinates, search the scene, retrieve a list of hits, sort them in distance order, pick the first and then highlight it (by diddling with the material lighting). Works perfectly, and with great precision.

Suggestions and questions.

  1. I couldn't find anything to create a ray so I rolled my own. Actually, I added it to the camera because that's the logical place for it. (which also means the camera needs to keep the Viewport).
  2. The returned list of hits includes the scene itself, sky box and all the lights, all at distance zero. I had to filter them out. Q: Is that right?
  3. I couldn't work out whether the model hits are based on bounding box or mesh. Obviously mesh is more accurate. Q: Which is it?
  4. I couldn't find anything to sort the list of hits or find the closest, so I wrote my own (one line of Linq). Could be a useful addition to Scene.

It seems to me that this combo of creating a ray and picking the nearest model out of a scene, based on mesh rather than bounding box, is going to be a pretty common need.

Viewport Camera.Viewport { get; set; } // also sets the aspect ratio
Ray Camera.GetRay(float x, float y);
T Scene.Find<T>(Ray ray);

Oct 26, 2011 at 12:46 PM
Q1: Use this extension method GraphicsDevice.Viewport.CreatePickRay. But camera seems to be more fit to put this method.
Q2: Well yes, because Scene.FindAll will return all objects that intersects the ray.
Q3 & Q4:
It is based on the bounding box of the objects added to the scene. So it is a rough query. To get more precise result, you should test to see if the returned object is IPickable and call the IPickable.Intersects. For terrains, it will test against the heightmap precisely, for models, if the model is processed using ExtendedModelProcessor and GenerateCollisionData is turned on, it will test against a octree approximation of that model (Precision can be controlled by ExtendedModelProcessor.CollisionTreeDepth), otherwise it just test against the bounding box of eath model mesh. I haven't test it though.

I was about to add these more precise ray casting and sorting methods to Scene, just didn't found a good signature for them:D
Oct 27, 2011 at 12:32 AM

Q1. Yes, I knew about that method but Viewport was not available in the function where I was doing the picking. Much more sensible to keep it with the camera IMHO.

Q2. IMHO finding lights, sky box and scene is not useful. I think they could be taken out easily by setting the bounding box to null or empty, and nothing useful is lost.

Q3. The bounding box test is a good start. It would be useful to be able to refine that by using the bounding sphere and/or intersection with the mesh for more realistic results. I can't see how to do that at present.

Q4. The three function signatures provided are my suggestions . My camera implementation has Viewport and GetRay.