cgv
|
The VR support distributed over several libraries and plugins. The following list gives a brief overview:
<cgv/libs/vr>
basic interface to implement vr apps that is independent of cgv framework and specific vr api. It builds on the concept of a driver that provides instances of vr kits and supports calibration through a calibration matrix. There can be several drivers in use at the same time. A simple registry is used to manage drivers and vr kits. The vr_kit class provides access to the display and the controllers with a simple state polling api.
<cgv/3rd/openvr>
a copy of the openvr library such that it compiles within the build system of the framework. There is one change to support compilation with unicode characters under windows.
<cgv/plugins/openvr_driver>
implements the vr interface for the openvr api. The only thing that needs to be done is to add the openvr_driver
plugin as dependent project in the .pj-file.
Currently, under windows steam vr changes the framebuffer type to non sRGB. Then the gamma correction needs to be set to 1.0f with cgv::render::context::set_gamma(1.0f) instead of the standard value of 2.2f. As this happens even if no vr device is attached.
One can define the option CGV_OPTIONS=NO_OPENVR
when one is not using a vr kit. Then openvr is not initialized by the openvr driver.
<cgv/test/vr>
Plugin that implements a vr driver emulating one or several vr kits that can be controlled with keyboard. More information on its usage can be found in Emulation of Virtual VR Kits.
<cgv/plugins/cg_vr>
This plugin connects <cgv/libs/vr>
to <cgv/gui>
by translating changes in the vr kit states into events dispatched though the cgv::gui::event_handler interface. The central class for this is cgv::gui::vr_server. Please see its documentation. VR events are declared in the cgv/plugins/cg_vr/vr_events.h header and marked with the cgv::gui::EF_VR event flag.
<cgv/plugins/crg_vr_view>
This plugin extends the stereo_view_interactor class of the crg_stereo_view plugin with vr support to the vr_view_interactor class. It connects to the on_device_change signal of the cgv::gui::vr_server singleton and keeps track of device changes in order to initialize and destruct their framebuffers in the opengl context of the vr_view_interactor.
It keeps a current vr_kit which can be selected with {Ctrl-Alt-0..3}
or through the user interface. It can render vr kits with meshes and or with spheres representing eyes and controllers. If the meshes are not provided in the CGV_DATA
path and in Debug configuration the sphere rendering is the default.
Furthermore, the action zone boundaries can be rendered as a dashed fence. It can also debug all emitted vr events in the text console window. The vr_view_interactor manages its own view which can be controlled with the mouse as in the case of the stereo_view_interactor.
Further rendering passes are issued to render from the views of the hmds of the present vr kits. The current vr kit states are queried with pose_query=2
for the currently selected vr kit and with pose_query=1
for the others. The rendered vr views are submitted to the hmds and can optionally blit in the current framebuffer. The queried states are dispatched in the cgv::gui::vr_server singleton with the cgv::gui::vr_server::check_new_state() function such that you should use the second or third option descripted in the detailed documentation of the cgv::gui::vr_server.
The vr_view_interactor provides the following configuration methods:
All vr events provide information on the state of the vr_kit that generated the event. Further convenience functions that can be called also during the draw process are
<cgv/plugins/vr_test>
an advanced example of how to use the vr in the cgv framework that includes picking and grabbing of boxes through controller rays and a touch of the controller touchpad, offline text rendering to display an information board and rendering a polygonal mesh (currently the file name is hard coded and needs to be changed in the code to some local meshes)
Each vr driver has an optional 3x4 matrix to transform all tracked poses. The transformation can be enabled with vr::vr_driver::enable_calibration_transformation() and disabled with vr::vr_driver::enable_calibration_transformation(). One can query the current transformation matrix with vr::vr_driver::put_calibration_transformation(). Setting the calibration matrix is restricted to classes derived from vr::vr_calibration_base.
Typically, one does not deal with the calibration matrix directly, but uses the functionality implemented in vr_view_interactor. To define the calibration matrix in a way that the coordinates of the tracking system align with the physical world, one follows the following procedure:
{Shift-Ctrl-0..3}
with the number key corresponding to the controller index (you can also use a tracker for calibration). Then vr_view_interactor sets its calibration location vectors and update and enable the calibration matrix of the current vr driver such that tracked position of the calibrated controller matches the position of the focus point in the virtual scene[vr interactor]
tab and open the [VR calibration]
UI node. Adjust the [tracking_rotation]
slider to match the 2D rotation of the virtual controller and the physical controller. The vr_view_interactor always updates the driver calibration matrix when this rotation angle is changed.[calibration_file_path]
. Please choose .cal
as extension.To automatically read your calibration at program start add the following line to your .pj
-file:
type(vr_view_interactor):calibration_file_path="D:/develop/table.cal"
When you add the plugin <cgv/test/vr/vr_emulator.pj>
to the list of dependent projects in your .pj
-file:
addProjectDeps = [ ... , "vr_emulator", ... ]; addProjectDirs = [ ... , CGV_DIR."/test/vr", ... ];
the plugin automatically creates an instance of the vr_emulator
class that generates a new tabgroup in the UI and handles keyboard shortcuts. You can configure the vr_emulator
instance in your configuration file. See cgv/test/vr/config.def
for a documented list of possible configurations, which include creation of vr kits at program start.
After program start you can create a new vr_kit with the shortcut {Ctrl-Alt-N}
.
Each vr_kit is controlled by a very simple model of the human body that can move and turn, bend the hip forward/backward, turn the head left or right (yaw) and move each hand in a local 3D coordinate system with origin in the corresponding shoulder and oriented as the hip coordinate system.
To control the body model the vr_emulator allows to use the keys {0}
, {1}
, {2}
, and {3}
as modifier keys to control up to 4 vr_kits with the keyboard. The arrow keys allow to move and rotate. {PgUp}
and {PgDn}
control hip bending and {Home}
and {End}
yawing.
The controller keys of each kit are can be toggled with the following keys pressed while holding the modifier key ({0 .. 3}
) of the vr kit:
{W}
... left menu button{X}
... left grip button{Q}
... left system button{E}
... left A button{A}
... left pad touch{S}
... left pad press{I}
... right menu button{O}
... right grip button{U}
... right system button{B}
... right A button{J}
... right pad press{K}
... right pad touchTo make sure that all keys are dispatched by vr_emulator
, select it for keyboard focus with the tab key or by selecting its tab group.
The most convenient approach to use vr in a cgv application is through the plugin <cgv/plugins/crg_vr_view>
which replaces the plugin <cgv/plugins/crg_stereo_view>
of a none vr application. To get access to vr kits you need the plugin <cgv/plugins/openvr_driver>
to use openvr and or <cgv/test/vr_emulator>
to use the vr emulation. Finally, you need to include the libraries <cgv/libs/vr>
and <cgv/libs/cg_vr>
.
To implement your application main class, e.g. vr_viewer, derive it as usual from cgv::base::node, cgv::render::drawable, cgv::gui::event_handler, and optionally from cgv::gui::provider if you want to provide a classic UI.
You typically enable and configure VR in your drawable::init method by connecting the cgv::gui::vr_server singleton to the event processing of the main window and telling the cgv::render::vr_view_interactor instance which vr events should be generated and how the main rendering window should be configured. In <cgv/plugins/vr_test>
you can find an example where the following code fragments are important:
For the includes you need to add the following include paths in your .pj file:
addIncDirs=[INPUT_DIR, CGV_DIR."/libs", CGV_DIR."/test"];
If you have enabled the device (cgv::gui::VRE_DEVICE) and status (cgv::gui::VRE_STATUS) events, you can set special callbacks to get informed of device changes and changes of the tracking and attachement status of hmds, controllers and trackers. This can already be prepared in your constructor:
These callbacks are implemented like this:
The vr events are dispatched through your handle method and where you can ensure that you only process vr events by
For examples of how to process vr events please checkout <cgv/plugins/vr_test/vr_test.cxx>
.
To get device information of the vr kit and its attached controllers and trackers, the vr::vr_kit class provides the vr::vr_kit::get_device_info() function that stores all static device information. The information on controllers and trackers is filled when they are attached, what can change during program execution. Information on not attached controllers and trackers might be invalid. The attachment status can be tracked in the status events and is also accessible in all vr events through the get_state() function, e.g. cgv::gui::vr_key_event::get_state(). When browsing the documentation on the vr::vr_kit_info class, always check also the inheritance hierarchy as for example the serial number is available for all derived device classes from the vr::vr_device_info class.