Python API Reference#

Note

Applies to: Spatial Extensions, Kit 109.0.3+, CloudXR 6

Complete reference for the Spatial Extensions Python API.

Module: omni.kit.xr.core#

Primary module for XR functionality.

XRCore#

Main singleton class for XR system access.

Getting Instance#

from omni.kit.xr.core import XRCore

xr_core = XRCore.get_singleton()

Profile Management#

# Enable profile
XRCore.request_enable_profile(name: str) -> None

# Disable current profile
xr_core.request_disable_profile() -> None

# Get current profile
xr_core.get_current_profile() -> XRProfile
xr_core.get_current_xr_profile() -> XRProfile
xr_core.get_current_profile_name() -> str
xr_core.get_xr_current_profile_name() -> str

# Get specific profile
xr_core.get_profile(name: Union[str, XRToken]) -> XRProfile
xr_core.ensure_profile(name: Union[str, XRToken]) -> XRProfile

# List profiles
xr_core.get_profile_list() -> list[XRProfile]
xr_core.get_profile_name_list() -> list[str]

Example:

# Enable VR — request_enable_profile is a static method on XRCore
XRCore.request_enable_profile("vr")

# Get current
profile = xr_core.get_current_profile()
print(f"Active profile: {profile.get_name()}")

# List all
profiles = xr_core.get_profile_name_list()
print(f"Available: {profiles}")

Status Checking#

xr_core.is_xr_enabled() -> bool          # XR system enabled
xr_core.is_xr_display_enabled() -> bool  # Display active
xr_core.is_xr_viewport_enabled() -> bool # Viewport active
xr_core.is_gui_enabled() -> bool         # GUI system enabled
xr_core.is_fsd_enabled() -> bool         # FSD enabled

Input Devices#

# Get device
xr_core.get_input_device(handle: Union[str, XRToken]) -> Optional[XRInputDevice]

# Check if exists
xr_core.has_input_device(handle: Union[str, XRToken]) -> bool

# Get multiple devices
xr_core.get_input_devices(handle: Union[str, XRToken]) -> list[XRInputDevice]

# Get all devices
xr_core.get_all_input_devices() -> list[XRInputDevice]

Example:

# Get controller
left = xr_core.get_input_device("/user/hand/left")

# Check existence
if xr_core.has_input_device("/user/hand/left"):
    print("Left controller connected")

# Get all
devices = xr_core.get_all_input_devices()
for device in devices:
    print(f"Device: {device.get_name()}")

Message Bus & Events#

# Get message bus
xr_core.get_message_bus() -> carb.events.IEventStream

# Dispatch custom event
xr_core.dispatch_message_bus_and_check_consume(
    event_type: int,
    event_dict: dict
) -> bool

# Bind global input event generator
xr_core.bind_input_event_generator(
    event_name: str,
    event_list: Iterable[str],
    tooltips: Union[dict[str, str], str] = {}
) -> Optional[XREventGenerator]

# Unbind event generator
xr_core.unbind_input_event_generator(event_name: str) -> None

Raycasting#

# Submit raycast query
xr_core.submit_raycast_query(
    ray: XRRay,
    callback: Callable[[XRRay, XRRayQueryResult], None]
) -> None

# Submit multiple raycasts
xr_core.submit_multi_raycast_query(
    rays: list[XRRay],
    callback: Callable[[list[XRRay], list[XRRayQueryResult]], None]
) -> None

# Async raycast
await xr_core.execute_raycast_query_async(ray: XRRay) -> XRRayQueryResult

# Async multi-raycast
await xr_core.execute_multi_raycast_query_async(
    rays: list[XRRay]
) -> list[XRRayQueryResult]

Example:

from omni.kit.xr.core import XRRay
from pxr import Gf

# Create ray
origin = Gf.Vec3d(0, 100, 0)
direction = Gf.Vec3d(0, 0, -1)
ray = XRRay(origin, direction, 0.0, 1000.0)

# Async raycast
result = await xr_core.execute_raycast_query_async(ray)
if result.valid:
    print(f"Hit: {result.get_target_usd_path()}")

USD Layer Management#

# Create XRUsdLayer
xr_core.create_xr_usd_layer(
    usd_path: str,
    meters_per_unit: float = 0.01,
    up_axis: str = 'y',
    ui_layer_name: str = '',
    component_layer_name: str = ''
) -> XRUsdLayer

Coordinate Systems#

xr_core.get_coordinate_system() -> XRCoordinateSystem
xr_core.get_stage_coordinate_system() -> XRCoordinateSystem

Transform Utilities#

# Set/get transforms
xr_core.set_local_transform_matrix(
    prim: Union[Usd.Prim, Sdf.Path, str],
    matrix: Union[Gf.Matrix4d, Iterable[float], Iterable[Iterable[float]]],
    layer_identifier: Union[str, None] = None
) -> None

xr_core.get_local_transform_matrix(
    prim: Union[Usd.Prim, Sdf.Path, str]
) -> Gf.Matrix4d

xr_core.set_world_transform_matrix(...) -> None
xr_core.get_world_transform_matrix(...) -> Gf.Matrix4d

# Reorient matrices
xr_core.reorient_transform_matrix_up_right(
    matrix: Union[Gf.Matrix4d, ...],
    y_up: bool = True
) -> Gf.Matrix4d

xr_core.reorient_transform_matrix_no_roll(
    matrix: Union[Gf.Matrix4d, ...],
    y_up: bool = True
) -> Gf.Matrix4d

Scene Navigation#

# Get/set stage anchor
xr_core.get_stage_anchor_prim_path() -> Optional[str]
xr_core.schedule_set_stage_anchor(stage_anchor: str) -> None
xr_core.detach_stage_anchor() -> None

# Teleport
xr_core.schedule_teleport_to_view(
    stage_anchor: str,
    view_pose: Union[Gf.Matrix4d, ...]
) -> None

# Navigation
xr_core.schedule_apply_viewport_navigation(
    dx: float, dy: float, dz: float,
    yaw: float, pitch: float
) -> None

# Space origin
xr_core.schedule_set_space_origin(
    space_origin_pose: Union[Gf.Matrix4d, ...]
) -> None

xr_core.schedule_move_space_origin_relative_to_camera(
    dx: float, dy: float, dz: float
) -> None

xr_core.schedule_rotate_space_origin_relative_to_camera(
    yaw: float, pitch: float
) -> None

View Configuration#

xr_core.get_current_view_config() -> XRToken
xr_core.get_current_blend_mode() -> XRToken

XRProfile#

Profile configuration (VR, AR, TabletAR).

# Get profile name
profile.get_name() -> str

# Enable/check status
profile.request_enable_profile() -> None
profile.is_enabled() -> bool

# Settings paths
profile.get_persistent_path() -> str      # e.g., "/persistent/xr/profile/vr"
profile.get_non_persistent_path() -> str
profile.get_scene_persistent_path() -> str

# AR mode
profile.get_ar_mode() -> bool
profile.set_ar_mode(ar_mode: bool) -> None

# Configuration
profile.set_config(config: Any) -> None
profile.get_config() -> Any

# Teleport
profile.teleport(
    transform: Union[Gf.Matrix4d, ...]
) -> None

XRInputDevice#

Input device (controller, HMD, etc.).

# Device info
device.get_name() -> XRToken
device.get_type() -> XRToken
device.is_active() -> bool

# Poses
device.get_raw_pose(pose_name: Union[XRToken, str] = '') -> Gf.Matrix4d
device.get_pose(pose_name: Union[XRToken, str] = '') -> Gf.Matrix4d
device.get_virtual_world_pose(pose_name: Union[XRToken, str] = '') -> Gf.Matrix4d

device.get_pose_names() -> list[XRToken]
device.has_pose(pose_name: Union[XRToken, str]) -> bool

# Input gestures
device.get_input_gesture_value(
    input_name: Union[XRToken, str],
    gesture_name: Union[XRToken, str]
) -> float

device.has_input(input_name: Union[XRToken, str]) -> bool
device.has_input_gesture(
    input_name: Union[XRToken, str],
    gesture_name: Union[XRToken, str]
) -> bool

device.get_input_names() -> list[XRToken]
device.get_input_gesture_names(
    input_name: Union[XRToken, str]
) -> list[XRToken]

# Event generators
device.bind_event_generator(
    input_name: Union[XRToken, str],
    event_name: str,
    event_list: Iterable[str],
    tooltips: Union[dict[str, str], str] = {}
) -> Optional[XREventGenerator]

device.unbind_event_generator(event_name: str) -> None

# Base inputs (for simulated inputs)
device.get_input_base(
    input_name: Union[XRToken, str]
) -> XRToken

device.get_overlapping_inputs(
    input_name: Union[XRToken, str]
) -> list[XRToken]

Example:

device = xr_core.get_input_device("/user/hand/left")

# Get pose
pose = device.get_pose("aim")
position = pose.ExtractTranslation()

# Read input
trigger = device.get_input_gesture_value("trigger", "value")

# Bind event
generator = device.bind_event_generator(
    "trigger", "my_trigger",
    ["press", "release"],
    {"press": "Fire"}
)

XRUsdLayer#

USD layer for XR UI elements.

Creation & Properties#

# Get properties
layer.get_id() -> int
layer.is_valid() -> bool
layer.get_top_level_prim_path() -> str
layer.get_layer_name() -> str

# Get layers
layer.get_layer() -> Sdf.Layer
layer.get_ui_layer() -> Sdf.Layer
layer.get_component_layer() -> Sdf.Layer

# Coordinate system
layer.get_coordinate_system(
    path: Union[Usd.Prim, Sdf.Path, str, XRToken] = ''
) -> XRCoordinateSystem

Adding Objects#

# Add asset
layer.add_asset(
    path: Union[Sdf.Path, str, XRToken],
    group: str,
    file_path: str,
    layer_identifier: str = '',
    transform: Union[Gf.Matrix4d, ...] = None,
    transform_type: XRTransformType = XRTransformType.local,
    pickable: bool = False,
    visible: bool = True
) -> str

# Add beam
layer.add_beam(
    path: Union[Sdf.Path, str, XRToken],
    group: str,
    material_reference: Union[Sdf.Path, str, XRToken],
    transform: Union[Gf.Matrix4d, ...] = None,
    transform_type: XRTransformType = XRTransformType.local,
    max_length: float = 20.0,
    length: float = -1.0,
    tube_radius: float = 0.005,
    visible: bool = True
) -> str

# Add teleport arc
layer.add_teleport_arc(
    path: Union[Sdf.Path, str, XRToken],
    group: str,
    material_reference: Union[Sdf.Path, str, XRToken],
    transform: Union[Gf.Matrix4d, ...] = None,
    transform_type: XRTransformType = XRTransformType.local,
    max_height: float = 3.0,
    tube_radius: float = 0.02,
    num_segments: int = 120,
    visible: bool = True
) -> str

# Add link to input device
layer.add_link_to_input_device(
    path: Union[Sdf.Path, str, XRToken],
    group: str,
    input_device_name: Union[str, XRToken],
    pose_name: Union[str, XRToken],
    transform: Union[Gf.Matrix4d, ...] = None,
    transform_type: XRTransformType = XRTransformType.local,
    visible: bool = True
) -> str

# Add reorient
layer.add_reorient(
    path: Union[Sdf.Path, str, XRToken],
    group: str,
    alignment: XROrientationAlignment = XROrientationAlignment.world,
    input_device: Union[str, None, XRToken] = None,
    pose_name: Union[str, None, XRToken] = None,
    visible: bool = True
) -> str

Transform Management#

# Set transform
layer.set_transform(
    path: Union[Sdf.Path, Usd.Prim, str, XRToken],
    transform: Union[Gf.Matrix4d, ...],
    transform_type: XRTransformType = XRTransformType.local,
    use_usd: bool = False
) -> None

# Get transform
layer.get_transform(
    path: Union[Sdf.Path, Usd.Prim, str, XRToken],
    transform_type: XRTransformType = XRTransformType.local,
    use_usd: bool = False
) -> Gf.Matrix4d

# Position shortcuts
layer.set_position(
    path: Union[Sdf.Path, Usd.Prim, str, XRToken],
    position: Union[Gf.Vec3d, Iterable[float]],
    transform_type: XRTransformType = XRTransformType.local,
    use_usd: bool = False
) -> None

layer.get_position(
    path: Union[Sdf.Path, Usd.Prim, str, XRToken],
    transform_type: XRTransformType = XRTransformType.local
) -> Gf.Vec3d

Visibility & Pickability#

layer.show(path: Union[Usd.Prim, Sdf.Path, str, XRToken] = '') -> None
layer.hide(path: Union[Usd.Prim, Sdf.Path, str, XRToken] = '') -> None
layer.is_visible(path: Union[Usd.Prim, Sdf.Path, str, XRToken] = '') -> bool

layer.set_pickable(
    path: Union[Sdf.Path, Usd.Prim, str, XRToken],
    pickable: bool
) -> None

layer.get_pickable(
    path: Union[Sdf.Path, Usd.Prim, str, XRToken]
) -> bool

Removal#

layer.remove(path: Union[Sdf.Path, Usd.Prim, str, XRToken]) -> None
layer.remove_group(group: str) -> None
layer.clear() -> None

layer.is_managed_prim(
    path: Union[Usd.Prim, Sdf.Path, str, XRToken]
) -> bool

XRSettings#

Settings management.

from omni.kit.xr.core import XRSettings

xr_settings = XRSettings.get_singleton()

# Get setting
xr_settings.get_setting(path: str) -> Any

# Set setting
xr_settings.set_setting(path: str, value: Any) -> None

# Subscribe to changes
xr_settings.subscribe_to_change(
    path: str,
    callback: Callable[[], None]
) -> Subscription

Helper Classes#

XRRay#

Ray for raycasting.

from omni.kit.xr.core import XRRay
from pxr import Gf

ray = XRRay(
    origin: Gf.Vec3d,
    direction: Gf.Vec3d,
    min_t: float = 0.0,
    max_t: float = inf
)

# Properties
ray.origin    # Gf.Vec3d
ray.forward   # Gf.Vec3d (direction)
ray.min_t     # float
ray.max_t     # float

XRRayQueryResult#

Raycast hit result.

# Properties
result.valid          # bool
result.hit_position   # Gf.Vec3d
result.hit_t          # float (distance)
result.normal         # Gf.Vec3d
result.instance_id    # int

# Methods
result.get_target_usd_path() -> str
result.get_target_enclosing_model_usd_path() -> str

XRToken#

Immutable string identifier.

from omni.kit.xr.core import XRToken

token = XRToken("my_identifier")

# Convert to string
name = str(token)

XRCoordinateSystem#

Coordinate system info.

coord_system = xr_core.get_coordinate_system()

# Properties
coord_system.meters_per_unit  # float
coord_system.up_axis          # str ('y' or 'z')
coord_system.up_axis_index    # int

# Direction vectors
coord_system.get_up_vector() -> Gf.Vec3d
coord_system.get_forward_vector() -> Gf.Vec3d
coord_system.get_backward_vector() -> Gf.Vec3d
coord_system.get_left_vector() -> Gf.Vec3d
coord_system.get_right_vector() -> Gf.Vec3d

Event Types#

XRCoreEventType#

from omni.kit.xr.core import XRCoreEventType

# Frame events
XRCoreEventType.pre_sync_update
XRCoreEventType.post_sync_update
XRCoreEventType.post_device_events_update
XRCoreEventType.post_layer_update

# Profile events
XRCoreEventType.profile_changed
XRCoreEventType.profile_list_updated

# System events
XRCoreEventType.system_changed
XRCoreEventType.system_list_updated

# Static methods
XRCoreEventType.profile_enable(profile_name) -> int
XRCoreEventType.profile_disable(profile_name) -> int
XRCoreEventType.system_enable(system_name) -> int
XRCoreEventType.system_disable(system_name) -> int

Enums#

XRAnchorMode#

from omni.kit.xr.core import XRAnchorMode

XRAnchorMode.active_camera
XRAnchorMode.custom_anchor
XRAnchorMode.scene_origin

XROrientationAlignment#

from omni.kit.xr.core import XROrientationAlignment

XROrientationAlignment.world
XROrientationAlignment.device
XROrientationAlignment.device_no_roll
XROrientationAlignment.device_up_right
XROrientationAlignment.anchor
XROrientationAlignment.anchor_no_roll
XROrientationAlignment.anchor_up_right

XRTransformType#

from omni.kit.xr.core import XRTransformType

XRTransformType.local   # Relative to parent
XRTransformType.stage   # World space
XRTransformType.scope   # Intermediate scope

Complete Example#

import omni.kit.xr.core
import carb.events
from pxr import Gf

class XRApplication:
    """Complete XR application example."""
    
    def __init__(self):
        self.xr_core = omni.kit.xr.core.XRCore.get_singleton()
        self.xr_usd_layer = None
        self.subscriptions = []
    
    def startup(self):
        """Start XR."""
        # Subscribe to XR enabled
        message_bus = self.xr_core.get_message_bus()
        self.subscriptions.append(
            message_bus.create_subscription_to_pop_by_type(
                carb.events.type_from_string("xr_display.enable"),
                self._on_xr_display_enabled
            )
        )
        
        # Enable VR
        self.xr_core.request_enable_profile("vr")
    
    def _on_xr_display_enabled(self, event):
        """XR display active."""
        print("XR display enabled - setting up")
        
        # Create USD layer
        self._xr_usd_layer = self.xr_core.create_xr_usd_layer(
            usd_path="/_xr/app",
            meters_per_unit=0.01,
            up_axis='y'
        )
        
        # Set up controllers
        self._setup_controllers()
        
        # Set up input
        self._setup_input()
    
    def _setup_controllers(self):
        """Create controller models."""
        for device_name in ["/user/hand/left", "/user/hand/right"]:
            device_path = self._xr_usd_layer.ensure_device_prim_path(device_name)
            
            # Add beam
            beam = self._xr_usd_layer.add_beam(
                path=f"{device_path}/beam",
                group="tools",
                material_reference="/World/Materials/Beam",
                max_length=1000.0,
                tube_radius=0.3
            )
            
            # Link to controller
            self._xr_usd_layer.add_link_to_input_device(
                path=beam,
                group="tools",
                input_device_name=device_name,
                pose_name="aim"
            )
    
    def _setup_input(self):
        """Set up input handling."""
        left = self.xr_core.get_input_device("/user/hand/left")
        
        if left:
            # Bind trigger
            left.bind_event_generator(
                "trigger", "select",
                ["press"],
                {"press": "Select"}
            )
            
            # Subscribe
            message_bus = self.xr_core.get_message_bus()
            self.subscriptions.append(
                message_bus.create_subscription_to_pop_by_type(
                    carb.events.type_from_string("select.press"),
                    self._on_select
                )
            )
    
    def _on_select(self, event):
        """Handle selection."""
        left = self.xr_core.get_input_device("/user/hand/left")
        pose = left.get_pose("aim")
        
        origin = pose.ExtractTranslation()
        forward = pose.TransformDir(Gf.Vec3d(0, 0, -1))
        
        ray = omni.kit.xr.core.XRRay(origin, forward, 0.0, 1000.0)
        
        import asyncio
        asyncio.ensure_future(self._select_async(ray))
    
    async def _select_async(self, ray):
        """Async selection."""
        result = await self.xr_core.execute_raycast_query_async(ray)
        
        if result.valid:
            print(f"Selected: {result.get_target_usd_path()}")
    
    def shutdown(self):
        """Shutdown XR."""
        self.subscriptions.clear()
        
        if self._xr_usd_layer:
            self._xr_usd_layer.clear()
        
        if self.xr_core.is_xr_enabled():
            self.xr_core.request_disable_profile()

# Usage
app = XRApplication()
app.startup()

Next Steps#