Magnum::OvrIntegration::Session class

Session.

Wraps ovrSession, ovrHmdDesc and methods from the Oculus SDK which directly affect an HMD and its properties.

Usage

Instances of Session are created by Context.

std::unique_ptr<Session> session = Context::get().initialize().createSession();
session->configureRendering();

// ...

Once the HMD is configured, you can poll and get the head pose.

std::unique_ptr<DualQuaternion> poses = session->pollEyePoses().eyePoses();

DualQuaternion leftPose = poses.get()[0];
DualQuaternion rightPose = poses.get()[1];

Rendering to the HMD

Rendering to an HMD is done via the Compositor. It's results are rendered directly to the Rift. The compositor layers usually require you to render to a set of textures which are then rendered to the rift with distortion, chromatic abberation and possibly timewarp.

A setup for such a TextureSwapChain for an eye could look like this:

const Int eye = 0; // left eye
Vector2i textureSize = session.fovTextureSize(eye);
std::unique_ptr<TextureSwapChain> swapChain = session.createTextureSwapChain(textureSize);

// create the framebuffer which will be used to render to the current texture
// of the texture chain later.
Framebuffer framebuffer{{}, textureSize};
framebuffer.mapForDraw(Framebuffer::ColorAttachment(0));

// setup depth attachment
Texture2D* depth = new Texture2D();
depth->setMinificationFilter(Sampler::Filter::Linear)
      .setMagnificationFilter(Sampler::Filter::Linear)
      .setWrapping(Sampler::Wrapping::ClampToEdge)
      .setStorage(1, TextureFormat::DepthComponent24, textureSize);

// ...

// switch to framebuffer and attach textures
framebuffer.bind();
framebuffer.attachTexture(Framebuffer::ColorAttachment(0), _textureChain->activeTexture(), 0)
           .attachTexture(Framebuffer::BufferAttachment::Depth, *depth, 0)
           .clear(FramebufferClear::Color | FramebufferClear::Depth);

// ... render scene

// commit changes to the TextureSwapChain
swapChain->commit();

framebuffer.detach(Framebuffer::ColorAttachment(0))
           .detach(Framebuffer::BufferAttachment::Depth);

Usually, especially for debugging, you will want to have a mirror of the Compositor result displayed to a window.

Texture2D& mirrorTexture = session->createMirrorTexture(resolution);
Framebuffer mirrorFramebuffer{Range2Di::fromSize({}, resolution)};
mirrorFramebuffer.attachTexture(Framebuffer::ColorAttachment(0), mirrorTexture, 0)
                 .mapForRead(Framebuffer::ColorAttachment(0));

// ...

// blit mirror texture to defaultFramebuffer.
const Vector2i size = mirrorTexture->imageSize(0);
Framebuffer::blit(mirrorFramebuffer,
                  defaultFramebuffer,
                  {{0, size.y()}, {size.x(), 0}},
                  {{}, size},
                  FramebufferBlit::Color, FramebufferBlitFilter::Nearest);

Public functions

auto configureRendering() -> Session&
Configure rendering to the Rift.
auto fovTextureSize(Int eye) -> Vector2i
Get preferred size for textures used for rendering to this HMD.
auto createMirrorTexture(const Vector2i& size) -> GL::Texture2D&
Create a mirror texture.
auto createTextureSwapChain(Int eye) -> std::unique_ptr<TextureSwapChain>
Convenience method to create a TextureSwapChain for this HMD.
auto createTextureSwapChain(const Vector2i& size) -> std::unique_ptr<TextureSwapChain>
Create a TextureSwapChain for this HMD.
auto headPoseState() const -> const PoseState&
Get the current tracked head pose as a PoseState.
auto calibratedOrigin() const -> DualQuaternion
The pose of the origin captured during calibration.
auto eyePoses() const -> std::array<DualQuaternion, 2>
Get transformation for the eyes since last Session::pollEyePoses() call.
auto handPoseStates() const -> std::array<std::reference_wrapper<const PoseState>, 2>
Get the transformation of hand trackers since last Session::pollTrackers() call.
auto pollTrackers() -> Session&
Refresh cached tracking state.
auto pollEyePoses() -> Session&
Refresh cached eye poses.
auto pollController(ControllerType types, InputState& state) -> Session&
Get input state of given controller type.
auto resolution() const -> Vector2i
Resolution of the HMD's display.
auto defaultEyeFov(Int eye) const -> Vector2
Tan of the FoV for an eye.
auto projectionMatrix(Int eye, Float near, Float far) const -> Matrix4
Get the projection matrix.
auto orthoSubProjectionMatrix(Int eye, const Matrix4& proj, const Vector2& scale, Float distance) const -> Matrix4
Get a projection matrix for projection to an orthogonal plane.
auto ovrSession() const -> ::ovrSession
Get the underlying ovrSession
auto ovrHmdDesc() const -> ::ovrHmdDesc
Get the underlying ovrHmdDesc
auto ovrViewScaleDesc() const -> const ::ovrViewScaleDesc&
Get the underlying ovrViewScale
auto worldScale() const -> Float
World scale (in meters per unit)
auto setWorldScale(Float scale) -> Session&
Set world scale.
auto isDebugHmd() const -> bool
Whether this HMD is a connection to a virtual or real device.
auto ovrEyePoses() const -> const Containers::StaticArrayView<2, const ovrPosef>
Get a pointer to the most current eye poses as ovrPosef
auto ovrHandPoseStates() const -> const Containers::StaticArrayView<2, const ovrPoseStatef>
ovrHandPoseStates
void recenterTrackingOrigin() const
Re-centers the sensor position and orientation.
void setTrackingOrigin(TrackingOrigin origin) const
Sets the tracking origin type.
void clearShouldRecenterFlag() const
Clear SessionStatusFlag::ShouldRecenter.
auto currentFrameIndex() const -> Long
Get the current frame index.
auto incFrameIndex() -> Long
Increment the frame index.
void setPerformanceHudMode(PerformanceHudMode mode) const
Set performance HUD mode.
void setDebugHudStereoMode(DebugHudStereoMode mode) const
Set debug HUD Setero Mode.
void setLayerHudMode(LayerHudMode mode) const
Set layer HUD mode.
auto trackingState() const -> StatusFlags
Tracking state.
auto user() const -> std::string
Name of the active Oculus profile.
auto playerName() const -> std::string
Name set in the active Oculus profile.
auto playerGender() const -> std::string
Gender set in the active Oculus profile.
auto playerHeight() const -> Float
Player height set in the active Oculus profile.
auto eyeHeight() const -> Float
Eye height set in the active Oculus profile.
auto neckToEyeDistance() const -> std::array<Float, 2>
Neck to eye distance set in the active Oculus profile.
auto eyeToNoseDistance() const -> std::array<Float, 2>
Eye to node distance set in the active Oculus profile.
auto status() const -> SessionStatusFlags
Status of the OVR session.

Function documentation

Session& Magnum::OvrIntegration::Session::configureRendering()

Configure rendering to the Rift.

Returns Reference to self (for method chaining)

Includes setting up HMD to eye offsets internally.

Vector2i Magnum::OvrIntegration::Session::fovTextureSize(Int eye)

Get preferred size for textures used for rendering to this HMD.

Parameters
eye Eye index to get the texture size for

GL::Texture2D& Magnum::OvrIntegration::Session::createMirrorTexture(const Vector2i& size)

Create a mirror texture.

Parameters
size Size for the mirror texture
Returns Reference to the created mirror texture. Its destruction is handled by the Session.

The libOVR compositor will render a copy of its result to the texture returned by this method.

std::unique_ptr<TextureSwapChain> Magnum::OvrIntegration::Session::createTextureSwapChain(Int eye)

Convenience method to create a TextureSwapChain for this HMD.

Parameters
eye Eye index which will be used to get the preferred size for the texture.

std::unique_ptr<TextureSwapChain> Magnum::OvrIntegration::Session::createTextureSwapChain(const Vector2i& size)

Create a TextureSwapChain for this HMD.

Parameters
size Size for the textures in the created set

DualQuaternion Magnum::OvrIntegration::Session::calibratedOrigin() const

The pose of the origin captured during calibration.

Returns the origin of recentered space. As long as Session::recenterTrackingOrigin() has not been called, this method returns an identity transformation.

std::array<DualQuaternion, 2> Magnum::OvrIntegration::Session::eyePoses() const

Get transformation for the eyes since last Session::pollEyePoses() call.

Returns array of two DualQuaternions describing tranformation and orientation of each eye.

std::array<std::reference_wrapper<const PoseState>, 2> Magnum::OvrIntegration::Session::handPoseStates() const

Get the transformation of hand trackers since last Session::pollTrackers() call.

Returns array of two PoseStates describing tranformation and orientation of each hand. The first referring to the left hand, the second referring to the right hand.

Session& Magnum::OvrIntegration::Session::pollTrackers()

Refresh cached tracking state.

Returns Reference to self (for method chaining)

Use eyePoses() to access the result.

Session& Magnum::OvrIntegration::Session::pollEyePoses()

Refresh cached eye poses.

Returns Reference to self (for method chaining)

Use eyePoses() to access the result. Calls pollTrackers(). Call pollTrackers() directly, if you do not need to calculate the eye poses.

Session& Magnum::OvrIntegration::Session::pollController(ControllerType types, InputState& state)

Get input state of given controller type.

Parameters
types Controller type to get the input state of
state Receives the resulting input state
Returns Reference to self (for method chaining)

Vector2 Magnum::OvrIntegration::Session::defaultEyeFov(Int eye) const

Tan of the FoV for an eye.

Parameters
eye Eye index

Returns vector of eye FoVs, x being horizontal and y vertical.

Matrix4 Magnum::OvrIntegration::Session::projectionMatrix(Int eye, Float near, Float far) const

Get the projection matrix.

Parameters
eye The eye index
near Distance to near frustum plane
far Distance to far frustum plane
Returns The projection matrix for eye

Get the projection matrix for an eye index for which should be used for prespective rendering to this HMD.

Matrix4 Magnum::OvrIntegration::Session::orthoSubProjectionMatrix(Int eye, const Matrix4& proj, const Vector2& scale, Float distance) const

Get a projection matrix for projection to an orthogonal plane.

Parameters
eye The eye index
proj Projection matrix, usually created by Session::projectionMatrix()
scale Scale for the 2D plane
distance Distance of the plane from HMD position
Returns The projection matrix for eye

Get a projection matrix which can be used for projection onto a 2D plane orthogonal to the HMDs view/screen with distance from HMDs position.

Session& Magnum::OvrIntegration::Session::setWorldScale(Float scale)

Set world scale.

Parameters
scale world scale (in meters per unit)
Returns Reference to self (for method chaining)

const Containers::StaticArrayView<2, const ovrPosef> Magnum::OvrIntegration::Session::ovrEyePoses() const

Get a pointer to the most current eye poses as ovrPosef

Returns pointer to an ovrPosef[2] containing the most recently polled eye poses.

const Containers::StaticArrayView<2, const ovrPoseStatef> Magnum::OvrIntegration::Session::ovrHandPoseStates() const

ovrHandPoseStates

The most recent calculated pose for each hand when hand controller tracking is present. The first element refers to the left hand and the second to the right hand. These values can be combined with the result of pollController() with ControllerType::Touch for complete hand controller information.

void Magnum::OvrIntegration::Session::recenterTrackingOrigin() const

Re-centers the sensor position and orientation.

This resets the (x,y,z) positional components and the yaw orientation component. The Roll and pitch orientation components are always determined by gravity and cannot be redefined. All future tracking will report values relative to this new reference position.

The headset cannot be facing vertically upward or downward but rather must be roughly level otherwise this function will fail with OvrIntegration::Error::InvalidHeadsetOrientation.

For more info, see the notes on each TrackingOrigin enumeration to understand how recenter will vary slightly in its behavior based on the current tracking origin setting, see setTrackingOrigin().

void Magnum::OvrIntegration::Session::setTrackingOrigin(TrackingOrigin origin) const

Sets the tracking origin type.

When the tracking origin is changed, all of the calls that either provide or accept ovrPosef will use the new tracking origin provided.

void Magnum::OvrIntegration::Session::clearShouldRecenterFlag() const

Clear SessionStatusFlag::ShouldRecenter.

Clears the ShouldRecenter status bit in the session status, allowing further recenter requests to be detected. Since this is automatically done by Session::recenterTrackingOrigin(), this is only needs to be called when application is doing its own re-centering.

Long Magnum::OvrIntegration::Session::incFrameIndex()

Increment the frame index.

Returns the previous index value. This method is called by Compositor::submitFrame().

void Magnum::OvrIntegration::Session::setPerformanceHudMode(PerformanceHudMode mode) const

Set performance HUD mode.

Performance HUD enables the HMD user to see information critical to the real-time operation of the VR application such as latency timing and CPU & GPU performance metrics.

void Magnum::OvrIntegration::Session::setDebugHudStereoMode(DebugHudStereoMode mode) const

Set debug HUD Setero Mode.

Debug HUD is provided to help developers gauge and debug the fidelity of their app's stereo rendering characteristics. Using the provided quad and crosshair guides, the developer can verify various aspects such as VR tracking units (e.g. meters), stereo camera-parallax properties (e.g. making sure objects at infinity are rendered with the proper separation), measuring VR geometry sizes and distances and more.

void Magnum::OvrIntegration::Session::setLayerHudMode(LayerHudMode mode) const

Set layer HUD mode.

Layer HUD enables the HMD user to see information about a layer.