Two questions about picking

Have jReality programming problems or questions? Post them here.
Post Reply
olaf
Posts: 16
Joined: Mon 16. Feb 2009, 05:24
Location: Australia
Contact:

Two questions about picking

Post by olaf » Tue 24. Mar 2009, 08:15

1) How can I change the sensitivity of picking? I've noticed that if I have two objects A and B with A in front of B, then sometimes A is picked even if the whole mouse pointer is clearly off A. What I'd like to do is tell the toolsystem to pick only objects within, say, 3 pixels of the current mouse position.

2) What is a good way to implement a 'rubberband' selection (marking a rectangular region of the screen by dragging and then selecting all objects or faces that have non-obscured portions within that region)?

User avatar
gunn
Posts: 323
Joined: Thu 14. Dec 2006, 09:56
Location: TU Berlin
Contact:

Post by gunn » Tue 24. Mar 2009, 13:20

This is in response to your first question.

As I understand the pick system, the behavior you describe is incorrect. There could be a number of explanations. In any case it would help to have more information about the pick which is being returned. This is provided by the method toString() on the class PickResult, which is the type of tc.getCurrentPick() (tc is the ToolContext). I've recently edited this method to include the pick type also, so best results will be provided by first updating jReality.

Once you have this information, the next question is, is the type of the pick valid? There are two ways that picking of points can be ''turned off'': The first is that you have used the method PickUtility.setPickable(...) to turn off picking of points.
The second is that drawing of points has been turned off using the Appearance attribute CommonAttributes.EDGE_DRAW.

If either of these methods have been used to turn off picking of points, then it is a mistake for the pick type to be "point".

If the pick type is wrong, that would explain why it appears that the cursor is not over object A but is picking object A nonetheless. If on the other hand the pick type is a valid type, there's still one more possible explanation:

It may be that the pick type is "point", and that drawing and picking of points is enabled, but you are not rendering spheres (attribute CommonAttributes.SPHERES_DRAW is false). The pick system picks ''as if'' spheres are being drawn! So , it could calculate a pick point that is visibly incorrect since the non-sphere rendering might be significantly smaller (in pixel space) than the sphere rendering. In this case, set SPHERES_DRAW to true and see if the picking error persists. (The same strategy can also be applied in the case of edges and tubes if the pick type is "edge").

I suppose it goes without saying that the TODO list for the developer tutorial has just been expanded by one topic!

Regarding your second question, I'll have to think a bit about it before responding. It would be useful to have such a selection tool as part of the jReality distribution!
jReality core developer

olaf
Posts: 16
Joined: Mon 16. Feb 2009, 05:24
Location: Australia
Contact:

Post by olaf » Tue 24. Mar 2009, 14:56

Many thanks! I was not drawing spheres or tubes. Setting both POINT_RADIUS and SPHERE_RADIUS to sufficiently small values solved the problem.

User avatar
gunn
Posts: 323
Joined: Thu 14. Dec 2006, 09:56
Location: TU Berlin
Contact:

Post by gunn » Wed 1. Apr 2009, 10:08

I haven't had any great insights on this. The only idea I've had is kind of brute force: Convert the dragged-out rectangle into a 3D frustum and sample it with a regular array of rays using the PickSystem.computePick() method. This returns a list of hits; merge the front hits (you might also want to use ALL the hits in some cases) from ALL the rays and extract the information you want at the level you want (SGC, geometry, face, etc).

Assuming you find a reasonable way to highlight the objects you have selected (there is a SelectionRenderer class in the tutorial.util package which draws wireframe bounding boxes, but that's about all there is in jreality), you could continue shooting rays as long as the user holds down the mouse button, so that you could visually test if all the objects you're hoping to select have been selected. If you have a fine array of polygons, it might take a while until all have been hit by a ray.

Further suggestion: Inside of the tool you can use tc.getPickSystem() to get an implementation of PickSystem(), otherwise you can use an instance of AABBPickSystem as implementation of PickSystem.
jReality core developer

olaf
Posts: 16
Joined: Mon 16. Feb 2009, 05:24
Location: Australia
Contact:

Post by olaf » Wed 1. Apr 2009, 10:26

Thanks! I'm not sure I like the sampling idea too much, but since my geometries and scene graphs are very simple in the case I'm looking at, I might be able to write something up that intersects the geometry directly with the selected frustrum.

What's a good way to compute the ray corresponding to the current mouse position in world coordinates from inside a tool?

User avatar
gunn
Posts: 323
Joined: Thu 14. Dec 2006, 09:56
Location: TU Berlin
Contact:

Post by gunn » Fri 3. Apr 2009, 13:25

The method getCurrentPick() on the ToolContext instance passed into the perform(), activate(), and deactivate() methods (on Tool) returns a PickResult of the frontmost hit (or null if nothing was hit) obtained by casting a ray from the camera position through the current cursor position out into the world.

The nitty-gritty of how this is done is in the class de.jreality.toolsystem.ToolSystem, but it sounds like you might be able to get by by using the getCurrentPick() method and avoid having to look under the hood.
jReality core developer

User avatar
gunn
Posts: 323
Joined: Thu 14. Dec 2006, 09:56
Location: TU Berlin
Contact:

Post by gunn » Fri 3. Apr 2009, 22:37

Forgot to mention: de.jreality.scene.pick.PickResult contains all the important information about the picked object. Just look at the javadoc.
jReality core developer

Post Reply