Package org.jdesktop.wonderland.client.input

Source Code of org.jdesktop.wonderland.client.input.InputManager$WindowSwingViewMarker

/**
* Open Wonderland
*
* Copyright (c) 2010 - 2011, Open Wonderland Foundation, All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* The Open Wonderland Foundation designates this particular file as
* subject to the "Classpath" exception as provided by the Open Wonderland
* Foundation in the License file that accompanied this code.
*/

/**
* Project Wonderland
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied
* this code.
*/
package org.jdesktop.wonderland.client.input;

import com.jme.math.Ray;
import java.awt.Canvas;
import java.awt.Component;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
import java.awt.event.KeyListener;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.util.EventObject;
import org.jdesktop.mtgame.CameraComponent;
import org.jdesktop.wonderland.common.ExperimentalAPI;
import org.jdesktop.wonderland.common.InternalAPI;
import java.util.logging.Logger;
import org.jdesktop.mtgame.Entity;
import org.jdesktop.mtgame.EntityComponent;
import org.jdesktop.mtgame.PickDetails;
import org.jdesktop.mtgame.WorldManager;
import org.jdesktop.mtgame.PickInfo;
import org.jdesktop.wonderland.client.jme.ClientContextJME;
import org.jdesktop.wonderland.client.jme.input.KeyEvent3D;
import org.jdesktop.wonderland.client.jme.input.MouseEvent3D;
import org.jdesktop.wonderland.client.jme.JmeClientMain;
import javax.swing.SwingUtilities;
import org.jdesktop.wonderland.client.jme.input.InputPicker3D;
import org.jdesktop.wonderland.client.jme.input.FocusEvent3D;

/**
* A singleton container for all of the processor objects in the Wonderland input subsystem.
* <br><br>
* The <code>InputManager</code> supports event listener (<code>EventListener</code>) objects.
* These listeners can be added to entities
* in the world in order to allow these entities to respond to events. These events can be generated as a result
* of user input or can be programmatically generated by other parts of the client.
* <br><br>
* The <code>InputManager</code> also supports a set of global event listeners. These are independent of
* any entities. The system always delivers all events to global event listeners which are willing
* to consume these events. Note: the return value of <code>propagateToParent()</code> for global listeners
* is ignored. Note: The <code>pickDetails</code> field of an event is null for events received by the
* global listeners.
* <br><br>
* In Wonderland Release 0.4, the Wonderland client provided the notion of an "event mode." The event mode
* could be either App or World. When the event mode was App, only event listeners which controlled the
* shared apps were to consume events. When the event mode was World, only event listeners which controlled
* the non-app parts of the scene (aka "world") were to consume events. This essentially provided a single focus for
* all input events, which had a binary value. The new Wonderland <code>InputManager</code> provides a more
* general model of focus.
* <br><br>
* The <code>InputManager</code> provides "focus sets" for different classes of events. Each distinct event class
* can have its own focus set. A focus set is a set of one or more entities that have focus for that
* class of event. For example, the <code>KeyEvent3D</code> class can have a focus set consisting of Entity1 and the
* <code>MouseEvent3D</code> class can have a focus set consisting of Entity2 and Entity3. Unlike Wonderland Release 0.4,
* each event class can have a different set of focussed entities. Notice also that there can be multiple
* focussed entities instead of just one.
* When an entity is handed to an event listener via an event listener method such as, <code>consumesEvent</code> etc.,
* that method can determine the entity to which the event was distributed by calling <code>Event.getEntity()</code>.
* The method can determine if the entity has focus by calling <code>Event.isFocussed()</code>. (Note that
* <code>isFocussed</code> returns whether the entity had focus at the time the event was delivered to the
* listener).
* <br><br>
* Note that the concept of focus in this input system is merely advisory. Event listeners can be programmed to
* use the <code>isFocussed</code> flag or ignore it. For example, a shared app event listener could be written
* to ignore events when the entity of the shared app does not have focus. Or, a 3D "xeyes" type of app could
* be written to accept all mouse motion events, regardless of whether their entity has focus,
* and change the gaze of the eyes to follow the mouse pointer's location no matter where it moves on the screen.
* <br><br>
* It is intended that the Wonderland client provide one or more focus managers which change the
* focussed entities based on user input or some other stimuli. These focus managers will be the responsible
* for implementing the focus management policy--the <code>InputManager</code> merely provides the mechanism.
* The goal is to allow multiple and different focus managers to be experimented with over time.
*
* @author deronj
*/

// TODO: low: InputPicker doesn't deal with multiple cameras properly.

@ExperimentalAPI
public abstract class InputManager
    implements MouseListener, MouseMotionListener, MouseWheelListener,
               KeyListener, FocusListener, DropTargetListener
{
    private static final Logger logger = Logger.getLogger(InputManager.class.getName());

    /** The singleton input manager */
    protected static InputManager inputManager;

    /** The singleton input picker. (Used only in non-embedded swing case). */
    protected InputPicker inputPicker;

    /** The singleton event distributor. */
    protected EventDistributor eventDistributor;

    /** The canvas from which this input manager should receive events. */
    protected Canvas canvas;

    /** Are we running on a Mac? */
    private static boolean isMac = "Mac OS X".equals(System.getProperty("os.name"));

    /** The global focus wildcard entity */
    protected Entity globalFocusEntity;

    /** The ways that a focus set can be changed. */
    public enum FocusChangeAction {
  /** Add the given entities to the focus sets of the given event classes. */
  ADD,
  /** Remove the given entities from the focus sets of the given event classes. */
  REMOVE,
  /**
    * Replace the previous focus sets for the given event classes with a new focus set
    * which contains the given entities. Note that the new set may be the empty set.
    */
        REPLACE
    };

    /**
     * An object which indicates how to modify the focus set.
     */
    public class FocusChange {

  /** The action to perform on the focus sets. */
  public FocusChangeAction action;

  /** The event classes whose focus set is to be changed. */
  public Class[] eventClasses;

  /** The target entities */
  public Entity[] entities;

        /**
   * Create an instance of FocusChange.
   * @param action The action to perform on the focus sets.
   * @param eventClasses The event classes whose focus sets are to be changed.
   * @param entities The target entities.
   * @throws IllegalArgumentException If any class in <code>eventClasses</code> are not the Wonderland
   * base event class or one of its subclasses.
   *
   */
  public FocusChange (FocusChangeAction action, Class[] eventClasses, Entity[] entities) {
      for (Class clazz : eventClasses) {
    if (!Event.class.isAssignableFrom(clazz)) {
        throw new IllegalArgumentException("Class is not a Wonderland event class or one of its subclasses: " + clazz.getName());
    }
      }
      this.action = action;
      this.eventClasses = eventClasses;
      this.entities = entities;
  }
    }

    /**
     * Create a new instance of InputManager.
     */
    protected InputManager () {
  // Note: the global focus entity must be initialized early so that the Wonderland client can register
  // global listeners. The Wonderland client does this before it calls initialize.
  initializeGlobalFocus(ClientContextJME.getWorldManager());

        EventListenerBaseImpl.initializeEventListeners();
    }

    /**
     * Return the input manager singleton.
     * <br>
     * INTERNAL ONLY.
     */
    @InternalAPI
    static public InputManager inputManager () {
        return inputManager;
    }

    /**
     * Return the event distributor singleton.
     */
    EventDistributor getEventDistributor () {
  return eventDistributor;
    }

    /**
     * Initialize the input manager to receive input events from the given AWT canvas
     * and start the input manager running. This method does not define a camera
     * component, so picking on events will not start occuring until a camera component
     * is specified with a subsequent call to <code>setCameraComponent</code>.
     * @param canvas The AWT canvas which generates AWT user events.
     */
    public void initialize (Canvas canvas) {
  initialize(canvas, null);
    }

    /**
     * Initialize the input manager to receive input events from the given AWT canvas
     * and start the input manager running. The input manager will perform picks with the
     * given camera. This routine can only be called once. To subsequently change the
     * camera, use <code>setCameraComponent</code>. To subsequently change the focus manager,
     * use <code>setFocusManager</code>.
     * @param canvas The AWT canvas which generates AWT user events.
     * @param cameraComp The mtgame camera component to use for picking operations.
     */
    public void initialize (Canvas canvas, CameraComponent cameraComp) {
  if (this.canvas != null) {
      throw new IllegalStateException("initialize has already been called for this InputManager");
  }
  this.canvas = canvas;
  inputPicker.setCanvas(canvas);

  setCameraComponent(cameraComp);

  canvas.addKeyListener(this);
  canvas.addMouseListener(this);
  canvas.addMouseMotionListener(this);
  canvas.addMouseWheelListener(this);
  canvas.addFocusListener(this);
        canvas.setDropTarget(new DropTarget(canvas, this));

  logger.fine("Input System initialization complete.");
    }

    /**
     * Initialize the global focus wildcard entity.
     */
    private void initializeGlobalFocus (WorldManager wm) {
  globalFocusEntity = new Entity("Global Focus");
  wm.addEntity(globalFocusEntity);
    }

    /**
     * Returns the global focus entity.
     */
    public Entity getGlobalFocusEntity () {
  return globalFocusEntity;
    }

    /**
     * TODO: later: use for injecting a non-deliverable mouse event in order to implement programmatic
     * (non-user-generated) enter/exit events.
     * INTERNAL ONLY.
     * <br>
     * The synthetic, "priming" mouse event should not be delivered to users.
     */
    @InternalAPI
    public static class NondeliverableMouseEvent extends MouseEvent {
  NondeliverableMouseEvent (Component source, int id, long when, int modifiers, int x, int y,
          int clickCount, boolean popupTrigger, int button) {
      super(source, id, when, modifiers, x, y, clickCount, popupTrigger, button);
  }
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void mouseClicked(MouseEvent e) {
  inputPicker.pickMouseEvent3D(e);
    }
   
    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void mouseEntered(MouseEvent e) {
  inputPicker.pickMouseEvent3D(e);

        if (isMac) {
            ensureKeyFocusInMainWindow();
        }
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void mouseExited(MouseEvent e) {
  inputPicker.pickMouseEvent3D(e);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void mousePressed(MouseEvent e) {
  inputPicker.pickMouseEvent3D(e);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void mouseReleased(MouseEvent e) {
  inputPicker.pickMouseEvent3D(e);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void mouseDragged(MouseEvent e) {
  inputPicker.pickMouseEvent3D(e);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void mouseMoved(MouseEvent e) {
  inputPicker.pickMouseEvent3D(e);
    }
   
    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void mouseWheelMoved(MouseWheelEvent e) {
  inputPicker.pickMouseEvent3D(e);
    }
   
    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void keyPressed(KeyEvent e) {
  inputPicker.pickKeyEvent(e);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void keyReleased(KeyEvent e) {
  inputPicker.pickKeyEvent(e);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void keyTyped(KeyEvent e) {
  inputPicker.pickKeyEvent(e);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void focusGained(FocusEvent e) {
        FocusEvent3D event = (FocusEvent3D) ((InputPicker3D)inputPicker).createWonderlandEvent(e);
        eventDistributor.enqueueEvent(event, (PickInfo)null);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void focusLost(FocusEvent e) {
        FocusEvent3D event = (FocusEvent3D) ((InputPicker3D)inputPicker).createWonderlandEvent(e);
        eventDistributor.enqueueEvent(event, (PickInfo)null);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void dragEnter(DropTargetDragEvent e) {
        inputPicker.pickDropEvent(e);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void dragExit(DropTargetEvent e) {
        inputPicker.pickDropEvent(e);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void dragOver(DropTargetDragEvent e) {
        inputPicker.pickDropEvent(e);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void drop(DropTargetDropEvent e) {
        logger.warning("Drop: " + e.getCurrentDataFlavors().length + " items");

        inputPicker.pickDropEvent(e);
    }

    /**
     * INTERNAL ONLY
     * {@inheritDoc}
     */
    @InternalAPI
    public void dropActionChanged(DropTargetDragEvent e) {
        inputPicker.pickDropEvent(e);
    }

    /**
     * Make sure that the Wonderland client main (3D) window has key focus.
     */
    public static void ensureKeyFocusInMainWindow() {
        SwingUtilities.invokeLater(new Runnable () {
            public void run () {               
                Canvas canvas = JmeClientMain.getFrame().getCanvas();
                if (!canvas.requestFocusInWindow()) {
                    logger.info("Focus request for main canvas rejected.");
                }
            }
        });
    }


    /**
     * Register a global event listener with the input manager. If the listener has already been
     * registered this action is a no-op.
     *
     * The input manager attempts to distribute newly arriving events to all registered global listeners.
     * It calls the consumesEvent method of the listener. If this returns true then the computeEvent
     * and commitEvent of the listener are called.
     *
     * Note: It is not a good idea to call addGlobalEventListener from inside the
     * EventListener.computeEvent method. However, it is okay to call this from inside EventListener.
     * commitEvent method if necessary.
     *
     * @param listener The global event listener to be added.
     */
    public void addGlobalEventListener (EventListener listener) {
  eventDistributor.addGlobalEventListener(listener);
    }

    /**
     * Remove this global event listener.
     *
     * Note: It is not a good idea to call this from inside EventListener.computeEvent function.
     * However, it is okay to call this from inside EventListener.commitEvent function if necessary.
     *
     * @param listener The entity to which to attach this event listener.
     */
    public void removeGlobalEventListener (EventListener listener) {
  eventDistributor.removeGlobalEventListener(listener);
    }

    /**
     * Add an event listener to the specified entity
     * @param listener
     * @param entity
     */
    public void addEventListener(EventListener listener, Entity entity) {
        listener.addToEntity(entity);
    }

    /**
     * Remove an event listener from the specified entity
     * @param listener
     * @param entity
     */
    public void removeEventListener(EventListener listener, Entity entity) {
        listener.removeFromEntity(entity);
    }

    /**
     * Specify the camera component to be used for picking.
     *
     * @param cameraComp The mtgame camera component to use for picking operations.
     */
    public void setCameraComponent (CameraComponent cameraComp) {
  inputPicker.setCameraComponent(cameraComp);
    }

    /**
     * Returns the camera component that is used for picking.
     */
    public CameraComponent getCameraComponent () {
  return inputPicker.getCameraComponent();
    }

    /**
     * The base changeFocus method. Atomically changes the focus sets. The other focus utility methods call
     * this method. This method is for use by the Wonderland client focus manager.
     * @param changes An array of the changes to make to the focus sets.
     */
    public void changeFocus (FocusChange[] changes) {
  eventDistributor.enqueueEvent(new FocusChangeEvent(changes));
    }

    /**
     * A utility method. Atomically add the given entities to the focus sets of the given event classes.
     * This method is for use by the Wonderland client focus manager.
     * @param eventClasses The event classes whose focus sets are to be modified.
     * @param entities The entities to add to the focus sets.
     * @throws IllegalArgumentException If any class in <code>eventClasses</code> are not the Wonderland
     * base event class or one of its subclasses.
     */
    public void addFocus (Class[] eventClasses, Entity[] entities) {
  changeFocus(new FocusChange[] { new FocusChange(FocusChangeAction.ADD, eventClasses, entities) });
    }

    /**
     * A utility method. Atomically remove the given entities from the focus sets of the given event classes.
     * This method is for use by the Wonderland client focus manager.
     * @param eventClasses The event classes whose focus sets are to be modified.
     * @param entities The entities to add to the focus sets.
     * @throws IllegalArgumentException If any class in <code>eventClasses</code> are not the Wonderland
     * base event class or one of its subclasses.
     */
    public void removeFocus (Class[] eventClasses, Entity[] entities) {
  changeFocus(new FocusChange[] { new FocusChange(FocusChangeAction.REMOVE, eventClasses, entities) });
    }

    /**
     * A utility method. Atomically replace the focus sets of the given event classes with the given entities.
     * This method is for use by the Wonderland client focus manager.
     * @param eventClasses The event classes whose focus sets are to be modified.
     * @param entities The entities to add to the focus sets.
     * @throws IllegalArgumentException If any class in <code>eventClasses</code> are not the Wonderland
     * base event class or one of its subclasses.
     */
    public void replaceFocus (Class[] eventClasses, Entity[] entities) {
  changeFocus(new FocusChange[] { new FocusChange(FocusChangeAction.REPLACE, eventClasses, entities) });
    }

    /**
     * A utility method. Atomically add the given entities to the focus sets of the KeyEvent3D
     * and MouseEvent3D event classes. This method is for use by the Wonderland client focus manager.
     * @param entities The entities to add to the focus sets.
     */
    public void addKeyMouseFocus (Entity[] entities) {
  addFocus(new Class[] { KeyEvent3D.class, MouseEvent3D.class}, entities);
    }

    /**
     * A utility method. Atomically remove the given entities from the focus sets of the KeyEvent3D
     * and MouseEvent3D event classes. This method is for use by the Wonderland client focus manager.
     * @param entities The entities to add to the focus sets.
     */
    public void removeKeyMouseFocus (Entity[] entities) {
  removeFocus(new Class[] { KeyEvent3D.class, MouseEvent3D.class}, entities);
    }

    /**
     * A utility method. Atomically replace the focus sets of the KeyEvent3D and MouseEvent3D
     * event classes with the given entities. This method is for use by the Wonderland client focus manager.
     * @param entities The entities to add to the focus sets.
     */
    public void replaceKeyMouseFocus (Entity[] entities) {
  replaceFocus(new Class[] { KeyEvent3D.class, MouseEvent3D.class}, entities);
    }

    /**
     * A utility method. Atomically add the given entity to the focus sets of the KeyEvent3D
     * and MouseEvent3D event classes. This method is for use by the Wonderland client focus manager.
     * @param entity The entity to add to the focus sets.
     */
    public void addKeyMouseFocus (Entity entity) {
  addKeyMouseFocus(new Entity[] { entity });
    }

    /**
     * A utility method. Atomically remove the given entity from the focus sets of the KeyEvent3D
     * and MouseEvent3D event classes. This method is for use by the Wonderland client focus manager.
     * @param entity The entity to add to the focus sets.
     */
    public void removeKeyMouseFocus (Entity entity) {
  removeKeyMouseFocus(new Entity[] { entity });
    }

    /**
     * A utility method. Atomically replace the focus sets of the KeyEvent3D and MouseEvent3D
     * event classes with the given entity. This method is for use by the Wonderland client focus manager.
     * @param entity The entity to add to the focus sets.
     */
    public void replaceKeyMouseFocus (Entity entity) {
  replaceKeyMouseFocus(new Entity[] { entity });
    }

    /**
     * Returns true if the given entity is marked as having focus.
     * @param event The event to be delivered.
     * @param entity The entity to check if it is in the focus set.
     */
    public static boolean entityHasFocus (Event event, Entity entity) {
        return EventDistributor.entityHasFocus(event, entity);
    }

    /**
     * Returns true if the given entity is marked as having focus.
     * @param event The event to be delivered.
     * @param entity The entity to check if it is in the focus set.
     */
    public static boolean entityHasFocus (EventObject event, Entity entity) {
        InputPicker picker = InputManager.inputManager().inputPicker;
        Event wlEvent = picker.createWonderlandEvent(event);

        return entityHasFocus(wlEvent, entity);
    }

    /**
     * Inject an event into the input system. The event doesn't have an associated entity. Therefore
     * it will only be distributed to the global event listeners.
     *
     * NOTE: make sure that the class of the argument event implements clone.
     *
     * @param event The event to be distributed to enabled global event listeners.
     */
    public void postEvent (Event event) {
  eventDistributor.enqueueEvent(event);
    }

    /**
     * Inject an event, with an associated entity into the system
     *
     * @param event
     * @param entity
     */
    public void postEvent(Event event, Entity entity) {
        eventDistributor.enqueueEvent(event, entity);
    }

    /* NOTE: I've decided not to implement an entity variant of postEvent at this time. */

    /**
     * The return type for pickMouseEventSwing. If entity is non-null it is the entity hit by the pick.
     * The pickDetails is the specific picking details for that entity.
     * <br>
     * FOR APP BASE ONLY.
     */
    public static class PickEventReturn {

  /** The pick hit entity. */
  public Entity entity;

  /** Pick details for the destination input sensitive object. **/
  public PickDetails destPickDetails;

  /** Pick details for the hit input sensitive object. **/
  public PickDetails hitPickDetails;

  /** Constructs a new instance of PickEventReturn */
  public PickEventReturn (Entity entity, PickDetails destPickDetails, PickDetails hitPickDetails) {
      this.entity = entity;
      this.destPickDetails = destPickDetails;
      this.hitPickDetails = hitPickDetails;
  }
    }   

    /**
     * FOR USE BY APP BASE ONLY.
     * <br><br>
     * Picker for mouse events for the Embedded Swing case.
     * To be called by theEmbedded Swing toolkit createCoordinateHandler.
     * <br><br>
     * Returns non-null if window is a WindowSwing. If it is a WindowSwing then
     * return the appropriate hit entity and the corresponding pick info.
     *
     * @param awtEvent The event whose entity and pickInfo need to be picked.
     * @return An object of class PickEventReturn, which contains the return
     * values entity and pickDetails.
     */
    public PickEventReturn pickMouseEventSwing (MouseEvent awtMouseEvent) {
  if (inputPicker == null) {
      return null;
  }
  return inputPicker.pickMouseEventSwing(awtMouseEvent);
    }

    /**
     * An entity component which allows us to identify a pick hit entity as a view of a WindowSwing.
     * <br>
     * FOR APP BASE ONLY.
     */
    @InternalAPI
    public static class WindowSwingViewMarker extends EntityComponent {}

    /**
     * An entity component which allows us to figure out whether a WindowSwing should consume events.
     * <br>
     * FOR APP BASE ONLY.
     */
    @InternalAPI
    public abstract static class WindowSwingEventConsumer extends EntityComponent {
        public enum EventAction { DISCARD, CONSUME_2D, CONSUME_3D };
        public abstract EventAction consumesEvent (MouseEvent3D me3d);
    }

    /**
     * Calculate a pick ray from the current eye position into the given
     * point in screen coordinates.
     */
    public Ray pickRayWorld (int x, int y) {
  if (inputPicker == null) {
      return null;
  }
  return inputPicker.calcPickRayWorld(x, y);
    }

    /**
     * Perform a pick using a ray which extends from the eye position through the given
     * screen point.
     * point in screen coordinates.
     */
    public PickInfo pick (int x, int y) {
  if (inputPicker == null) {
      return null;
  }
  return inputPicker.pickEventScreenPos(x, y);
    }
}
TOP

Related Classes of org.jdesktop.wonderland.client.input.InputManager$WindowSwingViewMarker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.