Merge pull request #184 from Schmarni-Dev/xr_space_sync_set
XrSpaceSyncSet and OxrSessionConfig
This commit is contained in:
@@ -1,27 +1,28 @@
|
|||||||
//! A simple 3D scene with light shining over a cube sitting on a plane.
|
//! A simple 3D scene with light shining over a cube sitting on a plane.
|
||||||
|
|
||||||
use bevy::{prelude::*, render::pipelined_rendering::PipelinedRenderingPlugin};
|
use bevy::{prelude::*, render::pipelined_rendering::PipelinedRenderingPlugin};
|
||||||
use bevy_mod_openxr::{add_xr_plugins, init::OxrInitPlugin};
|
use bevy_mod_openxr::{add_xr_plugins, resources::OxrSessionConfig};
|
||||||
use openxr::EnvironmentBlendMode;
|
use openxr::EnvironmentBlendMode;
|
||||||
|
|
||||||
fn main() {
|
fn main() -> AppExit {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins(
|
.add_plugins(add_xr_plugins(
|
||||||
add_xr_plugins(DefaultPlugins.build().disable::<PipelinedRenderingPlugin>()).set(
|
// Disabling Pipelined Rendering should reduce latency a little bit for button inputs
|
||||||
OxrInitPlugin {
|
// and increase accuracy for hand tracking, controller positions and similar,
|
||||||
blend_modes: Some(vec![
|
// the views are updated right before rendering so they are as accurate as possible
|
||||||
EnvironmentBlendMode::ALPHA_BLEND,
|
DefaultPlugins.build().disable::<PipelinedRenderingPlugin>(),
|
||||||
EnvironmentBlendMode::ADDITIVE,
|
))
|
||||||
EnvironmentBlendMode::OPAQUE,
|
.insert_resource(OxrSessionConfig {
|
||||||
]),
|
blend_modes: Some(vec![
|
||||||
..Default::default()
|
EnvironmentBlendMode::ALPHA_BLEND,
|
||||||
},
|
EnvironmentBlendMode::OPAQUE,
|
||||||
),
|
]),
|
||||||
)
|
..default()
|
||||||
|
})
|
||||||
.add_plugins(bevy_xr_utils::hand_gizmos::HandGizmosPlugin)
|
.add_plugins(bevy_xr_utils::hand_gizmos::HandGizmosPlugin)
|
||||||
.add_systems(Startup, setup)
|
.add_systems(Startup, setup)
|
||||||
.insert_resource(ClearColor(Color::NONE))
|
.insert_resource(ClearColor(Color::NONE))
|
||||||
.run();
|
.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// set up a simple 3D scene
|
/// set up a simple 3D scene
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_mod_openxr::{
|
use bevy_mod_openxr::{
|
||||||
add_xr_plugins, features::overlay::OxrOverlaySessionEvent, init::OxrInitPlugin,
|
add_xr_plugins, features::overlay::OxrOverlaySessionEvent, init::OxrInitPlugin,
|
||||||
types::OxrExtensions,
|
resources::OxrSessionConfig, types::OxrExtensions,
|
||||||
};
|
};
|
||||||
use openxr::EnvironmentBlendMode;
|
use openxr::EnvironmentBlendMode;
|
||||||
|
|
||||||
@@ -16,14 +16,17 @@ fn main() {
|
|||||||
exts.extx_overlay = true;
|
exts.extx_overlay = true;
|
||||||
exts
|
exts
|
||||||
},
|
},
|
||||||
|
..OxrInitPlugin::default()
|
||||||
|
}))
|
||||||
|
.insert_resource(OxrSessionConfig {
|
||||||
blend_modes: Some({
|
blend_modes: Some({
|
||||||
vec![
|
vec![
|
||||||
EnvironmentBlendMode::ALPHA_BLEND,
|
EnvironmentBlendMode::ALPHA_BLEND,
|
||||||
EnvironmentBlendMode::OPAQUE,
|
EnvironmentBlendMode::OPAQUE,
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
..OxrInitPlugin::default()
|
..OxrSessionConfig::default()
|
||||||
}))
|
})
|
||||||
.insert_resource(ClearColor(Color::NONE))
|
.insert_resource(ClearColor(Color::NONE))
|
||||||
.add_plugins(bevy_xr_utils::hand_gizmos::HandGizmosPlugin)
|
.add_plugins(bevy_xr_utils::hand_gizmos::HandGizmosPlugin)
|
||||||
.add_systems(Startup, setup)
|
.add_systems(Startup, setup)
|
||||||
|
|||||||
@@ -1,24 +1,17 @@
|
|||||||
//! A simple 3D scene with light shining over a cube sitting on a plane.
|
//! A simple 3D scene with light shining over a cube sitting on a plane.
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_mod_openxr::{add_xr_plugins, init::OxrInitPlugin};
|
use bevy_mod_openxr::add_xr_plugins;
|
||||||
use bevy_mod_xr::session::{XrSessionPlugin, XrState};
|
use bevy_mod_xr::session::{XrSessionPlugin, XrState};
|
||||||
|
|
||||||
fn main() {
|
fn main() -> AppExit {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins(
|
.add_plugins(add_xr_plugins(DefaultPlugins).set(XrSessionPlugin { auto_handle: true }))
|
||||||
add_xr_plugins(DefaultPlugins)
|
|
||||||
.set(XrSessionPlugin { auto_handle: true })
|
|
||||||
.set(OxrInitPlugin {
|
|
||||||
blend_modes: Some(vec![openxr::EnvironmentBlendMode::OPAQUE]),
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.add_plugins(bevy_xr_utils::hand_gizmos::HandGizmosPlugin)
|
.add_plugins(bevy_xr_utils::hand_gizmos::HandGizmosPlugin)
|
||||||
.add_systems(Startup, setup)
|
.add_systems(Startup, setup)
|
||||||
.add_systems(Update, handle_input)
|
.add_systems(Update, handle_input)
|
||||||
.insert_resource(AmbientLight::default())
|
.insert_resource(AmbientLight::default())
|
||||||
.run();
|
.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_input(
|
fn handle_input(
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use bevy_mod_xr::hands::{
|
|||||||
use bevy_mod_xr::hands::{LeftHand, RightHand, XrHandBoneEntities};
|
use bevy_mod_xr::hands::{LeftHand, RightHand, XrHandBoneEntities};
|
||||||
use bevy_mod_xr::session::{XrPreDestroySession, XrSessionCreated};
|
use bevy_mod_xr::session::{XrPreDestroySession, XrSessionCreated};
|
||||||
use bevy_mod_xr::spaces::{
|
use bevy_mod_xr::spaces::{
|
||||||
XrPrimaryReferenceSpace, XrReferenceSpace, XrSpaceLocationFlags, XrSpaceVelocityFlags,
|
XrPrimaryReferenceSpace, XrReferenceSpace, XrSpaceLocationFlags, XrSpaceSyncSet,
|
||||||
XrVelocity,
|
XrSpaceVelocityFlags, XrVelocity,
|
||||||
};
|
};
|
||||||
use openxr::{SpaceLocationFlags, SpaceVelocityFlags};
|
use openxr::{SpaceLocationFlags, SpaceVelocityFlags};
|
||||||
|
|
||||||
@@ -31,7 +31,12 @@ impl Default for HandTrackingPlugin {
|
|||||||
|
|
||||||
impl Plugin for HandTrackingPlugin {
|
impl Plugin for HandTrackingPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_systems(PreUpdate, locate_hands.run_if(openxr_session_running));
|
app.add_systems(
|
||||||
|
PreUpdate,
|
||||||
|
locate_hands
|
||||||
|
.in_set(XrSpaceSyncSet)
|
||||||
|
.run_if(openxr_session_running),
|
||||||
|
);
|
||||||
if self.default_hands {
|
if self.default_hands {
|
||||||
app.add_systems(XrPreDestroySession, clean_up_default_hands)
|
app.add_systems(XrPreDestroySession, clean_up_default_hands)
|
||||||
.add_systems(XrSessionCreated, spawn_default_hands);
|
.add_systems(XrSessionCreated, spawn_default_hands);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use bevy::render::RenderSet;
|
|||||||
use openxr::sys::SystemPassthroughProperties2FB;
|
use openxr::sys::SystemPassthroughProperties2FB;
|
||||||
use openxr::PassthroughCapabilityFlagsFB;
|
use openxr::PassthroughCapabilityFlagsFB;
|
||||||
|
|
||||||
|
use crate::exts::OxrEnabledExtensions;
|
||||||
use crate::layer_builder::PassthroughLayer;
|
use crate::layer_builder::PassthroughLayer;
|
||||||
use crate::resources::*;
|
use crate::resources::*;
|
||||||
use crate::session::OxrSession;
|
use crate::session::OxrSession;
|
||||||
@@ -14,25 +15,31 @@ pub struct OxrPassthroughPlugin;
|
|||||||
|
|
||||||
impl Plugin for OxrPassthroughPlugin {
|
impl Plugin for OxrPassthroughPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
let resources = app
|
if app
|
||||||
.world()
|
.world()
|
||||||
.get_resource::<OxrInstance>()
|
.get_resource::<OxrEnabledExtensions>()
|
||||||
.and_then(|instance| {
|
.is_some_and(|e| e.fb_passthrough)
|
||||||
app.world()
|
{
|
||||||
.get_resource::<OxrSystemId>()
|
let resources = app
|
||||||
.map(|system_id| (instance, system_id))
|
.world()
|
||||||
});
|
.get_resource::<OxrInstance>()
|
||||||
if resources.is_some_and(|(instance, system)| {
|
.and_then(|instance| {
|
||||||
supports_passthrough(instance, *system).is_ok_and(|s| s)
|
app.world()
|
||||||
}) {
|
.get_resource::<OxrSystemId>()
|
||||||
app.sub_app_mut(RenderApp).add_systems(
|
.map(|system_id| (instance, system_id))
|
||||||
Render,
|
});
|
||||||
insert_passthrough
|
if resources.is_some_and(|(instance, system)| {
|
||||||
.in_set(RenderSet::PrepareAssets)
|
supports_passthrough(instance, *system).is_ok_and(|s| s)
|
||||||
.run_if(resource_added::<OxrSession>),
|
}) {
|
||||||
);
|
app.sub_app_mut(RenderApp).add_systems(
|
||||||
} else {
|
Render,
|
||||||
error!("Passthrough is not supported with this runtime")
|
insert_passthrough
|
||||||
|
.in_set(RenderSet::PrepareAssets)
|
||||||
|
.run_if(resource_added::<OxrSession>),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
error!("Passthrough is not supported with this runtime")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,10 +89,7 @@ pub fn create_passthrough(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn supports_passthrough(
|
pub fn supports_passthrough(instance: &OxrInstance, system: OxrSystemId) -> OxrResult<bool> {
|
||||||
instance: &OxrInstance,
|
|
||||||
system: OxrSystemId,
|
|
||||||
) -> OxrResult<bool> {
|
|
||||||
if instance.exts().fb_passthrough.is_none() {
|
if instance.exts().fb_passthrough.is_none() {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,14 +54,8 @@ pub struct OxrInitPlugin {
|
|||||||
/// Extensions wanted for this session.
|
/// Extensions wanted for this session.
|
||||||
// TODO!() This should be changed to take a simpler list of features wanted that this crate supports. i.e. hand tracking
|
// TODO!() This should be changed to take a simpler list of features wanted that this crate supports. i.e. hand tracking
|
||||||
pub exts: OxrExtensions,
|
pub exts: OxrExtensions,
|
||||||
/// List of blend modes the openxr session can use. If [None], pick the first available blend mode.
|
|
||||||
pub blend_modes: Option<Vec<EnvironmentBlendMode>>,
|
|
||||||
/// List of backends the openxr session can use. If [None], pick the first available backend.
|
/// List of backends the openxr session can use. If [None], pick the first available backend.
|
||||||
pub backends: Option<Vec<GraphicsBackend>>,
|
pub backends: Option<Vec<GraphicsBackend>>,
|
||||||
/// List of formats the openxr session can use. If [None], pick the first available format
|
|
||||||
pub formats: Option<Vec<wgpu::TextureFormat>>,
|
|
||||||
/// List of resolutions that the openxr swapchain can use. If [None] pick the first available resolution.
|
|
||||||
pub resolutions: Option<Vec<UVec2>>,
|
|
||||||
/// Passed into the render plugin when added to the app.
|
/// Passed into the render plugin when added to the app.
|
||||||
pub synchronous_pipeline_compilation: bool,
|
pub synchronous_pipeline_compilation: bool,
|
||||||
pub render_debug_flags: RenderDebugFlags,
|
pub render_debug_flags: RenderDebugFlags,
|
||||||
@@ -76,10 +70,7 @@ impl Default for OxrInitPlugin {
|
|||||||
exts.enable_hand_tracking();
|
exts.enable_hand_tracking();
|
||||||
exts
|
exts
|
||||||
},
|
},
|
||||||
blend_modes: Some(vec![openxr::EnvironmentBlendMode::OPAQUE]),
|
|
||||||
backends: default(),
|
backends: default(),
|
||||||
formats: Some(vec![wgpu::TextureFormat::Rgba8UnormSrgb]),
|
|
||||||
resolutions: default(),
|
|
||||||
synchronous_pipeline_compilation: false,
|
synchronous_pipeline_compilation: false,
|
||||||
render_debug_flags: default(),
|
render_debug_flags: default(),
|
||||||
}
|
}
|
||||||
@@ -89,13 +80,14 @@ impl Default for OxrInitPlugin {
|
|||||||
impl Plugin for OxrInitPlugin {
|
impl Plugin for OxrInitPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_event::<OxrInteractionProfileChanged>();
|
app.add_event::<OxrInteractionProfileChanged>();
|
||||||
|
app.init_resource::<OxrSessionConfig>();
|
||||||
match self.init_xr() {
|
match self.init_xr() {
|
||||||
Ok((
|
Ok((
|
||||||
instance,
|
instance,
|
||||||
system_id,
|
system_id,
|
||||||
WgpuGraphics(device, queue, adapter_info, adapter, wgpu_instance),
|
WgpuGraphics(device, queue, adapter_info, adapter, wgpu_instance),
|
||||||
session_create_info,
|
|
||||||
enabled_exts,
|
enabled_exts,
|
||||||
|
graphics_info,
|
||||||
)) => {
|
)) => {
|
||||||
app.insert_resource(enabled_exts)
|
app.insert_resource(enabled_exts)
|
||||||
.add_plugins((
|
.add_plugins((
|
||||||
@@ -150,7 +142,7 @@ impl Plugin for OxrInitPlugin {
|
|||||||
unfocused_mode: UpdateMode::Continuous,
|
unfocused_mode: UpdateMode::Continuous,
|
||||||
})
|
})
|
||||||
.insert_resource(OxrSessionStarted(false))
|
.insert_resource(OxrSessionStarted(false))
|
||||||
.insert_non_send_resource(session_create_info)
|
.insert_non_send_resource(graphics_info)
|
||||||
.init_non_send_resource::<OxrSessionCreateNextChain>();
|
.init_non_send_resource::<OxrSessionCreateNextChain>();
|
||||||
|
|
||||||
app.world_mut()
|
app.world_mut()
|
||||||
@@ -215,8 +207,8 @@ impl OxrInitPlugin {
|
|||||||
OxrInstance,
|
OxrInstance,
|
||||||
OxrSystemId,
|
OxrSystemId,
|
||||||
WgpuGraphics,
|
WgpuGraphics,
|
||||||
SessionConfigInfo,
|
|
||||||
OxrEnabledExtensions,
|
OxrEnabledExtensions,
|
||||||
|
SessionGraphicsCreateInfo,
|
||||||
)> {
|
)> {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let entry = OxrEntry(openxr::Entry::linked());
|
let entry = OxrEntry(openxr::Entry::linked());
|
||||||
@@ -282,19 +274,12 @@ impl OxrInitPlugin {
|
|||||||
|
|
||||||
let (graphics, graphics_info) = instance.init_graphics(system_id)?;
|
let (graphics, graphics_info) = instance.init_graphics(system_id)?;
|
||||||
|
|
||||||
let session_create_info = SessionConfigInfo {
|
|
||||||
blend_modes: self.blend_modes.clone(),
|
|
||||||
formats: self.formats.clone(),
|
|
||||||
resolutions: self.resolutions.clone(),
|
|
||||||
graphics_info,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
instance,
|
instance,
|
||||||
OxrSystemId(system_id),
|
OxrSystemId(system_id),
|
||||||
graphics,
|
graphics,
|
||||||
session_create_info,
|
|
||||||
OxrEnabledExtensions(exts),
|
OxrEnabledExtensions(exts),
|
||||||
|
graphics_info,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -349,19 +334,19 @@ fn init_xr_session(
|
|||||||
instance: &OxrInstance,
|
instance: &OxrInstance,
|
||||||
system_id: openxr::SystemId,
|
system_id: openxr::SystemId,
|
||||||
chain: &mut OxrSessionCreateNextChain,
|
chain: &mut OxrSessionCreateNextChain,
|
||||||
SessionConfigInfo {
|
OxrSessionConfig {
|
||||||
blend_modes,
|
blend_modes,
|
||||||
formats,
|
formats,
|
||||||
resolutions,
|
resolutions,
|
||||||
graphics_info,
|
}: OxrSessionConfig,
|
||||||
}: SessionConfigInfo,
|
graphics_info: SessionGraphicsCreateInfo,
|
||||||
) -> OxrResult<(
|
) -> OxrResult<(
|
||||||
OxrSession,
|
OxrSession,
|
||||||
OxrFrameWaiter,
|
OxrFrameWaiter,
|
||||||
OxrFrameStream,
|
OxrFrameStream,
|
||||||
OxrSwapchain,
|
OxrSwapchain,
|
||||||
OxrSwapchainImages,
|
OxrSwapchainImages,
|
||||||
OxrGraphicsInfo,
|
OxrCurrentSessionConfig,
|
||||||
)> {
|
)> {
|
||||||
let (session, frame_waiter, frame_stream) =
|
let (session, frame_waiter, frame_stream) =
|
||||||
unsafe { instance.create_session(system_id, graphics_info, chain)? };
|
unsafe { instance.create_session(system_id, graphics_info, chain)? };
|
||||||
@@ -463,7 +448,7 @@ fn init_xr_session(
|
|||||||
}
|
}
|
||||||
.ok_or(OxrError::NoAvailableBlendMode)?;
|
.ok_or(OxrError::NoAvailableBlendMode)?;
|
||||||
|
|
||||||
let graphics_info = OxrGraphicsInfo {
|
let graphics_info = OxrCurrentSessionConfig {
|
||||||
blend_mode,
|
blend_mode,
|
||||||
resolution,
|
resolution,
|
||||||
format,
|
format,
|
||||||
@@ -485,14 +470,16 @@ pub fn create_xr_session(world: &mut World) {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let device = world.resource::<RenderDevice>();
|
let device = world.resource::<RenderDevice>();
|
||||||
let instance = world.resource::<OxrInstance>();
|
let instance = world.resource::<OxrInstance>();
|
||||||
let create_info = world.non_send_resource::<SessionConfigInfo>();
|
let session_config = world.resource::<OxrSessionConfig>();
|
||||||
|
let session_create_info = world.non_send_resource::<SessionGraphicsCreateInfo>();
|
||||||
let system_id = world.resource::<OxrSystemId>();
|
let system_id = world.resource::<OxrSystemId>();
|
||||||
match init_xr_session(
|
match init_xr_session(
|
||||||
device.wgpu_device(),
|
device.wgpu_device(),
|
||||||
instance,
|
instance,
|
||||||
**system_id,
|
**system_id,
|
||||||
&mut chain,
|
&mut chain,
|
||||||
create_info.clone(),
|
session_config.clone(),
|
||||||
|
session_create_info.clone(),
|
||||||
) {
|
) {
|
||||||
Ok((session, frame_waiter, frame_stream, swapchain, images, graphics_info)) => {
|
Ok((session, frame_waiter, frame_stream, swapchain, images, graphics_info)) => {
|
||||||
world.insert_resource(session.clone());
|
world.insert_resource(session.clone());
|
||||||
@@ -525,7 +512,7 @@ pub fn destroy_xr_session(world: &mut World) {
|
|||||||
world.remove_resource::<OxrFrameStream>();
|
world.remove_resource::<OxrFrameStream>();
|
||||||
world.remove_resource::<OxrSwapchain>();
|
world.remove_resource::<OxrSwapchain>();
|
||||||
world.remove_resource::<OxrSwapchainImages>();
|
world.remove_resource::<OxrSwapchainImages>();
|
||||||
world.remove_resource::<OxrGraphicsInfo>();
|
world.remove_resource::<OxrCurrentSessionConfig>();
|
||||||
world.insert_resource(XrState::Available);
|
world.insert_resource(XrState::Available);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,7 +557,7 @@ struct OxrRenderResources {
|
|||||||
frame_stream: OxrFrameStream,
|
frame_stream: OxrFrameStream,
|
||||||
swapchain: OxrSwapchain,
|
swapchain: OxrSwapchain,
|
||||||
images: OxrSwapchainImages,
|
images: OxrSwapchainImages,
|
||||||
graphics_info: OxrGraphicsInfo,
|
graphics_info: OxrCurrentSessionConfig,
|
||||||
session_destroy_flag: XrDestroySessionRender,
|
session_destroy_flag: XrDestroySessionRender,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ impl LayerProvider for ProjectionLayer {
|
|||||||
let stage = world.get_resource::<XrPrimaryReferenceSpace>()?;
|
let stage = world.get_resource::<XrPrimaryReferenceSpace>()?;
|
||||||
let openxr_views = world.get_resource::<OxrViews>()?;
|
let openxr_views = world.get_resource::<OxrViews>()?;
|
||||||
let swapchain = world.get_resource::<OxrSwapchain>()?;
|
let swapchain = world.get_resource::<OxrSwapchain>()?;
|
||||||
let graphics_info = world.get_resource::<OxrGraphicsInfo>()?;
|
let graphics_info = world.get_resource::<OxrCurrentSessionConfig>()?;
|
||||||
let rect = openxr::Rect2Di {
|
let rect = openxr::Rect2Di {
|
||||||
offset: openxr::Offset2Di { x: 0, y: 0 },
|
offset: openxr::Offset2Di { x: 0, y: 0 },
|
||||||
extent: openxr::Extent2Di {
|
extent: openxr::Extent2Di {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ impl Plugin for OxrRenderPlugin {
|
|||||||
|
|
||||||
app.add_plugins((
|
app.add_plugins((
|
||||||
ExtractResourcePlugin::<OxrFrameState>::default(),
|
ExtractResourcePlugin::<OxrFrameState>::default(),
|
||||||
ExtractResourcePlugin::<OxrGraphicsInfo>::default(),
|
ExtractResourcePlugin::<OxrCurrentSessionConfig>::default(),
|
||||||
ExtractResourcePlugin::<OxrSwapchainImages>::default(),
|
ExtractResourcePlugin::<OxrSwapchainImages>::default(),
|
||||||
ExtractResourcePlugin::<OxrViews>::default(),
|
ExtractResourcePlugin::<OxrViews>::default(),
|
||||||
))
|
))
|
||||||
@@ -151,7 +151,7 @@ pub fn clean_views(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_views<const SPAWN_CAMERAS: bool>(
|
pub fn init_views<const SPAWN_CAMERAS: bool>(
|
||||||
graphics_info: Res<OxrGraphicsInfo>,
|
graphics_info: Res<OxrCurrentSessionConfig>,
|
||||||
mut manual_texture_views: ResMut<ManualTextureViews>,
|
mut manual_texture_views: ResMut<ManualTextureViews>,
|
||||||
swapchain_images: Res<OxrSwapchainImages>,
|
swapchain_images: Res<OxrSwapchainImages>,
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
@@ -304,7 +304,7 @@ pub fn insert_texture_views(
|
|||||||
swapchain_images: Res<OxrSwapchainImages>,
|
swapchain_images: Res<OxrSwapchainImages>,
|
||||||
mut swapchain: ResMut<OxrSwapchain>,
|
mut swapchain: ResMut<OxrSwapchain>,
|
||||||
mut manual_texture_views: ResMut<ManualTextureViews>,
|
mut manual_texture_views: ResMut<ManualTextureViews>,
|
||||||
graphics_info: Res<OxrGraphicsInfo>,
|
graphics_info: Res<OxrCurrentSessionConfig>,
|
||||||
) {
|
) {
|
||||||
let index = swapchain.acquire_image().expect("Failed to acquire image");
|
let index = swapchain.acquire_image().expect("Failed to acquire image");
|
||||||
let image = &swapchain_images[index as usize];
|
let image = &swapchain_images[index as usize];
|
||||||
@@ -324,7 +324,7 @@ pub fn wait_image(mut swapchain: ResMut<OxrSwapchain>) {
|
|||||||
pub fn add_texture_view(
|
pub fn add_texture_view(
|
||||||
manual_texture_views: &mut ManualTextureViews,
|
manual_texture_views: &mut ManualTextureViews,
|
||||||
texture: &wgpu::Texture,
|
texture: &wgpu::Texture,
|
||||||
info: &OxrGraphicsInfo,
|
info: &OxrCurrentSessionConfig,
|
||||||
index: u32,
|
index: u32,
|
||||||
) -> ManualTextureViewHandle {
|
) -> ManualTextureViewHandle {
|
||||||
let view = texture.create_view(&wgpu::TextureViewDescriptor {
|
let view = texture.create_view(&wgpu::TextureViewDescriptor {
|
||||||
@@ -381,7 +381,7 @@ pub fn end_frame(world: &mut World) {
|
|||||||
let _span = debug_span!("xr_end_frame").entered();
|
let _span = debug_span!("xr_end_frame").entered();
|
||||||
if let Err(e) = frame_stream.end(
|
if let Err(e) = frame_stream.end(
|
||||||
frame_state.predicted_display_time,
|
frame_state.predicted_display_time,
|
||||||
world.resource::<OxrGraphicsInfo>().blend_mode,
|
world.resource::<OxrCurrentSessionConfig>().blend_mode,
|
||||||
&layers,
|
&layers,
|
||||||
) {
|
) {
|
||||||
error!("Failed to end frame stream: {e}");
|
error!("Failed to end frame stream: {e}");
|
||||||
|
|||||||
@@ -106,13 +106,13 @@ impl OxrInstance {
|
|||||||
pub fn init_graphics(
|
pub fn init_graphics(
|
||||||
&self,
|
&self,
|
||||||
system_id: openxr::SystemId,
|
system_id: openxr::SystemId,
|
||||||
) -> OxrResult<(WgpuGraphics, SessionCreateInfo)> {
|
) -> OxrResult<(WgpuGraphics, SessionGraphicsCreateInfo)> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
self.1;
|
self.1;
|
||||||
_ => {
|
_ => {
|
||||||
let (graphics, session_info) = Api::init_graphics(&self.2, self, system_id)?;
|
let (graphics, session_info) = Api::init_graphics(&self.2, self, system_id)?;
|
||||||
|
|
||||||
Ok((graphics, SessionCreateInfo(Api::wrap(session_info))))
|
Ok((graphics, SessionGraphicsCreateInfo(Api::wrap(session_info))))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -127,12 +127,12 @@ impl OxrInstance {
|
|||||||
pub unsafe fn create_session(
|
pub unsafe fn create_session(
|
||||||
&self,
|
&self,
|
||||||
system_id: openxr::SystemId,
|
system_id: openxr::SystemId,
|
||||||
info: SessionCreateInfo,
|
info: SessionGraphicsCreateInfo,
|
||||||
chain: &mut OxrSessionCreateNextChain,
|
chain: &mut OxrSessionCreateNextChain,
|
||||||
) -> OxrResult<(OxrSession, OxrFrameWaiter, OxrFrameStream)> {
|
) -> OxrResult<(OxrSession, OxrFrameWaiter, OxrFrameStream)> {
|
||||||
if !info.0.using_graphics_of_val(&self.1) {
|
if !info.0.using_graphics_of_val(&self.1) {
|
||||||
return OxrResult::Err(OxrError::GraphicsBackendMismatch {
|
return OxrResult::Err(OxrError::GraphicsBackendMismatch {
|
||||||
item: std::any::type_name::<SessionCreateInfo>(),
|
item: std::any::type_name::<SessionGraphicsCreateInfo>(),
|
||||||
backend: info.0.graphics_name(),
|
backend: info.0.graphics_name(),
|
||||||
expected_backend: self.1.graphics_name(),
|
expected_backend: self.1.graphics_name(),
|
||||||
});
|
});
|
||||||
@@ -330,23 +330,39 @@ pub struct OxrRenderLayers(pub Vec<Box<dyn LayerProvider + Send + Sync>>);
|
|||||||
|
|
||||||
/// Resource storing graphics info for the currently running session.
|
/// Resource storing graphics info for the currently running session.
|
||||||
#[derive(Clone, Copy, Resource, ExtractResource)]
|
#[derive(Clone, Copy, Resource, ExtractResource)]
|
||||||
pub struct OxrGraphicsInfo {
|
pub struct OxrCurrentSessionConfig {
|
||||||
pub blend_mode: EnvironmentBlendMode,
|
pub blend_mode: EnvironmentBlendMode,
|
||||||
pub resolution: UVec2,
|
pub resolution: UVec2,
|
||||||
pub format: wgpu::TextureFormat,
|
pub format: wgpu::TextureFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Resource, Debug)]
|
||||||
/// This is used to store information from startup that is needed to create the session after the instance has been created.
|
/// This is used to store information from startup that is needed to create the session after the instance has been created.
|
||||||
pub struct SessionConfigInfo {
|
pub struct OxrSessionConfig {
|
||||||
/// List of blend modes the openxr session can use. If [None], pick the first available blend mode.
|
/// List of blend modes the openxr session can use. If [None], pick the first available blend mode.
|
||||||
pub blend_modes: Option<Vec<EnvironmentBlendMode>>,
|
pub blend_modes: Option<Vec<EnvironmentBlendMode>>,
|
||||||
/// List of formats the openxr session can use. If [None], pick the first available format
|
/// List of formats the openxr session can use. If [None], pick the first available format
|
||||||
pub formats: Option<Vec<wgpu::TextureFormat>>,
|
pub formats: Option<Vec<wgpu::TextureFormat>>,
|
||||||
/// List of resolutions that the openxr swapchain can use. If [None] pick the first available resolution.
|
/// List of resolutions that the openxr swapchain can use. If [None] pick the first available resolution.
|
||||||
pub resolutions: Option<Vec<UVec2>>,
|
pub resolutions: Option<Vec<UVec2>>,
|
||||||
/// Graphics info used to create a session.
|
}
|
||||||
pub graphics_info: SessionCreateInfo,
|
impl Default for OxrSessionConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
blend_modes: Some(vec![openxr::EnvironmentBlendMode::OPAQUE]),
|
||||||
|
formats: Some(vec![wgpu::TextureFormat::Rgba8UnormSrgb]),
|
||||||
|
resolutions: default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Info needed to create a session. Mostly contains graphics info.
|
||||||
|
/// This is an API agnostic version of [openxr::Graphics::SessionCreateInfo] used for some of this library's functions
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct SessionGraphicsCreateInfo(pub GraphicsWrap<Self>);
|
||||||
|
|
||||||
|
impl GraphicsType for SessionGraphicsCreateInfo {
|
||||||
|
type Inner<G: GraphicsExt> = G::SessionCreateInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ExtractResource, Resource, Clone, Default)]
|
#[derive(ExtractResource, Resource, Clone, Default)]
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ use bevy::{platform::collections::hash_set::HashSet, prelude::*};
|
|||||||
use bevy_mod_xr::{
|
use bevy_mod_xr::{
|
||||||
session::{XrFirst, XrHandleEvents},
|
session::{XrFirst, XrHandleEvents},
|
||||||
spaces::{
|
spaces::{
|
||||||
XrDestroySpace, XrPrimaryReferenceSpace, XrReferenceSpace, XrSpace, XrSpaceLocationFlags,
|
XrDestroySpace, XrPrimaryReferenceSpace, XrReferenceSpace, XrSpace, XrSpaceLocationFlags, XrSpaceSyncSet, XrSpaceVelocityFlags, XrVelocity
|
||||||
XrSpaceVelocityFlags, XrVelocity,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use openxr::{
|
use openxr::{
|
||||||
@@ -20,9 +19,6 @@ use crate::{
|
|||||||
session::OxrSession,
|
session::OxrSession,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(SystemSet, Hash, Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
pub struct OxrSpaceSyncSet;
|
|
||||||
|
|
||||||
/// VERY IMPORTANT!! only disable when you know what you are doing
|
/// VERY IMPORTANT!! only disable when you know what you are doing
|
||||||
pub struct OxrSpacePatchingPlugin;
|
pub struct OxrSpacePatchingPlugin;
|
||||||
impl Plugin for OxrSpacePatchingPlugin {
|
impl Plugin for OxrSpacePatchingPlugin {
|
||||||
@@ -47,7 +43,7 @@ impl Plugin for OxrSpatialPlugin {
|
|||||||
.add_systems(
|
.add_systems(
|
||||||
PreUpdate,
|
PreUpdate,
|
||||||
update_space_transforms
|
update_space_transforms
|
||||||
.in_set(OxrSpaceSyncSet)
|
.in_set(XrSpaceSyncSet)
|
||||||
.run_if(openxr_session_running),
|
.run_if(openxr_session_running),
|
||||||
)
|
)
|
||||||
.register_required_components::<XrSpaceLocationFlags, OxrSpaceLocationFlags>()
|
.register_required_components::<XrSpaceLocationFlags, OxrSpaceLocationFlags>()
|
||||||
|
|||||||
@@ -87,12 +87,3 @@ impl<G: GraphicsExt> TryFrom<SwapchainCreateInfo> for openxr::SwapchainCreateInf
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Info needed to create a session. Mostly contains graphics info.
|
|
||||||
/// This is an API agnostic version of [openxr::Graphics::SessionCreateInfo] used for some of this library's functions
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct SessionCreateInfo(pub GraphicsWrap<Self>);
|
|
||||||
|
|
||||||
impl GraphicsType for SessionCreateInfo {
|
|
||||||
type Inner<G: GraphicsExt> = G::SessionCreateInfo;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ use bevy::{
|
|||||||
|
|
||||||
use crate::session::XrTracker;
|
use crate::session::XrTracker;
|
||||||
|
|
||||||
|
#[derive(SystemSet, Hash, Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub struct XrSpaceSyncSet;
|
||||||
|
|
||||||
/// Any Spaces will be invalid after the owning session exits
|
/// Any Spaces will be invalid after the owning session exits
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Component, Clone, Copy, Hash, PartialEq, Eq, Reflect, Debug, ExtractComponent)]
|
#[derive(Component, Clone, Copy, Hash, PartialEq, Eq, Reflect, Debug, ExtractComponent)]
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ use bevy_mod_openxr::{
|
|||||||
openxr_session_available, openxr_session_running,
|
openxr_session_available, openxr_session_running,
|
||||||
resources::{OxrFrameState, OxrInstance, Pipelined},
|
resources::{OxrFrameState, OxrInstance, Pipelined},
|
||||||
session::OxrSession,
|
session::OxrSession,
|
||||||
spaces::{OxrSpaceLocationFlags, OxrSpaceSyncSet},
|
spaces::OxrSpaceLocationFlags,
|
||||||
};
|
};
|
||||||
use bevy_mod_xr::{
|
use bevy_mod_xr::{
|
||||||
session::{XrSessionCreated, XrTracker, XrTrackingRoot},
|
session::{XrSessionCreated, XrTracker, XrTrackingRoot},
|
||||||
spaces::{XrPrimaryReferenceSpace, XrReferenceSpace},
|
spaces::{XrPrimaryReferenceSpace, XrReferenceSpace, XrSpaceSyncSet},
|
||||||
};
|
};
|
||||||
use openxr::Posef;
|
use openxr::Posef;
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ impl Plugin for TrackingUtilitiesPlugin {
|
|||||||
app.add_systems(
|
app.add_systems(
|
||||||
PreUpdate,
|
PreUpdate,
|
||||||
update_head_transforms
|
update_head_transforms
|
||||||
.in_set(OxrSpaceSyncSet)
|
.in_set(XrSpaceSyncSet)
|
||||||
.run_if(openxr_session_running),
|
.run_if(openxr_session_running),
|
||||||
);
|
);
|
||||||
//external
|
//external
|
||||||
@@ -73,8 +73,8 @@ impl Plugin for TrackingUtilitiesPlugin {
|
|||||||
//create actions
|
//create actions
|
||||||
app.add_systems(Startup, create_actions.run_if(openxr_session_available));
|
app.add_systems(Startup, create_actions.run_if(openxr_session_available));
|
||||||
|
|
||||||
app.add_systems(PreUpdate, update_left_grip.after(OxrSpaceSyncSet));
|
app.add_systems(PreUpdate, update_left_grip.after(XrSpaceSyncSet));
|
||||||
app.add_systems(PreUpdate, update_right_grip.after(OxrSpaceSyncSet));
|
app.add_systems(PreUpdate, update_right_grip.after(XrSpaceSyncSet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user