We recommend configuring the 3D display as a secondary display, such that the main computer's desktop shows up on a regular LCD, and VR applications show up on the 3D display. This can be achieved in several ways, but we recommend configuring the two displays as two separate X screens under the same X server. This X configuration file, which will need to be copied into /etc/X11/xorg.conf on the main computer, can serve as a template.
The template configuration file sets up two X screens: the first connected to the main display, a regular LCD, and the second one connected to the 3D display. The second screen is positioned to the right of the main screen (i.e., if the mouse cursor moves out of the main display towards the right, it will enter the 3D display), but this can be changed if the physical setup is different by replacing "RightOf" with "LeftOf" in line 7 in the template configuration file. Apart from that, the configuration file needs to be adapted in the following ways:
Section "Device" Identifier "Videocard0" ... Option "ConnectedMonitor" "CRT-0, DFP-1" Option "UseDisplayDevice" "CRT-0" ... EndSection
Section "Device" Identifier "Videocard1" ... Option "ConnectedMonitor" "CRT-0, DFP-1" Option "UseDisplayDevice" "DFP-1" ... EndSection
If everything works, the operating system's login prompt, and the user's desktop after logging in, show up on the main display, while the 3D display only shows a background image. The mouse cursor can be moved between main display and 3D display, but windows can not (this is intentional). Running glxgears as glxgears -display :0.1 will show a window with three rotating gears on the 3D display instead of the main display.
The main benefit of using HDMI 1.4a stereo modes is that newer TVs automatically switch into 3D modes when receiving them, whereas other ways of generating stereo require some interaction by the user every time the TV is turned on. The main drawback of HDMI 1.4a stereo modes is that most TVs on the market today implement only the minimum required set of modes to qualify for the "HD 3D ready" sticker, and that those modes are not very useful for VR applications. For example, while there is a full-HD 1920x1080 stereo mode, current TVs only support it at 24Hz refresh rate, which is too low for serious use.
Note: As of Vrui version 1.0-068, the packaged Vrui.cfg configuration file already contains a template section for 3D displays (called section "3dtv.idav.ucdavis.edu"). Editing that section might get results more quickly, but we nonetheless recommend following the steps laid out here.
section "hostname.domainname" ... section Window display :0.1 windowFullscreen true windowType Mono screenName Screen viewerName Viewer toolKillZonePos (0, 0) endsection ... endsection
The above settings are for the recommended setup, where the 3D TV is handled as a separate X screen. It is possible to run the 3D TV in so-called "TwinView" mode, where the two displays form a single seamless virtual display and windows can be moved freely between the displays. While TwinView offers some benefits, we do not recommend it because it is less reliable. Depending on how the computer is started, and whether the 3D TV is turned on or off when the user logs in, the 3D TV might or might not be recognized automatically, or it might show up in different places relative to the main display. But if an advanced user wants to employ TwinView, the "Window" section has to be modified. The "display :0.1" and "windowFullscreen true" settings have to be removed, and the following settings have to be inserted:
section "hostname.domainname" ... section Window windowPos (<windowX>, <windowY>), (1920, 1080) decorate false endsection ... endsectionThe <windowX> and <windowY> values define the top-left corner of the display window, and, since TwinView defines a single virtual screen, depend on the exact TwinView setup, and the size of the main display. For example, if the 3D TV's display is positioned to the right of the main display, then <windowX> must be equal to the width of the main display. If the 3D TV is positioned to the left, <windowX> must be 0. <windowY> is typically 0 when the displays are positioned side-by-side, but this might be different when the main display's vertical resolution is higher than the 3D TV's. Stereo will not work correctly if the window positions are off by even one pixel. Caveat emptor.
windowType SplitViewportStereo
leftViewportPos (0, 540), (1920, 540) # Squish left frame by half and place it on top
rightViewportPos (0, 0), (1920, 540) # Squish right frame by half and place it on bottom
To enable side-by-side, the equivalent new settings are:
windowType SplitViewportStereo
leftViewportPos (0, 0), (960, 1080) # Squish left frame by half and place it on left
rightViewportPos (960, 0), (960, 1080) # Squish right frame by half and place it on right
Passive-stereo 3D TVs typically use row-interleaving, and some expose this stereo mode directly via row-interleaved stereo. If supported, this is the ideal mode for passive-stereo 3D TVs (the next best is top-bottom, see above). To select row-interleaved stereo, the windowType Mono setting in the above configuration file fragment has to be changed to:
windowType InterleavedViewportStereo
interleavePattern RRLL
The interleavePattern RRLL setting tells Vrui to interleave the left and right views row-by-row instead of the default checkerboard (which would be interleavePattern LRRL). If this pattern results in flipped stereo, replace with interleavePattern LLRR.
windowType SplitViewportStereo
leftViewportPos (0, 1125), (1920, 1080) # Place left frame on top of right frame and "active space"
rightViewportPos (0, 0), (1920, 1080) # Place right frame on bottom
![]() |
| Figure 1: The recommended physical coordinate system used throughout this guide. The origin is on the floor, directly underneath the center of the TV screen; the X axis points to the right when looking at the TV, the Y axis points into the TV, and the Z axis points up, forming a right-handed coordinate system. The unit of measurement in physical space is 1 inch. |
section "hostname.domainname" ... section Window # Disable automatic screen size determination: autoScreenSize false # Disable desktop-like behaviors: panningViewport false navigate false movePrimaryWidgets false endsection endsectionSince the above settings are the default values for their respective tags, the same effect can be achieved by simply removing these tags from the "Window" section.
The second step is to measure the 3D display's size, i.e., it's exact width and height. As a first approximation it is sufficient to measure the inside size of the display's bezel; however, because most projection TVs use significant overscan, the image is typically larger than that. To get accurate immersive display, especially after installing the optical tracking system, one needs to extrapolate the actual image size by measuring a calibration grid. This will be done very precisely, using a piece of survey equipment, in Step 8. Either way, the display's width and height have to be entered into the "Screen" section:
section "hostname.domainname" ... section Screen name Screen deviceMounted false origin (<displayX>, 0.0, <displayZ>) horizontalAxis (1.0, 0.0, 0.0) width <displayWidth> verticalAxis (0.0, 0.0, 1.0) height <displayHeight> endsection ... endsectionThis will define Vrui's physical coordinate system as follows: the X axis goes from left to right parallel to the 3D display's screen, the Z axis goes upwards parallel to the screen, and the Y axis goes into the screen. The physical coordinate units are whatever units are used to measure width and height (inches, meters, etc.). We recommend setting <displayX> and <displayZ> such that the coordinate system's origin is on the floor, directly below the center of the screen; i.e., <displayX> = -<displayWidth>/2 and <displayZ> = <height of display's lower edge above the floor> (but this is completely arbitrary, and will be changed later anyways when the optical tracking system is calibrated).
After the screen's dimensions have been defined, Vrui should be told the overall size of its display space. These settings are at the beginning of the environment's main section, and should be changed as follows:
section "hostname.domainname" ... inchScale <size of an inch in physical coordinates> meterScale <size of a meter in physical coordinates> displayCenter (0.0, 0.0, <height of display center>) displaySize <display radius> forwardDirection (0.0, 1.0, 0.0) upDirection (0.0, 0.0, 1.0) floorPlane (0.0, 0.0, 1.0), 0.0 ... newInputDevicePosition (0.0, -6.0, <height of display center>) ... frontplaneDist 1.0 backplaneDist 1000.0 ... endsection
section "hostname.domainname" ... section Viewer name Viewer headTracked false headDeviceTransformation translate (<viewerX>, <viewerY>, <viewerZ>) viewDirection (0.0, 1.0, 0.0) monoEyePosition (0.0, 0.0, 0.0) leftEyePosition (-<eyeSeparation>/2, 0.0, 0.0) rightEyePosition (<eyeSeparation>/2, 0.0, 0.0) headLightEnabled true headLightPosition (0.0, 0.0, 0.0) headLightDirection (0.0, 1.0, 0.0) headLightColor (1.0, 1.0, 1.0) headLightSpotCutoff 180.0 headLightSpotExponent 0.0 endsection ... endsection
After these changes, the stereoscopic display of Vrui application should look correct. When the viewer is in the configured position, cubes should appear as cubes (not stretched boxes), and spheres should appear as spheres (not ellipsoids).
section "hostname.domainname" ... glyphSize 0.333 ... uiSize 0.075 ... uiFontTextHeight 0.15 ... uiSliderWidth 0.225 ... endsectionThe uiFontTextHeight setting should be adapted until the fonts look "just right." After that, the uiSize should be set to half the font height, and the uiSliderWidth setting should be set to uiSize+uiFontHeight. The glyphSize setting defines the size of input device glyphs, such as the cones used for tracked input devices, or the wireframe boxes used for virtual input devices, and should be set to a comfortable size.
Similarly, depending on the 3D screen's configured size, the default mouse-based navigation tools might be too sensitive. Their behaviors can be configured via tool-specific sections in Vrui's tool section. To adjust the default mouse navigation tool ("Mouse (Multiple Buttons)"), create a new section with that tool class' internal name, MouseNavigationTool, somewhere in the Tools section:
section "hostname.domainname" ... section Tools ... defaultTools DefaultTools section MouseNavigationTool rotateFactor <rotate> rotatePlaneOffset <offset> scaleFactor <scale> endsection ... endsection ... endsectionIn this section, rotateFactor is the distance by which the mouse cursor has to be moved to rotate the view by one radians. By default, this is set to 3"; a larger value will make mouse rotation less sensitive. The value to choose is a matter of personal preference, and a comfortable value should be found by experimentation. The rotatePlaneOffset setting is a secondary value influencing navigation behavior (but hard to explain). For large (72") screens, it should be set to 6" instead of the default of 3". The scaleFactor setting is analogous to rotateFactor; it is the distance by which the mouse has to be moved along the scaling direction (up/down by default) to scale the view by a factor of e (2.71...); again, larger values will make scaling less sensitive.
On many 3D displays, the hardware mouse curser is distorted or "chopped up." This can be fixed by rendering a "fake" mouse cursor. In the mouse input device adapter's section, insert the following settings:
section "hostname.domainname" ... section MouseAdapter ... fakeMouseCursor true mouseCursorSize (<width>, <height>, 0.0) ... endsection endsectionThe mouseCursorSize setting is optional, and should be omitted initially. It can later be added to adjust the size of the cursor if it appears too large or too small. The cursor's width and height are defined in physical coordinate units.
Finally, the size of Vrui's "tool kill zone" (the red box in the lower-left hand corner of the screen) should be adjusted such that it is big enough to be found easily. The size is configured in the environment's tool section:
section "hostname.domainname" ... section Tools ... killZoneSize (<width>, 0.1, <height>) ... endsection ... endsectionThe width and height of the kill zone are given in physical coordinates, i.e., inches in the default setup. The kill zone should be comfortably big; for a 72" 3D TV, we recommend a width of 6" and a height of 3".
By default, the tool kill zone is placed in the lower-left hand corner of the screen. For right-handed users, it might be more comfortable to move it to the lower-right hand corner. To do so, edit the kill zone's position in the environment's window section:
section "hostname.domainname" ... section Window ... toolKillZonePos (<posX>, <posY>) ... endsection ... endsectionThe kill zone positions are relative to the screen. a <posX> of 0.0 corresponds to the left edge, 1.0 corresponds to the right edge. Analogously, a <posY> of 0.0 corresponds to the bottom edge, and 1.0 corresponds to the top edge. To move the kill zone to the lower-right hand corner, set its position to (1, 0).
An important decision is where to place the tracking cameras with respect to the 3D TV. An alternative blueprint for low-cost VR environments, the IQ-station, places the cameras on the edge or around the TV screen. Due to the small field of view of the cameras, this requires six cameras to create a sufficient tracking space. We recommend to mount the cameras on the ceiling or a wall above the 3D TV, which will lead to a large tracking volume and high-quality tracking using only three cameras (a $1500 savings). One recommended OptiTrack camera placement is shown in Figure 2; an alternative placement that works with lower ceilings, and can sometimes yield better tracking results, is shown in Figure 3.
![]() |
| Figure 2: One recommended camera placement for a three-camera NaturalPoint OptiTrack optical tracking system. The shown TV's diagonal is 72", and each camera's horizontal field of view is 45°. The vertical field of view of the cameras should not include the screen itself to reduce ghost tracking markers due to reflection, as shown in the side view. |
![]() |
| Figure 3: Alternative camera placement for a three-camera NaturalPoint OptiTrack optical tracking system for rooms with lower ceilings. The left and right cameras are pushed outwards by about 1-2 feet to increase the width of the tracking volume, and cover the entire TV screen. The extended stereo baseline yields more stable tracking, but the increased displacement between the cameras makes it harder to construct reliable tracking markers. The shown flat screen TV's diagonal is 70", and each camera's horizontal field of view is 45°. As in Figure 2, the vertical field of view of the cameras exactly grazes the screen's surface to prevent ghost tracking markers. |
OptiTrack allows assigning arbitrary names to defined rigid bodies, but we recommend naming the rigid body attached to the tracked 3D glasses "Head," and the one attached to the Wiimote "Wand." After all rigid bodies have been defined, OptiTrack's rigid body toolkit can be used to visually test the tracking quality. As all tracked devices are moved around in the tracking space, OptiTrack should be able to follow them, and tell them apart. If tracking fails, or OptiTrack has trouble telling the rigid bodies apart, it might be necessary to change the physical layout of the tracking antlers.
After initial setup, the following steps have to be performed each time OptiTrack's rigid body toolkit is started, before Vrui will be able to receive tracking data:
The template section contains comments indicating which settings have to be changed:
![]() |
| Figure 4: Diagram showing the overall structure of the device and driver setup. The Windows PC is connected to the OptiTrack cameras via USB, and is running the OptiTrack driver software. The Linux PC is connected to the Wiimote, and is running Vrui's own device driver (VRDeviceDaemon) and any Vrui applications. VRDeviceDaemon talks to OptiTrack's driver via the VRPN protocol, and to the Wiimote via Bluetooth. Vrui applications, and the DeviceTest utility, talk to VRDeviceDaemon via its own internal protocol. |
After VRDevices.cfg has been changed according to the preceding section, it is possible to start VRDeviceDaemon from a terminal window, without any command line arguments. Figure 5 shows a typical start-up sequence. Upon startup, VRDeviceDaemon will first try to connect to the OptiTrack rigid body toolkit, print some status information, and then try to connect to the Wiimote. At that point it will prompt the user to press buttons 1 and 2 on the Wiimote simultaneously to put the device into discovery mode. When the user presses these buttons (see important note below), the blue LEDs at the base of the Wiimote will start flashing. The number of flashing LEDs indicates the charge level of the battery (4 LEDs: full, 1 LED: almost empty). VRDeviceDaemon will try to connect to the Wiimote for 30 seconds after the prompt appears; if it cannot connect in that period, it will print an error message and terminate. If it connects successfully, VRDeviceDaemon will print the number of served trackers (should match the number of configured senders, e.g., 2 in the default configuration) and the number of buttons and valuators, which should be 13 and 2, respectively, for a Wiimote with optional Nunchuck attachment. Finally, it will print "Waiting for client connection" and wait for client connections.
Important Note: Pressing buttons 1+2 simultaneously no longer works with newer Wiimote models, particularly with the new Wiimote Plus that has an integrated MotionPlus extension. On these models, pressing 1+2 will put the Wiimote into temporary discovery mode, which requires using an authenticated Bluetooth protocol and does not work with VRDeviceDaemon. The new connection procedure is to press the red "sync" button hidden underneath the battery cover only for the first time a particular Wiimote is connected to VRDeviceDaemon, and press any single button (except the 1+2 combo) every time afterwards. This new procedure, which does not work with older Wiimotes, will bypass discovery mode and directly connect to the last Bluetooth host with which the Wiimote was connected, which takes much less time. In case the Wiimote is reset by pressing the 1+2 combo, of by being connected to a different Bluetooth host, the sync button has to be used again the next time it is connected to VRDeviceDaemon.
> VRDeviceDaemon VRDeviceDaemon: Reading configuration file VRDeviceDaemon: Initializing device manager VRDeviceManager: Loading device VRPN1 of type VRPNClient VRPNConnection: Checking server version number... done VRPNConnection: Server version is vrpn: ver. 07.15 VRPNClient: Initializing senders... done VRDeviceManager: Loading device Wiimote1 of type WiimoteTracker WiimoteTracker: Connecting to bluetooth device 00:1F:C5:21:CA:46. WiimoteTracker: Please press buttons 1 and 2 to initiate connection... done WiimoteTracker: Connected wiimote's battery level is 58% VRDeviceManager: Managing 2 trackers, 13 buttons, 2 valuators VRDeviceDaemon: Initializing device server VRDeviceServer: Waiting for client connection |
| Figure 5: Typical VRDeviceDaemon start-up sequence when started on-demand from a terminal window. When the "Please press buttons 1 and 2 to initiate connection..." prompt appears, the user has 30 seconds to do so or the driver will abort with an error message (but see the important note above). After the "Waiting for client connection" message appears, the driver is ready to serve tracking data to Vrui applications. |
DeviceTest <server host name>:<server port> [-t <tracker index>] [-alltrackers] [-p | -o | -f | -v] [-b]
It is important to ensure that the tracking results reported by VRDeviceTest roughly match the expected behavior. I.e., when moving a tracked device to the right, the X coordinate of its position should increase; when moving it up, the Z coordinate should increase. When a device is moved close to the center of the screen, its displayed position should roughly match the screen center as configured in Vrui.cfg.
section "hostname.domainname" ... inputDeviceAdapterNames (MouseAdapter) ... endsectionand replace it with
section "hostname.domainname" ... inputDeviceAdapterNames (MouseAdapter, DeviceDaemonAdapter) ... endsectionThen, find section MouseAdapter, and, after it, insert a new section DeviceDaemonAdapter:
section "hostname.domainname" ... section MouseAdapter ... endsection section DeviceDaemonAdapter inputDeviceAdapterType DeviceDaemon serverName "hostname.domainname" serverPort 8555 inputDeviceNames (Head, Wand) section Head name Head trackType 6D trackerIndex 0 endsection section Wand name Wand trackType 6D trackerIndex 1 numButtons 13 buttonIndexBase 0 numValuators 2 valuatorIndexBase 0 deviceGlyphType Cone endsection endsection ... endsection
This change will create two new 3D input devices, one ("Head") representing the tracked 3D glasses, and the other ("Wand") representing the Wiimote, including its buttons and the (optional) joystick in the Nunchuck extension. The next steps are to tell Vrui to use the Head device for head tracking, and to attach some default interaction tools to the Wand device.
section "hostname.domainname" ... section Viewer ... headTracked false ... endsection ... endsectionand replace the headTracked setting with
section "hostname.domainname" ... section Viewer ... headTracked true headDevice <head device name> ... endsection ... endsectionwhere <head device name> is the name of the input device attached to the tracked 3D glasses as configured above, i.e., Head in the recommended configuration.
section "hostname.domainname" ... section Tools ... toolClassNames (..., \ WalkSurfaceNavigationTool, \ ScaleNavigationTool, \ ValuatorScalingNavigationTool, \ WandNavigationTool, \ SixDofWithScaleNavigationTool, \ TwoHandedNavigationTool, \ MultiDeviceNavigationTool, \ FlyNavigationTool, \ ValuatorFlyNavigationTool, \ ValuatorTurnNavigationTool, \ ValuatorFlyTurnNavigationTool, \ WalkNavigationTool, \ ForceJumpNavigationTool) ... endsection ... endsectionVrui allows to dynamically attach user interation tools to input devices, but it is useful to have a set of default tools that is available as soon as a Vrui application starts. Default tool assignments are listed as individual sections underneath the DefaultTools section inside an environment's Tools section. Each section defines one tool, and sections are processed in the order in which they are listed. Find the DefaultTools section
section "hostname.domainname" ... section Tools ... section DefaultTools ... endsection ... endsection ... endsectionand insert three new sections after section MenuTool as follows:
section "hostname.domainname" ... section Tools ... section DefaultTools ... section MenuTool ... endsection section WandNavTool toolClass WandNavigationTool bindings ((<wand device name>, Button3, Button8)) endsection section WandGUITool toolClass WidgetTool bindings ((<wand device name>, Button8)) endsection section WandMenuTool toolClass RayMenuTool bindings ((<wand device name>, Button8)) endsection endsection ... endsection ... endsectionwhere <wand device name> is the name of the wand device as configured in the DeviceDaemonAdapter section.
After these changes, Vrui should render head-tracked stereo, i.e., the image on the screen should change as the tracked 3D glasses are moved in the tracking space, and it should display a grey cone roughly following the motions of the Wiimote. When pressing the arrow down button on the Wiimote, a Vrui application's main menu should be displayed, and when pressing the "A" button, the 3D model displayed by an application can be moved in position and orientation. Pressing first the "A" button, and then the arrow down button while holding the "A" button allows to increase or decrease the size of the displayed model by moving the Wiimote forward or backwards.
The first step happens in the root section. After the screenNames setting, insert a screenProtectors setting as follows:
section "hostname.domainname" ... screenNames (...) screenProtectors ( (<head device name>, (0.0, 0.0, 0.0), 24.0), \ (<wand device name>, (0.0, 0.0, 0.0), 6.0) ) ... endsectionEach item in the screenProtectors list defines a sphere around an input device. The input device is identified by its name (such as "Head" or "Wand"), and the sphere is defined by its center point in the device's local coordinate system, and its radius in physical coordinate units. The settings here, assuming Vrui uses inches as physical coordinate units, define a sphere of radius 24 inches around the head device's origin, and a sphere of radius 6 inches around the wand device's origin. For 3D TVs, where users typically sit very close to the screen, the wand sphere's radius can be reduced, say to 4 inches. This is a matter of taste and experimentation. The radius needs to be large enough such that the screen saver grid can be displayed early enough to prevent the user from hitting the screen with the wand device, based on the user's typical reaction time and maximum speed of moving the wand.
The second step happens in the window section. The protectScreens setting needs to be set to true if it exists, or needs to be removed (the setting defaults to true):
section "hostname.domainname" ... section Window ... protectScreens true ... endsection ... endsection
Unfortunately, performing this first calibration properly requires a 3D measuring device, which can accurately measure the 3D positions of arbitrary points in space, such as a geodetic theodolite with a laser range finder (a so-called "Total Station"). If such a device is available, Vrui contains three calibration utilities that more or less automate the process. A user simply has to measure a set of regularly placed points on the 3D display's screen (to measure its size and position in space), and then measure the positions of a set of tracking markers which are captured at the same time by the OptiTrack system.
First, the XBackground utility is run to show a regular grid on the 3D TV:
XBackground -display :0.1 -type 2 -size 300The argument after -display indicates on which screen to show the calibration grid. In the recommended setup, the 3D TV corresponds to display :0.1. The argument after -size specifies the grid spacing in pixels. 300 is a good compromise between effort and precision for 3D TVs running at a resolution of 1920x1080 pixels. Important note: The 3D TV needs to be switched out of 3D mode when XBackground is run, to avoid a distortion of the grid. When properly set up, all grid cells should appear exactly square.
Then, MeasureEnvironment itself is run:
MeasureEnvironment -t <serial port name> -npc <OptiTrack server name> -rootSection Desktop<serial port name> is the name of the serial port connected to the Total Station, e.g., /dev/ttyUSB0, and <OptiTrack server name> is the host name or IP address of the Windows computer running the OptiTrack software. As built, the Natural Point client only works with the new OptiTrack (Tracking Tools) software. Connecting it to the older (Rigid Body Toolkit) software requires one small change in the source code. The -rootSection Desktop setting tells Vrui to run the application in desktop mode on the computer's main display instead of the 3D TV. The recommended measurement process is described in detail on the utility's manual page. MeasureEnvironment will save all recorded points upon exit, but it is recommended to save the current point set at multiple points in the procedure, and at least after completing each stage, to minimize data loss.
ScreenCalibrator -screenSize 1920 1080 -squareSize 300 -metersToInches MeasuredPoints.csv TrackingPoints.csv -rootSection DesktopThe -screenSize argument specifies the size of the 3D TV screen in pixels. 1920 1080 is the standard resolution of 3D TVs. The -squareSize argument specifies the size of the calibration grid in pixels; this value must match the same value given on XBackground's command line. -metersToInches instructs ScreenCalibrator to automatically convert all measurements from meters, which is the default unit of measurement both for the Total Station and OptiTrack, to inches, which is Vrui's physical measurement unit used in this guide. If a different measurement unit was chosen, the -metersToInches argument needs to be replaced with -unitScale <scale>, where <scale> is the conversion factor from meters to the chosen unit. If Vrui's unit is meters, the argument is -unitScale 1.0, if it is centimeters, it is unitScale 100.0, if it is inches, it is -unitScale 39.37007874, or simply -metersToInches. MeasuredPoints.csv is the default name of the file containing Total Station measurements, and TrackingPoints.csv is the default name of the file containing OptiTrack measurements, when using the NaturalPoint client. -rootSection Desktop again instructs Vrui to run the application on the main display in desktop mode.
When ScreenCalibrator is started, it immediately calculates the screen transformation, i.e., the position, orientation, and exact size of the 3D TV, and the tracking transformation, i.e., the conversion from OptiTrack coordinates to Vrui coordinates. ScreenCalibrator's display will show the collected measurement points (floor points in red, screen points in green, ball points in purple and OptiTrack points in yellow). It will show the best-fitting rectangular screen in green, and the best-fitting projective (keystone-corrected) screen in blue. For flat-screen 3D TVs, the green and blue quadrilaterals will be almost exactly the same; for projection-based TVs, there might be significant differences due to internal keystone distortion. The configuration settings returned by ScreenCalibrator will undo that distortion as much as possible. If there is a significant difference between the green and blue quadrilaterals for a flat-screen TV, something probably went wrong during measurement. Finally, ScreenCalibrator will show the alignment quality of the optical tracking system by drawing yellow/purple lines connecting each pair of associated ball and tracking points. In a good configuration, these lines should be invisible at a scale where the entire screen is visible, because the aligned 3D coordinates will match almost exactly. Lines will only show up when zooming into individual point pairs. If there are visible alignment lines, both OptiTrack's intrinsic calibration procedure and the environment measurement steps should be repeated.
The result of running ScreenCalibrator are two sets of Vrui settings. The first set describes the exact size and position of the 3D display's screen, including keystone correction, and needs to be pasted into Vrui.cfg, in the environment's Screen section. The second set is a global transformation from OptiTrack space to Vrui space, and needs to be pasted into VRDevices.cfg, in the environment's Calibrator section. Both sets of settings assume the "standard" 3D TV setup, where the screen is centered above the origin, and more or less aligned to the (x, z) plane, with the y axis pointing into the screen. If Vrui's environment was set up using a different coordinate system, the values returned by ScreenCalibrator will not work directly and need to be transformed manually.
origin (-31.638, 0.151329, 29.0991)
horizontalAxis (1, -0.000486263, -0.000351728)
width 63.277
verticalAxis (0.00034805, -0.00754295, 0.999971)
height 35.7028
offAxis true
homography ( ( 31.7043, 0.00439951, -0.000280895 ), \
( 0.16926, 18.0794, 0.00544898 ), \
( 31.6448, 17.8926, 1 ) )
These settings replace the settings of the same names in the environment's Screen section in Vrui.cfg, i.e., the Screen section becomes:
section "hostname.domainname" ... section Screen name Screen deviceMounted false origin (-31.638, 0.151329, 29.0991) horizontalAxis (1, -0.000486263, -0.000351728) width 63.277 verticalAxis (0.00034805, -0.00754295, 0.999971) height 35.7028 offAxis true homography ( ( 31.7043, 0.00439951, -0.000280895 ), \ ( 0.16926, 18.0794, 0.00544898 ), \ ( 31.6448, 17.8926, 1 ) ) endsection ... endsectionThe homography setting defines the keystone correction factors appropriate for the used 3D TV. These are from a 72" DLP projection TV with noticeable distortion; for modern flat screen (LED/LCD/Plasma) TVs, the homography matrix should be very close to a scaling and translation matrix.
transformation translate (-0.122542, -9.505, 1.65272) \
* scale 39.3701 \
* rotate (0.00461419, -0.696002, -0.718025), 179.689
This setting replaces the setting of the same name in the environment's Calibrator section in VRDevices.cfg, i.e., the Calibrator section becomes:
section "hostname.domainname" ... section DeviceManager ... section VRPN1 ... section Calibrator transformation translate (-0.122542, -9.505, 1.65272) \ * scale 39.3701 \ * rotate (0.00461419, -0.696002, -0.718025), 179.689 endsection ... endsection ... endsection ... endsection
Vrui contains a calibration application, AlignTrackingMarkers, to create such local coordinate transformations. When using an old version of the OptiTrack software (the "rigid body toolkit"), it reads the rigid body definition file created by OptiTrack (file extension .rdef), and allows the user to visually adjust the local coordinate systems as desired. With the newer "tracking tools" version of the OptiTrack software, AlignTrackingMarkers connects directly to the running OptiTrack software, and then offers the same visual interface. The AlignTrackingMarkers application is described in detail on the Calibration Utilities page. Because the application works best in desktop mode, it should be run with the -rootSection Desktop additional command line option. For old (rigid body toolkit) OptiTrack:
AlignTrackingMarkers -inches <OptiTrack .rdef file name> <rigid body name> -rootSection DesktopFor new (tracking tools) OptiTrack:
AlignTrackingMarkers -inches -npc <OptiTrack server name> <rigid body ID> -rootSection DesktopBoth command lines assume that Vrui has been configured to use inches as physical measurement units. If that is not the case, refer to the Calibration Utilities page. The <rigid body name> in the first line is the alphanumeric name assigned to the rigid body in OptiTrack (such as "Head" or "Wand"). The <OptiTrack server name> in the second line is the host name or IP address of the Windows computer running the OptiTrack software, and the <rigid body ID> is the numerical ID assigned to the rigid body inside OptiTrack. For the direct connection to work, UDP ports 1510 and 1511 must be opened on the Linux computer's firewall, and the two computers must be able to send multicast packets to each other. In practice, this means they need to be connected to the same network switch.
Finally, the Tracking Tools software won't stream rigid body model data to clients unless it can see the rigid body. This means that, before starting AlignTrackingMarkers for a rigid body, that body must be placed in the field-of-view of the tracking cameras, ideally on a stable surface.
For hand-held input devices such as the Wiimote, the origin of the coordinate system defines the "hot spot" for interactions. It should therefore be in an obvious and easily-observed position. Most users will use the physical input device itself to judge where they are grabbing virtual space, without specifically looking for the virtual cone representing the device's position in virtual space. For example, in a tracking antler arrangement like the one shown in Figure 6, the origin should be in the center of the most forward-pointing reflective marker. The Y axis is the input device's major pointing direction, i.e., menu selection and GUI interaction rays will by default point along the Y axis. Therefore, the axis should point straight forward from the device. The X axis should point to the right, and the Z axis will then point straight up.
![]() |
| Figure 6: "Canonical" layout of local coordinate systems for head-tracked glasses and tracked Wiimote. The glasses are drawn from the front, which is why the X axis is going to the left (when put on, the X axis points to the right). The coordinate system origin on the Wiimote is chosen such that it is easiest to interact with virtual objects in the environment. |
Final transformation: translate (-0.096585, -1.048017, 0.367297) * rotate (-0.179350, -0.866056, -0.466668), 140.707679To apply it, open VRDevices.cfg and find the environment's main section:
section "hostname.domainname" ... section DeviceManager ... section VRPN1 ... # Enter calibration transformations for the rigid bodies here trackerPostTransformation0 translate (0.0, 0.0, 0.0) \ * rotate (1.0, 0.0, 0.0), 0.0 trackerPostTransformation1 translate (0.0, 0.0, 0.0) \ * rotate (1.0, 0.0, 0.0), 0.0 ... endsection ... endsection ... endsectionThen replace the appropriate trackerPostTransformation, i.e., trackerPostTransformation0 for the tracked 3D glasses and trackerPostTransformation1 for the Wiimote, with the final transformation (the output after "Final transformation:"). Assuming that AlignTrackingMarkers above was run for the Head rigid body, the result would be:
section "hostname.domainname" ... section DeviceManager ... section VRPN1 ... # Enter calibration transformations for the rigid bodies here trackerPostTransformation0 translate (-0.096585, -1.048017, 0.367297) \ * rotate (-0.179350, -0.866056, -0.466668), 140.707679 trackerPostTransformation1 translate (0.0, 0.0, 0.0) \ * rotate (1.0, 0.0, 0.0), 0.0 ... endsection ... endsection ... endsection(Backslashes can be used in configuration files to break long values over multiple lines.)
section "hostname.domainname" ... section Viewer ... monoEyePosition (<monoX>, <monoY>, <monoZ>) ... leftEyePosition (<leftX>, <leftY>, <leftZ>) rightEyePosition (<rightX>, <rightY>, <rightZ>) ... headLightPosition (<monoX>, <monoY>, <monoZ>) ... endsection ... endsection(<leftX>, <leftY>, <leftZ>) and (<rightX>, <rightY>, <rightZ>) are the 3D positions of the viewer's left and right eyes, respectively, in the head tracker's local coordinate system, i.e., relative to its origin and along its axes. In the canonical head tracker coordinate system layout, <leftX> is typically equal to -<rightX> and <leftY> = <rightY> and <leftZ> = <rightZ>. The monoEyePosition and headLightPosition tags should be set to the midpoints of the line connecting the left and right eye positions. In the canonical head tracker coordinate system layout, this typically means <monoX> = 0 and <monoY> = <leftY> = <rightY> and <monoZ> = <leftZ> = <rightZ>.
As it is typically difficult to measure a viewer's eye positions precisely, it is usually necessary to judge the alignment result visually and adjust the positions until the alignment is sufficiently good. Vrui contains a utility for this purpose, VruiCalibrator in the ExamplePrograms subdirectory. On startup, VruiCalibrator displays a wireframe cube in the center of the display, and a coordinate frame for each tracked device, drawn as a red line parallel to the device's X axis, a green line parallel to the Y axis, and a blue line parallel to the Z axis. The intersection of the three lines indicates the coordinate system's origin. The process is to put on the head-tracked glasses, and hold a tracked device in front of the display. Ideally, the three lines' intersection should always exactly coincide with the device's hot spot, e.g., with the most forward-facing reflective ball, no matter where the device is moved and how it is oriented.
| Figure 7: Video showing 3D Visualizer on our 72" projector-based 3D TV to visualize and analyze an X-ray computed tomogram of a patient's head. Notice how the grey cone indicating the Wiimote's position exactly follows the physical Wiimote, or, more precisely, the top sphere in its tracking antler, which was configured as its center point. The slight delay between motions of the physical Wiimote and its cone is due to the low performance of the (cheap) Windows computer running the tracking software. Instead of the theoretical maximum of 100 samples per second, it can only achieve around 40 samples/second. |