Picking

From JPCT
Revision as of 20:28, 6 September 2010 by Admin (Talk | contribs)

Jump to: navigation, search

Picking

Picking in jPCT can be implemented in two ways. One of these ways is usually a bit faster but doesn't work for compiled objects, while the other one works for all objects but might be a bit slower.


The fast way

As said, this doesn't work on compiled objects. If you are using the software renderer only or the hardware renderer in hybrid mode (i.e. without compiled objects), it's save to use though. To use this way, you have to make the objects in questions "selectable". You can do this be calling

obj.setSelectable(Object3D.MOUSE_SELECTABLE);

on your objects. Then, you render the scene and get your picking coordinates from your input device in screen space. Most likely mouse coordinates or similar. Then you do this:

SimpleVector dir=Interact2D.reproject2D3D(camera, frameBuffer, x, y);
int[] res=Interact2D.pickPolygon(world.getVisibilityList(), dir);

In res, you'll find the polygon- and the object number (in that order), if the picking actually picked something. If not, res is null. Your picked Object3D is now

Object3D picked=world.getObject(res[1]);

Please note that there are two variants of the pickPolygon-methods. The simple one (see above) makes unselectable objects act as a block to the picking ray, i.e. even if an object isn't selectable, it will still block the ray so that no object behind that object can be picked.

The compatible way

This works with all renderers and all objects, but depending on the scene it might by a bit slower. It's the only one that is available in jPCT-AE. Unlike the former approach, this is actually a kind of collision detection, which is why it triggers collision events too. Just like above, you have to make your objects pickable. However, because it's a collision detection, this works different. Instead of using setSelectable(...), you have to use setCollisionMode(...). For example:

obj.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);

Like above, you need your 2D picking coordinates. With them, you need a direction vector in world space. This is simple:

SimpleVector dir=Interact2D.reproject2D3DWS(camera, frameBuffer, x, y);

Armed with this vector, you can now go to World and do

Object[] res=world.calcMinDistanceAndObject3D(camera.getPosition(), dir, 10000 /*or whatever*/);

The result is an Object[]-array with the Float-distance to the picked object in the first slot and the picked Object3D in the second. If nothing has been hit, the result will be [COLLISION_NONE, null].