BackendOpenXR

Struct BackendOpenXR 

Source
pub struct BackendOpenXR;
Expand description

This class is NOT of general interest, unless you are trying to add support for some unusual OpenXR extension! StereoKit should do all the OpenXR work that most people will need. If you find yourself here anyhow for something you feel StereoKit should support already, please add a feature request on GitHub!

This class contains handles and methods for working directly with OpenXR. This may allow you to activate or work with OpenXR extensions that StereoKit hasn’t implemented or exposed yet. Check that Backend.XRType is OpenXR before using any of this.

These properties may best be used with some external OpenXR binding library, but you may get some limited mileage with the API as provided here. https://stereokit.net/Pages/StereoKit/Backend.OpenXR.html

see implementations in crate::tools::xr_fb_passthrough crate::tools::os_api

§Examples

use stereokit_rust::system::{Backend, BackendOpenXR, BackendXRType};

// This must be set before initializing StereoKit.
BackendOpenXR::use_minimum_exts(false);
BackendOpenXR::exclude_ext("XR_EXT_hand_tracking");
BackendOpenXR::request_ext("XR_EXT_hand_tracking");

stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!

let xr_type = Backend::xr_type();
let eyes_sample_time = BackendOpenXR::eyes_sample_time();
let instance         = BackendOpenXR::instance();
let session          = BackendOpenXR::session();
let space            = BackendOpenXR::space();
let system_id        = BackendOpenXR::system_id();
let time             = BackendOpenXR::time();
let ext_enabled      = BackendOpenXR::ext_enabled("XR_EXT_hand_tracking");
let get_function_ptr = BackendOpenXR::get_function_ptr("xrGetHandTrackerEXT");
let get_function     = BackendOpenXR::get_function::<unsafe extern "C" fn()>("xrGetHandTrackerEXT");
BackendOpenXR::set_hand_joint_scale(1.0);
BackendOpenXR::use_minimum_exts(true);

xr_mode_stop_here!();
// These are the expected results for offscreen tests on a PC:
assert_eq!( xr_type, BackendXRType::None);
 assert_ne!( xr_type, BackendXRType::OpenXR);
assert_eq!(eyes_sample_time, 0);
assert_eq!(instance, 0);
assert_eq!(session, 0);
assert_eq!(space, 0);
assert_eq!(system_id, 0);
assert_eq!(time, 0);
assert_eq!(ext_enabled, false);
assert_eq!(get_function_ptr, None);
assert_eq!(get_function, None);

Implementations§

Source§

impl BackendOpenXR

Source

pub fn eyes_sample_time() -> i64

Type: XrTime. This is the OpenXR time of the eye tracker sample associated with the current value of. https://stereokit.net/Pages/StereoKit/Backend.OpenXR/EyesSampleTime.html

see also backend_openxr_get_eyes_sample_time

Source

pub fn instance() -> OpenXRHandleT

Type: XrInstance. StereoKit’s instance handle, valid after Sk.initialize. https://stereokit.net/Pages/StereoKit/Backend.OpenXR/Instance.html

see also backend_openxr_get_instance

§Examples
use stereokit_rust::system::BackendOpenXR;

let instance_handle = BackendOpenXR::instance();

// In XR mode, this would be a valid XrInstance handle for OpenXR operations
// In offscreen mode, returns 0

offscreen_mode_stop_here!();
assert_ne!(instance_handle, 0);
Source

pub fn session() -> OpenXRHandleT

Type: XrSession. StereoKit’s current session handle, this will be valid after SK.Initialize, but the session may not be started quite so early. https://stereokit.net/Pages/StereoKit/Backend.OpenXR/Session.html

see also backend_openxr_get_session

§Examples
use stereokit_rust::system::BackendOpenXR;

let session_handle = BackendOpenXR::session();

// In XR mode, this would be a valid XrSession handle for OpenXR session operations
// In offscreen mode, returns 0

offscreen_mode_stop_here!();
assert_ne!(session_handle, 0);
Source

pub fn space() -> OpenXRHandleT

Type: XrSpace. StereoKit’s primary coordinate space, valid after SK.Initialize, this will most likely be created from XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT or XR_REFERENCE_SPACE_TYPE_LOCAL. https://stereokit.net/Pages/StereoKit/Backend.OpenXR/Space.html

see also backend_openxr_get_space

§Examples
use stereokit_rust::system::BackendOpenXR;

let space_handle = BackendOpenXR::space();

// In XR mode, this would be a valid XrSpace handle for coordinate transformations
// In offscreen mode, returns 0

offscreen_mode_stop_here!();
assert_ne!(space_handle, 0);
Source

pub fn system_id() -> OpenXRHandleT

Type: XrSystemId. This is the id of the device StereoKit is currently using! This is the result of calling xrGetSystem with XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY. https://stereokit.net/Pages/StereoKit/Backend.OpenXR/SystemId.html

see also backend_openxr_get_system_id

§Examples
use stereokit_rust::system::BackendOpenXR;

let system_id = BackendOpenXR::system_id();

// In XR mode, this would be a valid XrSystemId for the current XR device
// In offscreen mode, returns 0

offscreen_mode_stop_here!();
assert_ne!(system_id, 0);
Source

pub fn time() -> i64

Type: XrTime. This is the OpenXR time for the current frame, and is available after Sk.initialize. https://stereokit.net/Pages/StereoKit/Backend.OpenXR/Time.html

see also backend_openxr_get_time

§Examples
use stereokit_rust::system::BackendOpenXR;

let current_time = BackendOpenXR::time();

// In offscreen mode, returns 0

offscreen_mode_stop_here!();
assert_ne!(current_time, 0);
Source

pub fn use_minimum_exts(value: bool)

Tells StereoKit to request only the extensions that are absolutely critical to StereoKit. You can still request extensions via OpenXR.RequestExt, and this can be used to opt-in to extensions that StereoKit would normally request automatically. https://stereokit.net/Pages/StereoKit/Backend.OpenXR/UseMinimumExts.html

see also backend_openxr_use_minimum_exts

Source

pub fn add_composition_layer<T>(xr_composition_layer_x: &mut T, sort_order: i32)

This allows you to add XrCompositionLayers to the list that StereoKit submits to xrEndFrame. You must call this every frame you wish the layer to be included. https://stereokit.net/Pages/StereoKit/Backend.OpenXR/AddCompositionLayer.html

  • xr_composition_layer_x - A serializable XrCompositionLayer struct that follows the XrCompositionLayerBaseHeader data pattern.
  • sort_order - An sort order value for sorting with other composition layers in the list. The primary projection layer that StereoKit renders to is at 0, -1 would be before it, and +1 would be after.

see also backend_openxr_composition_layer

§Examples
use stereokit_rust::system::BackendOpenXR;

// Only works in XR mode but offscreen accept it.
use openxr_sys as oxr;

// Create projection views for left eye only
let mut projection_views = [
    oxr::CompositionLayerProjectionView {
        ty: oxr::StructureType::COMPOSITION_LAYER_PROJECTION_VIEW,
        next: std::ptr::null(),
        sub_image: oxr::SwapchainSubImage {
            swapchain: oxr::Swapchain::from_raw(0), // Should be valid swapchain
            image_rect: oxr::Rect2Di {
                offset: oxr::Offset2Di { x: 0, y: 0 },
                extent: oxr::Extent2Di { width: 1024, height: 1024 },
            },
            image_array_index: 0,
        },
        pose: oxr::Posef {
            orientation: oxr::Quaternionf { x: 0.0, y: 0.0, z: 0.0, w: 1.0 },
            position: oxr::Vector3f { x: -0.032, y: 0.0, z: 0.0 }, // Left eye offset
        },
        fov: oxr::Fovf {
            angle_left: -0.7853981, // -45 degrees
            angle_right: 0.7853981,  // 45 degrees
            angle_up: 0.7853981,     // 45 degrees
            angle_down: -0.7853981,  // -45 degrees
        },
    }
];

let mut composition_layer = oxr::CompositionLayerProjection {
    ty: oxr::StructureType::COMPOSITION_LAYER_PROJECTION,
    next: std::ptr::null(),
    layer_flags: oxr::CompositionLayerFlags::BLEND_TEXTURE_SOURCE_ALPHA,
    space: oxr::Space::from_raw(BackendOpenXR::space()),
    view_count: 1,
    views: projection_views.as_ptr(),
};

test_steps!( // !!!! Get a proper main loop !!!!
    BackendOpenXR::add_composition_layer(&mut composition_layer, 0);
);
Source

pub fn add_end_frame_chain<T>(xr_base_header: &mut T)

This adds an item to the chain of objects submitted to StereoKit’s xrEndFrame call! https://stereokit.net/Pages/StereoKit/Backend.OpenXR/AddEndFrameChain.html

  • xr_base_header - An OpenXR object that will be chained into the xrEndFrame call.

see also backend_openxr_end_frame_chain

§Examples
use stereokit_rust::system::BackendOpenXR;

// Only works in XR mode but offscreen accept it.
use openxr_sys as oxr;
let mut frame_end_info = oxr::FrameEndInfo {
    ty: oxr::StructureType::FRAME_END_INFO,
    next: std::ptr::null(),
    display_time: oxr::Time::from_nanos(BackendOpenXR::time()),
    environment_blend_mode:  oxr::EnvironmentBlendMode::OPAQUE,
    layer_count: 0,
    layers: std::ptr::null_mut(), // Should be filled with valid layers
     
};

test_steps!( // !!!! Get a proper main loop !!!!
    BackendOpenXR::add_end_frame_chain(&mut frame_end_info);
);
Source

pub fn exclude_ext(extension_name: impl AsRef<str>)

This ensures that StereoKit does not load a particular extension! StereoKit will behave as if the extension is not available on the device. It will also be excluded even if you explicitly requested it with RequestExt earlier, or afterwards. This MUST be called before SK.Initialize. https://stereokit.net/Pages/StereoKit/Backend.OpenXR/ExcludeExt.html

  • extension_name - The extension name as listed in the OpenXR spec. For example: “XR_EXT_hand_tracking”.

see also backend_openxr_ext_exclude

§Examples
use stereokit_rust::system::BackendOpenXR;

// This must be called before SK.Initialize
BackendOpenXR::exclude_ext("XR_EXT_hand_tracking");
BackendOpenXR::exclude_ext("XR_FB_passthrough");

stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!

offscreen_mode_stop_here!();
// Later, we can check if the extensions were not loaded:
assert_eq!(BackendOpenXR::ext_enabled("XR_EXT_hand_tracking"), false);
assert_eq!(BackendOpenXR::ext_enabled("XR_FB_passthrough"), false);
Source

pub fn request_ext(extension_name: impl AsRef<str>)

Requests that OpenXR load a particular extension. This MUST be called before SK.Initialize. Note that it’s entirely possible that your extension will not load on certain runtimes, so be sure to check ExtEnabled to see if it’s available to use. https://stereokit.net/Pages/StereoKit/Backend.OpenXR/RequestExt.html

  • extension_name - The extension name as listed in the OpenXR spec. For example: “XR_EXT_hand_tracking”.

see also backend_openxr_ext_request

§Examples
use stereokit_rust::system::BackendOpenXR;

// This must be called before SK.Initialize
BackendOpenXR::request_ext("XR_EXT_hand_tracking");
BackendOpenXR::request_ext("XR_the_ext_that_does_not_exist");

stereokit_rust::test_init_sk!(); // !!!! Get a proper way to initialize sk !!!!

offscreen_mode_stop_here!();
// Later, check if extensions were loaded as we can't be sure they are ok for this runtime:
assert_eq!(BackendOpenXR::ext_enabled("XR_EXT_hand_tracking"), true);
assert_eq!(BackendOpenXR::ext_enabled("XR_the_ext_that_does_not_exist"), false);
Source

pub fn ext_enabled(extension_name: impl AsRef<str>) -> bool

This tells if an OpenXR extension has been requested and successfully loaded by the runtime. This MUST only be called after SK.Initialize. https://stereokit.net/Pages/StereoKit/Backend.OpenXR/ExtEnabled.html

  • extension_name - The extension name as listed in the OpenXR spec. For example: “XR_EXT_hand_tracking”.

see also backend_openxr_ext_enabled

§Examples
use stereokit_rust::system::BackendOpenXR;

// Check if an extension is enabled (only works in XR mode)
let hand_tracking_enabled = BackendOpenXR::ext_enabled("XR_EXT_hand_tracking");
let imaginary_enabled = BackendOpenXR::ext_enabled("XR_the_ext_that_does_not_exist");

offscreen_mode_stop_here!();
// In offscreen mode, extensions are never enabled
assert_eq!(hand_tracking_enabled, true);
assert_eq!(imaginary_enabled, false);
Source

pub fn get_function_ptr(function_name: impl AsRef<str>) -> Option<VoidFunction>

This is basically xrGetInstanceProcAddr from OpenXR, you can use this to get and call functions from an extension you’ve loaded.

§Important Note

It is more relevant to use the openxrs crate which contains the function signatures

https://stereokit.net/Pages/StereoKit/Backend.OpenXR/GetFunctionPtr.html

  • function_name - The name of the function to get the pointer for.

see also backend_openxr_get_function

§Examples
use stereokit_rust::system::BackendOpenXR;

// Get a function pointer from an OpenXR extension (only works in XR mode)
let hand_tracker_fn = BackendOpenXR::get_function_ptr("xrCreateHandTrackerEXT");
let passthrough_fn = BackendOpenXR::get_function_ptr("xrInexistantFunction");

offscreen_mode_stop_here!();
// In offscreen mode, function pointers are None
assert_eq!(hand_tracker_fn.is_some(), true);
assert_eq!(passthrough_fn, None);
Source

pub fn get_function<T>(function_name: impl AsRef<str>) -> Option<T>

This is basically xrGetInstanceProcAddr from OpenXR, you can use this to get and call functions from an extension you’ve loaded.

§Important Note

It is more relevant to use the openxrs crate which contains the function signatures

https://stereokit.net/Pages/StereoKit/Backend.OpenXR/GetFunctionPtr.html

  • function_name - The name of the function to get the pointer for.

see also backend_openxr_get_function

§Examples
use stereokit_rust::system::BackendOpenXR;

// Get a typed function pointer from an OpenXR extension (only works in XR mode)
let hand_tracker_fn: Option<unsafe extern "C" fn()> = BackendOpenXR::get_function("xrCreateHandTrackerEXT");

offscreen_mode_stop_here!();
// In offscreen mode, function pointers are None
assert_eq!(hand_tracker_fn.is_some(), true);
Source

pub fn set_hand_joint_scale(joint_scale_factor: f32)

This sets a scaling value for joints provided by the articulated hand extension. Some systems just don’t seem to get their joint sizes right! https://stereokit.net/Pages/StereoKit/Backend.OpenXR/SetHandJointScale.html

  • joint_scale_factor - 1 being the default value, 2 being twice as large as normal, and 0.5 being half as big as normal.

see also backend_openxr_set_hand_joint_scale

§Example
use stereokit_rust::system::{Backend, BackendOpenXR, BackendXRType};

// Adjust hand joint scaling (only effective in XR mode with hand tracking)
BackendOpenXR::set_hand_joint_scale(1.2); // Make joints 20% larger

// Or make them smaller
BackendOpenXR::set_hand_joint_scale(0.8); // Make joints 20% smaller

// Reset to default
BackendOpenXR::set_hand_joint_scale(1.0);

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more