Firing the Beam


Picking with a Mouse Click

Picking projects a pick shape (usually a line or ray) into the scene from the user's viewpoint through the mouse pointer position on screen until it intersects with a shape in the scene (see Figure 23-3).

Java 3D's PickCanvas class is used to turn a mouse click into a ray (a PickShape object). Java 3D finds the pickable shapes that intersect with the PickShape object, returning them as a list of PickResult objects. Returning the PickResult object closest to the viewer is possible.

A single PickResult may contain many PickIntersection objects, which hold the data for each intersection of the shape (e.g., the ray may go through the front and back face of a shape, leading to two intersection points).

The complexity of the picking coding is somewhat alleviated by using Java 3D's PickMouseBehavior utility class, a subclass of Behaviour, which hides much of the picking mechanism. The general format for a subclass of PickMouseBehavior is given in Example 23-1.

Example 23-1. A typical PickMouseBehavior subclass
     import javax.media.j3d.*;     import com.sun.j3d.utils.picking.PickTool;     import com.sun.j3d.utils.picking.PickResult;     import com.sun.j3d.utils.picking.behaviors.PickMouseBehavior;         // other imports as necessary...             public class ExamplePickBehavior extends PickMouseBehavior     {       public PickHighlightBehavior(Canvas3D canvas, BranchGroup bg, Bounds bounds)       { super(canvas, bg, bounds);         setSchedulingBounds(bounds);             pickCanvas.setMode(PickTool.GEOMETRY_INTERSECT_INFO);            // allows PickIntersection objects to be returned       }           public void updateScene(int xpos, int ypos)       {         pickCanvas.setShapeLocation(xpos, ypos);             // register mouse pointer location on the screen (canvas)             Point3d eyePos = pickCanvas.getStartPosition(  );             // get the viewer's eye location             PickResult pickResult = null;         pickResult = pickCanvas.pickClosest(  );             // get the intersected shape closest to the viewer             if (pickResult != null) {           PickIntersection pi =  pickResult.getClosestIntersection(eyePos);                 // get the closest intersect to the eyePos point            Point3d intercept = pi.getPointCoordinatesVW(  );                // extract the intersection pt in scene coords space           // use the intersection pt in some way...         }       } // end of updateScene(  )         } // end of ExamplePickBehavior class 

The constructor must pass the Canvas3D object, a BranchGroup, and bounds information to the superclass for the superclass to create a PickCanvas object and a PickShape. The PickCanvas object, pickCanvas, is available and can be used to configure the PickShape, such as changing the pick shape from a ray to a cone or adjusting the tolerance for how close a shape needs to be to the PickShape to be picked.

Many subclasses of PickShape (e.g., PickRay, PickCone, PickCylinder) specify different kinds of ray geometries; the default one employed by PickMouseBehavior is a line (PickRay). PickCanvas is intended to make picking based on mouse events easier. It's a subclass of PickTool, which has several additional methods for changing the pick shape and specifying what is returned by the picking operation.

The call to pickCanvas.setMode( ) in ExamplePickBehavior's constructor sets the level of detail for the returned pick and intersection data. The various modes are:


BOUNDS

This mode tests for intersection using the bounds of the shapes rather than the shapes themselves, so is quicker than the other two modes.


GEOMETRY

This mode uses the actual shapes in its tests, so is more accurate than the BOUNDS mode. The BOUNDS and GEOMETRY modes return the intersected shapes is.


GEOMETRY_INTERSECT_INFO

This mode tests for intersection using the shapes and returns details about the intersections, stored in PickIntersection objects. The level of detail is controlled by the capabilities set in the shapes using PickTool's setCapabilities( ) method.

From Mouse Click to Picked Object

The PickMouseBehavior class contains fully implemented initialize( ) and processStimulus( ) methods, which should not be changed when PickMouseBehavior is subclassed. Instead, the programmer should implement the updateScene( ) method, which is called whenever the user clicks the mouse buttonthis method is passed the (x, y) coordinate of the mouse click on the screen (the Canvas3D).

The first step in updateScene( ) is to call setShapeLocation( ) to inform pickCanvas of the mouse position so the PickShape (the ray) can be cast into the scene. The intersecting shapes can be obtained in various ways: pickClosest( ) gets the PickResult object closest to the viewer. There are other methods:

     PickResult[] pickAll(  );     PickResult[] pickAllSorted(  );     PickResult pickAny(  ); 

The first two return all the intersecting shapes, with the second method sorting them into increasing distance from the viewer. pickAny( ) returns any shape from the ones found, which should be quicker than finding the closest.

Finding Intersections

A PickResult will usually refer to a Shape3D containing a GeometryArray subclass made up of many surfaces. All the intersections between the shape and the ray can be obtained in the following way:

     PickIntersection pi;     for (int i = 0; i < pickResult.numIntersections(  ); i++) {       pi = pickResult.getIntersection(i);       // use pi in some way...     } 

More commonly, the intersection closest to some point in the scene is obtained:

     PickIntersection pi = pickResult.getClosestIntersection(pt); 

In ExamplePickBehavior, the point is the viewer's position, which is extracted from pickCanvas with getStartPosition( ).

A PickIntersection object can hold much information about the GeometryArray, such as the point, line, triangle, or quad that was intersected. The intersection point can be retrieved in terms of the picked shape's local coordinate system or in terms of the scene's coordinate system. If the picking level for the shape is INTERSECT_FULL, then there will be details about the closest vertex to the intersection point, and the color, normal and texture coordinates at the intersection point.

The call to getPointCoordinatesVW( ) obtains the intercept point in the scene's coordinate space:

     Point3d intercept = pi.getPointCoordinatesVW(  );  



Killer Game Programming in Java
Killer Game Programming in Java
ISBN: 0596007302
EAN: 2147483647
Year: 2006
Pages: 340

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net