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