renamed types and fixed errors

This commit is contained in:
awtterpip
2024-04-18 17:26:36 -05:00
parent f585c9e2dc
commit e2f7f840a9
13 changed files with 187 additions and 263 deletions

View File

@@ -7,14 +7,16 @@ edition = "2021"
default = ["vulkan"]
vulkan = ["dep:ash"]
# all dependencies are placed under this since on wasm, this crate is completely empty
# bevy can't be placed behind target or proc macros won't work properly
[dependencies]
bevy.workspace = true
# all other dependencies are placed under this since on wasm, this crate is completely empty
[target.'cfg(not(target_family = "wasm"))'.dependencies]
thiserror = "1.0.57"
wgpu = "0.19.3"
wgpu-hal = "0.19.3"
bevy_xr.path = "../bevy_xr"
bevy.workspace = true
ash = { version = "0.37.3", optional = true }

View File

@@ -6,7 +6,7 @@ use super::graphics::GraphicsBackend;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum OXrError {
pub enum OxrError {
#[error("OpenXR error: {0}")]
OpenXrError(#[from] openxr::sys::Result),
#[error("OpenXR loading error: {0}")]
@@ -52,7 +52,7 @@ pub use init_error::InitError;
/// This module is needed because thiserror does not allow conditional compilation within enums for some reason,
/// so graphics api specific errors are implemented here.
mod init_error {
use super::OXrError;
use super::OxrError;
use std::fmt;
#[derive(Debug)]
@@ -77,21 +77,21 @@ mod init_error {
}
#[cfg(feature = "vulkan")]
impl From<ash::vk::Result> for OXrError {
impl From<ash::vk::Result> for OxrError {
fn from(value: ash::vk::Result) -> Self {
Self::InitError(InitError::VulkanError(value))
}
}
#[cfg(feature = "vulkan")]
impl From<ash::LoadingError> for OXrError {
impl From<ash::LoadingError> for OxrError {
fn from(value: ash::LoadingError) -> Self {
Self::InitError(InitError::VulkanLoadingError(value))
}
}
}
impl From<Vec<Cow<'static, str>>> for OXrError {
impl From<Vec<Cow<'static, str>>> for OxrError {
fn from(value: Vec<Cow<'static, str>>) -> Self {
Self::UnavailableExtensions(UnavailableExts(value))
}

View File

@@ -2,8 +2,8 @@ use bevy::prelude::{Deref, DerefMut};
use openxr::ExtensionSet;
#[derive(Clone, Debug, Eq, PartialEq, Deref, DerefMut)]
pub struct OXrExtensions(ExtensionSet);
impl OXrExtensions {
pub struct OxrExtensions(ExtensionSet);
impl OxrExtensions {
pub fn raw_mut(&mut self) -> &mut ExtensionSet {
&mut self.0
}
@@ -27,21 +27,21 @@ impl OXrExtensions {
self
}
/// returns true if all of the extensions enabled are also available in `available_exts`
pub fn is_available(&self, available_exts: &OXrExtensions) -> bool {
pub fn is_available(&self, available_exts: &OxrExtensions) -> bool {
self.clone() & available_exts.clone() == *self
}
}
impl From<ExtensionSet> for OXrExtensions {
impl From<ExtensionSet> for OxrExtensions {
fn from(value: ExtensionSet) -> Self {
Self(value)
}
}
impl From<OXrExtensions> for ExtensionSet {
fn from(val: OXrExtensions) -> Self {
impl From<OxrExtensions> for ExtensionSet {
fn from(val: OxrExtensions) -> Self {
val.0
}
}
impl Default for OXrExtensions {
impl Default for OxrExtensions {
fn default() -> Self {
let exts = ExtensionSet::default();
//exts.ext_hand_tracking = true;
@@ -165,7 +165,7 @@ macro_rules! impl_ext {
) => {
$(
$macro! {
OXrExtensions;
OxrExtensions;
almalence_digital_lens_control,
bd_controller_interaction,
epic_view_configuration_fov,

View File

@@ -5,14 +5,14 @@ use std::any::TypeId;
use bevy::math::UVec2;
use crate::types::{AppInfo, OXrExtensions, Result, WgpuGraphics};
use crate::types::{AppInfo, OxrExtensions, Result, WgpuGraphics};
/// This is an extension trait to the [`Graphics`](openxr::Graphics) trait and is how the graphics API should be interacted with.
pub unsafe trait GraphicsExt: openxr::Graphics {
/// Wrap the graphics specific type into the [GraphicsWrap] enum
fn wrap<T: GraphicsType>(item: T::Inner<Self>) -> GraphicsWrap<T>;
/// Returns all of the required openxr extensions to use this graphics API.
fn required_exts() -> OXrExtensions;
fn required_exts() -> OxrExtensions;
/// Convert from wgpu format to the graphics format
fn from_wgpu_format(format: wgpu::TextureFormat) -> Option<Self::Format>;
/// Convert from the graphics format to wgpu format
@@ -64,7 +64,7 @@ pub type GraphicsBackend = GraphicsWrap<()>;
impl GraphicsBackend {
const ALL: &'static [Self] = &[Self::Vulkan(())];
pub fn available_backends(exts: &OXrExtensions) -> Vec<Self> {
pub fn available_backends(exts: &OxrExtensions) -> Vec<Self> {
Self::ALL
.iter()
.copied()
@@ -72,11 +72,11 @@ impl GraphicsBackend {
.collect()
}
pub fn is_available(&self, exts: &OXrExtensions) -> bool {
pub fn is_available(&self, exts: &OxrExtensions) -> bool {
self.required_exts().is_available(exts)
}
pub fn required_exts(&self) -> OXrExtensions {
pub fn required_exts(&self) -> OxrExtensions {
graphics_match!(
self;
_ => Api::required_exts()
@@ -125,14 +125,14 @@ impl<T: GraphicsType> GraphicsWrap<T> {
/// # Example
///
/// ```
/// pub struct OXrFrameStream(GraphicsWrap<XrFrameStream>);
/// pub struct OxrFrameStream(GraphicsWrap<XrFrameStream>);
///
/// impl GraphicsType for OXrFrameStream {
/// impl GraphicsType for OxrFrameStream {
/// // Here is the inner type
/// type Inner<G: GraphicsExt> = openxr::FrameStream<G>;
/// }
///
/// fn begin(frame_stream: &mut XrFrameStream) {
/// fn begin(frame_stream: &mut OxrFrameStream) {
/// graphics_match! {
/// // get the inner 'GraphicsWrap' struct
/// &mut frame_stream.0;

View File

@@ -8,8 +8,8 @@ use wgpu_hal::api::Vulkan;
use wgpu_hal::Api;
use super::{GraphicsExt, GraphicsType, GraphicsWrap};
use crate::error::OXrError;
use crate::types::{AppInfo, OXrExtensions, Result, WgpuGraphics};
use crate::error::OxrError;
use crate::types::{AppInfo, OxrExtensions, Result, WgpuGraphics};
#[cfg(not(target_os = "android"))]
const VK_TARGET_VERSION: Version = Version::new(1, 2, 0);
@@ -28,7 +28,7 @@ unsafe impl GraphicsExt for openxr::Vulkan {
GraphicsWrap::Vulkan(item)
}
fn required_exts() -> OXrExtensions {
fn required_exts() -> OxrExtensions {
let mut extensions = openxr::ExtensionSet::default();
extensions.khr_vulkan_enable2 = true;
extensions.into()
@@ -106,7 +106,7 @@ unsafe impl GraphicsExt for openxr::Vulkan {
reqs.min_api_version_supported,
reqs.max_api_version_supported.major() + 1
);
return Err(OXrError::FailedGraphicsRequirements);
return Err(OxrError::FailedGraphicsRequirements);
};
let vk_entry = unsafe { ash::Entry::load() }?;
let flags = wgpu::InstanceFlags::empty();
@@ -165,7 +165,7 @@ unsafe impl GraphicsExt for openxr::Vulkan {
VK_TARGET_VERSION.minor(),
VK_TARGET_VERSION.patch()
);
return Err(OXrError::FailedGraphicsRequirements);
return Err(OxrError::FailedGraphicsRequirements);
}
let wgpu_vk_instance = unsafe {
@@ -189,7 +189,7 @@ unsafe impl GraphicsExt for openxr::Vulkan {
let Some(wgpu_exposed_adapter) = wgpu_vk_instance.expose_adapter(vk_physical_device) else {
error!("WGPU failed to provide an adapter");
return Err(OXrError::FailedGraphicsRequirements);
return Err(OxrError::FailedGraphicsRequirements);
};
let enabled_extensions = wgpu_exposed_adapter

View File

@@ -25,27 +25,27 @@ use bevy_xr::session::EndXrSession;
use bevy_xr::session::XrSharedStatus;
use bevy_xr::session::XrStatus;
use crate::error::OXrError;
use crate::error::OxrError;
use crate::graphics::*;
use crate::resources::*;
use crate::types::*;
pub fn session_started(started: Option<Res<OXrSessionStarted>>) -> bool {
pub fn session_started(started: Option<Res<OxrSessionStarted>>) -> bool {
started.is_some_and(|started| started.get())
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, SystemSet)]
pub enum OXrPreUpdateSet {
pub enum OxrPreUpdateSet {
PollEvents,
HandleEvents,
}
pub struct OXrInitPlugin {
pub struct OxrInitPlugin {
/// Information about the app this is being used to build.
pub app_info: AppInfo,
/// 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
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.
@@ -59,9 +59,9 @@ pub struct OXrInitPlugin {
}
#[derive(Component)]
pub struct OXrTrackingRoot;
pub struct OxrTrackingRoot;
impl Plugin for OXrInitPlugin {
impl Plugin for OxrInitPlugin {
fn build(&self, app: &mut App) {
match self.init_xr() {
Ok((
@@ -83,9 +83,9 @@ impl Plugin for OXrInitPlugin {
),
synchronous_pipeline_compilation: self.synchronous_pipeline_compilation,
},
ExtractResourcePlugin::<OXrCleanupSession>::default(),
ExtractResourcePlugin::<OXrTime>::default(),
ExtractResourcePlugin::<OXrRootTransform>::default(),
ExtractResourcePlugin::<OxrCleanupSession>::default(),
ExtractResourcePlugin::<OxrTime>::default(),
ExtractResourcePlugin::<OxrRootTransform>::default(),
))
.add_systems(First, reset_per_frame_resources)
.add_systems(
@@ -93,7 +93,7 @@ impl Plugin for OXrInitPlugin {
(
poll_events
.run_if(session_available)
.in_set(OXrPreUpdateSet::PollEvents),
.in_set(OxrPreUpdateSet::PollEvents),
(
(create_xr_session, apply_deferred)
.chain()
@@ -109,7 +109,7 @@ impl Plugin for OXrInitPlugin {
.run_if(on_event::<DestroyXrSession>())
.run_if(status_equals(XrStatus::Exiting)),
)
.in_set(OXrPreUpdateSet::HandleEvents),
.in_set(OxrPreUpdateSet::HandleEvents),
),
)
.add_systems(
@@ -123,24 +123,24 @@ impl Plugin for OXrInitPlugin {
focused_mode: UpdateMode::Continuous,
unfocused_mode: UpdateMode::Continuous,
})
.init_resource::<OXrCleanupSession>()
.init_resource::<OXrRootTransform>()
.init_resource::<OxrCleanupSession>()
.init_resource::<OxrRootTransform>()
.insert_non_send_resource(session_create_info);
app.world
.spawn((TransformBundle::default(), OXrTrackingRoot));
.spawn((TransformBundle::default(), OxrTrackingRoot));
let render_app = app.sub_app_mut(RenderApp);
render_app
.insert_resource(instance)
.insert_resource(system_id)
.insert_resource(status)
.init_resource::<OXrRootTransform>()
.init_resource::<OXrCleanupSession>()
.init_resource::<OxrRootTransform>()
.init_resource::<OxrCleanupSession>()
.add_systems(
Render,
destroy_xr_session_render
.run_if(resource_equals(OXrCleanupSession(true)))
.run_if(resource_equals(OxrCleanupSession(true)))
.after(RenderSet::ExtractCommands),
)
.add_systems(
@@ -164,12 +164,12 @@ impl Plugin for OXrInitPlugin {
app.configure_sets(
PreUpdate,
(
OXrPreUpdateSet::PollEvents.before(handle_session),
OXrPreUpdateSet::HandleEvents.after(handle_session),
OxrPreUpdateSet::PollEvents.before(handle_session),
OxrPreUpdateSet::HandleEvents.after(handle_session),
),
);
let session_started = OXrSessionStarted::default();
let session_started = OxrSessionStarted::default();
app.insert_resource(session_started.clone());
@@ -180,24 +180,24 @@ impl Plugin for OXrInitPlugin {
}
pub fn update_root_transform(
mut root_transform: ResMut<OXrRootTransform>,
root: Query<&GlobalTransform, With<OXrTrackingRoot>>,
mut root_transform: ResMut<OxrRootTransform>,
root: Query<&GlobalTransform, With<OxrTrackingRoot>>,
) {
let transform = root.single();
root_transform.0 = *transform;
}
fn xr_entry() -> Result<OXrEntry> {
fn xr_entry() -> Result<OxrEntry> {
#[cfg(windows)]
let entry = openxr::Entry::linked();
#[cfg(not(windows))]
let entry = unsafe { openxr::Entry::load()? };
Ok(OXrEntry(entry))
Ok(OxrEntry(entry))
}
impl OXrInitPlugin {
fn init_xr(&self) -> Result<(OXrInstance, OXrSystemId, WgpuGraphics, SessionConfigInfo)> {
impl OxrInitPlugin {
fn init_xr(&self) -> Result<(OxrInstance, OxrSystemId, WgpuGraphics, SessionConfigInfo)> {
let entry = xr_entry()?;
let available_exts = entry.enumerate_extensions()?;
@@ -224,7 +224,7 @@ impl OXrInitPlugin {
} else {
available_backends.first().copied()
}
.ok_or(OXrError::NoAvailableBackend)?;
.ok_or(OxrError::NoAvailableBackend)?;
let exts = self.exts.clone() & available_exts;
@@ -265,7 +265,7 @@ impl OXrInitPlugin {
Ok((
instance,
OXrSystemId(system_id),
OxrSystemId(system_id),
graphics,
session_create_info,
))
@@ -274,7 +274,7 @@ impl OXrInitPlugin {
fn init_xr_session(
device: &wgpu::Device,
instance: &OXrInstance,
instance: &OxrInstance,
system_id: openxr::SystemId,
SessionConfigInfo {
blend_modes,
@@ -283,13 +283,13 @@ fn init_xr_session(
graphics_info,
}: SessionConfigInfo,
) -> Result<(
OXrSession,
OXrFrameWaiter,
OXrFrameStream,
OXrSwapchain,
OXrSwapchainImages,
OXrGraphicsInfo,
OXrStage,
OxrSession,
OxrFrameWaiter,
OxrFrameStream,
OxrSwapchain,
OxrSwapchainImages,
OxrGraphicsInfo,
OxrStage,
)> {
let (session, frame_waiter, frame_stream) =
unsafe { instance.create_session(system_id, graphics_info)? };
@@ -297,7 +297,7 @@ fn init_xr_session(
// TODO!() support other view configurations
let available_view_configurations = instance.enumerate_view_configurations(system_id)?;
if !available_view_configurations.contains(&openxr::ViewConfigurationType::PRIMARY_STEREO) {
return Err(OXrError::NoAvailableViewConfiguration);
return Err(OxrError::NoAvailableViewConfiguration);
}
let view_configuration_type = openxr::ViewConfigurationType::PRIMARY_STEREO;
@@ -343,7 +343,7 @@ fn init_xr_session(
None
}
}
.ok_or(OXrError::NoAvailableViewConfiguration)?;
.ok_or(OxrError::NoAvailableViewConfiguration)?;
let available_formats = session.enumerate_swapchain_formats()?;
@@ -358,7 +358,7 @@ fn init_xr_session(
} else {
available_formats.first().copied()
}
.ok_or(OXrError::NoAvailableFormat)?;
.ok_or(OxrError::NoAvailableFormat)?;
let swapchain = session.create_swapchain(SwapchainCreateInfo {
create_flags: SwapchainCreateFlags::EMPTY,
@@ -391,15 +391,15 @@ fn init_xr_session(
} else {
available_blend_modes.first().copied()
}
.ok_or(OXrError::NoAvailableBackend)?;
.ok_or(OxrError::NoAvailableBackend)?;
let stage = OXrStage(
let stage = OxrStage(
session
.create_reference_space(openxr::ReferenceSpaceType::STAGE, openxr::Posef::IDENTITY)?
.into(),
);
let graphics_info = OXrGraphicsInfo {
let graphics_info = OxrGraphicsInfo {
blend_mode,
resolution,
format,
@@ -419,19 +419,19 @@ fn init_xr_session(
/// This is used solely to transport resources from the main world to the render world.
#[derive(Resource)]
struct XrRenderResources {
session: OXrSession,
frame_stream: OXrFrameStream,
swapchain: OXrSwapchain,
images: OXrSwapchainImages,
graphics_info: OXrGraphicsInfo,
stage: OXrStage,
session: OxrSession,
frame_stream: OxrFrameStream,
swapchain: OxrSwapchain,
images: OxrSwapchainImages,
graphics_info: OxrGraphicsInfo,
stage: OxrStage,
}
pub fn create_xr_session(
device: Res<RenderDevice>,
instance: Res<OXrInstance>,
instance: Res<OxrInstance>,
create_info: NonSend<SessionConfigInfo>,
system_id: Res<OXrSystemId>,
system_id: Res<OxrSystemId>,
mut commands: Commands,
) {
match init_xr_session(
@@ -459,7 +459,7 @@ pub fn create_xr_session(
}
}
pub fn begin_xr_session(session: Res<OXrSession>, session_started: Res<OXrSessionStarted>) {
pub fn begin_xr_session(session: Res<OxrSession>, session_started: Res<OxrSessionStarted>) {
let _span = info_span!("xr_begin_session");
session
.begin(openxr::ViewConfigurationType::PRIMARY_STEREO)
@@ -467,7 +467,7 @@ pub fn begin_xr_session(session: Res<OXrSession>, session_started: Res<OXrSessio
session_started.set(true);
}
pub fn end_xr_session(session: Res<OXrSession>, session_started: Res<OXrSessionStarted>) {
pub fn end_xr_session(session: Res<OxrSession>, session_started: Res<OxrSessionStarted>) {
let _span = info_span!("xr_end_session");
session.end().expect("Failed to end session");
session_started.set(false);
@@ -496,7 +496,7 @@ pub fn transfer_xr_resources(mut commands: Commands, mut world: ResMut<MainWorld
}
/// Polls any OpenXR events and handles them accordingly
pub fn poll_events(instance: Res<OXrInstance>, status: Res<XrSharedStatus>) {
pub fn poll_events(instance: Res<OxrInstance>, status: Res<XrSharedStatus>) {
let _span = info_span!("xr_poll_events");
let mut buffer = Default::default();
while let Some(event) = instance
@@ -532,24 +532,24 @@ pub fn poll_events(instance: Res<OXrInstance>, status: Res<XrSharedStatus>) {
}
}
pub fn reset_per_frame_resources(mut cleanup: ResMut<OXrCleanupSession>) {
pub fn reset_per_frame_resources(mut cleanup: ResMut<OxrCleanupSession>) {
**cleanup = false;
}
pub fn destroy_xr_session(mut commands: Commands) {
commands.remove_resource::<OXrSession>();
commands.remove_resource::<OXrFrameWaiter>();
commands.remove_resource::<OXrSwapchainImages>();
commands.remove_resource::<OXrGraphicsInfo>();
commands.remove_resource::<OXrStage>();
commands.insert_resource(OXrCleanupSession(true));
commands.remove_resource::<OxrSession>();
commands.remove_resource::<OxrFrameWaiter>();
commands.remove_resource::<OxrSwapchainImages>();
commands.remove_resource::<OxrGraphicsInfo>();
commands.remove_resource::<OxrStage>();
commands.insert_resource(OxrCleanupSession(true));
}
pub fn destroy_xr_session_render(world: &mut World) {
world.remove_resource::<OXrSwapchain>();
world.remove_resource::<OXrFrameStream>();
world.remove_resource::<OXrStage>();
world.remove_resource::<OXrSwapchainImages>();
world.remove_resource::<OXrGraphicsInfo>();
world.remove_resource::<OXrSession>();
world.remove_resource::<OxrSwapchain>();
world.remove_resource::<OxrFrameStream>();
world.remove_resource::<OxrStage>();
world.remove_resource::<OxrSwapchainImages>();
world.remove_resource::<OxrGraphicsInfo>();
world.remove_resource::<OxrSession>();
}

View File

@@ -3,12 +3,12 @@ use std::mem;
use openxr::{sys, CompositionLayerFlags, Fovf, Posef, Rect2Di, Space};
use crate::graphics::graphics_match;
use crate::resources::OXrSwapchain;
use crate::resources::OxrSwapchain;
#[derive(Copy, Clone)]
pub struct SwapchainSubImage<'a> {
inner: sys::SwapchainSubImage,
swapchain: Option<&'a OXrSwapchain>,
swapchain: Option<&'a OxrSwapchain>,
}
impl<'a> SwapchainSubImage<'a> {
@@ -30,7 +30,7 @@ impl<'a> SwapchainSubImage<'a> {
&self.inner
}
#[inline]
pub fn swapchain(mut self, value: &'a OXrSwapchain) -> Self {
pub fn swapchain(mut self, value: &'a OxrSwapchain) -> Self {
graphics_match!(
&value.0;
swap => self.inner.swapchain = swap.as_raw()
@@ -59,7 +59,7 @@ impl<'a> Default for SwapchainSubImage<'a> {
#[derive(Copy, Clone)]
pub struct CompositionLayerProjectionView<'a> {
inner: sys::CompositionLayerProjectionView,
swapchain: Option<&'a OXrSwapchain>,
swapchain: Option<&'a OxrSwapchain>,
}
impl<'a> CompositionLayerProjectionView<'a> {
@@ -104,13 +104,13 @@ impl<'a> Default for CompositionLayerProjectionView<'a> {
}
}
pub unsafe trait CompositionLayer<'a> {
fn swapchain(&self) -> Option<&'a OXrSwapchain>;
fn swapchain(&self) -> Option<&'a OxrSwapchain>;
fn header(&self) -> &'a sys::CompositionLayerBaseHeader;
}
#[derive(Clone)]
pub struct CompositionLayerProjection<'a> {
inner: sys::CompositionLayerProjection,
swapchain: Option<&'a OXrSwapchain>,
swapchain: Option<&'a OxrSwapchain>,
views: Vec<sys::CompositionLayerProjectionView>,
}
impl<'a> CompositionLayerProjection<'a> {
@@ -154,7 +154,7 @@ impl<'a> CompositionLayerProjection<'a> {
}
}
unsafe impl<'a> CompositionLayer<'a> for CompositionLayerProjection<'a> {
fn swapchain(&self) -> Option<&'a OXrSwapchain> {
fn swapchain(&self) -> Option<&'a OxrSwapchain> {
self.swapchain
}

View File

@@ -7,7 +7,7 @@ use bevy::{
};
use bevy_xr::camera::XrCameraPlugin;
use bevy_xr::session::XrSessionPlugin;
use init::OXrInitPlugin;
use init::OxrInitPlugin;
use render::XrRenderPlugin;
pub mod error;
@@ -25,7 +25,7 @@ pub fn add_xr_plugins<G: PluginGroup>(plugins: G) -> PluginGroupBuilder {
.disable::<RenderPlugin>()
.disable::<PipelinedRenderingPlugin>()
.add_before::<RenderPlugin, _>(XrSessionPlugin)
.add_before::<RenderPlugin, _>(OXrInitPlugin {
.add_before::<RenderPlugin, _>(OxrInitPlugin {
app_info: default(),
exts: default(),
blend_modes: default(),

View File

@@ -12,7 +12,7 @@ use bevy::{
use bevy_xr::camera::{XrCamera, XrCameraBundle, XrProjection};
use openxr::{CompositionLayerFlags, ViewStateFlags};
use crate::init::{session_started, OXrPreUpdateSet};
use crate::init::{session_started, OxrPreUpdateSet};
use crate::layer_builder::*;
use crate::resources::*;
@@ -20,17 +20,17 @@ pub struct XrRenderPlugin;
impl Plugin for XrRenderPlugin {
fn build(&self, app: &mut App) {
app.add_plugins((ExtractResourcePlugin::<OXrViews>::default(),))
app.add_plugins((ExtractResourcePlugin::<OxrViews>::default(),))
.add_systems(
PreUpdate,
(
init_views.run_if(resource_added::<OXrGraphicsInfo>),
init_views.run_if(resource_added::<OxrGraphicsInfo>),
wait_frame.run_if(session_started),
locate_views.run_if(session_started),
update_views.run_if(session_started),
)
.chain()
.after(OXrPreUpdateSet::HandleEvents),
.after(OxrPreUpdateSet::HandleEvents),
)
.add_systems(
PostUpdate,
@@ -65,9 +65,9 @@ pub const XR_TEXTURE_INDEX: u32 = 3383858418;
// TODO: have cameras initialized externally and then recieved by this function.
/// This is needed to properly initialize the texture views so that bevy will set them to the correct resolution despite them being updated in the render world.
pub fn init_views(
graphics_info: Res<OXrGraphicsInfo>,
graphics_info: Res<OxrGraphicsInfo>,
mut manual_texture_views: ResMut<ManualTextureViews>,
swapchain_images: Res<OXrSwapchainImages>,
swapchain_images: Res<OxrSwapchainImages>,
mut commands: Commands,
) {
let _span = info_span!("xr_init_views");
@@ -93,22 +93,22 @@ pub fn init_views(
));
views.push(default());
}
commands.insert_resource(OXrViews(views));
commands.insert_resource(OxrViews(views));
}
pub fn wait_frame(mut frame_waiter: ResMut<OXrFrameWaiter>, mut commands: Commands) {
pub fn wait_frame(mut frame_waiter: ResMut<OxrFrameWaiter>, mut commands: Commands) {
let _span = info_span!("xr_wait_frame");
let state = frame_waiter.wait().expect("Failed to wait frame");
// Here we insert the predicted display time for when this frame will be displayed.
// TODO: don't add predicted_display_period if pipelined rendering plugin not enabled
commands.insert_resource(OXrTime(state.predicted_display_time));
commands.insert_resource(OxrTime(state.predicted_display_time));
}
pub fn locate_views(
session: Res<OXrSession>,
stage: Res<OXrStage>,
time: Res<OXrTime>,
mut openxr_views: ResMut<OXrViews>,
session: Res<OxrSession>,
stage: Res<OxrStage>,
time: Res<OxrTime>,
mut openxr_views: ResMut<OxrViews>,
) {
let _span = info_span!("xr_locate_views");
let (flags, xr_views) = session
@@ -125,7 +125,7 @@ pub fn locate_views(
flags & ViewStateFlags::ORIENTATION_VALID == ViewStateFlags::ORIENTATION_VALID,
flags & ViewStateFlags::POSITION_VALID == ViewStateFlags::POSITION_VALID,
) {
(true, true) => *openxr_views = OXrViews(xr_views),
(true, true) => *openxr_views = OxrViews(xr_views),
(true, false) => {
for (i, view) in openxr_views.iter_mut().enumerate() {
view.pose.orientation = xr_views[i].pose.orientation;
@@ -142,7 +142,7 @@ pub fn locate_views(
pub fn update_views(
mut query: Query<(&mut Transform, &mut XrProjection, &XrCamera)>,
views: ResMut<OXrViews>,
views: ResMut<OxrViews>,
) {
for (mut transform, mut projection, camera) in query.iter_mut() {
let Some(view) = views.get(camera.0 as usize) else {
@@ -162,8 +162,8 @@ pub fn update_views(
}
pub fn update_views_render_world(
views: Res<OXrViews>,
root: Res<OXrRootTransform>,
views: Res<OxrViews>,
root: Res<OxrRootTransform>,
mut query: Query<(&mut ExtractedView, &XrCamera)>,
) {
for (mut extracted_view, camera) in query.iter_mut() {
@@ -280,10 +280,10 @@ fn calculate_projection(near_z: f32, fov: openxr::Fovf) -> Mat4 {
/// # Safety
/// Images inserted into texture views here should not be written to until [`wait_image`] is ran
pub fn insert_texture_views(
swapchain_images: Res<OXrSwapchainImages>,
mut swapchain: ResMut<OXrSwapchain>,
swapchain_images: Res<OxrSwapchainImages>,
mut swapchain: ResMut<OxrSwapchain>,
mut manual_texture_views: ResMut<ManualTextureViews>,
graphics_info: Res<OXrGraphicsInfo>,
graphics_info: Res<OxrGraphicsInfo>,
) {
let _span = info_span!("xr_insert_texture_views");
let index = swapchain.acquire_image().expect("Failed to acquire image");
@@ -294,7 +294,7 @@ pub fn insert_texture_views(
}
}
pub fn wait_image(mut swapchain: ResMut<OXrSwapchain>) {
pub fn wait_image(mut swapchain: ResMut<OxrSwapchain>) {
swapchain
.wait_image(openxr::Duration::INFINITE)
.expect("Failed to wait image");
@@ -303,7 +303,7 @@ pub fn wait_image(mut swapchain: ResMut<OXrSwapchain>) {
pub fn add_texture_view(
manual_texture_views: &mut ManualTextureViews,
texture: &wgpu::Texture,
info: &OXrGraphicsInfo,
info: &OxrGraphicsInfo,
index: u32,
) -> ManualTextureViewHandle {
let view = texture.create_view(&wgpu::TextureViewDescriptor {
@@ -322,17 +322,17 @@ pub fn add_texture_view(
handle
}
pub fn begin_frame(mut frame_stream: ResMut<OXrFrameStream>) {
pub fn begin_frame(mut frame_stream: ResMut<OxrFrameStream>) {
frame_stream.begin().expect("Failed to begin frame")
}
pub fn end_frame(
mut frame_stream: ResMut<OXrFrameStream>,
mut swapchain: ResMut<OXrSwapchain>,
stage: Res<OXrStage>,
display_time: Res<OXrTime>,
graphics_info: Res<OXrGraphicsInfo>,
openxr_views: Res<OXrViews>,
mut frame_stream: ResMut<OxrFrameStream>,
mut swapchain: ResMut<OxrSwapchain>,
stage: Res<OxrStage>,
display_time: Res<OxrTime>,
graphics_info: Res<OxrGraphicsInfo>,
openxr_views: Res<OxrViews>,
) {
let _span = info_span!("xr_end_frame");
swapchain.release_image().unwrap();

View File

@@ -5,32 +5,32 @@ use bevy::prelude::*;
use bevy::render::extract_resource::ExtractResource;
use openxr::AnyGraphics;
use crate::error::OXrError;
use crate::error::OxrError;
use crate::graphics::*;
use crate::layer_builder::CompositionLayer;
use crate::types::*;
/// Wrapper around the entry point to the OpenXR API
#[derive(Deref, Clone)]
pub struct OXrEntry(pub openxr::Entry);
pub struct OxrEntry(pub openxr::Entry);
impl OXrEntry {
impl OxrEntry {
/// Enumerate available extensions for this OpenXR runtime.
pub fn enumerate_extensions(&self) -> Result<OXrExtensions> {
pub fn enumerate_extensions(&self) -> Result<OxrExtensions> {
Ok(self.0.enumerate_extensions().map(Into::into)?)
}
pub fn create_instance(
&self,
app_info: AppInfo,
exts: OXrExtensions,
exts: OxrExtensions,
layers: &[&str],
backend: GraphicsBackend,
) -> Result<OXrInstance> {
) -> Result<OxrInstance> {
let available_exts = self.enumerate_extensions()?;
if !backend.is_available(&available_exts) {
return Err(OXrError::UnavailableBackend(backend));
return Err(OxrError::UnavailableBackend(backend));
}
let required_exts = exts | backend.required_exts();
@@ -46,7 +46,7 @@ impl OXrEntry {
layers,
)?;
Ok(OXrInstance(instance, backend, app_info))
Ok(OxrInstance(instance, backend, app_info))
}
pub fn available_backends(&self) -> Result<Vec<GraphicsBackend>> {
@@ -58,13 +58,13 @@ impl OXrEntry {
/// Wrapper around [openxr::Instance] with additional data for safety.
#[derive(Resource, Deref, Clone)]
pub struct OXrInstance(
pub struct OxrInstance(
#[deref] pub openxr::Instance,
pub(crate) GraphicsBackend,
pub(crate) AppInfo,
);
impl OXrInstance {
impl OxrInstance {
pub fn into_inner(self) -> openxr::Instance {
self.0
}
@@ -84,7 +84,7 @@ impl OXrInstance {
)
}
/// Creates an [OXrSession]
/// Creates an [OxrSession]
///
/// # Safety
///
@@ -93,9 +93,9 @@ impl OXrInstance {
&self,
system_id: openxr::SystemId,
info: SessionCreateInfo,
) -> Result<(OXrSession, OXrFrameWaiter, OXrFrameStream)> {
) -> Result<(OxrSession, OxrFrameWaiter, OxrFrameStream)> {
if !info.0.using_graphics_of_val(&self.1) {
return Err(OXrError::GraphicsBackendMismatch {
return Err(OxrError::GraphicsBackendMismatch {
item: std::any::type_name::<SessionCreateInfo>(),
backend: info.0.graphics_name(),
expected_backend: self.1.graphics_name(),
@@ -105,7 +105,7 @@ impl OXrInstance {
info.0;
info => {
let (session, frame_waiter, frame_stream) = self.0.create_session::<Api>(system_id, &info)?;
Ok((session.into(), OXrFrameWaiter(frame_waiter), OXrFrameStream(Api::wrap(frame_stream))))
Ok((session.into(), OxrFrameWaiter(frame_waiter), OxrFrameStream(Api::wrap(frame_stream))))
}
)
}
@@ -113,22 +113,22 @@ impl OXrInstance {
/// Graphics agnostic wrapper around [openxr::Session]
#[derive(Resource, Deref, Clone)]
pub struct OXrSession(
pub struct OxrSession(
#[deref] pub openxr::Session<AnyGraphics>,
pub GraphicsWrap<Self>,
);
impl GraphicsType for OXrSession {
impl GraphicsType for OxrSession {
type Inner<G: GraphicsExt> = openxr::Session<G>;
}
impl<G: GraphicsExt> From<openxr::Session<G>> for OXrSession {
impl<G: GraphicsExt> From<openxr::Session<G>> for OxrSession {
fn from(session: openxr::Session<G>) -> Self {
Self::new(session)
}
}
impl OXrSession {
impl OxrSession {
pub fn new<G: GraphicsExt>(session: openxr::Session<G>) -> Self {
Self(session.clone().into_any_graphics(), G::wrap(session))
}
@@ -141,24 +141,24 @@ impl OXrSession {
)
}
/// Creates an [OXrSwapchain].
pub fn create_swapchain(&self, info: SwapchainCreateInfo) -> Result<OXrSwapchain> {
Ok(OXrSwapchain(graphics_match!(
/// Creates an [OxrSwapchain].
pub fn create_swapchain(&self, info: SwapchainCreateInfo) -> Result<OxrSwapchain> {
Ok(OxrSwapchain(graphics_match!(
&self.1;
session => session.create_swapchain(&info.try_into()?)? => OXrSwapchain
session => session.create_swapchain(&info.try_into()?)? => OxrSwapchain
)))
}
}
/// Graphics agnostic wrapper around [openxr::FrameStream]
#[derive(Resource)]
pub struct OXrFrameStream(pub GraphicsWrap<Self>);
pub struct OxrFrameStream(pub GraphicsWrap<Self>);
impl GraphicsType for OXrFrameStream {
impl GraphicsType for OxrFrameStream {
type Inner<G: GraphicsExt> = openxr::FrameStream<G>;
}
impl OXrFrameStream {
impl OxrFrameStream {
/// Indicate that graphics device work is beginning.
pub fn begin(&mut self) -> openxr::Result<()> {
graphics_match!(
@@ -204,17 +204,17 @@ impl OXrFrameStream {
/// Handle for waiting to render a frame. Check [`FrameWaiter`](openxr::FrameWaiter) for available methods.
#[derive(Resource, Deref, DerefMut)]
pub struct OXrFrameWaiter(pub openxr::FrameWaiter);
pub struct OxrFrameWaiter(pub openxr::FrameWaiter);
/// Graphics agnostic wrapper around [openxr::Swapchain]
#[derive(Resource)]
pub struct OXrSwapchain(pub GraphicsWrap<Self>);
pub struct OxrSwapchain(pub GraphicsWrap<Self>);
impl GraphicsType for OXrSwapchain {
impl GraphicsType for OxrSwapchain {
type Inner<G: GraphicsExt> = openxr::Swapchain<G>;
}
impl OXrSwapchain {
impl OxrSwapchain {
/// Determine the index of the next image to render to in the swapchain image array
pub fn acquire_image(&mut self) -> Result<u32> {
graphics_match!(
@@ -245,7 +245,7 @@ impl OXrSwapchain {
device: &wgpu::Device,
format: wgpu::TextureFormat,
resolution: UVec2,
) -> Result<OXrSwapchainImages> {
) -> Result<OxrSwapchainImages> {
graphics_match!(
&self.0;
swap => {
@@ -255,7 +255,7 @@ impl OXrSwapchain {
images.push(Api::to_wgpu_img(image, device, format, resolution)?);
}
}
Ok(OXrSwapchainImages(images.into()))
Ok(OxrSwapchainImages(images.into()))
}
)
}
@@ -263,23 +263,23 @@ impl OXrSwapchain {
/// Stores the generated swapchain images.
#[derive(Debug, Deref, Resource, Clone)]
pub struct OXrSwapchainImages(pub Arc<Vec<wgpu::Texture>>);
pub struct OxrSwapchainImages(pub Arc<Vec<wgpu::Texture>>);
/// Thread safe wrapper around [openxr::Space] representing the stage.
#[derive(Deref, Clone, Resource)]
pub struct OXrStage(pub Arc<openxr::Space>);
pub struct OxrStage(pub Arc<openxr::Space>);
/// Stores the latest generated [OXrViews]
/// Stores the latest generated [OxrViews]
#[derive(Clone, Resource, ExtractResource, Deref, DerefMut)]
pub struct OXrViews(pub Vec<openxr::View>);
pub struct OxrViews(pub Vec<openxr::View>);
/// Wrapper around [openxr::SystemId] to allow it to be stored as a resource.
#[derive(Debug, Copy, Clone, Deref, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Resource)]
pub struct OXrSystemId(pub openxr::SystemId);
pub struct OxrSystemId(pub openxr::SystemId);
/// Resource storing graphics info for the currently running session.
#[derive(Clone, Copy, Resource)]
pub struct OXrGraphicsInfo {
pub struct OxrGraphicsInfo {
pub blend_mode: EnvironmentBlendMode,
pub resolution: UVec2,
pub format: wgpu::TextureFormat,
@@ -299,9 +299,9 @@ pub struct SessionConfigInfo {
}
#[derive(Resource, Clone, Default)]
pub struct OXrSessionStarted(Arc<AtomicBool>);
pub struct OxrSessionStarted(Arc<AtomicBool>);
impl OXrSessionStarted {
impl OxrSessionStarted {
pub fn set(&self, val: bool) {
self.0.store(val, Ordering::SeqCst);
}
@@ -313,12 +313,12 @@ impl OXrSessionStarted {
/// The calculated display time for the app. Passed through the pipeline.
#[derive(Copy, Clone, Eq, PartialEq, Deref, DerefMut, Resource, ExtractResource)]
pub struct OXrTime(pub openxr::Time);
pub struct OxrTime(pub openxr::Time);
/// The root transform's global position for late latching in the render world.
#[derive(ExtractResource, Resource, Clone, Copy, Default)]
pub struct OXrRootTransform(pub GlobalTransform);
pub struct OxrRootTransform(pub GlobalTransform);
#[derive(ExtractResource, Resource, Clone, Copy, Default, Deref, DerefMut, PartialEq)]
/// This is inserted into the world to signify if the session should be cleaned up.
pub struct OXrCleanupSession(pub bool);
pub struct OxrCleanupSession(pub bool);

View File

@@ -1,13 +1,13 @@
use std::borrow::Cow;
use crate::error::OXrError;
use crate::error::OxrError;
use crate::graphics::{GraphicsExt, GraphicsType, GraphicsWrap};
pub use crate::openxr::exts::OXrExtensions;
pub use crate::openxr::exts::OxrExtensions;
pub use openxr::{EnvironmentBlendMode, SwapchainCreateFlags, SwapchainUsageFlags};
pub type Result<T> = std::result::Result<T, OXrError>;
pub type Result<T> = std::result::Result<T, OxrError>;
/// A container for all required graphics objects needed for a bevy app.
pub struct WgpuGraphics(
@@ -70,14 +70,14 @@ pub struct SwapchainCreateInfo {
}
impl<G: GraphicsExt> TryFrom<SwapchainCreateInfo> for openxr::SwapchainCreateInfo<G> {
type Error = OXrError;
type Error = OxrError;
fn try_from(value: SwapchainCreateInfo) -> Result<Self> {
Ok(openxr::SwapchainCreateInfo {
create_flags: value.create_flags,
usage_flags: value.usage_flags,
format: G::from_wgpu_format(value.format)
.ok_or(OXrError::UnsupportedTextureFormat(value.format))?,
.ok_or(OxrError::UnsupportedTextureFormat(value.format))?,
sample_count: value.sample_count,
width: value.width,
height: value.height,