summaryrefslogtreecommitdiffstats
path: root/src/VirtualInputDevice
diff options
context:
space:
mode:
authorkcr <kcr@28c7f869-5b4e-e670-f602-82bfaf57f300>2004-06-09 03:28:13 +0000
committerkcr <kcr@28c7f869-5b4e-e670-f602-82bfaf57f300>2004-06-09 03:28:13 +0000
commit53ebfcc5ad5554b67d2287f8b02c22ec8405af0f (patch)
tree70c8fabf4cbef5a9d2a50735c4e502d56ce156da /src/VirtualInputDevice
parent4dead457a59220406dd9fcd40997d7a7b27571b0 (diff)
Initial creation of j3d-examples sources in CVS repository
Diffstat (limited to 'src/VirtualInputDevice')
-rw-r--r--src/VirtualInputDevice/ButtonPositionControls.java207
-rw-r--r--src/VirtualInputDevice/HelloUniverse.html15
-rw-r--r--src/VirtualInputDevice/HelloUniverse.java134
-rw-r--r--src/VirtualInputDevice/HelloUniverse_plugin.html39
-rw-r--r--src/VirtualInputDevice/PositionControls.java68
-rw-r--r--src/VirtualInputDevice/README234
-rw-r--r--src/VirtualInputDevice/RotationControls.java71
-rw-r--r--src/VirtualInputDevice/SensorBehavior.java70
-rw-r--r--src/VirtualInputDevice/VirtualInputDevice.java258
-rw-r--r--src/VirtualInputDevice/WheelControls.java399
-rw-r--r--src/VirtualInputDevice/build.xml66
11 files changed, 1561 insertions, 0 deletions
diff --git a/src/VirtualInputDevice/ButtonPositionControls.java b/src/VirtualInputDevice/ButtonPositionControls.java
new file mode 100644
index 0000000..4335a87
--- /dev/null
+++ b/src/VirtualInputDevice/ButtonPositionControls.java
@@ -0,0 +1,207 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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:
+ *
+ * - Redistribution 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 MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS 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 THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.vecmath.*;
+import javax.media.j3d.*;
+
+public 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;
+ }
+}
diff --git a/src/VirtualInputDevice/HelloUniverse.html b/src/VirtualInputDevice/HelloUniverse.html
new file mode 100644
index 0000000..cd8d3de
--- /dev/null
+++ b/src/VirtualInputDevice/HelloUniverse.html
@@ -0,0 +1,15 @@
+<HTML>
+<HEAD>
+<TITLE>Hello, Universe!</TITLE>
+</HEAD>
+<BODY BGCOLOR="#000000">
+<applet align=middle code="HelloUniverse.class" width=350 height=350>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Hello Universe! instead of this paragraph.
+<hr>
+</blockquote>
+</applet>
+</BODY>
+</HTML>
diff --git a/src/VirtualInputDevice/HelloUniverse.java b/src/VirtualInputDevice/HelloUniverse.java
new file mode 100644
index 0000000..42f28a2
--- /dev/null
+++ b/src/VirtualInputDevice/HelloUniverse.java
@@ -0,0 +1,134 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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:
+ *
+ * - Redistribution 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 MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS 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 THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import com.sun.j3d.utils.applet.MainFrame;
+import com.sun.j3d.utils.geometry.ColorCube;
+import com.sun.j3d.utils.universe.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+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);
+ }
+}
diff --git a/src/VirtualInputDevice/HelloUniverse_plugin.html b/src/VirtualInputDevice/HelloUniverse_plugin.html
new file mode 100644
index 0000000..d3619d9
--- /dev/null
+++ b/src/VirtualInputDevice/HelloUniverse_plugin.html
@@ -0,0 +1,39 @@
+<HTML>
+<HEAD>
+<TITLE>Hello, Universe!</TITLE>
+</HEAD>
+<BODY BGCOLOR="#000000">
+<!--"CONVERTED_APPLET"-->
+<!-- CONVERTER VERSION 1.3 -->
+<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
+WIDTH = 350 HEIGHT = 350 ALIGN = middle codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
+<PARAM NAME = CODE VALUE = "HelloUniverse.class" >
+
+<PARAM NAME="type" VALUE="application/x-java-applet;version=1.2.2">
+<PARAM NAME="scriptable" VALUE="false">
+<COMMENT>
+<EMBED type="application/x-java-applet;version=1.2.2" CODE = "HelloUniverse.class" WIDTH = 350 HEIGHT = 350 ALIGN = middle scriptable=false pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html"><NOEMBED></COMMENT>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Hello Universe! instead of this paragraph.
+<hr>
+</blockquote>
+</NOEMBED></EMBED>
+</OBJECT>
+
+<!--
+<APPLET CODE = "HelloUniverse.class" WIDTH = 350 HEIGHT = 350 ALIGN = middle>
+<blockquote>
+<hr>
+If you were using a Java-capable browser,
+you would see Hello Universe! instead of this paragraph.
+<hr>
+</blockquote>
+
+</APPLET>
+-->
+<!--"END_CONVERTED_APPLET"-->
+
+</BODY>
+</HTML>
diff --git a/src/VirtualInputDevice/PositionControls.java b/src/VirtualInputDevice/PositionControls.java
new file mode 100644
index 0000000..4998c9e
--- /dev/null
+++ b/src/VirtualInputDevice/PositionControls.java
@@ -0,0 +1,68 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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:
+ *
+ * - Redistribution 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 MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS 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 THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.awt.Component;
+import javax.vecmath.Vector3f;
+
+// Classes that implement this interface must be a
+// subclass of java.awt.Component
+public 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 );
+}
diff --git a/src/VirtualInputDevice/README b/src/VirtualInputDevice/README
new file mode 100644
index 0000000..cacea02
--- /dev/null
+++ b/src/VirtualInputDevice/README
@@ -0,0 +1,234 @@
+/*
+ * @(#)README 1.5 01/06/20 16:19:00
+ *
+ * Copyright (c) 1996-2001 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.
+ */
+
+ Java 3D (TM) Input Device Driver Development Guide
+
+Topics
+
+ * Write Once, Run Anywhere (TM)
+ * Overview of the InputDevice and Sensor APIs
+ * Recipe for an Application Program that Uses Input Devices
+ * Location for Installation of Device Drivers
+ * Using a Preexistent Native Driver
+ * Package Naming Conventions
+ * Device Driver Constructor
+ * Driver Scheduling and Blocking Semantics
+
+
+Write Once, Run Anywhere
+
+Platform independence is the cornerstone of the Java (TM) platform.
+This vision now extends to external input devices as well. The
+overarching goal of the Java 3D input device architecture is to enable
+Java programs that use devices to run in a platform independent
+manner.
+
+We encourage developers to use Java APIs for their drivers. APIs such
+as the javax.comm API allow platform independent access to serial and
+parallel ports. However, even if a driver is partially written with
+native code, the Java 3D InputDevice interface is layered on top of the
+driver such that once the native portion of the driver has been
+installed into the local JRE, the application code is platform
+independent.
+
+In a future release, the Java 3D team is going to release a registry
+mechanism that will reside in the JRE as part of the Java 3D
+installation and allow registration of device drivers. The
+SimpleUniverse utility will be modified to allow querying of devices by
+generic characteristics, and will subsequently look up and instantiate
+the appropriate device driver registered with the registry mechanism.
+The Java 3D team also expects to release a set of generic mappings for
+devices. This will enable applications to count on the same behavior
+from different drivers for similar types of devices. There will also
+be personalized profiles that enable a user to specify device mappings
+for features like dominant hand preference and eye position.
+
+
+Overview of the InputDevice and Sensor APIs
+
+Java 3D abstracts the concept of a device via the InputDevice
+interface. The developer's implementation of the InputDevice interface
+is layered on top of the device driver. The device may be a real
+device such as a joystick or it may be a virtual device such as a piece
+of Java code that does transform calculations.
+
+A device sends data back to Java 3D by placing values into Sensor
+objects which the device code manages and updates. The Sensor class
+encapsulates a transform and a timestamp. The transform is specified
+in the TrackerBase coordinate system.
+
+Java 3D schedules calls to the device's pollAndProcessInput routine,
+which is a method in the InputDevice interface. This method is
+responsible for updating the devices sensor values. The sensors'
+values and time stamps are read by a user's behavior code and/or each
+frame (by the Java 3D implementation) when head tracking is enabled.
+There are several options for scheduling, and they are detailed in the
+InputDevice javadoc and in the section below entitled "Driver
+Scheduling and Blocking Semantics."
+
+Please read the javadocs for InputDevice and Sensor for more detailed
+information. There is also a sample program in the Java 3D release
+called VirtualInputDevice, which implements these concepts in Java code.
+
+
+Recipe for an Application Program that Uses Input Devices
+
+Please see the Java 3D example program in the examples directory called
+VirtualInputDevice for an example of using this code recipe:
+ 1) Implement the InputDevice interface with a class of your own
+ 2) Call the device's constructor from your main program
+ 3) Call initialize() on the device
+ 4) Call PhysicalEnvironment.addInputDevice(InputDevice) or if you are
+ using SimpleUniverse, call SimpleUniverse.getViewer().
+ getPhysicalEnvironment().addInputDevice(InputDevice)
+ 5) Assuming you want to modify the viewer's transform with the device:
+ add a WakeupOnElapsedFrames behavior to your scene graph that wakes
+ up every frame and in the processStimulus method modify the view
+ transform with the transform you pull out of Sensor.getRead.
+
+In a future release, it will be possible to replace steps 2, 3, & 4 with
+a single method call to the SimpleUniverse utility.
+
+
+Location for Installation of Device Drivers
+
+There are two suggested ways to package and distribute drivers.
+
+If a driver is written entirely in Java and if it is tightly coupled
+with a particular application without the expectation of reuse in other
+applications, then it should be bundled and distributed with the
+application itself.
+
+If a driver is not associated with any particular application program,
+if it contains any native code, or if it is expected to be used by more
+than one application program, then it should be installed directly into
+the end user's local JRE. It is expected that most drivers for real
+devices fall into this category. On the Solaris platform, the Java
+portion of the driver should be installed into jre/lib/ext as a
+uniquely named jar file and if there is native code it should be
+compiled into a shared object and installed into jre/lib/sparc. On the
+Win32 platform, the Java portion of the driver should be installed into
+jre\lib\ext as a uniquely named jar file and if there is native code it
+should be compiled into a standard dynamically linked library (dll) and
+installed into jre\bin.
+
+
+Using a Preexistent Native Driver
+
+It is possible to make a Java 3D driver out of a preexistent native
+driver. In order to do this, you need to create an InputDevice
+interface that uses JNI to access the associated native driver methods
+whenever the corresponding InputDevice interface method is called from
+Java 3D. The native portion of the driver must be installed into the
+target JRE.
+
+
+Package Naming Conventions
+
+All device drivers that are installed into the JRE should be part of a
+package that follows both standard Java and Java 3D naming
+conventions. For instance, an input device driver should be placed
+into a package called
+com.<company_name>.j3d.drivers.input.<device_name>. The package should
+be jarred up into a jar file that has a unique name.
+
+Any native .so or .dll files installed into the JRE should be uniquely
+named.
+
+
+Device Driver Constructor
+
+The constructor arguments for a device driver must be an array of
+strings. So a driver should have a single public constructor that
+takes an array of strings. The idea behind this requirement is that
+eventually the Java 3D registry will contain an array of string
+arguments to be sent to the device constructor at instantiation time.
+The SimpleUniverse API will also make a provision for optional String
+arguments to be added to the array of String arguments found in the
+registry.
+
+
+Driver Scheduling and Blocking Semantics
+
+When a device is registered with Java 3D via the
+PhysicalEnvironment.addInputDevice(InputDevice) method call,
+InputDevice.getProcessingMode() is called on the registered device.
+This method should return one of the three processing modes defined in
+the InputDevice interface: BLOCKING, NON_BLOCKING, and DEMAND_DRIVEN.
+
+ BLOCKING signifies that the driver for a device is a blocking driver
+ and that it should be scheduled for regular reads by Java 3D. A
+ blocking driver is defined as a driver that can cause the thread
+ accessing the driver (the Java 3D implementation thread calling the
+ pollAndProcessInput method) to block while the data is being accessed
+ from the driver.
+
+ NON_BLOCKING signifies that the driver for a device is a non-blocking
+ driver and that it should be scheduled for regular reads by Java 3D.
+ A non-blocking driver is defined as a driver that does not cause the
+ calling thread to block while data is being retrieved from the
+ driver. If no data is available from the device, pollAndProcessInput
+ should return without updating the sensor read value.
+
+ DEMAND_DRIVEN signifies that the Java 3D implementation should not
+ schedule regular reads on the sensors of this device; the Java 3D
+ implementation will only call pollAndProcessInput when one of the
+ device's sensors' getRead methods is called. A DEMAND_DRIVEN driver
+ must always provide the current value of the sensor on demand
+ whenever pollAndProcessInput is called. This means that DEMAND_DRIVEN
+ drivers are non-blocking by definition.
+
+It is important that you correctly classify your driver. If it is a
+NON_BLOCKING driver, most Java 3D implementations will choose to add
+inertia inside the scheduling thread to avoid starvation of the other
+Java 3D threads. If it is a BLOCKING driver, most Java 3D
+implementations will choose to spawn a separate scheduling thread for
+each BLOCKING device. If your driver is a DEMAND_DRIVEN driver, your
+driver must always provide the current value upon request along with
+the current time stamp.
+
+When running drivers with the Solaris operating system using the
+Solaris reference 1.2 JRE and green threads, you should be aware that
+there is a bug that forces all drivers to be BLOCKING. Thus, you
+should be careful to always use native threads on the Solaris reference
+1.2 JRE in order to get the expected behavior. This is not an issue
+with the Solaris 1.2 Performance JRE release, which is native threads
+only.
+
+
diff --git a/src/VirtualInputDevice/RotationControls.java b/src/VirtualInputDevice/RotationControls.java
new file mode 100644
index 0000000..5535f12
--- /dev/null
+++ b/src/VirtualInputDevice/RotationControls.java
@@ -0,0 +1,71 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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:
+ *
+ * - Redistribution 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 MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS 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 THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.awt.Component;
+
+// Classes that implement this interface must be a subclass
+// of java.awt.Component
+
+public 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();
+}
diff --git a/src/VirtualInputDevice/SensorBehavior.java b/src/VirtualInputDevice/SensorBehavior.java
new file mode 100644
index 0000000..3c8d4ee
--- /dev/null
+++ b/src/VirtualInputDevice/SensorBehavior.java
@@ -0,0 +1,70 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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:
+ *
+ * - Redistribution 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 MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS 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 THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import javax.media.j3d.*;
+import java.util.*;
+
+public 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 );
+ }
+
+}
diff --git a/src/VirtualInputDevice/VirtualInputDevice.java b/src/VirtualInputDevice/VirtualInputDevice.java
new file mode 100644
index 0000000..d148fd0
--- /dev/null
+++ b/src/VirtualInputDevice/VirtualInputDevice.java
@@ -0,0 +1,258 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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:
+ *
+ * - Redistribution 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 MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS 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 THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import javax.media.j3d.*;
+import javax.vecmath.*;
+import java.awt.*;
+import java.awt.event.*;
+
+public 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");
+ }
+ }
+
+}
diff --git a/src/VirtualInputDevice/WheelControls.java b/src/VirtualInputDevice/WheelControls.java
new file mode 100644
index 0000000..f4ac4d8
--- /dev/null
+++ b/src/VirtualInputDevice/WheelControls.java
@@ -0,0 +1,399 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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:
+ *
+ * - Redistribution 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 MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS 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 THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.event.*;
+
+public 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;
+ }
+}
diff --git a/src/VirtualInputDevice/build.xml b/src/VirtualInputDevice/build.xml
new file mode 100644
index 0000000..cbf53a8
--- /dev/null
+++ b/src/VirtualInputDevice/build.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 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:
+ *
+ * - Redistribution 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 MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS 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 THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+ -->
+
+<project basedir="." default="compile">
+ <target name="compile">
+ <javac debug="true" deprecation="true" destdir="." srcdir=".">
+ </javac>
+ </target>
+
+ <target name="all" depends="compile">
+ </target>
+
+ <target description="Clean all build products." name="clean">
+ <delete>
+ <fileset dir=".">
+ <include name="**/*.class"/>
+ </fileset>
+ </delete>
+ </target>
+
+</project>