diff options
author | kcr <kcr@28c7f869-5b4e-e670-f602-82bfaf57f300> | 2004-06-09 03:28:13 +0000 |
---|---|---|
committer | kcr <kcr@28c7f869-5b4e-e670-f602-82bfaf57f300> | 2004-06-09 03:28:13 +0000 |
commit | 53ebfcc5ad5554b67d2287f8b02c22ec8405af0f (patch) | |
tree | 70c8fabf4cbef5a9d2a50735c4e502d56ce156da /src/VirtualInputDevice | |
parent | 4dead457a59220406dd9fcd40997d7a7b27571b0 (diff) |
Initial creation of j3d-examples sources in CVS repository
Diffstat (limited to 'src/VirtualInputDevice')
-rw-r--r-- | src/VirtualInputDevice/ButtonPositionControls.java | 207 | ||||
-rw-r--r-- | src/VirtualInputDevice/HelloUniverse.html | 15 | ||||
-rw-r--r-- | src/VirtualInputDevice/HelloUniverse.java | 134 | ||||
-rw-r--r-- | src/VirtualInputDevice/HelloUniverse_plugin.html | 39 | ||||
-rw-r--r-- | src/VirtualInputDevice/PositionControls.java | 68 | ||||
-rw-r--r-- | src/VirtualInputDevice/README | 234 | ||||
-rw-r--r-- | src/VirtualInputDevice/RotationControls.java | 71 | ||||
-rw-r--r-- | src/VirtualInputDevice/SensorBehavior.java | 70 | ||||
-rw-r--r-- | src/VirtualInputDevice/VirtualInputDevice.java | 258 | ||||
-rw-r--r-- | src/VirtualInputDevice/WheelControls.java | 399 | ||||
-rw-r--r-- | src/VirtualInputDevice/build.xml | 66 |
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> |