0.16 support
This commit is contained in:
2377
Cargo.lock
generated
2377
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@ resolver = "2"
|
|||||||
members = ["crates/*", "crates/bevy_openxr/examples/android"]
|
members = ["crates/*", "crates/bevy_openxr/examples/android"]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
bevy = { version = "0.15", default-features = false, features = [
|
bevy = { git = "https://github.com/bevyengine/bevy", default-features = false, features = [
|
||||||
"bevy_render",
|
"bevy_render",
|
||||||
"bevy_core_pipeline",
|
"bevy_core_pipeline",
|
||||||
"bevy_winit",
|
"bevy_winit",
|
||||||
@@ -23,5 +23,5 @@ bevy_mod_openxr = { path = "crates/bevy_openxr", version = "0.2.1" }
|
|||||||
bevy_xr_utils = { path = "crates/bevy_xr_utils", version = "0.2.1" }
|
bevy_xr_utils = { path = "crates/bevy_xr_utils", version = "0.2.1" }
|
||||||
openxr = "0.19.0"
|
openxr = "0.19.0"
|
||||||
thiserror = "2.0.3"
|
thiserror = "2.0.3"
|
||||||
wgpu = "23"
|
wgpu = "24.0.1"
|
||||||
wgpu-hal = "23"
|
wgpu-hal = "24.0.2"
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ fn main() {
|
|||||||
.insert_resource(AmbientLight {
|
.insert_resource(AmbientLight {
|
||||||
color: Default::default(),
|
color: Default::default(),
|
||||||
brightness: 500.0,
|
brightness: 500.0,
|
||||||
|
affects_lightmapped_meshes: false,
|
||||||
})
|
})
|
||||||
.insert_resource(ClearColor(Color::NONE))
|
.insert_resource(ClearColor(Color::NONE))
|
||||||
.run();
|
.run();
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ use std::ptr;
|
|||||||
|
|
||||||
use bevy::ecs::schedule::ScheduleLabel;
|
use bevy::ecs::schedule::ScheduleLabel;
|
||||||
use bevy::ecs::system::RunSystemOnce;
|
use bevy::ecs::system::RunSystemOnce;
|
||||||
|
use bevy::platform_support::collections::HashMap;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::utils::HashMap;
|
|
||||||
use bevy_mod_xr::session::XrSessionCreatedEvent;
|
use bevy_mod_xr::session::XrSessionCreatedEvent;
|
||||||
use openxr::sys::ActionSuggestedBinding;
|
use openxr::sys::ActionSuggestedBinding;
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ pub(crate) fn run_action_binding_sugestion(world: &mut World) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn bind_actions(instance: Res<OxrInstance>, mut actions: EventReader<OxrSuggestActionBinding>) {
|
fn bind_actions(instance: Res<OxrInstance>, mut actions: EventReader<OxrSuggestActionBinding>) {
|
||||||
let mut bindings: HashMap<&str, Vec<ActionSuggestedBinding>> = HashMap::new();
|
let mut bindings: HashMap<&str, Vec<ActionSuggestedBinding>, _> = HashMap::new();
|
||||||
for e in actions.read() {
|
for e in actions.read() {
|
||||||
bindings.entry(&e.interaction_profile).or_default().extend(
|
bindings.entry(&e.interaction_profile).or_default().extend(
|
||||||
e.bindings
|
e.bindings
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use bevy::{
|
use bevy::{
|
||||||
ecs::system::Resource,
|
|
||||||
prelude::{Deref, DerefMut},
|
prelude::{Deref, DerefMut},
|
||||||
};
|
};
|
||||||
|
use bevy::prelude::Resource;
|
||||||
use openxr::ExtensionSet;
|
use openxr::ExtensionSet;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Deref, DerefMut, Resource)]
|
#[derive(Clone, Debug, Eq, PartialEq, Deref, DerefMut, Resource)]
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ pub fn create_passthrough(
|
|||||||
session: &OxrSession,
|
session: &OxrSession,
|
||||||
flags: openxr::PassthroughFlagsFB,
|
flags: openxr::PassthroughFlagsFB,
|
||||||
purpose: openxr::PassthroughLayerPurposeFB,
|
purpose: openxr::PassthroughLayerPurposeFB,
|
||||||
) -> Result<(OxrPassthrough, OxrPassthroughLayer)> {
|
) -> crate::types::Result<(OxrPassthrough, OxrPassthroughLayer)> {
|
||||||
let passthrough = session.create_passthrough(flags)?;
|
let passthrough = session.create_passthrough(flags)?;
|
||||||
|
|
||||||
let passthrough_layer = session.create_passthrough_layer(&passthrough, purpose)?;
|
let passthrough_layer = session.create_passthrough_layer(&passthrough, purpose)?;
|
||||||
@@ -82,7 +82,7 @@ pub fn create_passthrough(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn supports_passthrough(instance: &OxrInstance, system: OxrSystemId) -> Result<bool> {
|
pub fn supports_passthrough(instance: &OxrInstance, system: OxrSystemId) -> crate::types::Result<bool> {
|
||||||
if instance.exts().fb_passthrough.is_none() {
|
if instance.exts().fb_passthrough.is_none() {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::ffi::{c_void, CString};
|
|||||||
use ash::vk::Handle;
|
use ash::vk::Handle;
|
||||||
use bevy::log::{debug, error};
|
use bevy::log::{debug, error};
|
||||||
use bevy::math::UVec2;
|
use bevy::math::UVec2;
|
||||||
|
use bevy::render::render_resource::TextureFormat;
|
||||||
use openxr::{sys, Version};
|
use openxr::{sys, Version};
|
||||||
use wgpu_hal::api::Vulkan;
|
use wgpu_hal::api::Vulkan;
|
||||||
use wgpu_hal::Api;
|
use wgpu_hal::Api;
|
||||||
@@ -115,7 +116,6 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
|||||||
<Vulkan as Api>::Instance::desired_extensions(&vk_entry, VK_TARGET_VERSION_ASH, flags)?;
|
<Vulkan as Api>::Instance::desired_extensions(&vk_entry, VK_TARGET_VERSION_ASH, flags)?;
|
||||||
let device_extensions = [
|
let device_extensions = [
|
||||||
ash::khr::swapchain::NAME,
|
ash::khr::swapchain::NAME,
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
ash::khr::draw_indirect_count::NAME,
|
ash::khr::draw_indirect_count::NAME,
|
||||||
ash::khr::timeline_semaphore::NAME,
|
ash::khr::timeline_semaphore::NAME,
|
||||||
ash::khr::imageless_framebuffer::NAME,
|
ash::khr::imageless_framebuffer::NAME,
|
||||||
@@ -756,5 +756,8 @@ fn wgpu_to_vulkan(format: wgpu::TextureFormat) -> Option<ash::vk::Format> {
|
|||||||
AstcBlock::B12x12 => F::ASTC_12X12_SFLOAT_BLOCK_EXT,
|
AstcBlock::B12x12 => F::ASTC_12X12_SFLOAT_BLOCK_EXT,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
TextureFormat::R64Uint => {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ impl Plugin for OxrInitPlugin {
|
|||||||
RenderInstance(Arc::new(WgpuWrapper::new(wgpu_instance))),
|
RenderInstance(Arc::new(WgpuWrapper::new(wgpu_instance))),
|
||||||
),
|
),
|
||||||
synchronous_pipeline_compilation: self.synchronous_pipeline_compilation,
|
synchronous_pipeline_compilation: self.synchronous_pipeline_compilation,
|
||||||
|
debug_flags: Default::default(),
|
||||||
},
|
},
|
||||||
ExtractResourcePlugin::<OxrSessionStarted>::default(),
|
ExtractResourcePlugin::<OxrSessionStarted>::default(),
|
||||||
))
|
))
|
||||||
@@ -206,7 +207,7 @@ fn detect_session_destroyed(
|
|||||||
impl OxrInitPlugin {
|
impl OxrInitPlugin {
|
||||||
fn init_xr(
|
fn init_xr(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<(
|
) -> crate::types::Result<(
|
||||||
OxrInstance,
|
OxrInstance,
|
||||||
OxrSystemId,
|
OxrSystemId,
|
||||||
WgpuGraphics,
|
WgpuGraphics,
|
||||||
@@ -350,7 +351,7 @@ fn init_xr_session(
|
|||||||
resolutions,
|
resolutions,
|
||||||
graphics_info,
|
graphics_info,
|
||||||
}: SessionConfigInfo,
|
}: SessionConfigInfo,
|
||||||
) -> Result<(
|
) -> crate::types::Result<(
|
||||||
OxrSession,
|
OxrSession,
|
||||||
OxrFrameWaiter,
|
OxrFrameWaiter,
|
||||||
OxrFrameStream,
|
OxrFrameStream,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use bevy::{
|
|||||||
utils::default,
|
utils::default,
|
||||||
window::{PresentMode, Window, WindowPlugin},
|
window::{PresentMode, Window, WindowPlugin},
|
||||||
};
|
};
|
||||||
|
use bevy::render::camera::CameraPlugin;
|
||||||
use bevy_mod_xr::session::XrSessionPlugin;
|
use bevy_mod_xr::session::XrSessionPlugin;
|
||||||
use bevy_mod_xr::{camera::XrCameraPlugin, session::XrState};
|
use bevy_mod_xr::{camera::XrCameraPlugin, session::XrState};
|
||||||
use init::OxrInitPlugin;
|
use init::OxrInitPlugin;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use super::{openxr_session_available, resources::OxrInstance};
|
||||||
use bevy::{ecs::system::SystemId, prelude::*};
|
use bevy::{ecs::system::SystemId, prelude::*};
|
||||||
use bevy_mod_xr::session::{XrFirst, XrHandleEvents};
|
use bevy_mod_xr::session::{XrFirst, XrHandleEvents};
|
||||||
use openxr::{Event, EventDataBuffer};
|
use openxr::{Event, EventDataBuffer};
|
||||||
@@ -30,7 +31,7 @@ pub fn poll_events(world: &mut World) {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|v| SystemId::<OxrEventIn, ()>::from_entity(*v))
|
.map(|v| SystemId::<OxrEventIn, ()>::from_entity(*v))
|
||||||
{
|
{
|
||||||
if let Err(err) = world.run_system_with_input(handler, event) {
|
if let Err(err) = world.run_system_with(handler, event) {
|
||||||
error!("error when running oxr event handler: {err}");
|
error!("error when running oxr event handler: {err}");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -38,7 +39,6 @@ pub fn poll_events(world: &mut World) {
|
|||||||
world.insert_resource(handlers);
|
world.insert_resource(handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
use super::{openxr_session_available, resources::OxrInstance};
|
|
||||||
#[derive(Resource, Debug, Default)]
|
#[derive(Resource, Debug, Default)]
|
||||||
pub struct OxrEventHandlers(Vec<Entity>);
|
pub struct OxrEventHandlers(Vec<Entity>);
|
||||||
pub trait OxrEventHandlerExt {
|
pub trait OxrEventHandlerExt {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
use bevy::render::camera::CustomProjection;
|
||||||
use bevy::{
|
use bevy::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
render::{
|
render::{
|
||||||
camera::{ManualTextureView, ManualTextureViewHandle, ManualTextureViews, RenderTarget},
|
camera::{ManualTextureView, ManualTextureViewHandle, ManualTextureViews, RenderTarget},
|
||||||
extract_resource::ExtractResourcePlugin,
|
extract_resource::ExtractResourcePlugin,
|
||||||
pipelined_rendering::PipelinedRenderingPlugin,
|
pipelined_rendering::PipelinedRenderingPlugin,
|
||||||
view::ExtractedView,
|
view::{ExtractedView, NoFrustumCulling},
|
||||||
Render, RenderApp,
|
Render, RenderApp,
|
||||||
},
|
},
|
||||||
transform::TransformSystem,
|
transform::TransformSystem,
|
||||||
@@ -170,6 +171,8 @@ pub fn init_views<const SPAWN_CAMERAS: bool>(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
XrCamera(index),
|
XrCamera(index),
|
||||||
|
Projection::custom(XrProjection::default()),
|
||||||
|
NoFrustumCulling,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,13 +247,18 @@ pub fn locate_views(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_views(
|
pub fn update_views(
|
||||||
mut query: Query<(&mut Transform, &mut XrProjection, &XrCamera)>,
|
mut query: Query<(&mut Transform, &mut Projection, &XrCamera)>,
|
||||||
views: ResMut<OxrViews>,
|
views: ResMut<OxrViews>,
|
||||||
) {
|
) {
|
||||||
for (mut transform, mut projection, camera) in query.iter_mut() {
|
for (mut transform, mut projection, camera) in query.iter_mut() {
|
||||||
|
println!("we have this query");
|
||||||
let Some(view) = views.get(camera.0 as usize) else {
|
let Some(view) = views.get(camera.0 as usize) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
let projection = match projection.as_mut() {
|
||||||
|
Projection::Custom(custom) => custom.get_mut::<XrProjection>().unwrap(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
let projection_matrix = calculate_projection(
|
let projection_matrix = calculate_projection(
|
||||||
projection.near,
|
projection.near,
|
||||||
@@ -263,6 +271,11 @@ pub fn update_views(
|
|||||||
);
|
);
|
||||||
projection.projection_matrix = projection_matrix;
|
projection.projection_matrix = projection_matrix;
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Updateing projectinon matrix to: {:#?}",
|
||||||
|
projection.projection_matrix
|
||||||
|
);
|
||||||
|
|
||||||
let openxr::Quaternionf { x, y, z, w } = view.pose.orientation;
|
let openxr::Quaternionf { x, y, z, w } = view.pose.orientation;
|
||||||
let rotation = Quat::from_xyzw(x, y, z, w);
|
let rotation = Quat::from_xyzw(x, y, z, w);
|
||||||
transform.rotation = rotation;
|
transform.rotation = rotation;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub struct OxrEntry(pub openxr::Entry);
|
|||||||
|
|
||||||
impl OxrEntry {
|
impl OxrEntry {
|
||||||
/// Enumerate available extensions for this OpenXR runtime.
|
/// Enumerate available extensions for this OpenXR runtime.
|
||||||
pub fn enumerate_extensions(&self) -> Result<OxrExtensions> {
|
pub fn enumerate_extensions(&self) -> crate::types::Result<OxrExtensions> {
|
||||||
Ok(self.0.enumerate_extensions().map(Into::into)?)
|
Ok(self.0.enumerate_extensions().map(Into::into)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ impl OxrEntry {
|
|||||||
exts: OxrExtensions,
|
exts: OxrExtensions,
|
||||||
layers: &[&str],
|
layers: &[&str],
|
||||||
backend: GraphicsBackend,
|
backend: GraphicsBackend,
|
||||||
) -> Result<OxrInstance> {
|
) -> crate::types::Result<OxrInstance> {
|
||||||
let available_exts = self.enumerate_extensions()?;
|
let available_exts = self.enumerate_extensions()?;
|
||||||
|
|
||||||
if !backend.is_available(&available_exts) {
|
if !backend.is_available(&available_exts) {
|
||||||
@@ -53,7 +53,7 @@ impl OxrEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of all of the backends the OpenXR runtime supports.
|
/// Returns a list of all of the backends the OpenXR runtime supports.
|
||||||
pub fn available_backends(&self) -> Result<Vec<GraphicsBackend>> {
|
pub fn available_backends(&self) -> crate::types::Result<Vec<GraphicsBackend>> {
|
||||||
Ok(GraphicsBackend::available_backends(
|
Ok(GraphicsBackend::available_backends(
|
||||||
&self.enumerate_extensions()?,
|
&self.enumerate_extensions()?,
|
||||||
))
|
))
|
||||||
@@ -105,7 +105,7 @@ impl OxrInstance {
|
|||||||
pub fn init_graphics(
|
pub fn init_graphics(
|
||||||
&self,
|
&self,
|
||||||
system_id: openxr::SystemId,
|
system_id: openxr::SystemId,
|
||||||
) -> Result<(WgpuGraphics, SessionCreateInfo)> {
|
) -> crate::types::Result<(WgpuGraphics, SessionCreateInfo)> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
self.1;
|
self.1;
|
||||||
_ => {
|
_ => {
|
||||||
@@ -128,9 +128,9 @@ impl OxrInstance {
|
|||||||
system_id: openxr::SystemId,
|
system_id: openxr::SystemId,
|
||||||
info: SessionCreateInfo,
|
info: SessionCreateInfo,
|
||||||
chain: &mut OxrSessionCreateNextChain,
|
chain: &mut OxrSessionCreateNextChain,
|
||||||
) -> Result<(OxrSession, OxrFrameWaiter, OxrFrameStream)> {
|
) -> crate::types::Result<(OxrSession, OxrFrameWaiter, OxrFrameStream)> {
|
||||||
if !info.0.using_graphics_of_val(&self.1) {
|
if !info.0.using_graphics_of_val(&self.1) {
|
||||||
return Err(OxrError::GraphicsBackendMismatch {
|
return crate::types::Result::Err(OxrError::GraphicsBackendMismatch {
|
||||||
item: std::any::type_name::<SessionCreateInfo>(),
|
item: std::any::type_name::<SessionCreateInfo>(),
|
||||||
backend: info.0.graphics_name(),
|
backend: info.0.graphics_name(),
|
||||||
expected_backend: self.1.graphics_name(),
|
expected_backend: self.1.graphics_name(),
|
||||||
@@ -180,7 +180,7 @@ impl OxrFrameStream {
|
|||||||
display_time: openxr::Time,
|
display_time: openxr::Time,
|
||||||
environment_blend_mode: openxr::EnvironmentBlendMode,
|
environment_blend_mode: openxr::EnvironmentBlendMode,
|
||||||
layers: &[&dyn CompositionLayer],
|
layers: &[&dyn CompositionLayer],
|
||||||
) -> Result<()> {
|
) -> crate::types::Result<()> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
&mut self.0;
|
&mut self.0;
|
||||||
stream => {
|
stream => {
|
||||||
@@ -233,7 +233,7 @@ impl OxrSwapchain {
|
|||||||
/// Determine the index of the next image to render to in the swapchain image array.
|
/// Determine the index of the next image to render to in the swapchain image array.
|
||||||
///
|
///
|
||||||
/// Calls [`acquire_image`](openxr::Swapchain::acquire_image) internally.
|
/// Calls [`acquire_image`](openxr::Swapchain::acquire_image) internally.
|
||||||
pub fn acquire_image(&mut self) -> Result<u32> {
|
pub fn acquire_image(&mut self) -> crate::types::Result<u32> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
&mut self.0;
|
&mut self.0;
|
||||||
swap => Ok(swap.acquire_image()?)
|
swap => Ok(swap.acquire_image()?)
|
||||||
@@ -243,7 +243,7 @@ impl OxrSwapchain {
|
|||||||
/// Wait for the compositor to finish reading from the oldest unwaited acquired image.
|
/// Wait for the compositor to finish reading from the oldest unwaited acquired image.
|
||||||
///
|
///
|
||||||
/// Calls [`wait_image`](openxr::Swapchain::wait_image) internally.
|
/// Calls [`wait_image`](openxr::Swapchain::wait_image) internally.
|
||||||
pub fn wait_image(&mut self, timeout: openxr::Duration) -> Result<()> {
|
pub fn wait_image(&mut self, timeout: openxr::Duration) -> crate::types::Result<()> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
&mut self.0;
|
&mut self.0;
|
||||||
swap => Ok(swap.wait_image(timeout)?)
|
swap => Ok(swap.wait_image(timeout)?)
|
||||||
@@ -253,7 +253,7 @@ impl OxrSwapchain {
|
|||||||
/// Release the oldest acquired image.
|
/// Release the oldest acquired image.
|
||||||
///
|
///
|
||||||
/// Calls [`release_image`](openxr::Swapchain::release_image) internally.
|
/// Calls [`release_image`](openxr::Swapchain::release_image) internally.
|
||||||
pub fn release_image(&mut self) -> Result<()> {
|
pub fn release_image(&mut self) -> crate::types::Result<()> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
&mut self.0;
|
&mut self.0;
|
||||||
swap => Ok(swap.release_image()?)
|
swap => Ok(swap.release_image()?)
|
||||||
@@ -268,7 +268,7 @@ impl OxrSwapchain {
|
|||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
format: wgpu::TextureFormat,
|
format: wgpu::TextureFormat,
|
||||||
resolution: UVec2,
|
resolution: UVec2,
|
||||||
) -> Result<OxrSwapchainImages> {
|
) -> crate::types::Result<OxrSwapchainImages> {
|
||||||
graphics_match!(
|
graphics_match!(
|
||||||
&self.0;
|
&self.0;
|
||||||
swap => {
|
swap => {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use std::{mem::MaybeUninit, ptr, sync::Mutex};
|
use std::{mem::MaybeUninit, ptr, sync::Mutex};
|
||||||
|
|
||||||
use bevy::{prelude::*, utils::hashbrown::HashSet};
|
use bevy::{prelude::*};
|
||||||
|
use bevy::platform_support::*;
|
||||||
|
use bevy::platform_support::hash::FixedHasher;
|
||||||
use bevy_mod_xr::{
|
use bevy_mod_xr::{
|
||||||
session::{XrFirst, XrHandleEvents},
|
session::{XrFirst, XrHandleEvents},
|
||||||
spaces::{
|
spaces::{
|
||||||
@@ -64,7 +66,7 @@ fn destroy_space_event(instance: Res<OxrInstance>, mut events: EventReader<XrDes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static OXR_DO_NOT_CALL_DESTOY_SPACE_FOR_SPACES: Mutex<Option<HashSet<u64>>> = Mutex::new(None);
|
pub static OXR_DO_NOT_CALL_DESTOY_SPACE_FOR_SPACES: Mutex<Option<bevy::platform_support::collections::hash_set::HashSet<u64, bevy::platform_support::hash::RandomState>>> = Mutex::new(None);
|
||||||
pub static OXR_ORIGINAL_DESTOY_SPACE: Mutex<Option<openxr::sys::pfn::DestroySpace>> =
|
pub static OXR_ORIGINAL_DESTOY_SPACE: Mutex<Option<openxr::sys::pfn::DestroySpace>> =
|
||||||
Mutex::new(None);
|
Mutex::new(None);
|
||||||
|
|
||||||
@@ -72,7 +74,7 @@ fn patch_destroy_space(instance: ResMut<OxrInstance>) {
|
|||||||
OXR_DO_NOT_CALL_DESTOY_SPACE_FOR_SPACES
|
OXR_DO_NOT_CALL_DESTOY_SPACE_FOR_SPACES
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.replace(HashSet::new());
|
.replace(bevy::platform_support::collections::hash_set::HashSet::new());
|
||||||
let raw_instance_ptr = instance.fp() as *const _ as *mut openxr::raw::Instance;
|
let raw_instance_ptr = instance.fp() as *const _ as *mut openxr::raw::Instance;
|
||||||
unsafe {
|
unsafe {
|
||||||
OXR_ORIGINAL_DESTOY_SPACE
|
OXR_ORIGINAL_DESTOY_SPACE
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::{any::TypeId, marker::PhantomData};
|
use std::{any::TypeId, marker::PhantomData};
|
||||||
|
|
||||||
use bevy::app::{App, Plugin};
|
use bevy::app::{App, Plugin};
|
||||||
use bevy::ecs::system::Resource;
|
|
||||||
use bevy::math::Vec2;
|
use bevy::math::Vec2;
|
||||||
|
use bevy::prelude::Resource;
|
||||||
|
|
||||||
pub struct ActionPlugin<A: Action>(PhantomData<A>);
|
pub struct ActionPlugin<A: Action>(PhantomData<A>);
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ use core::panic;
|
|||||||
|
|
||||||
use bevy::app::{App, Plugin, PostUpdate};
|
use bevy::app::{App, Plugin, PostUpdate};
|
||||||
use bevy::core_pipeline::core_3d::Camera3d;
|
use bevy::core_pipeline::core_3d::Camera3d;
|
||||||
use bevy::ecs::component::{Component, StorageType};
|
use bevy::ecs::component::{Component, HookContext, Mutable, StorageType};
|
||||||
use bevy::ecs::reflect::ReflectComponent;
|
use bevy::ecs::reflect::ReflectComponent;
|
||||||
use bevy::ecs::schedule::IntoSystemConfigs;
|
use bevy::ecs::world::DeferredWorld;
|
||||||
use bevy::math::{Mat4, Vec3A, Vec4};
|
use bevy::math::{Mat4, Vec3A, Vec4};
|
||||||
use bevy::pbr::{PbrPlugin, PbrProjectionPlugin};
|
use bevy::pbr::{PbrPlugin, PbrProjectionPlugin};
|
||||||
use bevy::prelude::{Projection, SystemSet};
|
use bevy::prelude::{Projection, SystemSet};
|
||||||
use bevy::reflect::std_traits::ReflectDefault;
|
use bevy::reflect::std_traits::ReflectDefault;
|
||||||
use bevy::reflect::Reflect;
|
use bevy::reflect::Reflect;
|
||||||
use bevy::render::camera::{CameraProjection, CameraProjectionPlugin};
|
use bevy::render::camera::{CameraProjection, CameraProjectionPlugin, CustomProjection};
|
||||||
use bevy::render::extract_component::{ExtractComponent, ExtractComponentPlugin};
|
use bevy::render::extract_component::{ExtractComponent, ExtractComponentPlugin};
|
||||||
use bevy::render::view::{update_frusta, VisibilitySystems};
|
use bevy::render::view::{update_frusta, VisibilitySystems};
|
||||||
use bevy::transform::TransformSystem;
|
use bevy::transform::TransformSystem;
|
||||||
@@ -21,7 +21,7 @@ pub struct XrCameraPlugin;
|
|||||||
|
|
||||||
impl Plugin for XrCameraPlugin {
|
impl Plugin for XrCameraPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_plugins(CameraProjectionPlugin::<XrProjection>::default());
|
/*app.add_plugins(CameraProjectionPlugin::<XrProjection>::default());
|
||||||
app.add_systems(
|
app.add_systems(
|
||||||
PostUpdate,
|
PostUpdate,
|
||||||
update_frusta::<XrProjection>
|
update_frusta::<XrProjection>
|
||||||
@@ -30,31 +30,23 @@ impl Plugin for XrCameraPlugin {
|
|||||||
);
|
);
|
||||||
if app.is_plugin_added::<PbrPlugin>() {
|
if app.is_plugin_added::<PbrPlugin>() {
|
||||||
app.add_plugins(PbrProjectionPlugin::<XrProjection>::default());
|
app.add_plugins(PbrProjectionPlugin::<XrProjection>::default());
|
||||||
}
|
}*/
|
||||||
app.add_plugins((
|
app.add_plugins((ExtractComponentPlugin::<XrCamera>::default(),));
|
||||||
ExtractComponentPlugin::<XrProjection>::default(),
|
|
||||||
ExtractComponentPlugin::<XrCamera>::default(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, SystemSet)]
|
#[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, SystemSet)]
|
||||||
pub struct XrViewInit;
|
pub struct XrViewInit;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Reflect, ExtractComponent)]
|
#[derive(Debug, Clone, Reflect)]
|
||||||
#[reflect(Component, Default)]
|
#[reflect(Default)]
|
||||||
pub struct XrProjection {
|
pub struct XrProjection {
|
||||||
pub projection_matrix: Mat4,
|
pub projection_matrix: Mat4,
|
||||||
pub near: f32,
|
pub near: f32,
|
||||||
}
|
}
|
||||||
impl Component for XrProjection {
|
|
||||||
const STORAGE_TYPE: StorageType = StorageType::Table;
|
|
||||||
|
|
||||||
fn register_component_hooks(hooks: &mut bevy::ecs::component::ComponentHooks) {
|
fn on_projection_add(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {
|
||||||
hooks.on_add(|mut world, entity, _| {
|
|
||||||
world.commands().entity(entity).remove::<Projection>();
|
world.commands().entity(entity).remove::<Projection>();
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for XrProjection {
|
impl Default for XrProjection {
|
||||||
@@ -68,7 +60,7 @@ impl Default for XrProjection {
|
|||||||
|
|
||||||
/// Marker component for an XR view. It is the backends responsibility to update this.
|
/// Marker component for an XR view. It is the backends responsibility to update this.
|
||||||
#[derive(Clone, Copy, Component, ExtractComponent, Debug, Default)]
|
#[derive(Clone, Copy, Component, ExtractComponent, Debug, Default)]
|
||||||
#[require(Camera3d, XrProjection, XrTracker)]
|
#[require(Camera3d, XrTracker)]
|
||||||
pub struct XrCamera(pub u32);
|
pub struct XrCamera(pub u32);
|
||||||
|
|
||||||
impl CameraProjection for XrProjection {
|
impl CameraProjection for XrProjection {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use bevy::{
|
use bevy::{
|
||||||
ecs::{component::Component, entity::Entity, world::Command},
|
ecs::{component::Component, entity::Entity},
|
||||||
log::warn,
|
log::warn,
|
||||||
math::bool,
|
math::bool,
|
||||||
prelude::{Bundle, Commands, Deref, DerefMut, Resource, Transform, Visibility, World},
|
prelude::{Bundle, Commands, Deref, DerefMut, Resource, Transform, Visibility, World},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{session::XrTracker, spaces::XrSpaceLocationFlags};
|
use crate::{session::XrTracker, spaces::XrSpaceLocationFlags};
|
||||||
pub const HAND_JOINT_COUNT: usize = 26;
|
pub const HAND_JOINT_COUNT: usize = 26;
|
||||||
|
|
||||||
@@ -181,7 +180,7 @@ pub struct SpawnHandTracker<B: Bundle> {
|
|||||||
pub side: HandSide,
|
pub side: HandSide,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: Bundle> Command for SpawnHandTracker<B> {
|
impl<B: Bundle> bevy::prelude::Command for SpawnHandTracker<B> {
|
||||||
fn apply(self, world: &mut bevy::prelude::World) {
|
fn apply(self, world: &mut bevy::prelude::World) {
|
||||||
let Some(executor) = world.remove_resource::<SpawnHandTrackerCommandExecutor>() else {
|
let Some(executor) = world.remove_resource::<SpawnHandTrackerCommandExecutor>() else {
|
||||||
warn!("no SpawnHandTracker executor defined, skipping handtracker creation");
|
warn!("no SpawnHandTracker executor defined, skipping handtracker creation");
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ use std::sync::atomic::AtomicBool;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use bevy::app::{AppExit, MainScheduleOrder};
|
use bevy::app::{AppExit, MainScheduleOrder};
|
||||||
use bevy::ecs::component::StorageType;
|
use bevy::ecs::component::{HookContext, Mutable, StorageType};
|
||||||
use bevy::ecs::schedule::ScheduleLabel;
|
use bevy::ecs::schedule::ScheduleLabel;
|
||||||
|
use bevy::ecs::world::DeferredWorld;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::render::extract_resource::{ExtractResource, ExtractResourcePlugin};
|
use bevy::render::extract_resource::{ExtractResource, ExtractResourcePlugin};
|
||||||
use bevy::render::{Render, RenderApp, RenderSet};
|
use bevy::render::{Render, RenderApp, RenderSet};
|
||||||
@@ -96,16 +97,13 @@ pub struct XrTrackingRoot;
|
|||||||
struct TrackingRootRes(Entity);
|
struct TrackingRootRes(Entity);
|
||||||
|
|
||||||
/// Makes the entity a child of the XrTrackingRoot if the entity has no parent
|
/// Makes the entity a child of the XrTrackingRoot if the entity has no parent
|
||||||
#[derive(Clone, Copy, Hash, PartialEq, Eq, Reflect, Debug, Default)]
|
#[derive(Clone, Copy, Hash, PartialEq, Eq, Reflect, Debug, Default, Component)]
|
||||||
|
#[component(on_add = on_tracker_add)]
|
||||||
pub struct XrTracker;
|
pub struct XrTracker;
|
||||||
impl Component for XrTracker {
|
fn on_tracker_add(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {
|
||||||
const STORAGE_TYPE: StorageType = StorageType::SparseSet;
|
|
||||||
|
|
||||||
fn register_component_hooks(hooks: &mut bevy::ecs::component::ComponentHooks) {
|
|
||||||
hooks.on_add(|mut world, entity, _| {
|
|
||||||
if world
|
if world
|
||||||
.entity(entity)
|
.entity(entity)
|
||||||
.get_components::<Has<Parent>>()
|
.get_components::<Has<Children>>()
|
||||||
.is_some_and(identity)
|
.is_some_and(identity)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -114,8 +112,6 @@ impl Component for XrTracker {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
world.commands().entity(root).add_child(entity);
|
world.commands().entity(root).add_child(entity);
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct XrSessionPlugin {
|
pub struct XrSessionPlugin {
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ fn create_openxr_events(
|
|||||||
commands.entity(id).insert(oxr_action_set);
|
commands.entity(id).insert(oxr_action_set);
|
||||||
|
|
||||||
//since the actions are made from the sets lets go
|
//since the actions are made from the sets lets go
|
||||||
for &child in children.iter() {
|
for child in children.iter() {
|
||||||
//first get the action entity and stuff
|
//first get the action entity and stuff
|
||||||
let (create_action, bindings) = actions_query.get(child).unwrap();
|
let (create_action, bindings) = actions_query.get(child).unwrap();
|
||||||
//lets create dat action
|
//lets create dat action
|
||||||
@@ -158,7 +158,7 @@ fn create_openxr_events(
|
|||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
//since we need actions for bindings lets go!!
|
//since we need actions for bindings lets go!!
|
||||||
for &bind in bindings.iter() {
|
for bind in bindings.iter() {
|
||||||
//interaction profile
|
//interaction profile
|
||||||
//get the binding entity and stuff
|
//get the binding entity and stuff
|
||||||
let create_binding = bindings_query.get(bind).unwrap();
|
let create_binding = bindings_query.get(bind).unwrap();
|
||||||
@@ -197,7 +197,7 @@ fn create_openxr_events(
|
|||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
//since we need actions for bindings lets go!!
|
//since we need actions for bindings lets go!!
|
||||||
for &bind in bindings.iter() {
|
for bind in bindings.iter() {
|
||||||
//interaction profile
|
//interaction profile
|
||||||
//get the binding entity and stuff
|
//get the binding entity and stuff
|
||||||
let create_binding = bindings_query.get(bind).unwrap();
|
let create_binding = bindings_query.get(bind).unwrap();
|
||||||
@@ -236,7 +236,7 @@ fn create_openxr_events(
|
|||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
//since we need actions for bindings lets go!!
|
//since we need actions for bindings lets go!!
|
||||||
for &bind in bindings.iter() {
|
for bind in bindings.iter() {
|
||||||
//interaction profile
|
//interaction profile
|
||||||
//get the binding entity and stuff
|
//get the binding entity and stuff
|
||||||
let create_binding = bindings_query.get(bind).unwrap();
|
let create_binding = bindings_query.get(bind).unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user