Find attached an improved version of the Behavior I posted earlier.

--
Renoir Sewjee
Software Engineer
ISS International (Welkom)
Tel: +27 (0)57 912 2702
Fax: +27 (0)57 912 2652
--

/**
 * Picks a point out of a PointArray using a mouse press.
 *
 */

import java.awt.AWTEvent;

import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.InputEvent;

import java.util.Enumeration;
import java.util.ArrayList;

import com.sun.j3d.utils.picking.PickCanvas;
import com.sun.j3d.utils.picking.PickResult;
import com.sun.j3d.utils.picking.PickIntersection;

import javax.media.j3d.Behavior;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.WakeupOnAWTEvent;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.PointArray;

import javax.vecmath.Point3d;

import java.util.ArrayList;
import java.util.Iterator;

import com.sun.j3d.utils.picking.PickTool;

/*
 * In the code the index of the vertex that was picked is written to the standard 
error.  A more elegant
 * way to get this info to your other classes would be to maintain a list of 
PointPickedListeners which
 * you manage with the following methods:
 *
 * addPointPickedListener(PointPickedListener listener)
 * removePointPickedListener(PointPickedListener listener)
 * firePointPickedEvent(PointPickedEvent event)
 *
 */

public class PointPicker extends Behavior
{
    protected PickCanvas pickCanvas;

    protected WakeupOnAWTEvent wakeupCriterion;

    protected int x;
    protected int y;

    public PointPicker(Canvas3D canvas, BranchGroup scene)
    {
        pickCanvas = new PickCanvas(canvas, scene);
        // Objects within this disstance from the mouse location will be picked.
        pickCanvas.setTolerance(3.0f);
        // We want to get info (indices of points) from the intersected geometry (the 
PointArray).
        pickCanvas.setMode(PickCanvas.GEOMETRY_INTERSECT_INFO);
    }

    public void initialize()
    {
        // Wake up when a mouse button is pressed.
        wakeupCriterion = new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED);
        wakeupOn(wakeupCriterion);
    }

    public void processStimulus(Enumeration criteria)
    {
        while (criteria.hasMoreElements())
            {
                WakeupCriterion wakeup = (WakeupCriterion)criteria.nextElement();
                if (wakeup instanceof WakeupOnAWTEvent)
                    {
                        AWTEvent[] events = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
                        if (events.length > 0 && events[events.length-1] instanceof 
MouseEvent)
                            {
                                MouseEvent event = (MouseEvent)events[events.length-1];

                                int id  = event.getID();
                                int mod = event.getModifiers();

                                // If you wanted to pick only when you press certain 
mouse buttons
                                // you would use an if statement similar to the 
following:
                                // if (mod == InputEvent.BUTTON1_MASK)
                                //   {
                                //      THE CODE BELOW
                                //   }

                                // The location of the mouse event.
                                x = event.getX();
                                y = event.getY();

                                // Pick the closest node
                                pickCanvas.setShapeLocation(x, y);
                                Point3d eyePos        = pickCanvas.getStartPosition();
                                PickResult pickResult = pickCanvas.pickClosest();

                                // If nothing was picked (didn't click on one of the 
points) the PickResult
                                // will be null.  If we continue with a null result a 
NullPointerException
                                // will be thrown and the wakeupOn(wakeupCriterion) 
method will not be
                                // called, effectivly disabling the behavior.
                                if (pickResult != null)
                                    {
                                        // Get the closest intersection with the 
geometry.
                                        PickIntersection pickIntersection = 
pickResult.getClosestIntersection(eyePos);

                                        // Check that a PointArray was picked
                                        if (pickIntersection.getGeometryArray() 
instanceof PointArray)
                                            {
                                                // Get the vertex indices of the 
intersected primitive,
                                                // in this case the index of the 
intersected point in the PointArray.
                                                int[] indices = 
pickIntersection.getPrimitiveVertexIndices();

                                                // There should only be one index 
since this is a PointArray,
                                                // so we use indices[0].
                                                System.err.println("Index of picked 
point: " + String.valueOf(indices[0]));
                                            }
                                    }
                            }
                    }
            }

        wakeupOn(wakeupCriterion);
    }
}

Reply via email to