home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Homebrewer's Handbook
/
vr.iso
/
avril
/
avrilapp.txt
< prev
next >
Wrap
Text File
|
1996-03-19
|
77KB
|
2,007 lines
AVRIL Technical Reference -- Appendices
Version 2.0
March 28, 1995
Bernie Roehl
Note: These are the appendices for the technical reference
manual; the manual itself is kept in a separate file, as is the
Tutorial.
Appendix A - REVISION HISTORY
This is the second major release of AVRIL. The changes made
since the first pre-release (0.9c) are listed below.
Changes made in version 2.0:
Added support for a number of new devices.
The vrl_DevicePollAll() now returns non-zero if any of the
devices had new data.
Added support for stereoscopic rendering.
Added support for Gouraud shading, including the
vrl_RepComputeVertexNormals() function for computing vertex
normals as the average of polygon normals.
Standardized the display (i.e. scan-converter) and video (frame
buffer) interfaces.
Modified vrl_Palette type; it's no longer an array, it's now a
struct containing additional information about the palette
(specifically, the huemap).
Provided vrl_malloc(), vrl_calloc() and vrl_free() functions as
"wrappers" around the system functions.
Defined a "raster" type for bitmaps.
The vrl_SurfaceInit() function no longer takes a hue parameter.
The vrl_Surfacemap type is no longer just an array; it's a struct
containing additional information. New functions have been added
for accessing that information.
Surfaces are now kept in a list.
AVRIL Tech Ref -- Appendices 1
Surfacemaps are now kept in a list.
Replaced vrl_ObjectGetX() and its sister functions with
vrl_ObjectGetWorldX() and vrl_ObjectGetRelativeX() and company;
the first returns absolute world coordinates, the second returns
coordinates relative to the object's parent. Did the same for
vrl_ObjectGetLocation().
Added a vrl_TransformVertexToScreen() function, to convert a
vertex from object space to screen space.
All the file-loading functions now use the loadpath.
Renamed some of the reading and loading functions; the "Read"
type functions now take a FILE *, the "Load" type functions now
take a filename.
Fixed typo that caused the vrl_ShapeRescale() function to be
undefined.
Modified joystick driver to not zero out buttons and nbuttons
when a buttonmap is being used.
Changes made in version 1.1:
Added support for the Polhemus Isotrak.
Added the functions vrl_ObjectLookAt(), vrl_CameraLookAt() and
vrl_LightLookAt().
Simplified the code in cfg.c; as several people pointed out, it
was a complicated solution to a simple problem. Devices now have
"nicknames" by which they can be referenced by the application,
eliminating the need for the cfg.c code to keep track of that
information. The configuration file is read after (not before)
vrl_SystemStartup() is called, and a "display" statement will
simply re-initialize the display to use the new driver and/or
mode.
Fixed a bug in the horizon routine that had caused sky to be
displayed when looking straight down, and ground to be displayed
when looking straight up.
Changes made in version 0.9c:
Added support for multi-channel input devices.
Added support for serial communications.
Renamed all the types to begin with the "vrl_" prefix; the types
affected are Scalar, Factor, Angle, Vector and Matrix. Also
changed UNITY to VRL_UNITY. There are #defines at the end of
AVRIL Tech Ref -- Appendices 2
avril.h to ease the transition; they'll be removed for version
2.00.
Added vrl_Boolean and vrl_Time types.
Modified avril.h to #include <stdio.h> and #include <mem.h> (for
memcpy()).
Added #defines for XROT, YROT and ZROT for indexing device
channels.
Added various additional vector and matrix functions such as
vrl_VectorNegate() and vrl_VectorEqual(). Also added a new
global variable, the null vector vrl_VectorNULL.
Added a "leftside" parameter to the vrl_MatrixRotX(),
vrl_MatrixRotY(), vrl_MatrixRotZ(), and vrl_MatrixRotVector()
functions.
Removed the vrl_List structure and put names into the structs for
vrl_Lights, vrl_Cameras, and vrl_Objects. Added functions for
accessing those names, and for finding entities based on their
name. Also added routines for traversing and iterating over the
linked lists of vrl_Lights and vrl_Cameras.
Added vrl_ObjectRotate() and vrl_ObjectTranslate() routines, and
modified several older movement and rotation functions to make
calls to those two.
Made surface maps into a struct, rather than just an array of
vrl_Surface pointers. This allows for additional information
about a surface map to be kept, and for the surface maps to be
kept in a linked list.
Added the notions of a world having "bounds" and a "radius", and
routines for supporting those notions.
The RVD drivers are now searched for along the PATH, as well as
in the current directory.
Renamed all the vrl_New* functions to make their naming
consistent with everything else. For example, vrl_NewObject() is
now vrl_ObjectCreate(). Again, #defines were added to the end of
avril.h to ease the transition; these will be removed as of the
2.00 release.
Added a vrl_WorldUpdate() macro.
Added application-specific data to vrl_Objects, vrl_Lights and
vrl_Cameras.
Added functions to vrl_Objects, which get called during world updating.
AVRIL Tech Ref -- Appendices 3
Added ID numbers to facets.
Renamed vrl_SetFigurePartArray() to vrl_SetReadFIGpartArray() to
be more consistent.
Switched to using standard the DOS timer (at an accelerated rate,
and chaining to the old one periodically) because the RTC timer
interfered with Turbo Debugger.
Standardized on a tick rate of 1000 per second.
Eliminated the vrl_TimerAddHandler() routine, since there was too
much risk that handler routines would do things that ought not be
done inside an interrupt handler; a bug in Borland C 3.1 bug also
forced all routines called from within an interrupt to be
assembled without 386 instructions.
Added a call to directly query the frames per second rate.
Renamed the vrl_DrawCompass() and vrl_DropText() routines to
vrl_UserInterfaceDrawCompass() and vrl_UserInterfaceDropText() to
make it clear that they're a part of the user interface family of
functions.
Modified the vrl_PrimitiveSphere() routine to accept separate
counts of the number of longitudinal and latitudinal sides.
Add support for configuration files.
Added the additional mouse routines vrl_MouseGetUsage(),
vrl_MouseSetUsage(), vrl_MouseSetPointer(), vrl_MouseGetPointer()
and vrl_MouseGetLimits().
AVRIL Tech Ref -- Appendices 4
Appendix B - CFG FILE FORMAT
A CFG file is a platform-specific ascii file used to describe the
user's preferred configuration. It contains a series of
statements, one per line; anything after a '#' character on any
given line is taken as a comment, and blank lines are ignored.
At the moment, there are only a few statement types defined; this
is expected to change.
COMPASS state
If state is "on", then the compass should be displayed on
the screen.
FRAMERATE state
If state is "on", then the frame rate should be displayed on
the screen.
POSITION state
If state is "on", then the current X,Z position should be
displayed on the screen.
CURSOR state
If state is "on", then the cursor should be visible; this is
the default state.
DEVICE name type mode address irq buffsize
Sets up a device driver, and assigns it a symbolic name that
can be referenced by the application. The type field is the
name of a device type, like "Cyberman" or "Spaceball". The
mode is passed to the device using vrl_DeviceSetMode(), and
the address, irq and buffsize fields are just passed to the
call to vrl_SerialOpen(); see the section on Serial Ports
for details. All parameters except the name and type are
optional; devices that are not interfaced over a serial port
do not need the address, irq or buffsize parameters, and
devices all have a default mode. The name can be anything
you like; however, it should be something that's referenced
by the application. For example,
device headtracker Redbaron 0 0x2F8 3 2000
would set up the Logitech Red Baron ultrasonic tracking
device; the device would be hooked up to COM2 (address =
0x2F8, irq = 3) with a 2000 byte buffer. The application
would simply look up the device called "headtracker" and use
the values it returns without having to worry about what
kind of device it actually is.
DEVCONFIG name channel scale deadzone
Sets the scale and deadzone parameters for a particular
channel of a particular device. The name must match the
AVRIL Tech Ref -- Appendices 5
name of a device already specified with a DEVICE statement.
The channel can be either a number or one of the special
values X, Y, Z, XROT, YROT or ZROT. The scale can be either
a number (in which case it's taken to be a scalar distance)
or a number with an 'a' or 'A' in front of it (in which case
it's taken to be an angle). The deadzone value is a number,
specified in device coordinates. The deadzone is optional,
and defaults to zero.
For example,
devconfig headtracker 2 15
would cause channel 2 (the Z channel) to have a scale factor
of 15 and a deadzone of zero, while
devconfig headtracker YROT a45 10
would cause channel 4 (the Y rotation channel) to have an
angular scale factor of 45 degrees and a deadzone of 10
device units.
DISPLAYDRIVER name
Specifies which display driver to use. Currently the only
values are "ModeY" or "default". See also the description
for VIDEODRIVER, and the technical reference manual.
INCLUDE file
Includes the contents of the specified file as if they
appeared in the current file in place of the INCLUDE.
LOADPATH path
Specifies the path from which all subsequent files should be
loaded. The path is effectively prepended to any filename
that does not begin with a '/' or '\'.
STEREOTYPE type
Specifies which type of stereoscopic viewing to use. The
type can be any of the following:
NONE, SEQUENTIAL, ANAGLYPH_SEQUENTIAL,
ANAGLYPH_WIRE_ALTERNATE, ENIGMA, FRESNEL,
CYBERSCOPE, CRYSTALEYES, CHROMADEPTH, SIRDS,
TWOCARDS, ANAGLYPH_SOLID_ALTERNATE
See Appendix I for descriptions of each of the types; note
that not all of them are implemented yet in version 2.0 of
AVRIL.
STEREOPARAMS params
Sets parameters for the stereo viewing mode. The params
will differ from one type of stereo viewing to another. For
CHROMADEPTH, the parameters are the ChromaNear and ChromaFar
distances, in world units. For all other currently
AVRIL Tech Ref -- Appendices 6
supported modes, the parameters are the eyespacing and
(optionally) the convergence distance, both as floating-
point numbers. They must be in the same units (e.g. millimeters).
STEREOLEFT shift [rotation]
STEREORIGHT shift [rotation]
Specifies the shift and (optionally) the rotation for the
left or right eye. See the section on stereoscopic viewing
in the technical reference manual for details.
VERSION nn
Indicates which version of this specification the
configuration conforms to. This can be omitted; if present,
it should be set to 1.
VIDEODRIVER name [mode]
Specifies the name of the low-level video driver to use;
currently the only values are "Mode13", "ModeY" and
"7thSense". The mode indicates the graphics sub-mode to
use; it's passed directly to the driver function, in the
initialization call. See also the description for
DISPLAYDRIVER, and the technical reference manual.
Note the difference between the VIDEODRIVER and the
DISPLAYDRIVER. The VIDEODRIVER deals with the hardware, the
DISPLAYDRIVER with the scan-conversion module; see the technical
reference manual for details. You can, for example, have the
following:
videodriver mode13
displaydriver default
in which case mode 0x13 will be used throughout, or
videodriver modeY
displaydriver modeY
in which case mode Y will be used throughout. Alternatively, you
can mix them:
videodriver modeY
displaydriver default
in which case rendering will be done to an offscreen buffer, and
the completed screen image copied to the current draw page in
mode Y.
AVRIL Tech Ref -- Appendices 7
Appendix C - PLG FILE FORMAT
I originally designed PLG files for use with REND386; for better
or worse, they seem to have become something of a standard.
REND386, AVRIL, VR386 and Jon Blossom's Gossamer all use them for
object geometry description; there are also translators that turn
other formats into PLG, and the NorthCAD-3D program can generate
PLG files as output. The PLG in the name stands for "polygon".
There will soon be a file format for the interchange of
virtual objects and virtual worlds between VR systems; at that
point, support for the PLG file format will diminish. Conversion
programs will be made available to convert PLG files to the new
format.
A PLG file basically has three parts: a header line, a list
of vertices and a list of facets.
The header line has the object name, the number of vertices,
and the number of facets; for example:
kitchen_table 100 35
which would mean that the object "kitchen_table" has 100 vertices
and 35 facets.
The number of facets can optinally be followed by two
numbers; the first is ignored, and should be set to zero (it's
for compatability with VR386), and the second is the sorting
type. It should be set to zero if (and only if) you know the
object is convex (i.e. no part of the object can hide any other
part). Anything after those two numbers should be ignored, since
it may be used for future expansion.
Following this line are the vertices, one x,y,z triplet per
line (each value is a floating-point number, and they're
separated by spaces). For example:
18027 23025 98703
Vertex normals may optionally be specified after the vertex
coordinates. Anything after the vertex normals is ignored (for
future expansion).
This is followed by the facet information, one line per
facet; each of these lines is of the form
surfacedesc n v1 v2 v3 ...
The surfacedesc is described below. The n is the number of
vertices in the facet. The v1, v2, v3 and so on are indices into
AVRIL Tech Ref -- Appendices 8
the array of vertices; the vertices are listed in a counter-
clockwise order as seen from the "front" (i.e. visible side) of
the facet. Note that the vertices are counted "origin zero",
i.e. the first vertex is vertex number 0, not vertex number 1.
For example:
0x8002 4 8 27 5 12
would mean a four-sided facet bounded by vertices 8, 27, 5 and
12. This facet has a surface descriptor of 0x8002.
Anything after the list of vertex indices should be ignored.
The PLG format supports comments. Anything after a # should
be ignored by any program that parses PLG files. In addition,
lines beginning with a '*' should be ignored.
PLG files can have multiple copies of an object at different
resolutions. PLG files containing such multiple-resolution
versions of objects must have "#MULTI" as their first line.
For each object defined in such a file, the object name
includes a number specifying the pixel size of the object on the
screen. The object names for each representation must be
<name>_####
where #### is the smallest pixel width to use this representation
for. For example, TABLE_15 would be a valid name.
If the smallest rep size is zero, then that representation
will be used no matter how small the object gets. If the
smallest rep size is 1 or greater, then the object will vanish if
it gets too small.
The surface descriptor can either be a decimal integer or a
0x or 0X followed by a hexadecimal integer value. The surface
descriptor is a 16-bit value which is interpreted as follows:
H SSS CCCC BBBBBBBB
If the H bit is set, it indicates that this is a "mapped" surface
descriptor; the bottom 14 bits are taken to be an index into a
surface map.
If the H bit is clear, the SSS bits are interpreted as follows:
000 -- This facet is "solid shaded"; i.e. it should be
drawn in a fixed color, with no special effects.
If the CCCC bits are zero, then the BBBBBBBB bits
directly specify one of the 256 available colors;
AVRIL Tech Ref -- Appendices 9
if the CCCC bits are non-zero, then they specify
one of sixteen hues and the top four bits of
BBBBBBBB specify which shade of that hue to use.
001 -- This facet is "flat shaded"; i.e. it should be
drawn with a constant shading that is determined
by the angle at which light is striking it; thus,
as the facet moves around, its apparent brightness
will change. The CCCC bits specify one of sixteen
hues, and the bottom 8 bits BBBBBBBB represent the
"brightness" of the color. This brightness value
is multiplied by the cosine of the angle between
the facet's normal vector and the vector from the
facet to the light source; the result is used to
specify an offset into the given color's array of
shades. Note that if the CCCC value is 0, the
color will always be black.
010 -- This facet should be treated as being "metallic";
the CCCC bits (which should be non-zero) specify
one of the 16 hues, and the top 5 bits of the
BBBBBBBB value are used as an offset into a range
of shades to cycle through to give the metallic
effect, i.e. a starting offset into the color
cycle.
011 -- This facet should be treated as being
"transparent"; it is just like surface type 10,
except that alternating rows of dots are used
instead of solid colors, allowing you to "see
through" the facet.
100 -- This facet should be Gouraud shaded; the meaning
of the other bits is the same as for flat shading.
Other values of SSS are reserved and should not be used.
AVRIL Tech Ref -- Appendices 10
Appendix D - FIG FILE FORMAT
FIG files are a way of representing multi-segmented, hierarchical
entities.
This format will soon be considered obsolete.
There will soon be a file format for the interchange of
virtual objects and virtual worlds between VR systems; at that
point, support for the FIG file format will diminish. Conversion
programs will be made available to convert FIG files to the new
format.
The syntax of a figure file is simple, and very C-like. It
consists of a series of segments, each of which can possess a set
of attributes, as well as child segments. Each segment is
bounded by braces. Attributes are arbitrary text strings ending
in a semicolon.
The list of possible attributes is open-ended and
extensible; programs that read figure files should ignore any
attributes they don't recognize.
An example will make all this clearer.
{
comment = a human body;
name = pelvis; comment = this is the name of the root segment;
{
name = chest;
{ name = left upper arm; { name = left lower arm; } }
{ name = right upper arm; { name = right lower arm; } }
{ name = head; }
}
{ name = left upper leg; { name = right lower leg; } }
{ name = right upper leg; { name = right lower leg; } }
}
}
In general, attributes are of the form "keyword = value;", though
this is not a requirement. The attributes used above are name
and comment. Note that no program ever has to recognize a
comment attribute, since by definition comments should be
ignored.
The attributes currently defined are as follows:
name = somestring;
pos = x,y,z;
rot = x,y,z;
plgfile = filename scale x,y,z shift X,Y,Z sort type map filename;
AVRIL Tech Ref -- Appendices 11
segnum = someinteger;
The pos is the x,y,z displacement of the origin of this segment
relative to the parent's coordinate system. The rot is the
rotation of this segment relative to the parent. For root
objects (which have no parent) these values are the absolute
location and rotation of the entire figure in world coordinates.
The plgfile gives the name of a .plg file containing a
geometric representation of the segment. Note that the figure
file format does not strictly depend on .plg files; the reason
the syntax is "plgfile = " rather than just "file =" is because a
segment may have a large number of different representations and
an application can choose whichever one it likes.
The scale, shift, sort and map values are all optional, but
in order to specify any of them you must specify all the
preceding ones (i.e. you cannot simply omit the scale parameter).
The scale values represent the amount by which the object should
be scaled along each of its axes when it's loaded. The shift
value is the amount by which to shift the object's origin at load
time. The sort value is the type of depth-sorting to use for
this segment's representation (the default is zero). The map
value is the name of a file containing a list of unsigned values
that are to be used in surface remapping for this segment. If
the top bit of a color value is set in a plg file, the bottom
fourteen bits are used as an index into this map.
The difference between shift and pos is important. The
shift value is used to shift an object relative to its "native"
origin, while the pos value is the amount by which the new origin
should be displaced from the parent node's origin.
For example, suppose you want to represent the head of a
human figure with a cube. The cube may, in the .plg file, be
defined with its (0,0,0) point at one corner. Clearly, this
origin is inconvenient for the head, since if the origin is
centered over the neck of the figure then the head will be
displaced to one side.
Alternatively, the cube might be defined with its (0,0,0)
point at its geometric center. However, this is also
impractical; your head should not rotate freely about its center.
If it does, stop reading this document immediately and seek
medical attention.
What you do is shift the cube so that its origin lies below
the center of the cube, where your "neck joint" is. That's what
the shift value in the plgfile attribute specifies.
Important note: objects rotate about their [0,0,0] point as
loaded.
AVRIL Tech Ref -- Appendices 12
The pos attribute specifies where this neck joint is in
relation to the origin of the chest segment. If your chest were
longer vertically, then the pos attribute of the head segment
should be increased in the Y direction (for example).
The segnum attribute associates a simple integer value with
a segment, which can subsequently be used to refer to the segment
when manipulating it.
Note that a figure file can in fact contain a series of
segments; each of these is a root segment, so a figure file can
in effect store a complete scene description (excluding lights
and cameras).
AVRIL Tech Ref -- Appendices 13
Appendix E - WLD FILE FORMAT
WLD files were designed to store information about the layout of
objects in a virtual world.
This format will soon be considered obsolete.
There will soon be a file format for the interchange of virtual
objects and virtual worlds between VR systems; at that point,
support for the WLD file format will diminish. Conversion
programs will be made available to convert WLD files to the new
format.
A WLD file is entirely ascii. Each statement is one line;
anything after the first '#' is treated as a comment and ignored.
Blank lines are also ignored. The format is intended to be
highly extensible; any line which cannot be recognized should
simply be ignored. Each statement contains some information
about the scene; the possible types of statements are listed
below. Everything is case-insensitive; keywords are shown below
in uppercase, but are generally entered in lowercase.
LOADPATH path
Specifies a path prefix for loading files. Any files
(whether specified in the world file itself, subsequent
world files, or in referenced FIG files) will be loaded from
the specified directory. However, if a filename begins with
the '\' or '/' characters, it is used verbatim (i.e. the
LOADPATH setting is ignored).
PALETTE filename
Loads a 256-entry binary palette file (3 bytes (R,G,B) for
each entry). Note that alternate palettes may not handle
shading as well as the default one does. If there are more
that 768 bytes (256 times 3) in the file, the remaining
values are interpreted as a hue map; pairs of bytes are
starting indices (origin 0) and number of shades.
SKYCOLOR index
Specifies which of the 256 available colors should be used
for the "sky".
GROUNDCOLOR index
Specifies which of the 256 available colors should be used
for the "ground". If the sky and ground color are identical,
a solid screen clear is used; this is a bit faster.
SCREENCLEAR value
If the specified value is non-zero, then the screen will be
cleared before each frame; if it's zero, the screen clearing
is not done (this is useful if you know that the entire
AVRIL Tech Ref -- Appendices 14
window will be covered by the image, and that no background
will show through; in such a situation, specifying this
option will improve performance).
AMBIENT value
Specifies the level of the ambient light; 76 is the default,
and a good value to use.
LIGHT x,y,z
Specifies the location of a light source in world
coordinates.
CAMERA x,y,z tilt,pan,roll zoom
Specifies your starting location, viewing direction and zoom
factor. The x,y,z values are floating-point numbers giving
coordinates, the tilt,pan,roll values are floating-point
angles, and the zoom is a floating-point number giving the
zoom factor. Remember that the order of rotations is pan,
tilt, roll.
HITHER value
Specifies the near clipping distance in world coordinates.
The value should typically be 10 or more.
YON value
Specifies the far clipping distance in world coordinates.
The value should typically be 1000000 or more.
OBJECT [objname=]filename sx,sy,sz rx,ry,rz tx,ty,tz depthtype
mappings parent
Loads an object from a .plg file with the given filename.
If the objname= is present, it assigns the newly-loaded
object that name for future reference. The sx,sy,sz values
are floating-point scale factors to increase or decrease the
size of the object as it's loaded. The rx,ry,rz values are
the angles to rotate the object around in each of the three
axes; ry is done first, then rx and finally rz. The
tx,ty,tz values translate (move) the object to a new
location; this is done after the scaling and rotation. The
depthtype field is not currently used. The mappings feature
is explained below. The parent field is the name of the
object that this object is attached to; if omitted, the
child moves independently. If parent is the word "fixed",
then the object is fixed in space and cannot be moved. All
fields are optional, but you must include all the fields
prior to the last one you wish to use (i.e. you can only
leave things off the end, not off the beginning or out of
the middle).
FIGURE [figname=]filename sx,sy,sz rx,ry,rz tx,ty,tz parent
AVRIL Tech Ref -- Appendices 15
Loads a segmented figure from a FIG file with the given
filename. All the parameters have the same meaning as for
the OBJECT statement described above.
POLYOBJ npts surface x1,y1,z1 x2,y2,z2 [...] x8,y8,z8
Directly specifies a facet to be placed in the scene. The
value npts is the number of points (maximum 8), the surface
is a surface name (see below on surfaces) and the vertices
are given in world coordinates.
POLYOBJ2 npts surface1,surface2 x1,y1,z1 x2,y2,z2 [...] x8,y8,z8
Directly specifies a double-sided facet to be placed in the
scene. The value npts is the number of points (maximum 8),
surface1 and surface2 are surface names (see below on
surfaces) and the vertices are given in world coordinates.
INCLUDE filename
Includes the specified file as if its contents appeared at
the current point in the current file.
POSITION objname x,y,z
Moves (i.e. translates) the specified object to the given
x,y,z location.
ROTATE objname rx,ry,rz
Rotates the specified object to the given angles about each
of the axes. The angles are specified in floating point,
and are measured in degrees. The rotation order is Y then X
then Z.
VERSION number
Allows you to define a version number. Not currently used
for anything; can be omitted.
TITLE text
Allows you to define a title for your world.
About Mapping
A PLG file can contain indexed color values (such as 0x8002)
which are used to index a surface map. Entries in surface maps
refer to surfaces. Surfaces are created using the SURFACEDEF
statement, surface maps are created with the SURFACEMAP
statement, and entries are placed in them with the SURFACE
statement. The statement formats are as follows:
SURFACEDEF name value
Defines a new surface; maps a surface name (such as "wood")
to a numeric surface descriptor (value) of the type
described in Appendix C.
SURFACEMAP name maxentries
AVRIL Tech Ref -- Appendices 16
Marks the start of a new surface map. All subsequent
SURFACE entries will be placed in this map. The maxentries
field gives the maximum number of entries this surface map
will have; if omitted, it defaults to 10.
SURFACE index name
Defines an entry in the current surface map, which takes an
index value (the bottom 14 bits of the value in the .plg
file) and maps it into a surface name (which is in turn
mapped to a 16-bit color value).
USEMAP mapname
Causes all subsequently loaded objects that don't have a
mapname on their OBJECT statements to use the specified
mapname.
AVRIL Tech Ref -- Appendices 17
Appendix F - WRITING DEVICE DRIVERS
Writing device drivers for AVRIL is easy. You basically create a
single function with a unique name; for example, if you want to
support a (mythical) RealTronics Atomic Tracking System, your
function might be
int vrl_ATSDevice(vrl_DeviceCommand cmd, vrl_Device *device)
{
[...]
}
You should add an entry for your new function to the list in
avrildrv.h, and possibly to the cfg.c file.
Your driver routine will get called periodically by the
application. The vrl_Device struct is pre-allocated by AVRIL, so
you just have to fill in the various fields. The cmd is one of
VRL_DEVICE_INIT, VRL_DEVICE_RESET, VRL_DEVICE_SET_RANGE,
VRL_DEVICE_POLL, or VRL_DEVICE_QUIT.
When a device is first opened, AVRIL will set all the fields
in the vrl_Device struct to reasonable values. The
VRL_DEVICE_INIT call should fill in the following fields with
driver-specific information:
char *desc; /* user-readable device description */
int nchannels; /* number of input channels the device has */
vrl_DeviceChannel *channels; /* pointer to array of channels */
The desc is a string describing the device, the nchannels value
is the number of input channels the device has (should be at
least 6) and the channels field is set to point to an array of
vrl_DeviceChannel structs, one per channel. These channels
should be dynamically allocated, rather than using a static
struct; this is to allow for multiple instances of the same type
of device (for example, a Cyberman on each of COM1 and COM2, each
with its own channel-specific data). For this same reason, your
driver shouldn't use any global variables; you should instead
dynamically allocate memory for any additional per-device-
instance data and store the pointer to that data in the localdata
field of the vrl_Device struct. The VRL_DEVICE_INIT call should
also fill in the appropriate values for all the channels.
The VRL_DEVICE_INIT call may also choose to fill in some or all
of the following:
int nbuttons; /* number of buttons the device has */
int noutput_channels; /* number of output channels */
vrl_DeviceOutputFunction *outfunc; /* function to call to generate output */
vrl_DeviceMotionMode rotation_mode; /* rotation mode for this device */
AVRIL Tech Ref -- Appendices 18
vrl_DeviceMotionMode translation_mode; /* translation mode for this device */
vrl_Buttonmap *buttonmap; /* button mapping table for 2D devices */
int version; /* device struct version number */
int mode; /* mode of operation */
vrl_Time period; /* milliseconds between reads */
The number of buttons the device has is assumed to be zero unless
you set it otherwise, as is the number of output channels. The
outfunc field is a pointer to a function (probably declared
static in the same source file as your driver function) that
handles output to the device; this is described in more detail
below. If your device doesn't do output, leave this field at its
default value of NULL.
The meaning of the two vrl_DeviceMotionMode type fields is
described in the main part of the technical reference manual, in
the section on Devices. They both default to
VRL_MOTION_RELATIVE. The mode is driver-specific, and can be
initialized to whatever value you like (since the value is only
interpreted by your driver). The version field should be left at
its default value of zero by drivers following this version of
the driver specification; as the driver specification evolves,
this value will increase.
The period defaults to zero, meaning that a call to
vrl_DevicePoll() will always result in your driver function being
called with a cmd of VRL_DEVICE_POLL. If you don't want to be
polled every cycle, set the period to the minimum number of ticks
(usually milliseconds) that should elapse between polls. Note
that this is a minimum value; the delay between polls may be even
longer if the system is busy doing other things.
The VRL_DEVICE_RESET command is very similar to
VRL_DEVICE_INIT, and may in fact be the same for some devices.
The difference is that VRL_DEVICE_INIT does one-time
initializations (such as taking over interrupt vectors).
On receiving the VRL_DEVICE_RESET command, the driver should
note the current values of each channel and make them the
centerpoint for that channel. On receiving a
VRL_DEVICE_SET_RANGE command, it should make the current values
the range for that channel. See the notes below about
centerpoint and range.
The VRL_DEVICE_QUIT command should "shut down" the device,
putting it in a quiescent state and undoing anything that was
done in VRL_DEVICE_INIT and VRL_DEVICE_RESET (for example,
restoring interrupt vectors). It's also responsible for
releasing any memory that was dynamically allocated by
VRL_DEVICE_INIT, including that pointed to by the channels field
and the localdata field if it was used.
AVRIL Tech Ref -- Appendices 19
Serial devices can assume that when VRL_DEVICE_INIT is
called, the port they'll be using is already open, and that the
port field is set; the driver also does not need to (and should
not) close the port. However, devices that actually use the port
should check that it's not NULL, and return -4 if it is.
The VRL_DEVICE_POLL command should read the raw data from
the hardware (for example, by calling vrl_DeviceGetPacket()) and
decode the values into the rawdata fields of the appropriate
channels. You should be sure to set the changed field for any
channels that you update.
There are a number of values associated with each channel; they
are as follows:
struct _vrl_device_channel
{
vrl_32bit centerpoint; /* value of center point in raw device coords */
vrl_32bit deadzone; /* minimum acceptable value in device coords */
vrl_32bit range; /* maximum absolute value relative to zero */
vrl_Scalar scale; /* maximum returned value */
vrl_Boolean accumulate : 1; /* if set, accumulate values */
vrl_Boolean changed : 1; /* set if rawvalue has changed */
vrl_32bit rawvalue; /* current value in raw device coordinates */
vrl_32bit oldvalue; /* previous value in raw device coordinates */
vrl_Scalar value; /* current value (processed) */
};
The only fields you must set are centerpoint, deadzone, range,
scale and accumulate. The centerpoint is the current "zero"
value of the device; for example, the value an analog joystick on
a PC-compatible reports when the stick is at rest can be
considered its centerpoint.
The deadzone has two different interpretations. If the
accumulate flag is set, then the deadzone is the minimum
displacement from the centerpoint that will be recognized. If
the accumulate flag is clear, then the value is the minimum
change from the previous value (as stored in oldvalue by the
higher-level routines) that will be recognized.
The scale and range values are used to convert the rawvalue
into units more suitable for the application. The scale is the
number of world-space units corresponding to the range in device
units. The scale and deadzone should both be positive values,
and can be changed by the application. The range value can be
negative; this is useful for reversing the direction of a device
axis. The range value is only ever set by your driver.
The accumulate flag, in addition to controlling how the
deadzone is interpreted, causes the value to be scaled by the
elapsed time in seconds since the last poll.
AVRIL Tech Ref -- Appendices 20
The best way to understand all this is to consider what
happens when you read new values from the device in response to a
VRL_DEVICE_POLL command. First, you store the data for each
channel in the corresponding channel's rawvalue field. You can
re-map axes at this point (device coordinate Y goes into the Z
channel, for example); you may want to use the buttonmap (see
below) for this purpose. You should set the changed flag, to
indicate there's a new value there.
Next, the higher-level code takes your rawvalue and
subtracts the centerpoint. If the channel is in accumulate mode,
it checks if the absolute value of the data is less than
deadzone; if it is, it truncates it to zero. If the channel is
not in accumulate mode, the data is compared to the oldvalue
field; if it's within plus or minus deadzone of it, the data is
ignored.
Once the value has been centered and deadzoned, it is
multiplied by the scale and divided by the range. If accumulate
is set, the resulting value is multiplied by the elapsed time in
milliseconds and then divided by 1000 to convert to seconds.
Buttonmaps
Some 2D devices (such as mice and joysticks) can be used as
6D devices, by using their buttons to map their input axes to the
6 possible degrees of freedom. Such devices should set their
nbuttons field to zero (or at least to the number of buttons that
will not be used for mapping). They should also set their
buttonmap field to point to a default set of axis mappings.
The buttonmap field is a pointer to a two-dimensional array.
Each row of the array corresponds to a button combination; on a
two-button device, row 0 is for no buttons down, row 1 is for the
first button down, row 2 is for the second button down and row
three is for both buttons down. There are two columns in the
array, the first of which contains the index of the channel that
the input device's X value should be stored in, and the second of
which contains the index of the Y channel.
For example,
static vrl_Buttonmap default_map =
{ { YROT, Z }, { X, Y }, { ZROT, XROT }, { X, Y }};
Would mean that when no buttons are down, the device's X axis
corresponds to a Y rotation, and its Y channel to a Z
translation. When the first button is down, the device's X axis
corresponds to an X translation, and its Y axis to a Y
translation, and so on.
AVRIL Tech Ref -- Appendices 21
The application can change the buttonmap field (using
vrl_DeviceSetButtonmap()) to point to a different set of
mappings.
One thing to watch out for: since only two channels at a
time are active, the others should have their rawvalue set equal
to their centerpoint, and their changed flags set; otherwise,
they'll retain whatever values they had the last time a
particular button combination was active.
Output
Some devices are capable of tactile or auditory feedback;
those that are should set the outfunc field in the vrl_Device
struct to point to a function that does the actual work, and set
the noutput_channels field to the number of output channels the
device has. Such a function for our mythical ATS device might
look like this:
int vrl_ATSOutput(vrl_Device *dev, int parm1, vrl_Scalar parm2)
{
[...]
}
The parm1 parameter is the output channel number, and parm2 is
the value to output (in the range 0 to 255). The routine should
return 0 on success and non-zero on failure, although those
values are not currently used or reported.
AVRIL Tech Ref -- Appendices 22
Appendix G - WRITING VIDEO DRIVERS
The low-level interface to the video hardware is handled by video
drivers. Each video driver is simply a function of the form
vrl_32bit vrl_VideoDriverFunction(vrl_VideoCommand cmd, vrl_32bit lparm, void *pparm1);
The lparm is a 32 bit value, the pparm is a pointer to somewhere
in system memory, and the return value of the function is a 32-
bit value.
You can implement your own video driver by writing a function of
the form above (giving it a unique name) and setting it as the
driver function using
vrl_VideoSetDriver(YourDriver);
The application (and AVRIL itself) will call your function,
passing it a cmd to tell it what to do. Any commands you don't
want to deal with, you can ignore; however, be sure to return
zero as the value of the function. For example, if you only have
one physical page in your display adapter, you could ignore the
VRL_VIDEO_SET_DRAW_PAGE and VRL_VIDEO_SET_VIEW_PAGE calls.
The values for cmd, and the behaviour your function should
exhibit for each, are as follows:
VRL_VIDEO_GET_VERSION
Return the version number; for this specification, return 1.
VRL_VIDEO_GET_DESCRIPTION
The pparm parameter points to a buffer in system memory;
fill that buffer with anything you like (preferably,
something that describes your driver). The lparm parameter
gives the size of the buffer; don't write past the end.
VRL_VIDEO_SETUP
Enter graphics mode; the lparm parameter indicates which
submode to use. Return zero, unless for some reason you
can't enter graphics mode (in which case, return a non-zero
value). You should, if possible, save the current mode
before entering graphics mode. You should also set the
internal cursor flag to -1, and position the cursor at the
center of the screen.
VRL_VIDEO_SHUTDOWN
Exit graphics mode, and if possible, return to the mode that
was in effect before the last call to VRL_VIDEO_SETUP.
VRL_VIDEO_GET_MODE
Return the current graphics mode (zero is an acceptable value).
AVRIL Tech Ref -- Appendices 23
VRL_VIDEO_SET_DRAW_PAGE
Set the current drawing page to the value of lparm.
VRL_VIDEO_SET_VIEW_PAGE
Set the currently visible page to the value of lparm.
VRL_VIDEO_GET_NPAGES
Return the number of pages. If you only have one page,
return 1.
VRL_VIDEO_HAS_PALETTE
Return non-zero if your hardware uses a palette, or zero if
it doesn't (i.e., 15, 16 or 24 bit color).
VRL_VIDEO_SET_PALETTE
The top 16 bits of lparm are the starting index, the bottom
16 bits are the ending index, and pparm points to the entire
256-entry palette. Values from the starting index through
the ending index (inclusive) should be copied from the
palette in system memory to the physical palette. The
starting and ending indexes are "origin zero", i.e. the
first entry in the palette is zero, not one.
VRL_VIDEO_CHECK_RETRACE
Return non-zero if a vertical retrace is taking place.
VRL_VIDEO_GET_RASTER
Return a pointer to a vrl_Raster describing your display
hardware. It's important that the height, width and depth
fields are correct.
VRL_VIDEO_BLIT
Copy the contents of the vrl_Raster pointed to by pparm into
the current draw page. If pparm points to our raster (i.e.,
the one that references the physical framebuffer) don't
bother doing the copy.
VRL_VIDEO_CURSOR_HIDE
If the internal cursor flag is greater than or equal to
zero, erase the cursor (by restoring what was under it). In
any case, decrement the internal cursor flag.
VRL_VIDEO_CURSOR_SHOW
Increment the internal cursor flag; if it's equal to zero,
draw the cursor (saving what was under it).
VRL_VIDEO_CURSOR_RESET
Center the cursor on the screen, and set the internal cursor
flag to -1.
AVRIL Tech Ref -- Appendices 24
VRL_VIDEO_CURSOR_MOVE
The top 16 bits of lparm contain the new X coordinate, and
the bottom 16 bits contain the new Y coordinate. Move the
cursor to that location (restoring what was under it, and
saving what's under the new location).
VRL_VIDEO_CURSOR_SET_APPEARANCE
Set the cursor appearance to the data pointed to by pparm.
You should add an entry for your new function to the list in
avrildrv.h, and possibly to the cfg.c file.
If you wind up writing video drivers to support additional modes,
drop me some email (broehl@sunee.uwaterloo.ca). I'll happily
include your driver in the main AVRIL release, and give you full
credit for having written your driver.
AVRIL Tech Ref -- Appendices 25
Appendix H - WRITING DISPLAY DRIVERS
The interface to the display driver (i.e. scan-converter) is a
function of the form
vrl_32bit vrl_DisplayDriverFunction(vrl_DisplayCommand cmd, vrl_32bit lparm,
void *pparm1);
The lparm is a 32 bit value, the pparm is a pointer to somewhere
in system memory, and the return value of the function is a 32-
bit value.
You can implement your own display driver by writing a function
of the form above (giving it a unique name) and setting it as the
driver function using
vrl_DisplaySetDriver(YourDriver);
The application (and AVRIL itself) will call your function,
passing it a cmd to tell it what to do. Any commands you don't
want to deal with, you can ignore; however, be sure to return
zero as the value of the function. For example, if your driver
doesn't do Z-buffering, you could ignore the
VRL_DISPLAY_CLEAR_Z_BUFFER call. (Note that version 2.0 of AVRIL
does not yet support Z-buffering, so for now you can just ignore
all those calls).
The values for cmd, and the behaviour your function should
exhibit for each, are as follows:
VRL_DISPLAY_GET_VERSION
Return the version number; for this specification, return 1.
VRL_DISPLAY_GET_DESCRIPTION
The pparm parameter points to a buffer in system memory;
fill that buffer with anything you like (preferably,
something that describes your driver). The lparm parameter
gives the length of the buffer; don't write past the end.
VRL_DISPLAY_INIT
Initialize the display subsystem. The pparm parameter
points to a raster you should use.
VRL_DISPLAY_QUIT
De-initialize the display subsystem.
VRL_DISPLAY_CLEAR
Clear the display; lparm is the color to use.
VRL_DISPLAY_POINT
AVRIL Tech Ref -- Appendices 26
The pparm parameter points to a linked list of output
vertices; set those points on the current draw page.
VRL_DISPLAY_LINE
The pparm parameter points to a linked list of output
vertices; they should be connected sequentially by a series
of lines. The color of each line should be set from the
starting vertex of the line.
VRL_DISPLAY_CLOSED_LINE
The pparm parameter points to a linked list of output
vertices; they should be connected sequentially by a series
of lines. The last point should be connected back to the
first point. The color of each line should be set from the
starting vertex of the line.
VRL_DISPLAY_BOX
The pparm parameter points to a two-element linked list of
output vertices; the first output vertex is the top-left
corner of the box, and the second is the bottom-right
corner. The box should be filled with the color of the
first output vertex.
VRL_DISPLAY_TEXT
Display the text pointed to by pparm in the color specified
by lparm.
VRL_DISPLAY_TEXT_POSITION
The top 16 bits of lparm give the new X position for drawing
text, and the bottom 16 bits give the new Y position. The
text position marks the location where the top left corner
of the first character of a string will appear.
VRL_DISPLAY_GET_TEXTWIDTH
Return the width in pixels of the string pointed to by
pparm.
VRL_DISPLAY_GET_TEXTHEIGHT
Return the height in pixels of the string pointed to by
pparm.
VRL_DISPLAY_CAN_GOURAUD
Return non-zero if you support Gouraud shading.
VRL_DISPLAY_CAN_XY_CLIP
Return non-zero if you are willing to do all the X-Y
clipping.
VRL_DISPLAY_UPDATE_PALETTE
Do whatever you need to do when the palette changes; pparm
points to the new palette.
AVRIL Tech Ref -- Appendices 27
VRL_DISPLAY_BEGIN_FRAME
Do whatever you need to do at the beginning of a frame.
VRL_DISPLAY_END_FRAME
Do whatever you need to do at the end of a frame.
VRL_DISPLAY_SET_RASTER
The pparm parameter points to a vrl_Raster, which should be
used for all subsequent drawing.
VRL_DISPLAY_GET_RASTER
The pparm parameter is a pointer to a pointer to a
vrl_Raster; in other words, you should do the equivalent of:
*((vrl_Raster **) pparm1) = our_raster;
VRL_DISPLAY_SET_Z_BUFFER
The pparm parameter points to a vrl_Raster that you should
use as the new Z-buffer.
VRL_DISPLAY_GET_Z_BUFFER
The pparm parameter is a pointer to a pointer to a
vrl_Raster; in other words, you should do the equivalent of:
*((vrl_Raster **) pparm1) = our_z_raster;
VRL_DISPLAY_USE_Z_BUFFER
If lparm is non-zero, enable use of the Z-buffer; if lparm
is zero, disable the Z-buffer. Return 0 if you can't Z-
buffer, 1 if you do it in software, or 2 if you do it in
hardware.
VRL_DISPLAY_CLEAR_Z_BUFFER
Clear the Z-buffer, if you have one. Fill it with the value
of lparm (if possible).
VRL_DISPLAY_SET_SHADING
The lparm parameter is a hint from the user; the higher the
number, the more time you should spend on shading.
VRL_DISPLAY_POLY
This is where the action is. The pparm parameter points to
an output facet; draw it into the current framebuffer.
Easy, right?
The two data types used by the display driver are
vrl_OutputVertex and vrl_OutputFacet. A vrl_OutputVertex looks
like this:
struct _vrl_outvertex
{
vrl_ScreenCoord x,y,z; /* X, Y screen coordinates and Z-depth */
vrl_16bit red, green, blue; /* components of the color */
vrl_OutputVertex *next, *prev; /* doubly-linked circular list */
AVRIL Tech Ref -- Appendices 28
};
The vrl_ScreenCoord values are fractional; the number of bits to
the right of the binary point is specified by
VRL_SCREEN_FRACT_BITS.
The colors are in 8.8 format (i.e. 8 bits of color, 8 bits of
fraction). For paletted systems, only the red value is used;
it's interpreted as a palette index.
Note that future versions of AVRIL may support additional
information per vertex, such as texture map coordinates.
A vrl_OutputFacet looks like this:
struct _vrl_outfacet
{
vrl_OutputVertex *points; /* doubly-linked list of vertices for this facet */
vrl_Surface *surface; /* surface properties */
vrl_Color color; /* color of this facet (flat shading only) */
};
The list of points is doubly linked, with the next field pointing
at the next (clockwise) vertex and the prev field pointing back
to the previous (counterclockwise) vertex. The vrl_Surface
struct is the same one used throughout AVRIL; see the technical
reference manual for information about accessing the various
fields, especially the type (flat, Gouraud, etc).
For 8-bit systems, the vrl_Color value is a palette index (i.e.
only the bottom 8 bits of the 32-bit color field are used). For
15-, 16- and 32-bit systems, the actual color is stored in the 32
bit word; the bottom byte is red, the next one up is green, and
the next one up is blue. The top byte may be used as an "alpha"
channel; if not, it should be zero. Current versions of AVRIL
are 8-bit (paletted) only.
Note that future versions of AVRIL may provide additional
information for output vertices and output facets.
If you write display drivers, especially ones which support the
new 3D graphics accelerators coming on the market, please drop me
some email (broehl@sunee.uwaterloo.ca). Since I'm giving AVRIL
away for free, I can't afford to buy every card that comes out,
so I'm counting on other people to create drivers. I'll be happy
to include your drivers with the main AVRIL release, with full
credit.
AVRIL Tech Ref -- Appendices 29
Appendix I - STEREOSCOPIC VIEWING TYPES
A number of stereoscopic viewing types are supported in AVRIL.
The current version doesn't implement all of them, but all of
them are described here.
VRL_STEREOTYPE_NONE
Monoscopic; no stereo.
VRL_STEREOTYPE_ANAGLYPH_SEQUENTIAL
Field sequential, with alternate frames using red and blue
palettes. View with anaglyph (red-blue) glasses. Not yet
implemented.
VRL_STEREOTYPE_ANAGLYPH_WIRE_ALTERNATE
Wireframe anaglyph, with left-eye image on even scanlines
and right-eye image on odd scanlines. View with anaglyph
(red-blue) glasses.
VRL_STEREOTYPE_ANAGLYPH_SOLID_ALTERNATE
Similar to wireframe anaglyph, but solid instead of
wireframe.
VRL_STEREOTYPE_ENIGMA
Alternate scanline encoding, for use with CyberMaxx HMD.
VRL_STEREOTYPE_FRESNEL
Left-right split screen, for use with Fresnel viewer such as
the one described in Virtual Reality Creations.
VRL_STEREOTYPE_CYBERSCOPE
Left-eye image on left half of screen, right-eye image on
right half of screen, both rotated 90 degrees; should work
with Cyberscope from Simsalabim Systems Inc, but so far
untested (since I don't have one!).
VRL_STEREOTYPE_CRYSTALEYES
Puts left-eye image on top of screen, right-eye image on
bottom of screen, for eventual support of CrystalEyes
shutter glasses from StereoGraphics (can't do any real
development on this, since I don't have them!).
VRL_STEREOTYPE_CHROMADEPTH
Single-image system, mapping depth into red through blue
shades; view with Chromadepth glasses (which you can get at
most laser light shows, or with certain Valiant comic
books).
VRL_STEREOTYPE_SIRDS
Single-Image Random Dot Stereogram. Not yet implemented.
AVRIL Tech Ref -- Appendices 30
VRL_STEREOTYPE_TWOCARDS
Assumes two video cards, separate outputs going to the two
displays of an HMD.
VRL_STEREOTYPE_SEQUENTIAL
Field sequential, with shutter glasses; not yet supported in
AVRIL (as of version 2.0).
If you know of some way to produce stereoscopic images that I
haven't mentioned here, please drop me some email
(broehl@sunee.uwaterloo.ca).
AVRIL Tech Ref -- Appendices 31
Appendix J - INPUT DEVICES
The following devices are supported in AVRIL, as of version 2.0:
vrl_MouseDevice
Standard mouse; buttons are used to map two axes into six.
It works like this:
No buttons down: left-right causes Y rotation,
forward-back moves in Z
Left button down: left-right moves in X, forward-back
moves in Y
Right button down: left-right rotates around Z,
forward-back rotates around X
vrl_GlobalDevice
Global Devices Controller; not currently being manufactured.
Has tactile stimulation.
vrl_CybermanDevice
Logitech Cyberman. Has cheesy tactile feedback.
vrl_RedbaronDevice
Logitech ultrasonic mouse. Was originally code-named the
"Red Baron".
vrl_CTMDevice
CyberMaxx Tracking Module, in the CyberMaxx HMD.
vrl_VIODevice
Head tracker in the i-glasses! HMD from Virtual i/o.
vrl_SpaceballDevice
Original Spatial Systems Spaceball.
vrl_IsotrakDevice
Original Polhemus Isotrak. I'd add support for newer
versions, but I don't have them.
The ones below are PC-specific:
vrl_KeypadDevice
Uses keypad arrows, the PgUp and PgDn keys, and shifted
versions of each. It works like this:
no shift down: left-right arrows rotate in Y, up-down
arrows move in Z
left shift down: left-right arrows move in X, up-
down arrows move in Y
right shift down: left-right arrows rotate in Z, up-
down arrows rotate in X
PGUP and PGDN: move in Y (same as up and down arrows
with left shift)
AVRIL Tech Ref -- Appendices 32
vrl_JoystickDevice
Ordinary analog joystick; buttons are used to map two axes
into six. Also supports joystick-compatable devices such as
the popular PC gamepads (some of which are available in a
wireless version, which is good if you're in an HMD and
don't want to trip over the wire!). The buttons map like
this:
no buttons down: tilt left-right rotates in Y,
forward-back moves in Z
trigger button down: tilt left-right moves in X,
forward-back moves in Y
thumb down button: tilt left-right rotates around Z,
forward-back around X
vrl_FifthDevice
The FifthGlove, from Fifth Dimension Technologies (5DT).
The finger positions are mapped into channels 6 through 10
(channels 0 through 5 are not used, since the glove has no
built-in tracker).
vrl_CyberwandDevice
The CyberWand, from InWorld VR. The "hat" controller's axes
are mapped using the "pinky" and "grip" buttons (the grip
button being the one on the side of the stick, halfway up).
no buttons down: hat moves forward/backward,
sideways
pinky button down: hat rotates around X, Y
grip button down: hat moves up/down, rotates around Z
vrl_7thSenseDevice
Head tracker in the 7th Sense HMD from All-Pro.
vrl_PadDevice
A Nintendo-style gamepad, using the cable from the July 1990
Byte magazine. Works well with the Grip-It free-flying
joystick (which uses mercury switches for two-axis tilt
information).
Sorry, no PowerGlove driver yet. The timing stuff is hairy, and
I've got lots of other things to add to AVRIL. They're also not
manufacturing PowerGloves anymore. If someone else would like to
write one, go for it! I'll help if I can.
In fact, if you write a driver for any device, drop me some email
(broehl@sunee.uwaterloo.ca); since I'm giving AVRIL away for
free, I can't afford to buy every different input device on the
market, so adding support for them is difficult.
If you write drivers for AVRIL, I'll be happy to include them in
the main release and give you full credit for having written
them.
AVRIL Tech Ref -- Appendices 33
AVRIL Tech Ref -- Appendices 34