1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
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.
|