import java.awt.AWTEvent;import java.awt.event.*;import java.util.Enumeration;import javax.media.j3d.*;import javax.vecmath.*;import com.sun.j3d.utils.universe.*;public class NavigationBehavior extends Behavior {  protected static final double FAST_SPEED = 2.0;  protected static final double NORMAL_SPEED = 1.0;  protected static final double SLOW_SPEED = 0.5;  private TransformGroup transformGroup;  private Transform3D transform3D;  private WakeupCondition keyCriterion;  private final static double TWO_PI = (2.0 * Math.PI);  private double rotateXAmount = Math.PI / 16.0;  private double rotateYAmount = Math.PI / 16.0;  private double rotateZAmount = Math.PI / 16.0;  private double moveRate = 0.3;  private double speed = NORMAL_SPEED;  private int forwardKey = KeyEvent.VK_UP;  private int backKey = KeyEvent.VK_DOWN;  private int leftKey = KeyEvent.VK_LEFT;  private int rightKey = KeyEvent.VK_RIGHT;  public NavigationBehavior( TransformGroup tg )  {    transformGroup = tg;    transform3D = new Transform3D();  }  public void initialize()  {    WakeupCriterion[] keyEvents = new WakeupCriterion[2];    keyEvents[0] = new WakeupOnAWTEvent( KeyEvent.KEY_PRESSED );    keyEvents[1] = new WakeupOnAWTEvent( KeyEvent.KEY_RELEASED );   keyCriterion = new WakeupOr( keyEvents );    wakeupOn( keyCriterion );  }  public void processStimulus( Enumeration criteria )  {    WakeupCriterion wakeup;    AWTEvent[] event;    while( criteria.hasMoreElements() )    {      wakeup = (WakeupCriterion) criteria.nextElement();      if( !(wakeup instanceof WakeupOnAWTEvent) )        continue;      event = ((WakeupOnAWTEvent)wakeup).getAWTEvent();      for( int i = 0; i < event.length; i++ )      {        if( event[i].getID() == KeyEvent.KEY_PRESSED )        {          processKeyEvent((KeyEvent)event[i]);        }      }    }    wakeupOn( keyCriterion );  }  protected void processKeyEvent(KeyEvent event)  {    int keycode = event.getKeyCode();    if(event.isShiftDown()) speed = FAST_SPEED;    else speed = NORMAL_SPEED;    if( event.isAltDown() )      altMove(keycode);    else if( event.isControlDown())      controlMove(keycode);    else      standardMove(keycode);  }  //moves forward backward or rotates left right  private void standardMove(int keycode)  {    if(keycode == forwardKey)      moveForward();    else if(keycode == backKey)      moveBackward();    else if(keycode == leftKey)      rotLeft();    else if(keycode == rightKey)      rotRight();  }  //moves left right, rotate up down  protected void altMove(int keycode)  {    if(keycode == forwardKey)      rotUp();    else if(keycode == backKey)      rotDown();    else if(keycode == leftKey)      moveLeft();    else if(keycode == rightKey)      moveRight();  }  //move up down, rot left right  protected void controlMove(int keycode)  {    if(keycode == forwardKey)      moveUp();    else if(keycode == backKey)      moveDown();    else if(keycode == leftKey)      rollLeft();    else if(keycode == rightKey)      rollRight();  }  private void moveForward()  {    doMove(new Vector3d(0.0,0.0, -getMovementRate()));  }  private void moveBackward()  {    doMove(new Vector3d(0.0,0.0, getMovementRate()));  }  private void moveLeft()  {    doMove(new Vector3d( -getMovementRate() ,0.0,0.0));  }  private void moveRight()  {    doMove(new Vector3d(getMovementRate(),0.0,0.0));  }  private void moveUp()  {    doMove(new Vector3d(0.0, getMovementRate() ,0.0));  }  private void moveDown()  {    doMove(new Vector3d(0.0, -getMovementRate() ,0.0));  }  protected void rotRight()  {    doRotateY(getRotateRightAmount());  }  protected void rotUp()  {    doRotateX(getRotateUpAmount());  }  protected void rotLeft()  {    doRotateY(getRotateLeftAmount());  }  protected void rotDown()  {    doRotateX(getRotateDownAmount());  }  protected void rollLeft()  {     doRotateZ(getRollLeftAmount());  }  protected void rollRight()  {     doRotateZ(getRollRightAmount());  }  protected void doRotateY(double radians)  {    transformGroup.getTransform(transform3D);    Transform3D toMove = new Transform3D();    toMove.rotY(radians);    transform3D.mul(toMove);    transformGroup.setTransform(transform3D);  }  protected void doRotateX(double radians)  {    transformGroup.getTransform(transform3D);    Transform3D toMove = new Transform3D();    toMove.rotX(radians);    transform3D.mul(toMove);    transformGroup.setTransform(transform3D);  }  protected void doRotateZ(double radians)  {    transformGroup.getTransform(transform3D);    Transform3D toMove = new Transform3D();    toMove.rotZ(radians);    transform3D.mul(toMove);    transformGroup.setTransform(transform3D);  }  protected void doMove(Vector3d theMove)  {    transformGroup.getTransform(transform3D);    Transform3D toMove = new Transform3D();    toMove.setTranslation(theMove);    transform3D.mul(toMove);    transformGroup.setTransform(transform3D);  }  protected double getMovementRate()  {    return moveRate * speed;  }  protected double getRollLeftAmount()  {    return rotateZAmount * speed;  }  protected double getRollRightAmount()  {    return -rotateZAmount * speed;  }  protected double getRotateUpAmount()  {    return rotateYAmount * speed;  }  protected double getRotateDownAmount()  {    return -rotateYAmount * speed;  }  protected double getRotateLeftAmount()  {    return rotateYAmount * speed;  }  protected double getRotateRightAmount()  {    return -rotateYAmount * speed;  }  public void setRotateXAmount(double radians)  {    rotateXAmount = radians;  }  public void setRotateYAmount(double radians)  {    rotateYAmount = radians;  }  public void setRotateZAmount(double radians)  {    rotateZAmount = radians;  }  public void setMovementRate(double meters)  {    moveRate = meters; // Travel rate in meters/frame  }  public void setForwardKey(int key)  {    forwardKey = key;  }  public void setBackKey(int key)  {    backKey = key;  }  public void setLeftKey(int key)  {    leftKey = key;  }  public void setRightKey(int key)  {    rightKey = key;  }}