//
//  KeyboardBehaviorJ3D.java
//

/*
VisAD system for interactive analysis and visualization of numerical
data.  Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/

package visad.java3d;

import java.awt.AWTEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.rmi.RemoteException;
import java.util.Enumeration;

import javax.media.j3d.Behavior;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.Bounds;
import javax.media.j3d.WakeupCondition;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnAWTEvent;
import javax.media.j3d.WakeupOr;
import javax.vecmath.Point3d;

import visad.DisplayEvent;
import visad.DisplayImpl;
import visad.DisplayRenderer;
import visad.KeyboardBehavior;
import visad.MouseBehavior;
import visad.ProjectionControl;
import visad.VisADException;

/**
 *  KeyboardBehaviorJ3D is the VisAD class for keyboard control of
 *  rotation, translation, and zoom of display in Java3D.
 *  @author Troy Sandblom   NCAR/RAP May, 2000
 *  @author Don Murray (adapted to VisAD with input from Curtis)
 */
public class KeyboardBehaviorJ3D extends Behavior 
  implements KeyboardBehavior 
{

  private ProjectionControl proj;
  private DisplayRenderer displayRenderer;
  private MouseBehavior mouseBehavior;

  private double rotateAmount = 5.0;
  private double scaleAmount = .05;
  private double transAmount = .1;

  /** Identifier for function to rotate positively around the Z viewing axis*/
  public static final int ROTATE_Z_POS = 7;

  /** Identifier for function to rotate negatively around the Z viewing axis*/
  public static final int ROTATE_Z_NEG = 8;

  /** Identifier for function to rotate positively around the X viewing axis*/
  public static final int ROTATE_X_POS = 9;

  /** Identifier for function to rotate negatively around the X viewing axis*/
  public static final int ROTATE_X_NEG = 10;

  /** Identifier for function to rotate positively around the Y viewing axis*/
  public static final int ROTATE_Y_POS = 11;

  /** Identifier for function to rotate negatively around the Y viewing axis*/
  public static final int ROTATE_Y_NEG = 12;

/* WLH 19 Feb 2001
  // Maximum number of functions for this behavior
  private final int MAX_FUNCTIONS = 13;

  private int[] functionKeys = new int[MAX_FUNCTIONS];
  private int[] functionMods = new int[MAX_FUNCTIONS];
*/
  private int MAX_FUNCTIONS;
  private int[] functionKeys = null;
  private int[] functionMods = null;
 
  /**
   *  Condition that causes this Behavior to wake up.
   */
  protected WakeupCondition wakeupCondition = null;
    
  /**
   * Construct a new keyboard behavior for the DisplayRenderer.  You
   * need to add the behavior to the DisplayRenderer if you want to 
   * use it.  Default key assignments use the arrow keys to simulate
   * the default VisAD mouse behavior.

* Rotation (3D renderer only): *

* Zoom: * * Rotate: * * Translate: * * Reset: * *

* @see DisplayRendererJ3D#addKeyboardBehavior(KeyboardBehaviorJ3D behavior) * @see #mapKeyToFunction(int function, int keycode, int modifiers) to * change default key to function mappings * @param r DisplayRenderer to use. */ public KeyboardBehaviorJ3D(DisplayRendererJ3D r) { displayRenderer = r; boolean mode2D = displayRenderer.getMode2D(); proj = displayRenderer.getDisplay().getProjectionControl(); mouseBehavior = displayRenderer.getMouseBehavior(); WakeupCriterion[] wakeupCriteria = { new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED), new WakeupOnAWTEvent(KeyEvent.KEY_RELEASED), }; wakeupCondition = new WakeupOr(wakeupCriteria); Bounds bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 2000000.0); this.setSchedulingBounds(bounds); // WLH 19 Feb 2001 MAX_FUNCTIONS = 13; functionKeys = new int[MAX_FUNCTIONS]; functionMods = new int[MAX_FUNCTIONS]; // initialize array functions mapKeyToFunction( TRANSLATE_UP, KeyEvent.VK_UP, (mode2D == true) ? NO_MASK : InputEvent.CTRL_MASK); mapKeyToFunction( TRANSLATE_DOWN, KeyEvent.VK_DOWN, (mode2D == true) ? NO_MASK : InputEvent.CTRL_MASK); mapKeyToFunction( TRANSLATE_LEFT, KeyEvent.VK_LEFT, (mode2D == true) ? NO_MASK : InputEvent.CTRL_MASK); mapKeyToFunction( TRANSLATE_RIGHT, KeyEvent.VK_RIGHT, (mode2D == true) ? NO_MASK : InputEvent.CTRL_MASK); mapKeyToFunction(ZOOM_IN, KeyEvent.VK_UP, InputEvent.SHIFT_MASK); mapKeyToFunction(ZOOM_OUT, KeyEvent.VK_DOWN, InputEvent.SHIFT_MASK); mapKeyToFunction(RESET, KeyEvent.VK_R, InputEvent.CTRL_MASK); mapKeyToFunction(ROTATE_X_POS, KeyEvent.VK_DOWN, NO_MASK); mapKeyToFunction(ROTATE_X_NEG, KeyEvent.VK_UP, NO_MASK); mapKeyToFunction(ROTATE_Y_POS, KeyEvent.VK_LEFT, NO_MASK); mapKeyToFunction(ROTATE_Y_NEG, KeyEvent.VK_RIGHT, NO_MASK); mapKeyToFunction( ROTATE_Z_POS, KeyEvent.VK_LEFT, InputEvent.SHIFT_MASK); mapKeyToFunction( ROTATE_Z_NEG, KeyEvent.VK_RIGHT, InputEvent.SHIFT_MASK); } // WLH 19 Feb 2001 public KeyboardBehaviorJ3D(DisplayRendererJ3D r, int num_functions) { displayRenderer = r; boolean mode2D = displayRenderer.getMode2D(); proj = displayRenderer.getDisplay().getProjectionControl(); mouseBehavior = displayRenderer.getMouseBehavior(); WakeupCriterion[] wakeupCriteria = { new WakeupOnAWTEvent(KeyEvent.KEY_PRESSED), new WakeupOnAWTEvent(KeyEvent.KEY_RELEASED), }; wakeupCondition = new WakeupOr(wakeupCriteria); Bounds bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 2000000.0); this.setSchedulingBounds(bounds); MAX_FUNCTIONS = num_functions; functionKeys = new int[MAX_FUNCTIONS]; functionMods = new int[MAX_FUNCTIONS]; } /** * Initialize this behavior. NOTE: Applications should not call * this method. It is called by the Java 3D behavior scheduler. */ public void initialize() { wakeupOn(wakeupCondition); } /** * Process a stimulus meant for this behavior. This method is * invoked when a key is pressed. NOTE: Applications should not * call this method. It is called by the Java 3D behavior scheduler. * @param criteria an enumeration of triggered wakeup criteria */ public void processStimulus(Enumeration criteria) { WakeupOnAWTEvent event; WakeupCriterion genericEvent; AWTEvent[] events; while (criteria.hasMoreElements()) { genericEvent = (WakeupCriterion) criteria.nextElement(); if (genericEvent instanceof WakeupOnAWTEvent) { event = (WakeupOnAWTEvent) genericEvent; events = event.getAWTEvent(); // Process each event for (int i = 0; i < events.length; i++) { if (events[i] instanceof KeyEvent) processKeyEvent((KeyEvent)events[i]); } } wakeupOn(wakeupCondition); } } /** * Maps key represented by keycode & modifiers to the given function. * Each function can only have one key/modifier combination assigned * to it at a time. * @see java.awt.event.KeyEvent * @see java.awt.event.InputEvent * @param function keyboard function (ROTATE_X_POS, ZOOM_IN, etc) * @param keycode KeyEvent virtual keycodes * @param modifiers InputEvent key mask */ public void mapKeyToFunction(int function, int keycode, int modifiers) { if (function < 0 || function >= MAX_FUNCTIONS) return; functionKeys[function] = keycode; functionMods[function] = modifiers; } /** * Process a key event. Determines whether a meaningful key was pressed. * @param event KeyEvent stimulus */ public void processKeyEvent(KeyEvent event) { int id = event.getID(); if (id == KeyEvent.KEY_PRESSED) { int modifiers = event.getModifiers(); int keyCode = event.getKeyCode(); // determine whether a meaningful key was pressed for (int i=0; i

Ads help maintain this website.