pfCAVE CAVE/Performer Library (CAVELib Version 2.6)
2 March 1997
- Electronic Visualization Laboratory
- University of Illinois at Chicago
- 851 S. Morgan St., Room 1120
- Chicago, IL 60607-7053
- (312) 996-3002
- (312) 413-7585 fax
- cavesupport@evl.uic.edu
(c) 1996,1997 Electronic Visualization Laboratory, University of Illinois
at Chicago
Written by Dave Pape.
Introduction
pfCAVE is a small interface library which allows developers to
use Iris Performer in the CAVE. It takes care of the details of creating
Performer pipes and channels for the CAVE display, and uses CAVE library
functions to handle tracking and to generate the correct perspective projections.
It also provides some functions to translate between the two different
coordinate systems used by Performer and the CAVE.
The current version of pfCAVE is for Performer version 2.0 and includes
the "Performer coordinates" version of the CAVE library.
Basic pfCAVE Program
The basic form of a Performer/CAVE program is as follows:
#include <Performer/pf.h>
#include <pfcave.h>
pfScene * create_scene(void);
int main(int argc,char **argv)
{
pfInit();
pfCAVEConfig(&argc,argv,NULL);
pfConfig();
pfCAVEInitChannels();
/* In C, do this: */
pfChanScene(pfCAVEMasterChan(),create_scene());
/* In C++, do this instead:
pfCAVEMasterChan()->setScene(create_scene());
*/
while (!getbutton(ESCKEY))
{
pfSync();
pfCAVEPreFrame();
pfFrame();
pfCAVEPostFrame();
}
pfCAVEHalt();
pfExit();
}
pfScene * create_scene(void)
{
return pfNewScene();
}
These function calls must be added to a Performer program in order to
use the pfCAVE library:
- pfCAVEConfig(&argc,argv,NULL)
- The equivalent of CAVEConfig(). This must be called after pfInit()
and before pfConfig().
- pfCAVEInitChannels()
- Creates all the channels, and makes them a single channel group. This
must be called after pfConfig().
- pfCAVEPreFrame()
- Updates the tracker data and sets up new projections for each channel.
Should be called once per frame before pfFrame().
- pfCAVEPostFrame()
- Updates non-latency-critical data. Should be called once per frame
after pfFrame().
The header file (pfcave.h) is in /usr/local/CAVE/include; the library
binaries (libpfcave_igl.a and libpfcave_ogl.a) are in /usr/local/CAVE/lib.
pfCAVE Functions
Overview
As shown in the example program above, the functions pfCAVEConfig,
pfCAVEInitChannels, pfCAVEPreFrame, and pfCAVEPostFrame
take care of the basic CAVE control, and must be called in any pfCAVE program.
The CAVE library contains functions to set up transformations based
on tracker or navigation data. pfCAVE provides DCS functions to add equivalent
transformations to a Performer scene graph. pfCAVEDCSHeadTransform,
pfCAVEDCSWandTransform, pfCAVEDCSSensorTransform, pfCAVEDCSNetHeadTransform,
pfCAVEDCSNetWandTransform, and pfCAVEDCSNavTransform will
each update a DCS with the latest transformation that would be generated
by the similarly named CAVE function. The DCS will need to be updated once
per frame using these functions.
pfCAVE defines its own channel draw function (via pfChanTravFunc)
in order to handle the stereo buffering and the additional rendering for
the simulator and arpafloor displays. This function calls pfDraw
to render the Performer scene graph. If an application needs to call its
own rendering functions as well, it can do so by registering draw callbacks
with pfCAVEPreDrawFunc, pfCAVEDrawFunc, or pfCAVEPostDrawFunc.
Functions
- pfList * pfCAVEChannels(void)
- Returns a pfList which contains pointers to all of the channels created
by pfCAVE (the elements are all of type pfChannel *).
- void pfCAVEConfig(int *argc, char **argv, char **appdefaults)
- Reads the CAVE configuration, and initializes pfCAVE operations. This
function calls CAVEConfigure (passing it argc,argv,appdefaults)
to initialize the CAVE library data. It then configures Performer in multipipe
mode for the number of walls selected, and starts the CAVE tracking and
networking processes if they are needed.
pfCAVEConfig must be called after pfInit and before pfConfig.
- void pfCAVEDCSHeadTransform(pfDCS *dcs)
- Modifies the given pfDCS to contain the same translation and rotation
as the head tracker (the scaling part of the DCS is not changed). The data
used are in CAVE tracker coordinates.
- void pfCAVEDCSNavTransform(pfDCS *dcs)
- Modifies the given pfDCS to contain the current CAVE navigation transformation.
This DCS will transform from physical tracker coordinates to navigated
world coordinates; tracker coordinates are the base pfCAVE coordinate system,
so this DCS should not be under any other DCS/SCS in a scene graph.
- void pfCAVEDCSNetHeadTransform(pfDCS *dcs,volatile CAVE_USER_ST
*user)
- Modifies the given pfDCS to contain the same translation and rotation
as the head tracker for the networked user user (the scaling part
of the DCS is not changed). The data used are in navigated coordinates,
so the DCS should be placed under a CAVE navigation DCS (pfCAVEDCSNavTransform).
- void pfCAVEDCSNetWandTransform(pfDCS *dcs,volatile CAVE_USER_ST
*user)
- Modifies the given pfDCS to contain the same translation and rotation
as the wand tracker for the networked user user (the scaling part
of the DCS is not changed). The data used are in navigated coordinates,
so the DCS should be placed under the CAVE navigation DCS (pfCAVEDCSNavTransform).
- void pfCAVEDCSWandTransform(pfDCS *dcs)
- Modifies the given pfDCS to contain the same translation and rotation
as the wand tracker (the scaling part of the DCS is not changed). The data
used are in CAVE tracker coordinates.
- void pfCAVEDCSSensorTransform(pfDCS *dcs,CAVE_SENSOR_ST *sensor)
- Modifies the given pfDCS to contain the same translation and rotation
as the given sensor (the scaling part of the DCS is not changed). The data
used are in CAVE tracker coordinates.
- void pfCAVEDrawFunc(pfChanFuncType func)
- Sets a drawing callback function. func will be called by pfCAVE's
channel draw function in place of pfDraw. It will be passed pointers
to the channel and the channel data.
- void pfCAVEHalt(void)
- Cleans up before exiting. pfCAVEHalt calls CAVEHalt and
runs the exit commands (from the configuration file) for each active wall.
It should be called prior to pfExit.
- void pfCAVEInitChannels(void)
- Creates the pfCAVE channels. This function creates a separate channel
for each (eye,wall) combination that is active. The channels are
all put into a single channel group, which shares the scene, EarthSky model,
cull function, draw function, near & far clipping planes, and buffer
swap. pfCAVEInitChannels should be called after pfConfig.
- pfChannel *pfCAVEMasterChan(void)
- Returns the 'master' channel from the pfCAVE channel group.
- pfList * pfCAVEPipes(void)
- Returns a pfList which contains pointers to all the pipes that were
created (the elements are all of type pfPipe *).
- void pfCAVEPostDrawFunc(pfChanFuncType func)
- Sets a post-pfDraw application callback. func will be
called by pfCAVE's channel draw function immediately after pfDraw.
It will be passed pointers to the channel and the channel data.
- void pfCAVEPostFrame(void)
- Performs non-latency-critical post rendering actions. pfCAVEPostFrame
currently only updates CAVE networking data. It should be called at the
end of the frame loop, after pfFrame.
- void pfCAVEPreDrawFunc(pfChanFuncType func)
- Sets a pre-pfDraw application callback. func will be
called by pfCAVE's channel draw function immediately before pfDraw.
It will be passed pointers to the channel and the channel data. If no pre-draw
callback has been set, the pfCAVE channel draw function calls pfClearChan;
if a callback has been set, it is up to the callback to clear the channel.
- void pfCAVEPreFrame(void)
- Performs latency-critical pre-rendering actions. This function updates
tracking and sets up the projections for each of the pfCAVE channels. It
should be called once per frame, before pfFrame.
Special Notes
Simulator mode
pfCAVE supports the CAVE simulator display and tracking. The simulator
display includes the same controls and the CAVE and wand rendering as in
the CAVE library; the timing command displays Performer's channel statistics.
Tracking is updated in the main application process (by pfCAVEPreFrame);
when multiprocessing, this process does not have a window associated with
it, so there is no advantage to using serial tracking with the simulator
tracker. In fact, it can significantly increase the time taken by the application
stage. In this case, you may get better performance by adding 'SerialTracking
n' to your configuration for simulator mode (after 'Simulator y'
or 'TrackerType simulator').
CAVE library functions & variables
All of the normal CAVE library functions and global variables can be
used in a pfCAVE application, with the following exceptions:
- *CAVETime is not updated; use pfGetFrameTimeStamp() instead.
- The function CAVEWallTransform() is not available.
- CAVEInit, CAVEDisplay, CAVEInitApplication, CAVEFrameFunction,
and CAVEStopApplication should not be called.
- Only the network related callbacks should be used with CAVEAddCallback.