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: Function Reference

FreeVR: Function Reference

(ie. Reference Manual)

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

Introduction

This guide is a supplement to the Application Development Guide. It contains a list of the FreeVR functions available to the application programmer, along with a brief description of each.

The functions are broken down into the following categories:

A complete index of functions and macros is also provided:

The FreeVR Tutorials package provides an introduction to the most important of the functions in a gentle step by step manner.


The FreeVR Function naming scheme

As an aid for the FreeVR programmer to more rapidly figure out what a function does, or make an educated guess for the name of a desired function, FreeVR has adopted a function naming scheme for which all functions should follow. Unfortunately, some of the naming rules conflict with one another, and in these cases a precedence determination is made for each individual function.

  • All functions (and types) begin with "vr" — no exceptions.

  • All Performer related functions begin with "vrPf".

  • All identifying features of the function are included as part of the name.

  • Each word that identifies a feature begins with an upper case letter, and is followed by lower case letters.

  • Acronyms that identify a feature are capitalized throughout (eg. RW for "real world").

  • Functions related to a common utility or operation will begin their name with a word or words to describe this common base. Examples include the vrUserTravel...(), vrRender...(), vrShmem...(), and vrGet...() suites of functions. There are some exceptions caused by precedence of the final rule.

  • A group of functions with similar operations will include the types of arguments as part of the name. These function names will include references to each argument, appearing in the same left to right order. For example, there are many functions to set the value of a 4x4 matrix, all of the form vrMatrixSet...(), differing in what is being set and the type of values give. So, the translation of a vrMatrix can be set with either three double precision floats, or an array of doubles: vrMatrixSetTranslation3d() or vrMatrixSetTranslationAd().

  • In cases where the first argument is actually used as a memory placeholder for the return value, then the argument type will appear immediately after the initial "vr". This is generally the case for "Get" and math functions that return multivalue-types such as vrMatrix, vrPoint and vrVector. This rule generally takes precedence over the previous two rules.

If anyone disagrees with these rules, or whether a particular function does not follow these rules, and therefore should be renamed: now is the time to state your case (ie. before we get to version 1.0).

FreeVR Types

The rules for FreeVR type names are similar to the function scheme. Of course, types are much simpler, so generally consist only of the "vr" prefix, and then a name that begins with an upper case letter.

FreeVR types are defined generally for multi-valued collections of data, such as a 4x4 Homogeneous matrix used for graphics operations — vrMatrix. For functions that return single values (such as the value of a button or valuator), a basic int or double type is used. Many of the FreeVR types store all the values as a single array of doubles in field "v".

Common types used in VR applications include:

  • vrMatrix 16 doubles stored as array "v", in row-column order to match the OpenGL matrix format.

  • vrPoint 3 doubles stored in array "v".

  • vrVector 3 doubles stored in array "v".

  • vrEuler two arrays of 3 doubles for translational ("t" field) and rotational ("r" field) components.

NOTE: Because the types vrPoint and vrVector have the same internal representation, one can be converted to the other through a simple type-cast. However, there is a good reason why both types exist. And that reason is that mathematically speaking, they are different quantities. The difference basically amounts to how each 3-quantity array is extended when converted to a 4-quantity entity that will be multiplied by a 4x4 homogeneous matrix — a point has a "1" as the fourth value, while a vector has a "0".

NOTE: The use of vrEuler is not recommended. This type and related functions are provided only as a convenience for porting applications originally written with libraries that make use of Euler angles. There is one exception to this rule, and that is in the use of the billboarding functions (vrRenderGetBillboardAngles3d & vrRenderGetBillboardAnglesAd). In these cases, the relationship between the user and some location in space is returned as Euler angles which can be formulaically fed into OpenGL calls to rotate objects to face the user.

Along with the above types, FreeVR defines some "macro" values for accessing type subelements in a clear way. These are:

  • VR_X — the x component of a "v" field of a vrVector or vrQuat ("t" field of vrEuler)
  • VR_Y — the y component of a "v" field of a vrVector or vrQuat ("t" field of vrEuler)
  • VR_Z — the z component of a "v" field of a vrVector or vrQuat ("t" field of vrEuler)
  • VR_W — the w component of a "v" field of a vrQuat
  • VR_AZIM — the azimuth component of a vrEuler "r" field
  • VR_ELEV — the elevation component of a vrEuler "r" field
  • VR_ROLL — the roll component of a vrEuler "r" field


System Operation Functions

The functions for controlling the system are used to configure, start, stop, and otherwise setup the application. Most of these functions will appear in every FreeVR application. A minimal VR application using these functions is demonstrated below — not yet.

vrStart()
Calling vrStart() causes the FreeVR library to begin operation. Shared memory is initialized, the configuration is determined (if not already done by an earlier call to vrConfigure()), and all the processes necessary to control the VR system are begun (forked or multi-threaded).

The syntax is simply:

	vrStart();

	

vrConfigure()
Calling vrConfigure() is optional. It is generally used to pass configuration information to the system to override what is contained in all the configuration files. If it is used, it must be called prior to calling vrStart(). Configuration information can be passed along in one (or both) of two forms: program CLA style, or as an array of strings.

The syntax is:

	vrConfigure(argc, argv, argp);

	
The first two arguments are exactly the same format as the two arguments of main(). This is done to allow the programmer to simply pass the argc and argv values directly from main to vrConfigure.

The third argument is ...

vrFrame()
Calling vrFrame() is currently optional. This function is primarily used to allow the VR system to perform some housekeeping tasks, including the update of performance statistics information. It should be called once during each loop of the simulation (update) process.

NOTE: future versions of FreeVR may require this call rather than allowing it as an option. Therefore, it is best to include this call in the simulation loop, unless there is some specific reason which precludes its usage.

The syntax is:

	vrFrame();

	

vrExit()
vrExit() is called to shutdown the FreeVR application. The processes/threads generated by vrStart() are all instructed to shut themselves down, shared memory is closed, and the function returns to the main application thread.

The syntax is simply:

	vrExit();

	

vrSystemSetName()
The vrSystemSetName() function allows the application programmer to encode the name of the application within it. This information can be retrieved during the running of the application itself as part of the user-interface quick-reference display (available on any rendering screen by pressing the decimal/delete — "./del" — key on the numeric keypad).

The syntax is:

	vrSystemSetName(char *description_string);
	

vrSystemSetAuthors()
The vrSystemSetAuthors() function allow the application programmer(s) to encode their credits within the application. This information can be retrieved during the running of the application itself as part of the user-interface quick-reference display (available on any rendering screen by pressing the decimal/delete — "./del" — key on the numeric keypad).

The syntax is:

	vrSystemSetAuthors(char *description_string);
	

vrSystemSetExtraInfo()
The vrSystemSetExtraInfo() function allow the application programmer(s) to encode some extra information about the application into it. Typically, this information might be about some features of the user interface that are difficult to associate with a single input — such as chording operations. This information can be retrieved during the running of the application itself as part of the user-interface quick-reference display (available on any rendering screen by pressing the decimal/delete — "./del" — key on the numeric keypad).

The syntax is:

	vrSystemSetExtraInfo(char *description_string);
	

vrSystemSetStatusDescription()
The vrSystemSetExtraInfo() function allow the application programmer(s) to encode some extra information about the application into it. Typically, this information might be about some features of the user interface that are difficult to associate with a single input — such as chording operations. This information can be retrieved during the running of the application itself as part of the user-interface quick-reference display (available on any rendering screen by pressing the decimal/delete — "./del" — key on the numeric keypad).

The syntax is:

	vrSystemSetExtraInfo(char *description_string);
	

vrCallbackCreate()
The vrCallbackCreate() function wraps a function with specific arguments such that they can be used as a callback for a particular FreeVR operation. Once created, the callback can be assigned with the vrFunctionSetCallback() function (below).

The syntax is:

	vrCallbackCreate(func, nargs, arg1, ... argN);
	
The first argument is the function to be called. This function should not return a value (ie. be type "void()"). The second argument is the number of arguments to pass to the callback function (currently limited to the range of [0..5]). The rest of the arguments are the arguments that will be passed to the callback function each time it is invoked.

Note that the callback function will always be called with the same argument values. However, it is possible to pass a pointer into shared memory as one of the arguments, allowing the programmer to share the same data between callback functions and the primary process.

vrFunctionSetCallback()
The vrFunctionSetCallback() function is used to associate a callback with a particular FreeVR operation.

The syntax is:

	vrFunctionSetCallback(operation, callback);
	
The first argument is one of the following defined integers:
  • VRFUNC_DISPLAY — rendering to do for each eye
  • VRFUNC_DISPLAY_INIT — graphics process initialization code
  • VRFUNC_DISPLAY_EXIT — process termination code
  • VRFUNC_DISPLAY_FRAME — graphics operations done once each frame
  • VRFUNC_DISPLAY_SIM — rendering of the simulator display (replaces default)
The second argument is the wrapped callback function (ie. created using vrCallbackCreate()).

vrSystemSimCategory()
The vrSystemSimCategory() function allow the application programmer to differentiate between two categories of code within the world simulation. The only distinction made between these two categories is where the time spent within each category is reported in the application statistics display. (See the section on FreeVR statistics for information on how to render and interpret the statistics data.)

The syntax is:

	vrSystemSimCategory(int category);
	
where "category" is either "1" or "2". NOTE: time for each category is what is measured up until the point when the category is set (i.e. when this function is called, it is the operations that have already occurred that will be counted as part of the given category). The time from the last call to vrSystemSimCategory() to the end of the current frame is added to the statistics for category-1.

vrShmemAlloc() & vrShmemAlloc0()
These two functions allocate a block of memory from the FreeVR shared memory arena. vrShmemAlloc() does a standard memory allocation, and vrShmemAlloc0() allocates and then zeros the memory. Shared memory should be used for any information that is to be shared between processes.

The syntax is:

	void *pointer = vrShmemAlloc(size);
	void *pointer = vrShmemAlloc0(size);
	
Where "size" is an integer indicating the size of the desired memory block in bytes. A pointer to the new memory block is returned. It is good coding practice to type-case the returned value to the proper array or pointer type.

vrShmemStrDup()
This function also allocates memory from the FreeVR shared memory arena. In this case, it allocates the amount of memory necessary to store a given C-style character string array, and then copies that string into the newly allocated memory. A pointer to the allocated copy is returned.

The syntax is:

	char *new_string = vrShmemStrDup(string);
	
Where "string" is a character array or pointer with a C-style string.

vrShmemFree()
This function frees memory allocated through one of the FreeVR vrShmem...() allocator functions.

The syntax is:

	vrShmemFree(pointer);
	

vrShmemInit()
Calling vrShmemInit() is optional. Shared memory is automatically initialized during the configuration process. However, if a shared memory arena with a larger block of memory than is created by default is required, then this function can be called before calling vrConfigure() or vrStart() to set aside a given amount of memory.

The syntax is:

	vrShmemInit(size);
	
Where "size" is the amount of memory (in bytes) that should be set aside for the shared memory arena.

Functions to Read and Document Inputs

The functions for reading inputs are used to provide a means by which the user can interact with the system, to affect the state of the virtual world, and/or travel through it.

For each input type there is also a function that can be used to describe how that input is used. While not required, the use of these functions is strongly encouraged in order to provide users with a live, quick-reference of how to operate your program. This information can be displayed on any of the rendering screens by pressing the period/delete (./del) key on the numeric keypad (which toggles the information on and off).

The three common FreeVR-input types are:

  • 2-switch (aka button) — an integer
  • Valuator — a double
  • 6-sensor — usually a vrMatrix, may also be vrPoint, vrVector or vrEuler

The functions that return single-value inputs all begin with "vrGet" followed by one of the FreeVR-input types, and then the word "Value" or the word "Delta". The "Value" functions return the exact value of the input at the time of the call. The "Delta" versions return the difference between the current value, and what the value was the last time the input was read (either via a "value" or via a "delta" function call).

Functions that return complex types such as a vrMatrix use pointers for passing the values. This saves a little time, but also reduces the need for functions to allocate and deallocate the memory for the type on each call. Thus, for such functions, FreeVR expects the memory to be pre-allocated, and will place the return value there, and also give the pointer as the function's return value, so the function can be used as an argument to another function. The names of these functions will always have the name of the return type immediately after the initial "vr" moniker. So, a function that gets a 6-sensor value and returns a vrMatrix type will have the name vrMatrixGet...() instead of vrGetMatrix...().

The 6-sensor form of input also has the unique feature of being relative to a particular coordinate system. The two possible coordinate systems that can be requested are that of the real-world, and of the virtual world. When an application begins, these two coordinate systems are typically coincident.

The user-travel functions (described below) can be used to change the relative position between the real and virtual worlds. The real-world coordinate system is defined by the FreeVR configuration file. A typical CAVE facility sets the origin at the center of the floor, with the positive-X axis pointing to the right (when facing the front wall), and the positive-Y axis pointing up. (The positive-Z axis thus points away from the front wall in accordance to the right-hand rule.) Because the FreeVR library allows each user to have their own, independent position in the virtual world, the functions that provide the position of a user's virtual world coordinate system require an additional argument to specify which user.

vrInputSet2switchDescription()
This function associates a string with how the given 2-switch input in used within the application. This provides the end-user a quick-reference guide for how the application is operated.

The syntax is:

	int button_exists = vrInputSet2switchDescription(input number, string);
	
where the value returned indicates whether that button exists on the current system configuration. (If the button did not exist, a dummy button will be created, though the user will not be able to provide an input.) The "input number" argument specifies which input of type "2switch" to describe.

vrGet2switchValue() & vrGet2switchDelta()
The "2switch" input type typically is activated by the user as a button press, either on a hand held device, or a specific key on the keyboard. The numeric order of the buttons is determined entirely by the configuration file, so can differ from site to site. However, a typical configuration will set button number 0 to be the termination key (often the 'Esc' key on the keyboard), and inputs 1, 2 and 3 as three buttons on a hand held input.

The syntax is:

	int button_value = vrGet2switchValue(input number);
	int button_delta = vrGet2switchDelta(input number);
	
The "input number" argument specifies which input of type "2switch" to access.

vrInputSetValuatorDescription()
This function associates a string with how the given valuator input in used within the application. This provides the end-user a quick-reference guide for how the application is operated.

The syntax is:

	int valuator_exists = vrInputSetValuatorDescription(input number, string);
	
where the value returned indicates whether that valuator exists on the current system configuration. (If the valuator did not exist, a dummy button will be created, though the user will not be able to provide an input.) The "input number" argument specifies which input of type "2switch" to describe.

vrGetValuatorValue() & vrGetValuatorDelta()
The "valuator" input type typically is set by a dial, slider, or one axis of a joystick. The numeric order of the valuators is determine entirely by the configuration file, and thus can differ from site to site. A typical configuration that provides a joystick maps the joystick's X-axis (side to side) as number 0, and the Y-axis as valuator number 1.

The syntax is:

	double valuator_value = vrGetValuatorValue(input number);
	double valuator_delta = vrGetValuatorDelta(input number);
	
The "input number" argument specifies which input of type "valuator" to access.

vrInputSet6sensorDescription()
This function associates a string with how the given 6-DOF sensor input in used within the application. This provides the end-user a quick-reference guide for how the application is operated.

The syntax is:

	int sensor_exists = vrInputSet6sensorDescription(input number, string);
	
where the value returned indicates whether that sensor exists on the current system configuration. (If the sensor did not exist, a dummy sensor will be created, though the user will not be able to provide an input.) The "input number" argument specifies which input of type "6sensor" to describe.

vrMatrixGet6sensorValues()
The "6sensor" input type is typically set by a 6-dof tracker attached to a handheld devices, or a device worn by the user such as a head-mounted display, or pair of stereo glasses. It is also possible for some systems to directly track a part of the user's body through computer vision techniques. The numeric order of the 6sensors is determine entirely by the configuration file, and thus can differ from site to site. A typical configuration will set the sensing of the head of user-0 to 6sensor-0, and a handheld device to 6sensor-1. There is no de facto standard for additional sensors. The next one might track the head of user-1, or a second hand-held device.

The syntax is:

	vrMatrix *transform_value = vrMatrixGet6sensorValues(matrix *, input number);
	
The "matrix *" argument is a pointer to memory allocated as a vrMatrix type. This memory will be overwritten with the resultant data, and the same pointer value will be given as the return value. The "input number" argument specifies which input of type "6sensor" to access.

vrVectorGetRWFrom6sensorDir() & vrVectorGetVWFromUser6sensorDir()
Like vrMatrixGet6sensorValues(), these two functions also access inputs of type "6sensor". However, instead of reporting the entire 6-dof position of the sensor in a 4x4 matrix, only a 2-dof vector direction is reported: essentially equivalent to the azimuth and elevation of the sensor.

The syntax is:

	vrVector *vector_value = vrVectorGetRWFrom6sensorDir(vector *, input number, direction);
	vrVector *vector_value = vrVectorGetVWFromUser6sensorDir(vector *, user number, input number, direction);
	
Where the vector returned is a unit vector pointing in the same direction as one of the 6 cardinal directions from the sensor — as specified in the last argument. The input number in both cases is simply the choice of which "6sensor" to access, and in the second of the two functions the second argument specified the number of the user from which to obtain the relative position between the real and virtual worlds. In most applications, individual users are not treated any differently, and thus user 0 will work fine. The last argument, specifying the cardinal direction is done by giving one of six enumerated values:
  • VRDIR_FORE
  • VRDIR_BACK
  • VRDIR_UP
  • VRDIR_DOWN
  • VRDIR_LEFT
  • VRDIR_RIGHT

vrPointGetRWFrom6sensor() & vrPointGetVWFromUser6sensor()
The vrPointGetRWFrom6sensor() function is used to get the real-world location of a given 6sensor. That is, instead of the full 6-dof position of the sensor, only the 3-dof location is returned in the form of a vrPoint type.

The syntax is:

	vrPoint point_value = vrPointGetRWFrom6sensor(point *, input number);
	vrPoint point_value = vrPointGetVWFromUser6sensor(point *, user number, input number);
	
The input number in both cases is simply the choice of which "6sensor" to access, and in the second of the two functions the second argument specified the number of the user from which to obtain the relative position between the real and virtual worlds. In most applications, individual users are not treated any differently, and thus user 0 will work fine.

vrEulerGetRWFrom6sensor() & vrEulerGetVWFromUser6sensor()
The vrEulerGetRWFrom6sensor() function returns the full 6-dof position of the given sensor, but instead of returning a 4x4 matrix, it returns three translational values (the location), and three rotational values (the orientation) in Euler angles.

The use of Euler angles though, can be problematic, as they introduce singularities when certain rotations are performed leading to ambiguities in the values. This function is provided only as a convenience for people porting applications from other libraries that rely on Euler angles.

The syntax is:

	vrEuler euler_value = vrEulerGetRWFrom6sensor(euler *, input number);
	vrEuler euler_value = vrEulerGetVWFromUser6sensor(euler *, user number, input number);
	
The input number in both cases is simply the choice of which "6sensor" to access, and in the second of the two functions the second argument specified the number of the user from which to obtain the relative position between the real and virtual worlds. In most applications, individual users are not treated any differently, and thus user 0 will work fine. The "euler" argument is a pointer to existing memory allocated for a vrEuler type. Note that while the name "Euler" refers only to how the rotational component of a 6sensor's position, in FreeVR the vrEuler type also contains the translational component. The two components are stored in two separate array fields within the vrEuler structure: "r[3]" for rotation, and "t[3]" for translation. The order for the translation elements is: x,y,z. The values of VR_X, VR_Y, and VR_Z can be used for clarity. The order for the rotational elements is: azimuth, elevation, roll. The values VR_AZIM, VR_ELEV, and VR_ROLL can likewise be used for clarity.

Functions to Control the Rendering

This group of functions can be called from within the visual rendering process to affect how things are rendered. Most of them deal with changing the active coordinate system, with rendering actions that follow taking place in the altered state. One deals with the actual rendering of an object (text), because this can differ between instantiations of OpenGL, based on the windowing system, and a couple provide default renderings of world rendering.

vrRenderCategory()
The vrRenderCategory() function allows the application programmer to differentiate between two categories of code within the world rendering. The only distinction made between these two categories is where the time spent within each category is reported in the application statistics display. (See the section on FreeVR statistics for information on how to render and interpret the statistics data.)

The syntax is:

	vrRenderCategory(int category);
	
where "category" is either "1" or "2". NOTE: time for each category is what is measured up until the point when the category is set (i.e. when this function is called, it is the operations that have already occurred that will be counted as part of the given category). The time from the last call to vrRenderCategory() to the end of the current frame is added to the statistics for category-1.

vrRenderText()
The vrRenderText() function is used to render 2-D text. 2-D text is typically used for debugging and creating a minimal interface. The text string starting point may be positioned in a 3-D location, but it is raster, bitmap based, and therefore always the same size, regardless of where in the 3-D world it is positioned. Also, it will always be rendered horizontally across a display window.

The syntax is:

	vrRenderText(render-info, string);
	
The "render-info" argument is a handle passed to the draw routine by FreeVR, and contains relevant information for rendering the particular frame to a particular eye.

The "string" argument is a standard C-style pointer to a null-terminated array of characters. To position the string, the glRasterPos3f(x, y, z) OpenGL function must first be called. Also, it is very important to note that the color of the text must be set prior to calling glRasterPos3f().

The default font is "fixed" on X11 systems. This can be changed on a per-window or per-system basis in the FreeVR configuration file with the "font=<font-name>" argument. For a list of available fonts run "xlsfonts". Two other common choices are "12x24" and "10x20" when a font larger than the default is desired.

vrRenderTransform6sensor()
The vrRenderTransform6sensor() function replaces the matrix on the top of the OpenGL model-view rendering stack with one that will cause one of the 6sensors to be the origin of the rendering that follows.

This function is often used to render a pointer emanating from the end of a handheld device.

The syntax is:

	vrRenderTransform6sensor(render-info, input number);
	
The "render-info" argument is a handle passed to the draw routine by FreeVR, and contains relevant information for rendering the particular frame to a particular eye. The "input number" argument specifies which input of type "6sensor" to access.

vrRenderTransformUserTravel()
The vrRenderTransformUserTravel() function replaces the matrix on the top of the OpenGL model-view rendering stack with one that will cause the virtual world position to be the coordinate system from which the rendering that follows is based.

This function is generally used once in the visual render callback at the point where all the ensuing rendering is of objects considered part of the virtual world. It is used in conjunction with the "User Travel" functions described in the next section.

The syntax is:

	vrRenderTransformUserTravel(render-info);
	
The "render-info" argument is a handle passed to the draw routine by FreeVR, and contains relevant information for rendering the particular frame to a particular eye.

vrRenderGetBillboardAngles3d() & vrRenderGetBillboardAnglesAd()
The vrRenderGetBillboardAngles3d() and vrRenderGetBillboardAnglesAd() functions are provided in order to make the technique of rotating textures to always face the user (called "billboarding") easy to implement in FreeVR applications.

Basically all that needs to be done is to call the function, and the values of three angles will be returned. From these angles, it is an easy process to rotate the OpenGL matrix stack such that subsequently rendered objects (until the next glPopMatrix() call) will be reoriented based on the location of the user.

In the case of cylindrically rendered billboards, only the azimuth angle is used, and in the case of spherically rendered billboards, both the azimuth and elevation values are used. NOTE, the roll value is also returned, but very few applications require its use.

The syntax (and common usage) is:

	vrRenderGetBillboardAngles3d(rendinfo, &angles, object_xloc, object_yloc, object_zloc);
	glRotatef(angles.r[VR_AZIM], 0.0, 1.0, 0.0);
	glRotatef(angles.r[VR_ELEV], 1.0, 0.0, 0.0);	/* use only for spherical billboarding */
	
NOTE that the angles are always returned via a vrEuler angles type (the "&angles" argument), and that the 3d and Adsuffix refers to how the location of the object are passed to the function.

NOTE also that this function does not adhere to the naming convention in which functions returning a complex type start with the name of the type. In this case the fact that this is a class of render function takes precedence.

vrRenderPushPerspFrom6sensor() & vrRenderPopPersp()
The vrRenderPushPerspFrom6sensor() and vrRenderPopPersp() functions are provided as a means of temporarily shifting the perspective of the virtual world to that of a 6-sensor other than the one associated with the primary viewer. Thus OpenGL geometries rendered between these two function calls can be from the perspective of a second (or third) viewer.

One situation in which this can be useful is when two or more compatriots are working together on a task, each with their own hand-held user interface controller (e.g. "wand"). For the non-tracked users to best use their controllers, they will need to be interfacing with widgets/gadgets that are rendered relative to their particular position. Thus, the application should (and can) accommodate this by rendering this portion of the virtual world from that user's perspective.

The syntax (and common usage) is:

	vrRenderPushPerspFrom6sensor(rendinfo, USER2_HEAD);
	<render user #2's widgets>
	vrRenderPopPersp(rendinfo);
	
NOTE that vrRenderPushPerspFrom6sensor() will return "true" if is successfully performs its operation. Failure would be the result of a stack overflow. The depth of the stack is set by the library value VR_MAXPERSPDEPTH, and is currently set to 8. In practice, it should not be necessary to go deeper than 1.

vrRenderTransformWindow()
The vrRenderTransformWindow() function replaces the matrix on the top of the OpenGL model-view rendering stack with one that will cause the ensuing rendering commands to treat the lower-left corner of the window being rendered into as the origin of the coordinate system.

This function is seldom used, and in those cases where it is used, it is typically for debugging purposes, and could perhaps be used for a minimal (and probably not desirable) user interface.

The syntax is:

	vrRenderTransformWindow(render-info);
	
The "render-info" argument is a handle passed to the draw routine by FreeVR, and contains relevant information for rendering the particular frame to a particular eye.

vrRenderNullWorld()
The vrRenderNullWorld() function is seldom used by application programmers. It is provided as a convenience when the view of the virtual world is to be disabled by changing the rendering callback to render the basic, empty world. The function basically clears the screen and depth buffers, and then returns.

The syntax is:

	vrRenderNullWorld(render-info);
	
The "render-info" argument is a handle passed to the draw routine by FreeVR, and contains relevant information for rendering the particular frame to a particular eye.

vrRenderDefaultSimulator()
The vrRenderDefaultSimulator() function causes the simulator display set as the default to be rendered. This might be useful in some debugging circumstances, but is otherwise not recommended for application programming.

The syntax is:

	vrRenderDefaultSimulator(render-info);
	
The "render-info" argument is a handle passed to the draw routine by FreeVR, and contains relevant information for rendering the particular frame to a particular eye.

vrRenderSetWindowContext() & vrRenderGetWindowContext()
The vrRenderSetWindowContext() and vrRenderGetWindowContext() functions are used to pass information about a graphical rendering context between the graphics initialization and rendering callbacks. The information is transmitted by means of the vrRenderInfo structure that is passed into all rendering related routines.

The syntax is:

	vrRenderSetWindowContext(render-info, (void *)graphics_context);
	void *gfx_context = vrRenderGetWindowContext(render-info);

	
The "render-info" argument is a handle passed to the draw routine by FreeVR, and contains relevant information for rendering the particular frame to a particular eye.

vrRenderRequestExit()
The vrRenderRequestExit() function is used when the rendering callback routine (or graphics-initialization callback) encounter a fatal error situation that requires termination of the application. To allow the rest of FreeVR to cleanly exit, this function will set a flag that will be caught in vrFrame(), where a clean exit can be performed.

Math Functions

There are many math functions built into the FreeVR library. These functions typically deal with the manipulation of complex types such as matrices, vectors, points, Euler angles, and even quaternions. The time operations also fall into this category. Only a subset of the most commonly used functions are listed and described here. For a full list of functions look in the vr_math.h header file. If you feel one of these functions should be described here, send me mail.

vrVectorLength()
This function returns the length of the given vector.

The syntax is:

	double length = vrVectorLength(vrVector *vec);
	
Where the length of the single argument is calculated, and returned as a double precision float.

vrVectorNormalize()
This function performs a unit-normalization operation on a vector.

The syntax is:

	vrVector *dest = vrVectorNormalize(dest vector *, src vector *);
	
Where "dest vector *" points to the memory of the vector to be set, and "src vector *" points to the vector to be normalized. The normalized vector is placed in the memory pointed to by the first argument.

The returned vector result is a duplicate of the pointer given as the first argument.

NOTE that it is safe for the destination and source vectors to reference the same memory.

vrVectorSubtract()
This function performs a vector-subtraction operation between two vectors.

The syntax is:

	vrVector *result = vrVectorSubtract(result vector *, src1 vector *, src2 vector *);
	
Where "dest vector *" points to the memory of the vector to be set, and the argument "src2 vector *" will be subtracted from the vector at "src1 vector *".

The returned vector result is a duplicate of the pointer given as the first argument.

NOTE that it is safe for any (and all) of the vector pointers to refer to the same memory.

vrVectorFromTwoPoints()
This function sets the values for a vector as the offset of one point from another. Or, put another way, it is the movement required to get from the first point to the second.

The syntax is:

	vrVector *result = vrVectorFromTwoPoints(result vector *, src point1 *, src point2 *);
	
Where "result vector *" points to the memory of the vector to be set. The arguments "src point1 *" and "src point2 *" point to the memory of points 1 and 2 respectively.

The returned vector result is a duplicate of the pointer given as the first argument.

vrVectorAddScaledVectors()
This functions sets a vector's value to the summation of two vectors, each of which may be scaled by a scalar value.

The syntax is:

	vrVector *result = vrVectorAddScaledVectors(result vec *, src vec1 *, src vec2 *, scale1, scale2);
	
Where "result vec *" points to the memory of where the result should be placed. The arguments "src vec1 *" and "src vec2 *" point to the two vectors to be summed, and "scale1" and "scale2" are the multiplication values for each of the summands respectively.

The returned vector result is a duplicate of the pointer given as the first argument.

NOTE: if the intent is to add a vector to a location (ie. point), then it is better to use the function vrPointAddScaledVector().

NOTE that it is safe for any (and all) of the vector pointers to refer to the same memory.

vrVectorScale()
This function scales the given vector by a value. Vector scaling is defined as the multiplication of the scale value to each of the components of the vector.

The syntax is:

	vrVector *result = vrVectorScale(vector *, scale);
	
Where "vector *" is a pointer to the vector's memory, and "scale" is the multiplicand.

The returned vector result is a duplicate of the pointer given as the argument.

NOTE that unlike many of the other functions, the vector operand is modified in place.

vrVectorDotProduct()
This function returns the dot-product of two vectors. The dot-product is a measure of the difference between the directions two vectors point.

The syntax is:

	double vrVectorDotProduct(vector1 *, vector2 *);
	
Where "vector1 *" and "vector2 *" point to the memory locations of the two vectors that are to be dotted.

NOTE that whenever a vector from the origin to a point is needed for an operation such as the dot-product, it is often convenient to simply type-cast the vrPoint to a vrVector. This type-casting is possible because points and vectors have the same internal representation in FreeVR.

vrVectorCrossProduct()
This function returns the cross product of two vectors. The cross-product operation results in a vector that is perpendicular to both of the given vectors.

The syntax is:

	vrVector *result = vrVectorCrossProduct(result vector *, vector1 *, vector2 *);
	
Where "result vector *" points to the memory where the resultant vector values should be placed. The arguments "vector1 *" and "vector2 *" refer to the two multiplicands of the operation.

The returned vector result is a duplicate of the pointer given as the first argument.

Note that it is safe to have either of the operand vectors refer to the same memory as the resultant vector.

vrVectorTransformByMatrix()
This function transforms a vector by a 4x4 homogeneous matrix through a matrix multiplication operation. Because a matrix multiple between a 1x3 and 4x4 entities does not make sense, the vector is affectively extended to a 1x4 matrix, with the extra element set to 0 (NOTE: a point transformation sets this extra element to 1).

The syntax is:

	vrVector *result = vrVectorTransformByMatrix(result vector *, src vector *, matrix *);
	
Where "result vector *" points to the memory where the resultant vector values should be placed. The "src vector *" operand points to the memory of the initial vector to be transformed, and "matrix *" points to the vrMatrix with the transformation.

The returned vector result is a duplicate of the pointer given as the first argument.

NOTE that it is safe for the result and src pointers to reference the same memory.

vrPointTransformByMatrix()
This function transforms a point by a 4x4 homogeneous matrix using a matrix multiplication operation. Because a matrix multiply between a 1x3 and 4x4 entities does not make sense, the point is effectively extended to a 1x4 vector, with the extra element set to 1 (NOTE: a vector transformation sets this extra element to 0).

The syntax is:

	vrPoint *result = vrPointTransformByMatrix(result point *, src point *, matrix *);
	
Where "result point *" is a pointer to the memory where the resultant point values should be placed. The "src point *" operand points to the memory of the initial 3-D point to be transformed, and "matrix *" is a pointer to the vrMatrix with the transformation.

The returned vector result is a duplicate of the pointer given as the first argument.

NOTE that it is safe for the result and src pointers to reference the same memory.

vrPointTransformByQuat()
The vrPointTransformByQuat function transforms a point by the rotation represented by the given quaternion. As with the matrix equivalent to this operation, the given point value is extended to a 1x4 vector with the extra element set to 1 (NOTE: a vector transformation sets this extra element to 0).

The syntax is:

	vrPoint *result = vrPointTransformByQuat(result point *, src point *, quaternion *);
	
Where "result point *" is a pointer to the memory where the resultant point values should be placed. The "src point *" operand points to the memory of the initial 3-D point to be transformed, and "quaternion *" is a pointer to the vrQuat with the transformation.

The returned point result is a duplicate of the pointer given as the first argument.

NOTE that it is safe for the result and src pointers to reference the same memory.

vrPointGetTransFromMatrix()
The vrPointGetTransFromMatrix function extracts the translational component of a 4x4 matrix into a point representation. (Which in mathematical terms is the location where the operation in the matrix would move a point located at the origin.)

The syntax is:

	vrPoint *result = vrPointGetTransFromMatrix((vrPoint *)point, (vrMatrix *)matrix);
	
Where "point" is a pointer to the memory where the resultant point values should be placed.

The returned point result is a duplicate of the pointer given as the first argument.

NOTE that it is safe for the result and src pointers to reference the same memory.

vrMatrixSetTransFromVector()
The vrMatrixSetTransFromVector function replaces the translational component of a 4x4 matrix with the given vector.

The syntax is:

	vrMatrix *result = vrMatrixSetTransFromVector((vrMatrix *)matrix, (vrVector *)vector);
	
Where "matrix" is a pointer to the memory where the resultant matrix values should be placed.

The returned matrix result is a duplicate of the pointer given as the first argument.

NOTE that it is safe for the result and src pointers to reference the same memory.

vrVectorGetTransFromMatrix()
The vrVectorGetTransFromMatrix function extracts the translational component of a 4x4 matrix and sets the resultant vector to those values.

The syntax is:

	vrVector *result = vrVectorGetTransFromMatrix((vrVector *)vector, (vrMatrix *)matrix);
	
Where "vector" is a pointer to the memory where the resultant matrix values should be placed.

The returned vector result is a duplicate of the pointer given as the first argument.

NOTE that it is safe for the result and src pointers to reference the same memory.

vrPointAddScaledVector()
This function sets the location of one point as an offset from another point by the given vector multiplied by a scalar value.

The syntax is:

	vrPoint *result = vrPointAddScaledVector(result point *, src point *, vector *, scale);
	
Where the "result point *" points to the memory where the new location value should be placed, "src point *" points to the location of the current point, "vector *" points to the vector values, and scale is a double precision floating point number.

The returned point result is a duplicate of the pointer given as the first argument.

NOTE that it is safe for the result and src pointers to reference the same memory. In this case that point will be moved by the scaled vector.

vrMatrixSetIdentity()
This function replaces the values of a matrix with the identity transformation matrix.

The syntax is:

	vrMatrix *result = vrMatrixSetIdentity(matrix *);
	

Where "matrix *" points to the memory of the matrix to be set.

The returned matrix value is a duplicate of the pointer given as the argument.

vrMatrixSetTranslation3d()
This functions replaces the values of a matrix with one that produces a translation transformation of the given values. The rotational component of the matrix will be modified to produce an identity operation — i.e. no rotation. The "3d" at the end of the function name refers to the fact that after the matrix argument, three double precision float values are expected.

The syntax is:

	vrMatrix *result = vrMatrixSetTranslation3d(matrix *, x, y, z);
	

Where "matrix *" points to the memory of a vrMatrix structure in which to place the new values. The arguments "x", "y", and "z" are double precision floating point numbers of the translation transformation.

The returned matrix value is a duplicate of the pointer given as the argument.

vrMatrixSetTranslationAd()
This function replaces the values of a matrix with one that produces a translation transformation of the given values. The rotational component of the matrix will be modified to produce an identity operation — i.e. no rotation. The "Ad" at the end of the function name refers to the fact that after the matrix argument, an array of three double precision float values is expected.

The syntax is:

	vrMatrix *result = vrMatrixSetTranslationAd(matrix *, array);
	

Where "matrix *" points to the memory of a vrMatrix structure in which to place the new values. The argument "array" is a three element array of double precision floating point numbers of the translation transformation, in the order of X, Y, and Z. The FreeVR defined values of VR_X, VR_Y, and VR_Z can be used to index the proper elements in the array.

The returned matrix value is a duplicate of the pointer given as the argument.

vrMatrixSetRotationId()
This function replaces the values of a matrix with values that will produce a rotation transformation about the given cardinal axis. The translational component of the resultant matrix will be an identity translation (ie. no movement). The "Id" at the end of the function name refers to the fact that after the matrix argument, an integer value indicating the axis, and a single double precision float argument for the angle are required.

The syntax is:

	vrMatrix *result = vrMatrixSetRotationId(matrix *, axis, theta);
	

Where "matrix *" points to the memory of a vrMatrix structure in which to place the new values. The "axis" argument expects one of the defined values: VR_X, VR_Y, or VR_Z. The "theta" argument is the amount of the rotation given in degrees.

The returned matrix value is a duplicate of the pointer given as the argument.

vrMatrixSetRotation4d()
This function replaces the values of a matrix with values that will produce a rotation transformation about the given cardinal axis. The translational component of the resultant matrix will be an identity translation (ie. no movement). The "4d" at the end of the function name refers to the fact that after the matrix argument, four double precision floating point numbers are required.

The syntax is:

	vrMatrix *result = vrMatrixSetRotation4d(matrix *, x, y, z, theta);
	

Where "matrix *" points to the memory of a vrMatrix structure in which to place the new values. The "x", "y", and "z" arguments define the axis about which the rotation is to be performed, and the "theta" argument is the amount of the rotation given in degrees.

The returned matrix value is a duplicate of the pointer given as the argument.

vrMatrixSetRotationAd()
This function replaces the values of a matrix with values that will produce a rotation transformation about the given cardinal axis. The translational component of the resultant matrix will be an identity translation (ie. no movement). The "Ad" at the end of the function name refers to the fact that after the matrix argument, a four element array of double precision floating point numbers is required.

The syntax is:

	vrMatrix *result = vrMatrixSetRotationAd(matrix *, array);
	

Where "matrix *" points to the memory of a vrMatrix structure in which to place the new values. The "array", argument defines both the axis about which the rotation is to be performed, and the amount of the rotation. The axis values are accessed using the VR_X, VR_Y, and VR_Z defined values as indices into the array. The "theta" value is indexed using the VR_W predefined value.

The returned matrix value is a duplicate of the pointer given as the argument.

vrMatrixSetRotationFromQuat()
The vrMatrixSetRotationFromQuat() function assigns to a given matrix a rotational operation based on the quaternion representation of the rotation.

The syntax is:

	vrMatrix *result = vrMatrixSetRotationAd(matrix *, (vrQuat *)quaternion);
	
Where "matrix *" points to the memory of a vrMatrix structure in which to place the new values. The "quaternion" argument is also passed by reference as a pointer to an existing vrQuat type containing the 4-tuple components of the quaternion.

The returned matrix value is a duplicate of the pointer given as the argument.

vrMatrixSetFromQuat()
The vrMatrixSetFromQuat function sets a full 4x4 matrix to a rotational operation as defined by the given quaternion. The translational portion of the matrix is set to the identity operation.

The syntax is:

	vrMatrix *result = vrMatrixSetFromQuat(matrix *, (vrQuat *)quaternion);
	
Where "matrix *" points to the memory of a vrMatrix structure in which to place the new values. The "quaternion" argument is also passed by reference as a pointer to an existing vrQuat type containing the 4-tuple components of the quaternion.

The returned matrix value is a duplicate of the pointer given as the argument.

vrQuatSetFromMatrix()
The vrQuatSetFromMatrix function extracts the rotation portion of a 4x4matrix and creates a quaternion with the same rotational effect.

The syntax is:

	vrQuat *result = vrQuatSetFromMatrix(quat *, (vrMatrix *)matrix);
	
Where "quat *" points to the memory of a vrQuat structure in which to place the new values. The "matrix" argument is also passed by reference as a pointer to an existing vrMatrix type containing the 4x4 array of the matrix.

The returned quaternion value is a duplicate of the pointer given as the argument.

vrMatrixSetScale3d()
This function replaces the values of a matrix with values that will produce a scale (resizing) transformation along the axes. The translational and rotational components of the resultant matrix will be an identity transformation.

The syntax is:

	vrMatrix *result = vrMatrixSetScale3d(matrix *, x, y, z);
	

Where "matrix *" points to the memory of a vrMatrix structure in which to place the new values. The "x", "y", and "z" arguments define the amount of scaling to be performed along each axis. A negative value for an axis will flip the transformation about that axis.

The returned matrix value is a duplicate of the pointer given as the argument.

vrMatrixPreMult()
The vrMatrixPreMult() function applies a transformation operation specified by a 4x4 homogeneous matrix to another matrix using a in-place matrix multiply operation. In this case, the transformation is used as the first argument in the multiplication, thus resulting in an ordering whereby the new transformation can be thought to occur before the existing transformation of the first argument. There can be ambiguities in the notion of pre and post multiplication, so the best way to describe it is in equivalent equations:
Mleft' = Mright * Mleft
P * Mleft' = P * (Mright * Mleft)

The syntax is:

	vrMatrix *result = vrMatrixPreMult(matrix1 *, matrix2 *);
	

Where "matrix1" is the matrix to be modified by the transformation of "matrix2". Thus, the value of "matrix1" will be changed after returning from the function, and the returned matrix value is a duplicate of the pointer given as the argument.

This function is used by first creating a specific transformation with other functions, and then using this function to apply that transformation to another matrix. There are also several functions that combine both operations into a single function call. These functions have names similar to those above, but beginning with vrMatrixPre instead of vrMatrix, and the initial matrix argument is modified instead of replaced. Those functions are:

	vrMatrix mat_left = vrMatrixPreTranslate3d(mat_left, x, y, z);
	vrMatrix mat_left = vrMatrixPreRotateId(mat_left, axis, theta);
	vrMatrix mat_left = vrMatrixPreRotate4d(mat_left, x, y, z, theta);
	vrMatrix mat_left = vrMatrixPreScale3d(mat_left, x, y, z);

vrMatrixPostMult()
The vrMatrixPostMult() function applies a transformation operation specified by a 4x4 homogeneous matrix to another matrix using a in-place matrix multiply operation. In this case, the transformation is used as the second argument in the multiplication, thus resulting in an ordering whereby the new transformation can be thought to occur after the existing transformation of the first argument. There can be ambiguities in the notion of pre and post multiplication, so the best way to describe it is in equivalent equations:
Mleft' = Mleft * Mright
P * Mleft' = P * (Mleft * Mright)

The syntax is:

	vrMatrix *result = vrMatrixPostMult(matrix1 *, matrix2 *);
	

Where "matrix1" is the matrix to be modified by the transformation of "matrix2". Thus, the value of "matrix1" will be changed after returning from the function, and the returned matrix value is a duplicate of the pointer given as the argument.

This function is used by first creating a specific transformation with other functions, and then using this function to apply that transformation to another matrix. There are also several functions that combine both operations into a single function call. These functions have names similar to those above, but beginning with vrMatrixPost instead of vrMatrix, and the initial matrix argument is modified instead of replaced. Those functions are:

	vrMatrix mat_left = vrMatrixPostTranslate3d(mat_left, x, y, z);
	vrMatrix mat_left = vrMatrixPostRotateId(mat_left, axis, theta);
	vrMatrix mat_left = vrMatrixPostRotate4d(mat_left, x, y, z, theta);
	vrMatrix mat_left = vrMatrixPostScale3d(mat_left, x, y, z);

vrMatrixInvert() & vrMatrixInvertInPlace()
The vrMatrixInvert() and vrMatrixInvertInPlace() functions invert a given 4x4 homogeneous matrix, returning the result. The "InPlace" version will overwrite the source matrix.

The syntax is:

	vrMatrix *result = vrMatrixInvert(dst_matrix *, src_matrix *);
	vrMatrix *result = vrMatrixInvertInPlace(src_matrix *);
	

Where "dst_matrix" is the matrix to be modified by the inversion of "src_matrix". Thus, the value of "dst_matrix" will be changed after returning from the function, and the returned matrix value is a duplicate of the pointer given as the argument.

vrCurrentSimTime()
This function is used to get the time of the simulated virtual world. Time is returned in a double precision floating point value giving the number of seconds since starting the VR system with a call to vrStart().

The syntax is:

	vrTime time = vrCurrentSimTime();
	

Where no arguments are required, and the value returned is typed as a vrTime value. However, vrTime is currently implemented as a double, so the value returned can be used in any place a floating point number can be used.

VRMAT_ROWCOL()
This macro is a convenience for accessing elements of a vrMatrix type. It is generally clearer to access elements of the array in the conceptual 4x4 style of the matrix. However, the vrMatrix type is actually implemented as a single dimensional 16 element array for programming convenience. Thus, this macro is required to make is clear which element of the matrix is being accessed.

As access to individual elements of a vrMatrix are typically not required at the application-programmer level, this macro is intended for the internal use of the FreeVR library. However, there may be occasions for using it in an application.

The syntax is:

	double element = VRMAT_ROWCOL(row, col);
	

Where the "row" and "col" arguments are values between 0 and 3, inclusive, but generally accessed by the values: VR_X, VR_Y, VR_Z, and VR_W. The returned value of the specified element is a double precision floating point number.

NOTE: because VRMAT_ROWCOL is a macro there is no checking to verify the appropriateness of the arguments, so invalid values for "row" or "col" may cause unforeseen problems.


Special Math Functions for Converting Between VW & RW

This collection of mathematical operations are expressly for the purpose of converting points, vectors and matrices between the real world and virtual world coordinate systems. Thus, if the location of a user's head is known in real-world values, there is a function to find the head's location with respect to the virtual world coordinate system.

The relationship between the real and virtual world coordinate systems may be specific to each user. This is because FreeVR applications can allow individual users to travel through the virtual world independently. Thus, as with the User-travel functions, a user number must be specified to indicate which virtual world transformation to use. Applications not designed to handle more than one user should simply specify user number 0, which exists in all configurations.

vrPointGetVWUserFromRWPoint()
This function converts a vrPoint from real world coordinates into a point in virtual world coordinates relative to the given user.

The syntax is:

	vrPoint *result = vrPointGetVWUserFromRWPoint(*vw_point, user_num, *rw_point);
	

Where the first argument is a memory pointer to the vrPoint into which the virtual world coordinate values should be placed. The second argument is the number of the user whose travel matrix should be used (use '0' for applications that do not distinguish users). The third argument is the existing value for the point in real world coordinates.

The returned point result is a duplicate of the pointer given as the first argument.

NOTE: The two vrPoint* arguments may safely point to the same memory location, in which case the point will be changed from real world coordinates to virtual world coordinates in place.

vrPointGetRWFromVWUserPoint()
This function converts a vrPoint from virtual world coordinates relative to the given user into a point in real world coordinates.

The syntax is:

	vrPoint *result = vrPointGetRWFromVWUserPoint(*rw_point, user_num, *vw_point);
	

Where the first argument is a memory pointer to the vrPoint into which the real world coordinate values should be placed. The second argument is the number of the user whose travel matrix should be used (use '0' for applications that do not distinguish users). The third argument is the existing value for the point in virtual world coordinates.

The returned point result is a duplicate of the pointer given as the first argument.

NOTE: The two vrPoint* arguments may safely point to the same memory location, in which case the point will be changed from real world coordinates to virtual world coordinates in place.

vrPointGetRWLocationFromMatrix()
This function returns the translational portion of the vrMatrix as a vrPoint in real world coordinates.

The syntax is:

	vrPoint *result = vrPointGetRWLocationFromMatrix(*rw_point, *matrix);
	

Where, the first argument is a memory pointer to the vrPoint where the result should be placed, and the second argument is the vrMatrix from which to extract the values.

The returned point result is a duplicate of the pointer given as the first argument.

vrPointGetVWFromUserMatrix()
This function returns the translational portion of the vrMatrix as a vrPoint in virtual world coordinates relative to the given user.

The syntax is:

	vrPoint *result = vrPointGetVWFromUserMatrix(*vw_point, user_num, *matrix);
	

Where, the first argument is a memory pointer to the vrPoint where the result should be placed, the second argument is the number of the user whose travel matrix should be used (use '0' for applications that do not distinguish users), and the third argument is the vrMatrix from which to extract the values.

The returned point result is a duplicate of the pointer given as the first argument.

vrMatrixGetRWFromUserHead()
This function gets the 4x4 homogeneous matrix that represents the position of the giver user's head in real world coordinates.

The syntax is:

	vrMatrix *result = vrMatrixGetRWFromUserHead(*matrix, usernum);
	
Where the first argument is a memory pointer to the vrMatrix into which the values will be placed, and the second argument specifies which user's head position to extract. NOTE: "NULL" is returned if the given user does not exist, and the matrix pointed to by the first argument will not be affected.

The returned matrix value is a duplicate of the pointer given as the argument.

vrMatrixGetVWUserFromRWMatrix()
This function gets the 4x4 homogeneous matrix that represents the ...

The syntax is:

	vrMatrix *result = vrMatrixGetVWUserFromRWMatrix(*matrix, usernum, *rw_matrix);
	

NOTE: this function is to be called from the simulation process. ...


User Travel Functions

FreeVR includes functions to move the virtual world relative to the real world — from the perspective of a user. These are the "User Travel Functions". These functions allow the programmer to rotate the virtual world relative to the real world, to translate it, to reset it to the identity operation, and to set it to any matrix desired. This is referred to as the "travel matrix" in this section.

Calls to the User Travel functions are cumulative. That is, specifying a translation followed by a rotation results in a matrix with both operations integrated. All the User Travel functions perform pre-multiplies to the existing travel matrix.

FreeVR is unique from other VR libraries in that it can keep track of multiple users (as specified in the configuration file). Therefore, it would not make sense for applications to be forced to move all users together, so the User Travel functions can affect any particular individual user. There is also the option to move all users as one, with the special "VR_ALLUSERS" tag. Note though that for users to move independently, the application must be specifically programmed to allow this.

vrUserTravelLockSet() & vrUserTravelLockRelease()
These functions allow the matrix associated with user travel to be protected from usage while the application code is making multiple changes to the matrix. In other words they allow multiple changes to the matrix to be linked together as one atomic operation.

The syntax is:

	vrUserTravelLockSet(user_num);
	[travel operations that should appear atomic]
	vrUserTravelLockRelease(user_num);
	
Where "user_num" is an integer specifying which user should be moved, or the value VR_ALLUSERS to move everybody as one.

vrUserTravelReset()
This function resets the travel matrix for the specified user(s) to the identity matrix, resulting in the virtual world having the same coordinate system as the real world.

The syntax is:

	vrUserTravelReset(user_num);
	
Where "user_num" is an integer specifying which user should be moved, or the value VR_ALLUSERS to move everybody as one.

vrUserTravelTranslate3d()
This function adjusts the relative position between the real and virtual coordinate systems for the given user (or all users) as (translational) movement along one or more of the axes.

The syntax is:

	vrUserTravelTranslate3d(user_num, x, y, z);
	
Again "user_num" is the integer specifying the particular user that should be moved, or the value VR_ALLUSERS to move everybody as one. The "x", "y", and "z" arguments specify the distance to move along each of the Cartesian axes.

vrUserTravelTranslateAd() & vrUserTravelTranslateVec()
These functions adjust the relative position between the real and virtual coordinate systems for the given user (or all users) as (translational) movement along one or more of the axes.

The syntax is:

	vrUserTravelTranslateAd(user_num, (double *)xyz_array[]);
	vrUserTravelTranslateVec(user_num, (vrVector *)go_vector);
	
Again "user_num" is the integer specifying the particular user that should be moved, or the value VR_ALLUSERS to move everybody as one. The "xyz_array" argument specifies the distance to move along each of the Cartesian axes as an array of three values in the order of X, Y, and Z.

vrUserTravelRotateId()
This function adjusts the relative position between the real and virtual coordinate systems for the given user (or all users) as (rotational) movement about one of the axes.

The syntax is:

	vrUserTravelRotateId(user_num, axis, theta);
	
Again "user_num" is the integer specifying the particular user that should be moved, or the value VR_ALLUSERS to move everybody as one. Axis is an integer macro that declares which of the three primary Cartesian axes about which the rotation is performed: VR_X, VR_Y, or VR_Z. Theta is a double-precision floating point value (aka "double") specifying how much rotation should occur in degrees.

vrUserTravelScale()
This function adjusts the relative scale between the real and virtual coordinate systems for the given user (or all users) as a scaling operation about { the origin | the user's current location }.

The syntax is:

	vrUserTraveScale(user_num, (double)scale_factor);
	
Again "user_num" is the integer specifying the particular user that should be moved, or the value VR_ALLUSERS to move everybody as one.

vrUserTravelTransformMatrix()
This function adjusts the relative position between the real and virtual coordinate systems for the given user (or all users) as a complete 4x4 homogeneous transformation matrix.

The syntax is:

	vrMatrix matrix* = vrUserTravelTransformMatrix(user_num, matrix*);
	
Again "user_num" is the integer specifying the particular user that should be moved, or the value VR_ALLUSERS to move everybody as one. The "matrix*" argument is a pointer to a variable of type vrMatrix. The same address of the vrMatrix pointer is returned as the result of this function. This is sometimes useful for using this function call as an argument of other functions.

vrMatrixGetUserTravel()
This function puts the current travel matrix for a user into the memory pointed to by "matrix*".

The syntax is:

	vrMatrix matrix* = vrMatrixGetUserTravel(matrix*, user_num);
	
Once again, "user_num" is the integer specifying the particular user that should be moved, or the value VR_ALLUSERS to move everybody as one. And, as with vrUserTravelTransformMatrix() above, the "matrix*" argument is a pointer to a vrMatrix type where the value will be placed. Also, the pointer will be returned as the result of the function call to allow this function to be used as argument to another function that takes a vrMatrix argument.

Debugging and Printing Functions

This collection of miscellaneous functions are frequently used to help debug a FreeVR application, or the FreeVR library. Most of them directly deal with printing text to a command shell. The FreeVR printing functions are designed to help indicate from which process each message is generated. This is done by color coding the outputs. Typically output from the main (ie. simulation) process is the default foreground text color, and text from other processes are colored based on specifications in the configuration file.

It is worth noting that because the application user will typically be watching the VR displays, and not the command shells, print statement are only useful as a debugging tool, and not to print out constantly changing values. Therefore, efficiency of these functions was not a concern, and they are fairly inefficient. In fact, printing to the shell is always slow in C, and in FreeVR it is slower. Thus once the print statements have served their usefulness, it is wise to remove them from the compiled code.

vrDbgDo()
This is a generic function used as a boolean to help specify blocks of code that should be conditionally executed based on the given debug level, and the current debug settings.

The syntax is:

	if (vrDbgDo(debug_level)) { /* do debugging stuff here */ }
	

Where the one argument is the debug level at which the condition should be satisfied.

vrDbgPrintfN()
This is a printing function that will print the given message only if the given debug level matches the current debug settings. It operates similar to standard printf(), with one additional argument at the beginning to specify the debug level.

The syntax is:

	vrDbgPrintfN(debug_level, format, args...);
	

Where the first argument is the debug level at which the condition to print must be satisfied, and the format and any arguments associated with the format following. The format and following arguments are given exactly the same as for the C printf() function.

vrPrintf()
This printing function is used exactly like the standard C printf() function. The reason this is preferred in FreeVR is that it handles any possible text colors and redirections that might be specified for the process by the FreeVR configuration. In fact, by default FreeVR will use a macro definition to replace all calls to printf() with vrPrintf().

The syntax is:

	vrPrintf(format, args...);
	
Where the format and following args are given exactly as with the standard C printf() function.

vrFprintContext()
This function prints the values associated with the topmost FreeVR settings. The brief style of this information is generally output at the beginning of all FreeVR applications. It displays the version information about the library, the running status, the size of the shared memory, and the time at which the application was begun.

The syntax is:

	vrFprintContext(*fp, style);
	

Where the first argument is a pointer to an open FILE stream, and the second argument is the style (ie. verbosity) of how the information should be presented.

vrFprintConfig()
This function prints the values associated with the VR configuration of how the application is currently being run. The brief style of this information is generally output at the beginning of all FreeVR applications. It displays the chosen VR "system" from those available in the current configuration, the debug level information, visual rendering mode (eg. monoscopic or stereoscopic), the input mapping, and lists of all the objects in the chosen system.

The syntax is:

	vrFprintConfig(fp, style);
	

Where the first argument is a pointer to an open FILE stream, and the second argument is the style (ie. verbosity) of how the information should be presented.

vrFprintInput()
This function prints the values associated with the existing VR inputs. This information is not provided by default when an application is run. It displays the numbers of the input devices, each type of input, and the internal input controls, and then based on the style (ie. verbosity), it may output detailed information about each device and input.

The syntax is:

	vrFprintInput(fp, style);
	

Where the first argument is a pointer to an open FILE stream, and the second argument is the style (ie. verbosity) of how the information should be presented.


Functions for Locking Operations

The locking functions of FreeVR are very important for smooth operation in a multi-processor machine. The use of locks prevents separate processes/threads from reading and writing to the same section of memory at the same time, which would produce unknown (perhaps damaging) results. Whenever reading or writing to memory locations that are accessed from more than one process, locks should be used to guarantee safe reading and writing.

vrLockCreate()
As the name implies, this function creates a new vrLock structure that can be used to set and release locks.

The syntax is:

	vrLock lock = vrLockCreate();
	
Note that the vrLock type is a generic memory pointer, and thus does not require an additional specification to indicate that it is a pointer.

vrLockCreateName()
As the name implies, this function creates a new vrLock structure that can be used to set and release locks, and gives the programmer the opportunity to name the lock for debugging purposes.

The syntax is:

	vrLock lock = vrLockCreateName(name string);
	
The function takes a standard C-string as the argument and returns a vrLock type. Note that the vrLock type is a generic memory pointer, and thus does not require an additional specification to indicate that it is a pointer.

vrLockTrace()
Trace the operations performed on the given lock. This allows the programmer to see when the lock is set as a read-lock, when it is set as a write-lock, and when it is released. This function is useful when the system is hanging, and a bug in the locking is suspected.

The syntax is:

	vrLockTrace(lock, state);
	
The "lock" argument is the value returned by the call to vrLockCreate() creating the lock. The "state" argument is a boolean that indicates whether tracing should be activated (1) or deactivated (0).

vrLockFree()
The vrLockFree() function frees (ie. deallocates) the memory used by the specified lock, and therefore that lock can no longer be used.

The syntax is:

	vrLockFree(lock);
	
The "lock" argument is a value returned by a previous call to vrLockCreate().

vrLockWriteSet()
This function attempts to lock the given lock for writing. If the lock is already set for reading or writing, then it will wait (block) until the lock is freed, and will then lock it for this process.

The syntax is:

	vrLockWriteSet(lock);
	

Where the argument is the vrLock that is to be locked.

vrLockWriteRelease()
This function releases a lock that is set as a write lock.

The syntax is:

	vrLockWriteRelease(lock);
	

Where the argument is the vrLock that is to be released.

vrLockReadSet()
This function attempts to lock the given lock for writing. If the lock is already set for writing, then it will wait (block) until the lock is freed, and will then lock it for this process. NOTE: more than one process may put the same lock into read-lock mode.

The syntax is:

	vrLockReadSet(lock);
	

Where the argument is the vrLock that is to be locked.

vrLockReadRelease()
This function releases the read-lock placed on the given lock. NOTE that the lock may still have other read-locks attached to it.

The syntax is:

	vrLockReadRelease(lock);
	

Where the argument is the vrLock that is to be released.

vrLockReadToWrite()
This function first releases the existing read-lock, and then attempts to set the write-lock for the given lock. It will wait (block) until it is possible to set the lock for writing (ie. should there be other processes holding this lock with other read-locks).

The syntax is:

	vrLockReadToWrite(lock);
	

Where the argument is the vrLock that is to be switched.


Functions for Barrier Operations

The barrier functions of FreeVR are also very important for smooth operation in a multi-processor machine. The use of barriers allows multiple processes doing related activities to synchronize their operation. This is especially important for the rendering processes. For example, the visual rendering processes should all swap front and back buffers at precisely the same moment.

To operate correctly, a barrier must know how many processes are grouped together (a "barrier-group"). If there are less processes than the barrier expects, then it will hang waiting for the extra (non-existent) processes to reach the barrier. If there are more processes, then it will release the barrier before all the processes have arrived at the barrier point.

Care must also be taken with barriers, to assure that no process is waiting for the other process to reach the same barrier while the other process is waiting for some other event from a process in the same barrier-group.

vrBarrierCreate()
As the name implies, this function creates a new vrBarrier structure that can be used to synchronize events between processes.

The syntax is:

	vrBarrier *barrier = vrBarrierCreate(context, name, clients);
	
The function takes the context handle as the first argument, the name of the barrier (as an array of characters) as the second argument, and the number of clients in the group of processes that will use this barrier. A pointer to a vrBarrier type is returned.

vrBarrierIncrement()
...

The syntax is:

	vrBarrierIncrement(barrier, increment);
	
The function takes a pointer to the barrier, and ...

vrBarrierDecrement()
...

The syntax is:

	vrBarrierDecrement(barrier, decrement);
	
The function takes a pointer to the barrier, and ...

vrBarrierSync()
...

The syntax is:

	vrBarrierSync(barrier);
	
...

vrBarrierLastToSync()
...

The syntax is:

	int value = vrBarrierLastToSync(barrier);
	
...

vrBarrierFirstToSync()
...

The syntax is:

	int value = vrBarrierFirstToSync(barrier);
	
...

Special Functions for Performer library usage

Obviously, as of 2021, there's not much need to continue development of the Performer interface, so consider this a historical section.

The Performer version of the FreeVR library requires one or two extra function calls to operate correctly within the scheme of how the Performer library works. Primarily, this requires calls to the pfSync() and pfFrame() Performer routines as part of the simulation loop, along with functions for initializing and terminating operation of Performer.

There are also some additional FreeVR routines specifically for working with the Performer library. The primary two routines necessary are vrPfPreFrame() and vrPfMasterChannel(). The other functions listed in this section are also commonly used in Performer-FreeVR applications.

NOTE: a special concern with Performer applications is that the coordinate system used by Performer differs from the standard OpenGL system. While OpenGL uses a Y-up convention, Performer uses a Z-up convention. Thus, to transform objects (eg. vrPoint, vrVector, vrMatrix) from one coordinate system to the other, a 90 degree rotation about the X-axis is required. For example, to read the location of the wand and convert into Performer coordinates:

	/* create the point variable */
	vrPoint wand_point;

	/* create a conversion matrix */
	vrMatrix *pos90x = vrMatrixSetRotationId(vrMatrixCreate(), VR_X,  90.0);

	/* read the wand location in Y-up coordinates */
	vrPointGetVWFromUser6sensor(&wand_point, 0, WAND_SENSOR);

	/* convert the wand location to Z-up coordinates */
	vrPointTransformByMatrix(&wand_point, &wand_point, pos90x);

NOTE Further: I am now in the process of eliminating the need for the application programmer to deal with the conversion between Y-up and Z-up coordinate systems. However, please note that this is a transitional period for this, so to use the improved method, the function names have been altered slightly, and beginning with version 0.6a, the old functions names should be used to gain the new functionality. So if you skip the transition, all you'll need to do is remove your lines that manually convert from Y-up to Z-up coordinates.

There are now new "Pf" versions of all the inputs that respond with sensor values. These functions pre-convert the values into Z-up coordinates (typically, one would use only the first 4 of these):

	vrPointGetRWFrom6sensor() — vrPfPointGetRWFrom6sensor()
	vrPointGetVWFromUser6sensor() — vrPfPointGetVWFromUser6sensor()
	vrVectorGetRWFrom6sensorDir() — vrPfVectorGetRWFrom6sensorDir()
	vrVectorGetVWFromUser6sensorDir() — vrPfVectorGetVWFromUser6sensorDir()
	vrMatrixGet6sensorValues() — vrPfMatrixGet6sensorValues()
	vrMatrixGet6sensorValuesDirect() — vrPfMatrixGet6sensorValuesDirect()
	vrMatrixGet6sensorValuesDirectNoLastUpdate() — vrPfMatrixGet6sensorValuesDirectNoLastUpdate()
	vrMatrixGet6sensorRawValuesDirect() — vrPfMatrixGet6sensorRawValuesDirect()
	vrVectorfGetRWFrom6sensorDir() — vrPfVectorfGetRWFrom6sensorDir()
	vrVectorfGetVWFromUser6sensorDir() — vrPfVectorfGetVWFromUser6sensorDir()
	vrPointfGetRWFrom6sensor() — vrPfPointfGetRWFrom6sensor()
	vrPointfGetVWFromUser6sensor() — vrPfPointfGetVWFromUser6sensor()
	vrEulerGetRWFrom6sensor() — vrPfEulerGetRWFrom6sensor()
	vrEulerGetVWFromUser6sensor() — vrPfEulerGetVWFromUser6sensor()
And, the callback used to specify a DCS that transitions from the real world coordinate system to the virtual world has "_zup" appended to the name:
	vrPfDCSTransformUserTravel() — vrPfDCSTransformUserTravel_zup()

And let me reiterate that all these new functions will go away with version 0.6a, and the old function names should again be used, but without the need for converting to Performer's Z-up coordinate system.

vrPfPreFrame()
The vrPfPreFrame() function is called from within the main application process, inside the simulation loop. This function is where the perspective projection calculations are made and transferred to the Performer library data structures.

The syntax is:

	vrPfPreFrame();
Calling vrPfPreFrame() must be done between calls to pfSync() and pfFrame().

vrPfPostFrame()
The vrPfPostFrame() function is where FreeVR performs the operations that need to be done after the rendering. Currently, this function does not have any operations necessary for the functionality of FreeVR, but this may change in future versions, so should be included.

The syntax is:

	vrPfPostFrame(void);
	
Calling vrPfPostFrame() should be done after the call to pfFrame().

vrPfMasterChannel()
The vrPfMasterChannel() function returns a pointer to the pfChannel structure/class with the main rendering attribute settings. These settings include the pointer to the scene node (the primary usage of this function), the statistics to render, clipping plane information, etc.

The syntax is:

	pfChannel *chan = vrPfMasterChannel(void);
	
There are no arguments, and the returned value is a pointer to the master channel. This value need not be stored however, it can be used immediately, such as:
		pfScene *scene = createScene();
		vrPfMasterChannel()->setScene(scene);
	

vrPfDCSTransform6sensor()
Calling the vrPfDCSTransform6sensor() function alters the transformation matrix of a given pfDCS node based on the position of the given 6-sensor.

The syntax is:

	vrPfDCSTransform6sensor(pfDCS *, sensor_num);
	
The first argument is a pointer to the pfDCS node that will be altered, and the second argument the number of the 6-sensor. NOTE that any transformation value already in the pfDCS node will be overwritten.

vrPfDCSTransformUserTravelCB()
The vrPfDCSTransformUserTravelCB() function is a special Performer callback routine for use with pfDCS nodes. When assigned to a node, it will place the transformation matrix of the given user's travel coordinates into that pfDCS node.

The syntax is:

	dcsnode->setTravFuncs(PFTRAV_CULL, vrPfDCSTransformUserTravelCB, NULL);
	
Note that the arguments should be specified exactly as listed. The vrPfDCSTransformUserTravelCB() function is assigned as part of the CULL traversal, in order to make sure that the culling process takes the user travel transformation into account when pruning the world.

vrPfMatrixFromVrMatrix()& vrMatrixFromPfMatrix()
The vrPfMatrixFromVrMatrix() and vrMatrixFromPfMatrix() functions are used to convert Homogeneous 4x4 transformation matrices between the FreeVR and Performer internal formats. The primary difference between internal representations is that the FreeVR vrMatrix uses double precision floating point numbers whereas the Performer pfMatrix uses single precision. The secondary difference is that FreeVR uses a single 16 element array to store the values, and Performer uses a 4x4 array.

The syntax is:

	pfMatrix *mat = vrPfMatrixFromVrMatrix(pfMatrix *pfmat, vrMatrix *vrmat);
	vrMatrix *mat = vrMatrixFromPfMatrix(vrMatrix *vrmat, pfMatrix *pfmat);
	
The first argument in both cases is the one that will receive the data, and the second argument is the matrix that will be copied. In both cases, the function will return a duplicate of the pointer to the first matrix argument.


Alphabetical Index Listing of Functions and Macros








© Copyright William R. Sherman, 2024.