19.1.2 ObjectPickMapper class
The pick engine is truly only an engine; it does not handle or generate any events.
Event generation is, instead, the duty of the ObjectPickMapper class, which converts
input movement and drags into target object picks, including "no target" picks. The
picking itself is handled through delegation to a PickEngine object configured with
the desired pick root and target list. Both continuous and discrete picking modes are
supported. For continuous picking, pick events are reported only when the target
object changes, and not when the pick cursor moves, which helps to keep event handling
overhead to a minimum.
Picking modes
To accommodate various flavors of discrete and continuous picking, several methods
are provided. These methods affect only the mode of pick reporting for input drag
events. Continuous pick reporting, as a result of input movement events, is not
affected by these modes. The different modes can be combined, with the result being
an ORing of object pick events. The setDoPick method specifies that the pick tar-get
is reported when a drag starts, and no target is reported when the drag stops. This
is the default mode. The setDoDrag method specifies that the pick target is
reported only when the drag starts, which is useful for triggering the drag portion of a
drag-and-drop operation. The setDoDrop method specifies that the pick target is
reported continuously during the drag, and when the drag stops, which is useful for
tracking drop targets.
ObjectPickTarget interface
Pick reporting requires a new event interface. The ObjectPickTarget interface
reports both the pick index and the pick object. In general, the pick index should be
used if the event target has knowledge of the pick engine's target list, because it
uniquely identifies the object in the list (and the object reference may not). If the
event target is not privy to the target list, or if the pick event originates from a pick
process that does not use a list, then the pick object must be used. It is important to
keep these alternative uses of the event in mind when generating or handling
ObjectPickTarget events because some event targets use one or the other exclusively.
As with all other framework events, the event has a corresponding ObjectPickSplitter
class.
19.1.3 OverEnableMapper class
Knowing which object was picked using a pick engine and an object pick mapper is
only two thirds of the solution when it comes to mouseover object control. The
framework provides the last third of the solution in the form of the OverEnableMapper
class. To use this class, you have to create a list of control targets that implement
the EnableTarget interface, with a one-to-one correspondence between the event
targets in this list and the pick targets in the pick engine's target list, such as that used
by an ObjectPickMapper object. When a new target is picked, as indicated by the
input ObjectPickTarget event interface, any previous enable target is disabled
and the one corresponding to the new pick is enabled. Note that OverEnableMapper
uses only the index parameter in its input event interface.
For convenience, two special-purpose control targets can be set in addition to, or
in lieu of, the event list targets. The setEventTargetAny method establishes an
enable target that is notified when any target is picked; the setEventTargetNone
method establishes an event target that is notified when no target is picked.
19.1.4 Example: OverEnabling
This example demonstrates object picking and mouseover enabling of control inputs.
See
The virtual world contains four target objects: three in a central column (red, green,
blue) and one to the right (magenta). A screen shot is provided in figure 19. 2.
Do
- Drag the mouse (left button with SHIFT) in the display or use the arrow keys
(with SHIFT) to orbit the view in heading and elevation about the world origin.
- Drag the mouse (left button) on the top (red) target or use the ARROW keys to
translate it along the world X-Y axes.
- Drag the mouse (left button) on the
middle (green) target or use the ARROW
keys to rotate it about the world Y axis.
- Drag the mouse (left button) on the
bottom (blue) target or use the ARROW
keys to scale it along the world x-y axes.
- Drag the mouse (left button) on the
right (magenta) target or use the ARROW
keys to roll the target like a trackball.
- Repeat the drag operations from different
view directions.
Observe
- All target operations use mouseover to
enable the operation.
- Target picking can differentiate between
parent (green thing) and child (magenta thing) in the scene graph.
- All target operations use the first mouse button and no MODIFIER keys.
- All coordinate mapping is static, meaning that manipulation of targets will seem
nonintuitive if the view is not head-on.
The general structure of the code for this example is similar to that in the previous
example, which demonstrated actuator groups, but with one important difference.
In this example, the utility building block buildOverEnabler from the
IntuitiveBlocks class is used to perform overenabling of the target actuators. The first
code sample below is from the OverEnabling example class. It shows those portions
that deal with the translation target and overenabling. The second sample is from the
utility class. It shows how the utility building block combines the framework's core
building blocks for picking with move and drag sensors into a single convenient module
for overenabling.
Translation control and overenabling
Filename: J3duiBook/ examples/ OverEnabling/ OverEnabling. java
...
// setup manipulation targets
/// translation target
AffineGroup affineXlt= new AffineGroup( new TestThing(
TestThing.BOX_TRANSLATION, TestThing.BALL_DEFAULT));
getWorld().addSceneNode(BasicBlocks.buildTarget(
affineXlt, new Vector3d( 0, 3, 0))[ 0]);
...
// setup manipulation controls
InputDragMapper mapper;
/// translation, first button
mapper = ActuationBlocks.buildDirectMapper(
affineXlt.getTranslation(), new Vector2d(. 025, .025),
Mapper.DIM_X, Mapper.DIM_Y, true);
ActuationBlocks. buildRelativeDragger( mapper,
getView(), Input.BUTTON_FIRST,
Input.MODIFIER_NONE, Input.MODIFIER_NONE);
...
// setup over management
ArrayList pickList, enableList;
pickList= new ArrayList();
pickList.add( affineXlt);
pickList.add( sphere);
pickList.add( affineRot);
pickList.add( affineScl);
enableList = new ArrayList();
enableList.add( <affineXlt);
enableList.add( sphere);
enableList.add( affineRot);
enableList.add( affineScl);
IntuitiveBlocks. buildOverEnabler( getView(),
getWorld().getSceneRoot(), >pickList, enableList);
...
Utility block combining core blocks for overenabling
Filename: J3duiBook/ lib/ j3dui/ utils/ blocks/ IntuitiveBlocks. java
...
/**
Creates mouse move and drag sensors, an object picker, and
an over enabler and connects them together for continuous
target picking and enabling, whether during mouse movement
or dragging. All enable targets will be initialized as if
no target was picked.
@param view Source display.
@param pickRoot Scene graph pick root.
@param pickList List of pick targets.
@param enableList List of enable targets corresponding to
the targets in the pick list.
*/
public static final OverEnableMapper buildOverEnabler(
AppView view, BranchGroup pickRoot, ArrayList pickList,
ArrayList enableList) {
// setup over target enabling
OverEnableMapper enabler = new OverEnableMapper();
enabler.setEventTargets(enableList);
enabler.initEventTargets(-1);
// setup continuous target picking
ObjectPickMapper picker = new ObjectPickMapper( enabler,
new PickEngine( pickRoot, pickList));
/// generate mouse position for any move or drag
MouseDragSensor dragger = new MouseDragSensor( picker,
view.getDisplay(), view.getRoot());
dragger.setButtons( Input.BUTTON_ALL);
MouseMoveSensor mouseMove = new MouseMoveSensor(
picker, view.getDisplay(), view.getRoot());
return enabler;
}
...
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|