FreeVR: Virtual Reality Integration Library
FreeVR
Tutorials
User Guide
Programming
Functions

FreeVR

TUTORIALS

DOWNLOADS

GUIDES
    Administrator
    User
    Programming
    Function List
    Library Dev
    Socket Interface

MAN PAGES


All materials
Copyright © 2024
William R. Sherman

FreeVR: VR Administrator's Guide

FreeVR: VR Administrator's Guide

February 29, 2024 for FreeVR Version 0.7e
Written by Bill Sherman

Introduction

One of the primary features of FreeVR is the configuration flexibility. However, this boon can be the bane of the person responsible for administering the VR system. Flexibility necessitates a somewhat complex configuration file. The plan for the future is to aid the administrative process with GUI and other tools that can create a config file based on a set of parameters. For the moment however, the creating of the configuration file is largely a manual process, though some assistance can be garnered by looking at the freevr.bnf file (which describes the "language" of the configuration file). There are also many example configuration files in the etc directory named rc_sample_... something. Each has a specific flavor — the rc_sample_ks is the "Kitchen Sink" version which just has a lot of examples.

One tool that is available to help debug configurations as well as the library and some applications is the ability to communicate with a running FreeVR application via a socket port. This provides administrators and developers the ability to telnet or otherwise connect to a socket and view and manipulation information on the running FreeVR application. This process is described in the auxiliary Telnet/Socket Interface Manual.

Another aid for honing a configuration file is to use what we will refer to as a "live" simulator view — a simulator window with live tracking.

The Default Configuration

FreeVR contains a default configuration that provides some reasonable control and display features for testing a FreeVR application on a typical desktop environment (keyboard, mouse & monitor). This will have a simulator view under user control.

The inputs of the default configuration, and some of the configurations that can be specified operate in a way that mimics the presence of body-tracking hardware to allow the program developer to move the user's head and hand(s) (with wand(s)) around as well as push buttons, and move the joystick. The default system assumes a typical CAVE[tm] hardware setup, which includes two body trackers (head and wand), three buttons, and a 2-valuator joystick. The typical CAVE working volume is a 10x10x10' cube.

The primary key to know is the '?' (or '/') key. Pressing this key should display to the shell a usable collection of information to allow you to control the simulated inputs. The rest of the default inputs is:

  • 'Esc' key to quit
  • mouse buttons as wand buttons
  • holding spacebar while moving mouse as joystick valuators
  • arrows in upside-down "T" arrangement move the current 6-sensor
  • 'w' key make the "wand" the current 6-sensor
  • 's' key make the head ("skull") the current 6-sensor
  • 'r' key reset the current 6-sensor
  • leftshift key to change movement plane for arrow keys
  • leftalt key to rotate instead of translate current 6-sensor

The simulated window also has some controls to change the view into the virtual world:

  • keypad arrow keys to rotate the view
  • keypad plus key to move away from the origin
  • keypad minus key to move closer to the origin
  • keypad 5 key to re-center the view
  • keypad divide to toggle rendering of the simulator objects
  • keypad multiply to toggle rendering of the frame rate (this works on all of the windows)

The Configuration File

FreeVR currently looks in three places for configuration files that can override the built-in default configuration. Each subsequent file can override the previously read configuration files, so order matters. The order is:

  • $FREEVR_HOME/.freevrrc — [/usr/local/freevr by default]
  • ~/.freevrrc
  • ./.freevrrc

When the FreeVR distribution is first untarred, it is very likely that none of these files exist (the distribution does not contain any file called .freevrrc. However, one of the sample configuration files (rc_sample_<type>), can be copied or renamed to .freevrrc to run in some way other than the default. There is one file ("freevrrc_home") that is an example of what one might put in the "~/.freevrrc" file which is a common place for users to make custom tweaks to the overarching configuration -- especially users who are trying lots of configuration styles.

The file "freevr.bnf" (in the source directory) is an extended Baukus-Naur Form (eBNF) describing the syntax of configuration statements. Legal configuration files should fit this form. All the available, and currently planned options for each of the statements are listed in this file. Options that are not yet implemented are denoted by the ASCII frowny-face icon (":-(").

The basic syntactical form is a group of statements that define configuration "objects" that can be linked together to describe a complete "system." The generic format of an object description is:

	<object type> <object name> { "=" | "+=" } "{"
		<option 1> { "=" | "+=" | "*=" } <option settings> ";"
		...
	"}"
Where <object type> is one of: system, proc, window, eyelist, user, inputdevice, inputmap, or prop. The <object name> can be any valid string. The assignment operators ("=", "+=" or "*=") signify what type of assignment should take place. The basic equals ("=") assignment will override any previous value for the object type or option. The plus-equals ("+=") will append or add the given value to the object description, or option value. The times-equals ("*=") assignment is only valid for options with numeric values (including arrays and matrices), and will multiply the current value by the given value. A comma-separated list of <option settings> is terminated by a semicolon.

Statements other than object definition statements are also possible in the configuration description. Such statements include the usesystem statement, the set and setdefault statements, plus some miscellaneous commands such as echo and readconfig.

Separation of tokens in the configuration description is based only on generic whitespace. The use of newlines or tabs is never required.

Configuration Conditionals

A major factor in making the FreeVR configuration system so flexible is the ability to use conditionals during the configuration parsing. Conditionals can be used to startup a different system based on the machine's hostname, or based on the version of FreeVR that an application was compiled with, or even based on an environment variable set in the shell from which the application is launched. For example, an application launcher tool might have a setting to choose between stereoscopic and monoscopic rendering, and that setting can be passed to the configuration through the use of an environment variable. Or a CAVE with movable side walls might have multiple wall configurations built in, with the proper configuration selected by checking a system value. The syntax for the conditional statement will be familiar to any C/C++/C#/Java/etc. programmer:
	if <condition>
	then <statement>
	[else <statement>]
where:
  • <condition> is any mathematical expression (including the use of variables and functions) which is false when the result is zero ("0"), and true for every other value.
  • <statement> may be a single syntactically correct FreeVR configuration statement (that ends in a semicolon (";")), or a sequence of statements contained in a block-structure (statement(s) surrounded by curly braces — "{" and "}").
  • and the else clause is optional.

Thus portions of the configuration can be skipped or included based on factors external to the application and perhaps changing for particular circumstances — such as using monoscopic rendering for a VR photo-shoot.

Possible variables and functions available within the configuration system are discussed in the following two sections. One example of where a conditional might be used in a configuration file meant to augment earlier configurations (and therefore can't know a-priori whether, in this case, a "telnet" process is already in the "system" configuration):

# Add a "telnet" process to the current system if there isn't one already
if (numberprocsoftype("$system, telnet") == 0)
        system $system += { procs += "default-telnet"; }
Note: configuration functions will be described below, but notice that the configuration process only provides a single argument to the function, so even though it takes two arguments, they are provided as a single string which is split by the function handling routine.

Configuration Variables

One of the unique features (among VR libraries) of FreeVR is the ability to set and make use of variables in the FreeVR configuration file. The two primary uses of configuration variables are 1) allow a single setting to be used in multiple places within the configuration (including in mathematical expressions); and 2) for conditional settings within the configuration file, using the conditional statement. Another use can be for outputting information about the system to the terminal during initialization.

Configuration variables are of two types: built-in system variables, and standard shell environment variables. The environment variables may be set in the shell prior to running the VR application, or they may be set within the config file itself with the "setenv" command.

The built-in variables are typically used by the VR administrator to create a configuration system that can respond to specific conditions of the FreeVR setup. Some variables are not useful within the configuration, but can be used in the socket/telnet interface. Here is the current list of built-in variables

  • machine (or hostname)— the name of the computer on which the application is running
  • version — the version of FreeVR an application was compiled with (e.g. "v0.6g")
  • fullversion — a longer version string the application was compiled with (e.g. "FreeVR Version 0.6g")
  • versionnum — a numeric representation of the FreeVR version for more flexible conditionals (e.g. "607")
  • name — the name of the application, as assigned by the application [NOTE: this will not be set prior to reading the configuration file.]
  • author — the name of the application's author, as assigned by the application [NOTE: this will not be set prior to reading the configuration file.]
  • appstatus — an unconstrained string that an application can use to indicate a status [NOTE: this will not be set prior to reading the configuration file.]
  • freevrhomedir — the name of the directory where one can find the FreeVR system files
  • arch (or binaryformat) — the architecture of the compiled application (useful for making sure DSO's match the application)
  • system — the name of the currently set system that will be run (ie. the value of the last usesystem command).
  • def_visrenmode — the value of the currently set default visual rendering mode.
  • startup_error — error code from any problems found in the configuration
  • memsize — the size of the allocated shared memory space
  • sysstatus — the value of the FreeVR system status
  • systype — the overarching form-factor of the VR system (e.g. CAVE/stationary, HMD, Wall, Pit, Desktop, etc.)
  • compile — a string with the compilation data of the library
  • compile_options — the "-D" flags set when the FreeVR library was built
  • target — the Makefile "target" used in building the FreeVR library
  • time_immemorial — the beginning time of the running application
  • sim_time / time — time since the application began (time since "time_immemorial")
  • wall_time — the current time as reported by the system's operating system
  • wall_time_elapsed — the amount of time (in seconds) since the application began
  • debuglevel — the current value at (and below) which debugging output will be provided
  • debugthistoo — a single additional debug level that will be reported
  • debug:<levelname> — the value of a given debug level (e.g. $debug:common)
  • win_style — the type of windowing interface (e.g. "GLX")
  • gfx_style — the type of graphics renderer (e.g. "OpenGL")
  • sem_style — the type of semaphores used by this FreeVR build (e.g. "SYSVIPC")
  • shm_style — the type of shared-memory used by this FreeVR build (e.g. "SVR4MMAP")
  • sock_style — the type of socket API used by this FreeVR build (e.g. "BSD")
  • mp_style — the type of multi-processing API used by this FreeVR build (e.g. "FORK")

Variables are used by prepending their name with the dollar symbol ($). As of FreeVR Version 0.7e, string concatenation has been fully tested, and can be used to combine variables with other strings. (This feature existed in previous versions, but didn't work in all circumstances.)

Note that a complete list of debug levels can be found in the debug.1fv manpage.

Configuration Functions

There are a limited number of functions available in the FreeVR configuration parsing system. Two that run external tools and return a result, two that report whether there is a type of inputDevice or Visren process object defined in the configuration file (up to that point), a similar one that reports the number of a type of process in the given system configuration object, and one that converts numbers into strings (for the purpose of string concatenation). Specifically:

  • execStatus(<argument list>) — executes a system command and returns the status value
  • execPipe(<pipe-device>) — returns a string value read through a system pipe
  • existsInputDeviceType(<name>) — reports whether there is a InputDevice named <name> defined
  • existsVisrenDeviceType(<name>) — reports whether there is a Visren (visual rendering) device named <name> defined
  • numberprocsoftype("<system-name>, <process-type>") — reports the count of a type of process in the given system
  • string(<value>) — converts value to be a character string.

The use of these functions would mostly be in the circumstance where a personal configuration file ("~/.freevrrc") alters the configuration based on how the general system configuration files have been parsed. The string() function was created to make string concatenation work better when involving numerical values, though the concatenation operation itself was improved to handle numbers, diminishing the need for string().

Note: Because of the way the configuration parsing is handled, these configuration-functions only take a single argument, but in the case of numberprocsofType, there actually are two arguments, but they are passed together as a single string, which is then divided inside the function itself.

Configuration Objects and Hierarchy

The basis of FreeVR configuration is a collection of config-objects related in a directed graph. There are eight defined types of objects within the graph, two of which presently have very limited configurability ("Input-map" and "Prop").

The general organization of the directed graph is:


				      System
				      /    \
				     /      \
				    /        \
			      Processes     Input-map
			     /    |    \_         \
	             (Vis-Ren)  (Input)  (Telnet)  \...
		     Windows  Input-devices
			 |
		     Eye-list
		     /   |   \            Props
		   Eye  Eye  Eye ...
		     \  /      \
		     User      User

A VR "system" is built up from objects describing a portion of the overall layout. Multiple systems can be defined in the same configuration file. The usesystem config statement is used to select from among the available systems. Several systems are defined in the example freevr.rc file.

The "system" Object

The system object is used to bring together the main components that describe how the current hardware to be used. The system object links to a group of process objects, and a single inputmap object.

The system object has options for running an independent program at the beginning and end of FreeVR operation. These can be any program commands that might be typed into a shell. These options are: ExecAtStart and ExecAtStop. The are followed by the equal sign (=) and a string with the command (usually within quotation marks). Prior to execution, the string will replace the constants #N, and #P with the name and process-id of the system respectively. These two options are also available on a per-process basis. One possible use of these is to ensure external tracking is operational before starting, and perhaps putting it into hiatus when stopped.

If problems with the configuration are encountered during system initialization an error flag is set for each problem. Each flag is assigned a separate bit in the overall error code, and when any error is encountered, a shell command can be executed, and/or the system can prematurely terminate operations. To execute a command, the ExecUponError option can be set to a string in the same manner as ExecAtStart and ExecAtStop. The ExecUponError option has one additional string replacement — a #E in the command will be replaced with the decimal representation of the error code. This is useful to warn the user that the system may not be functioning properly.

A related option is the ExitUponError which takes a bitmask of the error types and if there are any errors, and the error code anded with the bitmask is non-zero, then the system will exit immediately — because things probably weren't going to work anyway. The ExitUponError value is set by given an equal sign and a number. [NOTE: ideally this number can be specified in hex or binary, but a bug in the current config parsing prevents this — or maybe it would work if given inside quotations.]

The types of errors currently encoded in the startup error code (and their bit values) are:

  • 0x01 — shared memory not successfully initialized
  • 0x02 — no valid processes found in the configuration
  • 0x04 — a bad process configuration was encountered
  • 0x08 — a bad window configuration was encountered
  • 0x10 — a problem with an input device was encountered
  • 0x20 — a problem with an input mapping was encountered
A basic system statement looks like:
    system "cave" = {
	    procs = "cave-visren1", "cave-visren2",
	    	"cave-visren3", "cave-visren4";
	    inputmap = "default";

	    exituponerror = 2;
	    execuponerror = "xmessage 'Problem found in the configuration — #E' > /dev/null"; 

	    execatstart = "xmessage 'Visbox system #N starting.  PID is #P' > /dev/null &";
	    execatstop =  "xmessage 'Visbox system #N stopping.' > /dev/null";
    }

The "process" Object

A FreeVR process is an operation that can be forked off of the main process and run independently. FreeVR processes are each defined to serve a particular role in the execution of the application. Thus far, the process types that have been implemented are: the visual rendering process (visren) and the input device communication process (input).

The two main options that need to be set for all processes are the <process type> (chosen from above), and a list of objects associated with the process. For visren processes, these should be window objects, and for input processes, they should be inputdevice objects. These are the only two options that are mandated.

Three other useful options are the sync, execAtStart, and execAtStop options. The execAtStart and execAtStop options work the same as their counterparts in the system object configuration.

For debugging purposes, there are three additional useful options: printcolor, printstring, and printfile. These all affect how (and where) text printed by the process will appear.

The printcolor option is used to specify a number that fits in the ANSI terminal sequence for changing the text color on that terminal. Any ANSI mode number can be used. Some common ones are:

  • 32 — green
  • 33 — yellow
  • 34 — blue
  • 35 — magenta
  • 36 — cyan
Red is also a valid choice, but it is already used by FreeVR to signify important warning and error messages, so it's use here is discouraged. NOTE: For readability of the configuration file, it is generally wise to set some variables that map the numbers to the corresponding colors. For example:
	setenv  ANSI_BLUE    34;

	[...]

	process "visren-default" += {
		printcolor = $ANSI_BLUE;
	}

The printstring option is used to specify a string that is prepended to all messages printed by the process. (For example, the name of the process.)

The printfile option is used to specify a file that all messages should be sent to instead of the startup-terminal. Note that if a terminal device is given, then the text will appear on that terminal instead. In fact, this was the initially desired use.

Note that the three print options can be used together in any way the configurer desires.

A basic visual-rendering "process" object definition might appear:

    process "cave-visren2" = {
	    type = visren;
	    objects = "left-cave";      # the left screen of the CAVE
	    sync = 1;                   # sync with all processes that use barrier #1
	    printcolor = $ANSI_BLUE;    # print in blue
	    printstring = "visren2: ";
	    printfile = "/dev/console";
    }

A basic input "process" object definition might appear:

    process "xwinsim-input" = {
	    type = input;
	    printcolor = $ANSI_MAGENTA;
	    objects = "xwinsim";
    
	    #DebugThisToo = $debug:xwin;   # uncomment for Xwindow debugging details
    }

The "window" Object

A window in FreeVR is the basic means of presenting the visual aspects of a virtual world to the user. At the moment, the type of graphics rendering that will occur within the window needs to be defined for each window (eg. "glx", "java3d", "performer"). At the moment, only type "glx" is implemented. It is uncertain if this choice will continue to be specifically linked to the window definitions. The only bits of information that are dependent on the type of graphics rendering are display options such as multi-sampling, and the method of determining which physical screen to render to (although on UNIX systems, the X-windows method can generally be assumed). The type of graphics window is set via the graphicstype option.

Window objects can be of four major types: in a fixed position in the real world, as is typically of CAVEs and other projection-based VR displays; attached to a user's head, as is the case for HMDs and BOOMs; attached to a user's hand, a less common but valid form of display; and finally as a "simulated" view into the virtual world. Currently, the only three types of window displays that have been implemented are the "fixed", "headmount" and "simulator" types. The nature of the window is set with the mount option, with potential values of: fixed, fixed, handheld and simulator. Currently, the "headmount" option has not been thoroughly tested, but at least partially works.

The position of the window in the real world, relative to the (RW) origin, is specified using the rw2w.translate, rw2w.rotate and rw2w.transform options. (NOTE: formerly, an underscore ('_') was used to link rw2w with the type of transformation, but to make configuration files more readable, and follow a more programmatic style convention, dots ('.') are now used — though for now, the underscore will still work.) Operations on the rw2w (ie. real-world to window) transformation matrix can be combined using the "*=" operation. Each method of transforming the matrix takes a different number of arguments. The rw2w.translate option takes three numbers — an X,Y, and Z displacement. The rw2w.rotate option takes four numbers — an axis specified by X,Y, and Z, followed by a rotation in degrees. The rw2w.transform options simply takes the 16 numbers that make up the complete matrix, in column-major ordering.

The eyelist and visrenmode options control how rendering to multiple eyes is handled. This is explained in more detail under the description of the eyelist objects.

Finally, window objects can have arguments specific to the type of rendering format being used (eg. "glx"). The args option is basically just a long string that is passed to the window-specific routines, and parsed therein. To keep things short, the three major window-argument options for "glx" are display, geometry, and decoration. The display and geometry arguments are the basic values for X-windows, and decoration should be set to either "none" or "title."

Here is a typical description of a window:

	window "left-cave" = {
		GraphicsType = "glx";
		args = "display=:0.0; geometry=1024x768+0+0; decoration=none";

		# These two options specify where the window is located in the RW
		mount = "fixed";
		rw2w.translate = 5.0, 0.0, -5.0;
		rw2w.rotate *= 0.0, 1.0, 0.0,  90.0;

		# Note that by defining the eyes and visrenmode to "default" will
		#   specifically override any settings in the "system" option, so
		#   they should only be included when necessary.
	#	eyelist = "default";
	#	visrenmode = default;
	}

The "eyelist" Object

The FreeVR eyelist object is the key to making the system extremely flexible with regards to the many ways stereoscopic and multi-user rendering can be configured. The object however is nothing more than six lists of eyes, where each eye specifies a user; the left, right or other eye of that user; and a colormask (which defaults to full color when not specified). The six lists correspond to four different visual rendering modes that can be selected by the visrenmode option of a "system," "window," or the global default. If no visrenmode is specified for a window, then it uses the default value for the system. If no visrenmode is specified for the system, then the global default is used. If no global default visrenmode is specified by the configuration, then the library default is used, which is the eyelist named "default."

The four choices for visrenmode are: "mono," "dualfb," "dualvp" and "anaglyphic."

The selected visrenmode choice then determines which of the lists of eyes will be used for rendering. For "mono" rendering, the "monofb" list is used. For "dualfb" (ie. dual frame buffer) rendering, the "leftfb" and "rightfb" lists are used. For "dualvp" (ie. dual view-port) rendering, the "leftvp" and "rightvp" lists are used. For the "anaglyphic" method, the "anaglfb" list is used.

The format of specifying an eye is: <user-name>:<eye-type>:<colormask> — with the final colon, and colormask being optional. Choices for eye-type are: "lefteye," "righteye" and "cyclops." The latter is best choice for monoscopic rendering.

These two examples will hopefully shed some light on this:

	eyelist "default example" = {
		monofb = default:cyclops;
		leftfb = default:lefteye;
		rightfb = default:righteye;
		leftvp = default:lefteye;
		rightvp = default:righteye;
		anaglfb = default:lefteye:red, default:righteye:blue;
	};

	# The following eyelist renders stereoscopic images to two tracked
	#   people by combining the dual frame buffer method of stereo with
	#   anaglyphic rendering.
	eyelist "specialA" = {
		leftfb = default:lefteye:blue, user2:lefteye:red ;
		rightfb = default:righteye:blue, user2:righteye:red;
	};

The "user" Object

Currently, the Freevr "user" object is used to specify just two things. The most important of these things is the interocular distance. The other is the color the user's head will be represented as in simulator display windows. Here is an example:

	user "greenuser" = {
		iod = 0.5;		# interocular distance (in feet)
		color = 84, 134, 72;    # a forest-green hue
	}
Note: the "iod" can be altered via the telnet process, as described in the Telnet/Socket Interface Manual.

The "inputdevice" Object

Input devices are one of the keys to providing a flexible VR library. A handful of input devices have already been integrated into FreeVR, with instructions for how developers can add new ones as needed — though because FreeVR can read VRPN and Vrui's Device Daemon, most devices are already covered. One of the goals of input configuration is that the application shouldn't have to know what types of inputs are available, in fact, applications should be runnable in as many environments as possible, and thus input devices need to be able to mimic other devices.

The main option of inputdevice specification is the type, The authoritative list of possible types can be found in the vr_input.opts.h file. This is the file used by FreeVR to access the routines necessary for communicating with the input device based on the type selected. An unauthoritative list of inputs types can be found in these web pages, and in the freevr.7fv manpage.

Input devices providing 6-dof position input information have two matrix transformations used to describe the relationship between the input hardware and the real-world. The "t2rw" transformation describes the relationship from the hardware's transmitter to the real-world origin. the "r2e" transformation describes the shift from the hardware's receiver to some entity (a user's bodypart, or some prop). The operations (t2rw.translate, t2rw.rotate, t2rw.transform, r2e.translate, r2e.rotate and r2e.transform) are all specified in the same manner as "rw2w" is for windows (above).

As with windows, a device independent argument string can be set with the args option. Arguments typically at least include the information necessary with communicating with the device — network ports, serial ports, baud rates, shared memory keys, etc. The source code of many of the input devices lists the available arguments at the comment at the top of the file. Also, the example rc_sample_<&ellipses;> files include "inputdevice" object for each of the implemented input devices.

Finally, "inputdevice" object must specify the inputs available from that device, and how those inputs are related to the physical hardware. The input and control options are used to specify this information.

The format of the input option is:

"input" <arbitrary input name> = <input type>(<input source>);
Where, the "arbitrary input name" is the string that will be used to describe inputs to the user in the help-screen, and to specify a particular input in "inputmap" objects Input type is one of "2switch," "valuator" or "6sensor"; and input source is what part of the hardware (or virtual device) should be used to generate the input. For example, for the magellan 6-dof input device, a button press input can be generated by pressing the "1" button on the hardware using:
	input "first magellan button" = "2switch(button[1])";

The format of the control option is:

"control" <device control> = <input type>(<input source>);
In this case, the "device control" is a specific string that is particular to the type of input, and activates some internal change in the input device. For example, to get the "magellan" device to reset the current 6-dof sensor when the "8" button is pressed:
	control "reset_sensor" = "2switch(button[8])";
In this case "reset_sensor" is defined in the "magellan" source code, with a list of possible controls given at the top of the file.

Here is a simple "inputdevice" object example for the Magellan. For a more complete example, see the rc_sample_6dof file:

	inputdevice "mag-default" = {
		type = "magellan";

		args = "baud=  9600; port = /dev/input/magellan";

		t2rw.translate = 0.0, 4.0, 0.0;
		r2e.rotate = 0.0, 0.0, 1.0,  -90.0;
		r2e.translate *= 1.0, 0.0, 0.0;

		input "2switch[1]" = "2switch(button[1])";
		input "2switch[2]" = "2switch(button[2])";
		input "2switch[3]" = "2switch(button[3])";
		input "valuator[x]" = "valuator(mag[tx])";
		input "valuator[y]" = "valuator(mag[ty])";
		input "6sensor[0]" = "6sensor(6dof[0], r2e)";
		input "6sensor[1]" = "6sensor(6dof[1])";
		input "6sensor[2]" = "6sensor(6dof[2])";

		control "toggle_space_limit" = "2switch(button[4])";
		control "toggle_relative" = "2switch(button[7])";
		control "next_sensor" = "2switch(button[5])";
		control "reset_sensor" = "2switch(button[6])";
		control "toggle_valuator" = "2switch(button[8])";
	}

Here is a table of the current list of controls available to various input devices:

  • Available on all input devices (or intended to be):
    • print_help — print info on how to use the input device
    • system_pause_toggle — toggle the system pause flag
    • print_context — print the overall FreeVR context data structure (for debugging)
    • print_config — print the overall FreeVR config data structure (for debugging)
    • print_input — print the overall FreeVR input data structure (for debugging)
    • print_struct — print the internal FoB data structure (for debugging)
  • General controls for simulating 6-sensors using valuators:
    • sensor_reset — reset the current 6-sensor
    • sensor_resetall — reset the all the 6-sensors
    • sensor_next — jump to the next 6-sensor on the list
    • setsensor() — set the simulated sensor to a particular one
    • toggle_relative — toggle whether movement is relative to sensor's position
    • toggle_space_limit — toggle whether 6-sensor can go outside working volume
    • toggle_return_to_zero — toggle whether return-to-zero operation is on

    • toggle_valuator — toggle valuator values instead of 6-sensor
    • temp_valuator — temporarily disable 6-sensor for valuator values
    • toggle_valuator_only — toggle whether translation is saved for valuator
    • temp_valuator_only — temporarily use translation values for valuator
    • toggle_swap_transrot — toggle whether to swap translation and rotation inputs
    • toggle_swap_yz — toggle the swapping of Y and Z translational movements

      Standard valuator controls:

    • set_transx — set the translation value for the simulated 6-sensor
    • set_transy — set the translation value for the simulated 6-sensor
    • set_transz — set the translation value for the simulated 6-sensor
    • set_azim — set the azimuth rotation value for the simulated 6-sensor
    • set_elev — set the elevation rotation value for the simulated 6-sensor
    • set_roll — set the roll rotation value for the simulated 6-sensor
  • General controls for simulating 6-sensors using buttons/keys
    • sensor_reset — reset the current 6-sensor
    • sensor_resetall — reset the all the 6-sensors
    • sensor_next — jump to the next 6-sensor on the list
    • setsensor() — set the simulated sensor to a particular one
    • toggle_relative — toggle whether movement is relative to sensor's position
    • toggle_space_limit — toggle whether 6-sensor can go outside working volume
    • toggle_return_to_zero — toggle whether return-to-zero operation is on

    • sensor_left — move the current sensor to the left
    • sensor_right — move the current sensor to the right
    • sensor_up — move the current sensor up
    • sensor_down — move the current sensor down
    • sensor_in — move the current sensor in
    • sensor_out — move the current sensor out
    • sensor_pazim — rotate positively about the azimuth
    • sensor_nazim — rotate negatively about the azimuth
    • sensor_pelev — rotate positively about the elevation
    • sensor_nelev — rotate negatively about the elevation
    • sensor_cw — roll the current sensor clockwise
    • sensor_ccw — roll the current sensor counter-clockwise
    • sensor_swap_yz — temporarily swap up/down key movement for in/out movement
    • sensor_rotate_sensor — temporarily (key) rotate the sensor instead of translate
    • pointer_xy_override — temporarily use pointer movement for sensor translation
    • pointer_xz_override — temporarily use pointer movement for sensor translation
    • pointer_rot_override — temporarily use pointer movement for sensor rotation
    • pointer_valuator — temporarily activate use of pointer as valuators
    • keyval_sign() — toggle the sign of a keyboard valuator
    • keyval_zero() — zero the value of a keyboard valuator
  • Controls on some input devices:
    • Ascension Flock of Birds
      • Standard only
    • Ascension Motionstar
      • Standard only
    • Polhemus Fastrak / Intersense IS-900
      • Standard only
    • Virtual Technologies Cyberglove
      • Standard only
      • Other specialized controls are planned but not implemented
    • Fakespace Pinchglove
      • Standard only
  • Xwindows interface
    • Standard
    • Generic controls for simulating 6-sensors using buttons/keys

    • toggle_silence — toggle whether keyboard gives aural feedback to controls
    • bell — ring the keyboard bell
    • softbell — ring the keyboard bell softer (only on keyboards with variable volume)
  • Linux Joydev interface
    • Standard
    • Generic controls for simulating 6-sensors using valuators
  • Linux EVIO HID interface
    • Standard
    • Generic controls for simulating 6-sensors using valuators
  • Magellan / SpaceMouse
    • Standard
    • Generic controls for simulating 6-sensors using valuators (w/o the "swap" controls)

    • toggle_use_null_region — toggle whether null-region is used
    • beep — cause the Magellan to beep
  • Spacetec Spaceball / Spaceorb
    • Standard
    • Generic controls for simulating 6-sensors using valuators (w/o the "swap" controls)

    • toggle_use_null_region — toggle whether null-region is used
  • Generic Shared Memory interface
    • Standard

    • print_values — print just the input values of the memory
  • Generic Static input interface
    • Standard only

The "inputmap" Object

In the current version of FreeVR, the "inputmap" system has not yet been implemented, with the exception of a couple of hard-coded settings. For now, the only inputmap that should be selected in the system configuration objects is the "default" map. In this mapping, every (non self-control) input from all the input devices in the selected system are included in the mapping. They are simply ordered by the order of the devices as they appear in the objects list of the input-processes, and the order in which they appear in the input options within those devices.

The "prop" Object

How props will be involved in FreeVR has not been completely worked out yet, so little will be said about them in this draft. Very little.

Conclusion

Once again, let me reiterate that the boon of FreeVR is the wide range of VR setups that can be configured — all at runtime. Yet, this means the configuration description will be a little complicated. Hopefully we'll have some more tools to aid in this process in the near future, but for now, it's easiest to work from one of the provided examples.

Good luck. (But the best advice is to start with an example configuration and work from there.)



© Copyright William R. Sherman, 2024.