Simple Universe : Universe Node « 3D « Java






Simple Universe

Simple Universe
/*
 * @(#)HelloUniverse.java 1.17 02/10/21 13:58:47
 * 
 * Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met: -
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer. - Redistribution in binary
 * form must reproduce the above copyright notice, this list of conditions and
 * the following disclaimer in the documentation and/or other materials provided
 * with the distribution.
 * 
 * Neither the name of Sun Microsystems, Inc. or the names of contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * 
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
 * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
 * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
 * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGES.
 * 
 * You acknowledge that Software is not designed,licensed or intended for use in
 * the design, construction, operation or maintenance of any nuclear facility.
 */

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.util.Enumeration;

import javax.media.j3d.Alpha;
import javax.media.j3d.Behavior;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.InputDevice;
import javax.media.j3d.RotationInterpolator;
import javax.media.j3d.Sensor;
import javax.media.j3d.SensorRead;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.WakeupOnElapsedFrames;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class HelloUniverse extends Applet {

  private SimpleUniverse u = null;

  public BranchGroup createSceneGraph() {

    BranchGroup objRoot = new BranchGroup();
    TransformGroup objTrans = new TransformGroup();
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    objRoot.addChild(objTrans);
    objTrans.addChild(new ColorCube(0.2));
    Transform3D yAxis = new Transform3D();
    Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0,
        4000, 0, 0, 0, 0, 0);
    RotationInterpolator rotator = new RotationInterpolator(rotationAlpha,
        objTrans, yAxis, 0.0f, (float) Math.PI * 2.0f);
    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
        100.0);
    rotator.setSchedulingBounds(bounds);
    objTrans.addChild(rotator);
    return objRoot;
  }

  public HelloUniverse() {

  }

  public void init() {
    // These are the string arguments given to the VirtualInputDevice
    // constructor. These are settable parameters. Look in the
    // VirtualInputDevice constructor for a complete list.
    String[] args = new String[10];
    args[0] = "printvalues";
    args[1] = "true";
    args[2] = "yscreeninitloc";
    args[3] = "50";
    args[4] = null;

    InputDevice device = new VirtualInputDevice(args);

    // now create the HelloUniverse Canvas
    setLayout(new BorderLayout());
    GraphicsConfiguration config = SimpleUniverse
        .getPreferredConfiguration();

    Canvas3D c = new Canvas3D(config);
    add("Center", c);

    // Create a simple scene and attach it to the virtual universe
    BranchGroup scene = createSceneGraph();
    u = new SimpleUniverse(c);

    // The InputDevice must be initialized before registering it
    // with the PhysicalEnvironment object.
    device.initialize();

    // Register the VirtualInputDevice with Java 3D
    u.getViewer().getPhysicalEnvironment().addInputDevice(device);

    TransformGroup viewTrans = u.getViewingPlatform()
        .getViewPlatformTransform();
    SensorBehavior s = new SensorBehavior(viewTrans, device.getSensor(0));
    s.setSchedulingBounds(new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
        Float.MAX_VALUE));
    scene.addChild(s);
    u.addBranchGraph(scene);
  }

  public void destroy() {
    u.cleanup();
  }

  public static void main(String[] args) {
    new MainFrame(new HelloUniverse(), 350, 350);
  }
}

class VirtualInputDevice implements InputDevice {

  private Vector3f position = new Vector3f();

  private Transform3D newTransform = new Transform3D();

  Sensor sensors[] = new Sensor[1];

  // The wheel controls control the view platform orientation
  private RotationControls rotControls;

  // The button position controls control the view platform position
  private PositionControls positionControls;

  private Transform3D rotTransX = new Transform3D();

  private Transform3D rotTransY = new Transform3D();

  private Transform3D rotTransZ = new Transform3D();

  private Vector3f initPos = new Vector3f();

  private int processingMode;

  private SensorRead sensorRead = new SensorRead();

  // These are the settable parameters.
  private boolean printvalues;

  private int xscreeninitloc;

  private int yscreeninitloc;

  private int xscreensize;

  private int yscreensize;

  private float xobjinitloc;

  private float yobjinitloc;

  private float zobjinitloc;

  private float xaxisrotinit;

  private float yaxisrotinit;

  private float zaxisrotinit;

  /*
   * Create a device, and use the string arguments in args to construct the
   * device with user preferences.
   */
  public VirtualInputDevice(String[] args) {

    // default user-definable values
    printvalues = false;
    xscreeninitloc = 400;
    yscreeninitloc = 0;
    xscreensize = 400;
    yscreensize = 200;
    xobjinitloc = 0.0f;
    yobjinitloc = 0.0f;
    zobjinitloc = 2.2f;
    xaxisrotinit = 0.0f;
    yaxisrotinit = 0.0f;
    zaxisrotinit = 0.0f;

    for (int i = 0; i < args.length; i += 2) {
      if (args[i] == null)
        break;
      else if (args[i] == "printvalues")
        printvalues = (Boolean.valueOf(args[i + 1])).booleanValue();
      else if (args[i] == "xscreeninitloc")
        xscreeninitloc = (Integer.valueOf(args[i + 1])).intValue();
      else if (args[i] == "yscreeninitloc")
        yscreeninitloc = (Integer.valueOf(args[i + 1])).intValue();
      else if (args[i] == "xscreensize")
        xscreensize = (Integer.valueOf(args[i + 1])).intValue();
      else if (args[i] == "yscreensize")
        yscreensize = (Integer.valueOf(args[i + 1])).intValue();
      else if (args[i] == "xobjinitloc")
        xobjinitloc = (Float.valueOf(args[i + 1])).floatValue();
      else if (args[i] == "yobjinitloc")
        yobjinitloc = (Float.valueOf(args[i + 1])).floatValue();
      else if (args[i] == "zobjinitloc")
        zobjinitloc = (Integer.valueOf(args[i + 1])).floatValue();
    }

    if (printvalues == true) {
      System.out.println("Initial values for VirtualInputDevice:");
      System.out.println("xscreeninitloc = " + xscreeninitloc);
      System.out.println("yscreeninitloc = " + yscreeninitloc);
      System.out.println("xscreeninitsize = " + xscreensize);
      System.out.println("yscreeninitsize = " + yscreensize);
      System.out.println("xobjinitloc = " + xobjinitloc);
      System.out.println("yobjinitloc = " + yobjinitloc);
      System.out.println("zobjinitloc = " + zobjinitloc);
      System.out.println("xaxisrotinit = " + xaxisrotinit);
      System.out.println("yaxisrotinit = " + yaxisrotinit);
      System.out.println("zaxisrotinit = " + zaxisrotinit);
    }

    // initialize the InputDevice GUI
    Frame deviceFrame = new Frame();
    deviceFrame.setSize(xscreensize, yscreensize);
    deviceFrame.setLocation(xscreeninitloc, yscreeninitloc);
    deviceFrame.setTitle("Virtual Input Device");
    ButtonPositionControls positionControls;
    // initialize position with initial x, y, and z position
    positionControls = new ButtonPositionControls(xobjinitloc, yobjinitloc,
        zobjinitloc);
    WheelControls rotControls;
    // initialize rotations with initial angles in radians)
    rotControls = new WheelControls(xaxisrotinit, yaxisrotinit,
        zaxisrotinit);
    positionControls.setDevice(this);
    Panel devicePanel = new Panel();
    devicePanel.setLayout(new BorderLayout());
    devicePanel.add("East", positionControls);
    devicePanel.add("West", rotControls);
    deviceFrame.add(devicePanel);
    deviceFrame.pack();
    deviceFrame.setVisible(true);

    initPos.set(xobjinitloc, yobjinitloc, zobjinitloc);

    this.positionControls = positionControls;
    this.rotControls = rotControls;

    // default processing mode
    processingMode = InputDevice.DEMAND_DRIVEN;

    sensors[0] = new Sensor(this);
  }

  public void close() {
  }

  public int getProcessingMode() {
    return processingMode;
  }

  public int getSensorCount() {
    return sensors.length;
  }

  public Sensor getSensor(int sensorIndex) {
    return sensors[sensorIndex];
  }

  public boolean initialize() {
    return true;
  }

  public void pollAndProcessInput() {

    sensorRead.setTime(System.currentTimeMillis());

    rotTransX.rotX(-rotControls.getXAngle());
    rotTransY.rotY(-rotControls.getYAngle());
    rotTransZ.rotZ(-rotControls.getZAngle());

    positionControls.getPosition(position);
    newTransform.set(position);
    newTransform.mul(rotTransX);

    newTransform.mul(rotTransY);
    newTransform.mul(rotTransZ);

    sensorRead.set(newTransform);
    sensors[0].setNextSensorRead(sensorRead);
  }

  public void processStreamInput() {
  }

  public void setNominalPositionAndOrientation() {

    sensorRead.setTime(System.currentTimeMillis());

    rotTransX.rotX(xaxisrotinit);
    rotTransY.rotY(yaxisrotinit);
    rotTransZ.rotZ(zaxisrotinit);

    position.set(initPos);

    newTransform.set(position);

    newTransform.mul(rotTransX);
    newTransform.mul(rotTransY);
    newTransform.mul(rotTransZ);

    sensorRead.set(newTransform);
    sensors[0].setNextSensorRead(sensorRead);
    rotControls.reset();
    positionControls.setPosition(initPos);
  }

  public void setProcessingMode(int mode) {

    // A typical driver might implement only one of these modes, and
    // throw an exception when there is an attempt to switch modes.
    // However, this example allows one to use any processing mode.

    switch (mode) {
    case InputDevice.DEMAND_DRIVEN:
    case InputDevice.NON_BLOCKING:
    case InputDevice.BLOCKING:
      processingMode = mode;
      break;
    default:
      throw new IllegalArgumentException("Processing mode must "
          + "be one of DEMAND_DRIVEN, NON_BLOCKING, or BLOCKING");
    }
  }

}

class SensorBehavior extends Behavior {

  private WakeupOnElapsedFrames conditions = new WakeupOnElapsedFrames(0);

  private TransformGroup transformGroup;

  private Sensor sensor;

  private Transform3D transform = new Transform3D();

  public SensorBehavior(TransformGroup tg, Sensor sensor) {
    transformGroup = tg;
    this.sensor = sensor;
  }

  public void initialize() {
    wakeupOn(conditions);
  }

  public void processStimulus(Enumeration criteria) {
    sensor.getRead(transform);
    transformGroup.setTransform(transform);
    wakeupOn(conditions);
  }

}

//Classes that implement this interface must be a
//subclass of java.awt.Component

interface PositionControls {

  /**
   * Get the position
   */
  public void getPosition(Vector3f pos);

  /**
   * Set the position
   */
  public void setPosition(Vector3f pos);

  /**
   * Increment added to position each time mouse is pressed or if the mouse is
   * held down each time the Sensor is read
   */
  public void setStepRate(float stepRate);
}

//Classes that implement this interface must be a subclass
//of java.awt.Component

interface RotationControls {

  /**
   * Get the angle of Rotation around the X Axis
   */
  public abstract float getXAngle();

  /**
   * Get the angle or Rotation around the Y Axis
   */
  public abstract float getYAngle();

  /**
   * Get the angle or Rotation around the Z Axis
   */
  public abstract float getZAngle();

  /**
   * Reset angles to original angle.
   */
  public abstract void reset();
}

class WheelControls extends Canvas implements RotationControls,
    MouseMotionListener, MouseListener {

  private final static int NONE = 0;

  private final static int SLIDE_Y = 1;

  private final static int SLIDE_X = 2;

  private final static int SLIDE_Z = 3;

  private int mode = NONE;

  private Dimension size;

  private int thickness;

  private int diameter;

  private int space;

  private int pipSize;

  private int pipOffset; // Amount pip is below wheel

  private int margin; // Margin between edge of Canvas and

  // controls

  private Polygon yPip;

  private Rectangle yBackClip;

  private Polygon xPip;

  private Rectangle xBackClip;

  private Polygon zPip;

  private Rectangle yArea;

  private Rectangle xArea;

  private Rectangle zArea;

  private Point oldMousePos = new Point();

  float yAngle = 0.0f;

  float xAngle = 0.0f;

  float zAngle = 0.0f;

  float yOrigAngle;

  float xOrigAngle;

  float zOrigAngle;

  float angleStep = (float) Math.PI / 30.0f;

  public WheelControls() {
    this(0.0f, 0.0f, 0.0f);
  }

  public WheelControls(float rotX, float rotY, float rotZ) {
    size = new Dimension(200, 200);

    xAngle = constrainAngle(rotX);
    yAngle = constrainAngle(rotY);
    zAngle = constrainAngle(rotZ);

    yOrigAngle = yAngle;
    xOrigAngle = xAngle;
    zOrigAngle = zAngle;

    setSizes();

    yPip = new Polygon();
    yPip.addPoint(0, 0);
    yPip.addPoint(-pipSize / 2, pipSize);
    yPip.addPoint(pipSize / 2, pipSize);

    xPip = new Polygon();
    xPip.addPoint(0, 0);
    xPip.addPoint(pipSize, -pipSize / 2);
    xPip.addPoint(pipSize, pipSize / 2);

    zPip = new Polygon();
    zPip.addPoint(diameter / 2, pipOffset);
    zPip.addPoint(diameter / 2 - pipSize / 2, pipOffset - pipSize);
    zPip.addPoint(diameter / 2 + pipSize / 2, pipOffset - pipSize);

    addMouseListener(this);
    addMouseMotionListener(this);
  }

  private void setSizes() {
    margin = 10;
    int width = size.width - margin * 2;
    thickness = width * 7 / 100;
    diameter = width * 70 / 100;
    space = width * 10 / 100;
    pipSize = width * 7 / 100;

    pipOffset = thickness / 2;

  }

  public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;

    g.drawOval(margin, margin, diameter, diameter);
    zArea = new Rectangle(margin, margin, diameter, diameter);
    drawZPip(g2, zAngle);

    g.drawRect(margin, margin + diameter + space, diameter, thickness); // Y
                                      // Wheel
    yArea = new Rectangle(margin, margin + diameter + space, margin
        + diameter, thickness + pipOffset);
    yBackClip = new Rectangle(margin - thickness, margin + diameter + space
        + thickness, margin + diameter + thickness * 2, thickness);
    drawYPip(g2, yAngle);

    g.drawRect(margin + diameter + space, margin, thickness, diameter); // X
                                      // Wheel
    xArea = new Rectangle(margin + diameter + space, margin, thickness
        + pipOffset, margin + diameter);
    xBackClip = new Rectangle(margin + diameter + space + thickness, margin
        - thickness, thickness, margin + diameter + thickness * 2);
    drawXPip(g2, xAngle);

  }

  public float getXAngle() {
    return xAngle;
  }

  public float getYAngle() {
    return yAngle;
  }

  public float getZAngle() {
    return zAngle;
  }

  public void reset() {
    // Overwrite the old pip
    drawYPip((Graphics2D) (this.getGraphics()), yAngle);
    yAngle = yOrigAngle;
    // Draw the new Pip
    drawYPip((Graphics2D) (this.getGraphics()), yAngle);

    // Overwrite the old pip
    drawXPip((Graphics2D) (this.getGraphics()), xAngle);
    xAngle = xOrigAngle;
    // Draw the new Pip
    drawXPip((Graphics2D) (this.getGraphics()), xAngle);

    drawZPip((Graphics2D) (this.getGraphics()), zAngle);

    zAngle = zOrigAngle;

    drawZPip((Graphics2D) (this.getGraphics()), zAngle);
    oldMousePos.setLocation(0, 0);
  }

  private void drawXPip(Graphics2D g2, float angle) {
    AffineTransform trans = new AffineTransform();
    int y;
    int xOrig = margin + diameter + space;
    int yOrig = margin;
    Color origColor = g2.getColor();

    if (angle <= Math.PI) {
      y = yOrig
          + diameter
          - (int) ((Math.abs(angle - Math.PI / 2) / (Math.PI / 2))
              * diameter / 2);
    } else
      y = yOrig
          + (int) ((Math.abs((angle - Math.PI * 1.5)) / (Math.PI / 2))
              * diameter / 2);

    if (angle < Math.PI / 2 || angle > Math.PI * 1.5)
      g2.setColor(Color.red); // Infront of wheel
    else {
      g2.setColor(Color.black); // Behind Wheel
      g2.setClip(xBackClip);
    }

    g2.setXORMode(getBackground());
    trans.setToTranslation(xOrig + pipOffset, y);
    g2.setTransform(trans);
    g2.fillPolygon(xPip);

    // Reset graphics context
    trans.setToIdentity();
    g2.setTransform(trans);
    g2.setColor(origColor);
    g2.setPaintMode();
  }

  private void drawYPip(Graphics2D g2, float angle) {
    AffineTransform trans = new AffineTransform();
    int x;
    int xOrig = margin;
    int yOrig = margin + diameter + space;
    Color origColor = g2.getColor();

    if (angle <= Math.PI) {
      x = xOrig
          + diameter
          - (int) ((Math.abs(angle - Math.PI / 2) / (Math.PI / 2))
              * diameter / 2);
    } else
      x = xOrig
          + (int) ((Math.abs((angle - Math.PI * 1.5)) / (Math.PI / 2))
              * diameter / 2);

    if (angle < Math.PI / 2 || angle > Math.PI * 1.5)
      g2.setColor(Color.red); // Infront on wheel
    else {
      g2.setColor(Color.black); // Behind Wheel
      g2.setClip(yBackClip);
    }

    g2.setXORMode(getBackground());
    trans.setToTranslation(x, yOrig + pipOffset);
    g2.setTransform(trans);
    g2.fillPolygon(yPip);

    // Reset graphics context
    trans.setToIdentity();
    g2.setTransform(trans);
    g2.setColor(origColor);
    g2.setPaintMode();
  }

  private void drawZPip(Graphics2D g2, float zAngle) {
    AffineTransform trans = new AffineTransform();
    Color origColor = g2.getColor();

    trans.translate(margin, margin);
    trans.rotate(zAngle, diameter / 2, diameter / 2);

    g2.setXORMode(getBackground());
    g2.setTransform(trans);
    g2.setColor(Color.red);
    g2.fillPolygon(zPip);

    // Reset graphics context
    trans.setToIdentity();
    g2.setTransform(trans);
    g2.setColor(origColor);
    g2.setPaintMode();
  }

  public Dimension getPreferredSize() {
    return size;
  }

  public void setSize(Dimension d) {
    // Set size to smallest dimension
    if (d.width < d.height)
      size.width = size.height = d.width;
    else
      size.width = size.height = d.height;
    setSizes();
  }

  public void mouseClicked(MouseEvent e) {
  }

  public void mouseEntered(MouseEvent e) {
  }

  public void mouseExited(MouseEvent e) {
  }

  public void mousePressed(MouseEvent e) {
    if (yArea.contains(e.getPoint())) {
      mode = SLIDE_Y;
      oldMousePos = e.getPoint();
    } else if (xArea.contains(e.getPoint())) {
      mode = SLIDE_X;
      oldMousePos = e.getPoint();
    } else if (zArea.contains(e.getPoint())) {
      mode = SLIDE_Z;
      oldMousePos = e.getPoint();
    }
  }

  public void mouseReleased(MouseEvent e) {
    mode = NONE;
  }

  public void mouseDragged(MouseEvent e) {
    Point pos = e.getPoint();

    int diffX = pos.x - oldMousePos.x;
    int diffY = pos.y - oldMousePos.y;

    switch (mode) {
    case NONE:
      break;
    case SLIDE_Y:
      // Overwrite the old pip
      drawYPip((Graphics2D) ((Canvas) e.getSource()).getGraphics(),
          yAngle);
      if (diffX < 0)
        yAngle -= angleStep;
      else if (diffX > 0)
        yAngle += angleStep;

      yAngle = constrainAngle(yAngle);

      // Draw the new Pip
      drawYPip((Graphics2D) ((Canvas) e.getSource()).getGraphics(),
          yAngle);
      oldMousePos = pos;
      break;
    case SLIDE_X:
      // Overwrite the old pip
      drawXPip((Graphics2D) ((Canvas) e.getSource()).getGraphics(),
          xAngle);
      if (diffY < 0)
        xAngle -= angleStep;
      else if (diffY > 0)
        xAngle += angleStep;

      xAngle = constrainAngle(xAngle);

      // Draw the new Pip
      drawXPip((Graphics2D) ((Canvas) e.getSource()).getGraphics(),
          xAngle);
      oldMousePos = pos;
      break;
    case SLIDE_Z:
      drawZPip((Graphics2D) ((Canvas) e.getSource()).getGraphics(),
          zAngle);

      if (diffX < 0)
        zAngle -= angleStep;
      else if (diffX > 0)
        zAngle += angleStep;

      zAngle = constrainAngle(zAngle);
      drawZPip((Graphics2D) ((Canvas) e.getSource()).getGraphics(),
          zAngle);
      oldMousePos = pos;
      break;
    default:
      throw (new RuntimeException("Internal Error"));
    }
  }

  public void mouseMoved(MouseEvent e) {
  }

  /**
   * Constrain angle to be 0 <angle <2PI
   */
  private float constrainAngle(float angle) {
    if (angle > (float) Math.PI * 2)
      return angle - (float) Math.PI * 2;
    if (angle < 0.0f)
      return angle + (float) Math.PI * 2;
    return angle;
  }
}

class ButtonPositionControls extends Panel implements PositionControls,
    MouseListener {
  private final static int STILL = 0;

  private final static int MOVING_UP = 1;

  private final static int MOVING_DOWN = 2;

  private final static int MOVING_LEFT = 3;

  private final static int MOVING_RIGHT = 4;

  private final static int MOVING_FORWARD = 5;

  private final static int MOVING_BACK = 6;

  // initial mode
  private int mode = STILL;

  Vector3f position = new Vector3f();

  Vector3f orig_position = new Vector3f();

  private Button leftB = new Button("Move Left");

  private Button rightB = new Button("Move Right");

  private Button upB = new Button("Move Up");

  private Button downB = new Button("Move Down");

  private Button forwardB = new Button("Move Forward");

  private Button backwardB = new Button("Move Back");

  private Button reset = new Button("Reset");

  private InputDevice device;

  private float step_rate = 0.0023f; // movement rate per millisecond

  private long time_last_state_change = System.currentTimeMillis();

  // the constructor arguments are the intitial X, Y, and Z positions
  public ButtonPositionControls(float x, float y, float z) {

    // up, down, right, and left movement buttons
    Panel panPanel = new Panel();
    panPanel.setLayout(new BorderLayout());
    panPanel.add("North", upB);
    panPanel.add("East", rightB);
    panPanel.add("South", downB);
    panPanel.add("West", leftB);

    // forward, backward, and reset buttons
    Panel p = new Panel();
    p.setLayout(new GridLayout(0, 1, 0, 0));
    p.add(forwardB);
    p.add(backwardB);
    p.add(reset);

    // set the initial position
    position.x = x;
    position.y = y;
    position.z = z;
    orig_position.set(position);

    // add a mouse listener to each button
    upB.addMouseListener(this);
    downB.addMouseListener(this);
    leftB.addMouseListener(this);
    rightB.addMouseListener(this);
    forwardB.addMouseListener(this);
    backwardB.addMouseListener(this);
    reset.addMouseListener(this);

    this.setLayout(new BorderLayout());
    add("East", p);
    add("West", panPanel);
  }

  public void setDevice(InputDevice device) {
    this.device = device;
  }

  public void getPosition(Vector3f pos) {
    calculateMotion();
    pos.set(position);
  }

  public void setPosition(Vector3f pos) {
    position.set(pos);
  }

  public void setStepRate(float stepRate) {
    step_rate = stepRate;
  }

  private void calculateMotion() {

    long current_time = System.currentTimeMillis();
    long elapsed_time = current_time - time_last_state_change;

    switch (mode) {
    case STILL:
      break;
    case MOVING_LEFT:
      position.x = orig_position.x - step_rate * elapsed_time;
      break;
    case MOVING_RIGHT:
      position.x = orig_position.x + step_rate * elapsed_time;
      break;
    case MOVING_UP:
      position.y = orig_position.y + step_rate * elapsed_time;
      break;
    case MOVING_DOWN:
      position.y = orig_position.y - step_rate * elapsed_time;
      break;
    case MOVING_FORWARD:
      position.z = orig_position.z - step_rate * elapsed_time;
      break;
    case MOVING_BACK:
      position.z = orig_position.z + step_rate * elapsed_time;
      break;
    default:
      throw (new RuntimeException("Unknown motion"));
    }
  }

  public void mouseClicked(MouseEvent e) {
  }

  public void mouseEntered(MouseEvent e) {
  }

  public void mouseExited(MouseEvent e) {
  }

  public void mousePressed(MouseEvent e) {
    if (e.getSource() == leftB && mode != MOVING_LEFT) {
      time_last_state_change = System.currentTimeMillis();
      mode = MOVING_LEFT;
      orig_position.set(position);
    } else if (e.getSource() == rightB && mode != MOVING_RIGHT) {
      time_last_state_change = System.currentTimeMillis();
      mode = MOVING_RIGHT;
      orig_position.set(position);
    } else if (e.getSource() == upB && mode != MOVING_UP) {
      time_last_state_change = System.currentTimeMillis();
      mode = MOVING_UP;
      orig_position.set(position);
    } else if (e.getSource() == downB && mode != MOVING_DOWN) {
      time_last_state_change = System.currentTimeMillis();
      mode = MOVING_DOWN;
      orig_position.set(position);
    } else if (e.getSource() == forwardB && mode != MOVING_FORWARD) {
      time_last_state_change = System.currentTimeMillis();
      mode = MOVING_FORWARD;
      orig_position.set(position);
    } else if (e.getSource() == backwardB && mode != MOVING_BACK) {
      time_last_state_change = System.currentTimeMillis();
      mode = MOVING_BACK;
      orig_position.set(position);
    } else if (e.getSource() == reset) {
      device.setNominalPositionAndOrientation();
    }
  }

  public void mouseReleased(MouseEvent e) {
    mode = STILL;
  }
}


           
       








Related examples in the same category

1.It creates a Virtual Universe and a Locale and attaches to the Locale
2.Hello Universe 1Hello Universe 1
3.Creates a scene with a different scaleCreates a scene with a different scale
4.Scenegraph that illustrates many of the Java 3D scenegraph NodesScenegraph that illustrates many of the Java 3D scenegraph Nodes
5.Illustrate some of the features of the SimpleUniverse class
6.Demonstrate the use of the Universe builder forDemonstrate the use of the Universe builder for
7.MainFrame and SimpleUniverseMainFrame and SimpleUniverse
8.A Switch Node and conditionally displays some of the child NodesA Switch Node and conditionally displays some of the child Nodes
9.Example AppearanceExample Appearance