2316
Cargo.lock
generated
2316
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"]
|
||||
|
||||
[workspace.dependencies]
|
||||
bevy = { version = "0.15", default-features = false, features = [
|
||||
bevy = { version = "0.16.0", default-features = false, features = [
|
||||
"bevy_render",
|
||||
"bevy_core_pipeline",
|
||||
"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" }
|
||||
openxr = "0.19.0"
|
||||
thiserror = "2.0.3"
|
||||
wgpu = "23"
|
||||
wgpu-hal = "23"
|
||||
wgpu = "24.0.1"
|
||||
wgpu-hal = "24.0.2"
|
||||
|
||||
@@ -21,8 +21,8 @@ fn main() {
|
||||
.add_systems(Update, handle_flight_input)
|
||||
// Realtime lighting is expensive, use ambient light instead
|
||||
.insert_resource(AmbientLight {
|
||||
color: Default::default(),
|
||||
brightness: 500.0,
|
||||
..AmbientLight::default()
|
||||
})
|
||||
.run();
|
||||
}
|
||||
@@ -48,7 +48,7 @@ fn setup_scene(
|
||||
|
||||
commands.spawn((
|
||||
Camera3d::default(),
|
||||
Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -132,14 +132,15 @@ fn handle_flight_input(
|
||||
//hard code speed for now
|
||||
let speed = 5.0;
|
||||
|
||||
let root = oxr_root.get_single_mut();
|
||||
let root = oxr_root.single_mut();
|
||||
match root {
|
||||
Ok(mut root_position) => {
|
||||
//lets assume HMD based direction for now
|
||||
let view = views.first();
|
||||
match view {
|
||||
Some(v) => {
|
||||
let reference_quat = root_position.rotation * v.pose.orientation.to_quat();
|
||||
let reference_quat =
|
||||
root_position.rotation * v.pose.orientation.to_quat();
|
||||
let locomotion_vector = reference_quat.mul_vec3(input_vector);
|
||||
|
||||
root_position.translation +=
|
||||
|
||||
@@ -7,18 +7,13 @@ use bevy_mod_openxr::{add_xr_plugins, init::OxrInitPlugin, types::OxrExtensions}
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(add_xr_plugins(DefaultPlugins).set(OxrInitPlugin {
|
||||
app_info: default(),
|
||||
exts: {
|
||||
let mut exts = OxrExtensions::default();
|
||||
exts.enable_fb_passthrough();
|
||||
exts.enable_hand_tracking();
|
||||
exts
|
||||
},
|
||||
blend_modes: default(),
|
||||
backends: default(),
|
||||
formats: default(),
|
||||
resolutions: default(),
|
||||
synchronous_pipeline_compilation: default(),
|
||||
..default()
|
||||
}))
|
||||
.add_plugins(bevy_xr_utils::hand_gizmos::HandGizmosPlugin)
|
||||
.add_systems(Startup, setup)
|
||||
@@ -26,6 +21,7 @@ fn main() {
|
||||
.insert_resource(AmbientLight {
|
||||
color: Default::default(),
|
||||
brightness: 500.0,
|
||||
affects_lightmapped_meshes: false,
|
||||
})
|
||||
.insert_resource(ClearColor(Color::NONE))
|
||||
.run();
|
||||
|
||||
@@ -49,23 +49,23 @@ fn handle_input(
|
||||
) {
|
||||
if keys.just_pressed(KeyCode::KeyE) {
|
||||
info!("sending end");
|
||||
end.send_default();
|
||||
end.write_default();
|
||||
}
|
||||
if keys.just_pressed(KeyCode::KeyC) {
|
||||
info!("sending create");
|
||||
create.send_default();
|
||||
create.write_default();
|
||||
}
|
||||
if keys.just_pressed(KeyCode::KeyD) {
|
||||
info!("sending destroy");
|
||||
destroy.send_default();
|
||||
destroy.write_default();
|
||||
}
|
||||
if keys.just_pressed(KeyCode::KeyB) {
|
||||
info!("sending begin");
|
||||
begin.send_default();
|
||||
begin.write_default();
|
||||
}
|
||||
if keys.just_pressed(KeyCode::KeyR) {
|
||||
info!("sending request exit");
|
||||
request_exit.send_default();
|
||||
request_exit.write_default();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ fn main() {
|
||||
}
|
||||
|
||||
fn attach_set(actions: Res<ControllerActions>, mut attach: EventWriter<OxrAttachActionSet>) {
|
||||
attach.send(OxrAttachActionSet(actions.set.clone()));
|
||||
attach.write(OxrAttachActionSet(actions.set.clone()));
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
@@ -45,7 +45,7 @@ struct ControllerActions {
|
||||
right: openxr::Action<Posef>,
|
||||
}
|
||||
fn sync_actions(actions: Res<ControllerActions>, mut sync: EventWriter<OxrSyncActionSet>) {
|
||||
sync.send(OxrSyncActionSet(actions.set.clone()));
|
||||
sync.write(OxrSyncActionSet(actions.set.clone()));
|
||||
}
|
||||
/// set up a simple 3D scene
|
||||
fn setup(
|
||||
@@ -82,12 +82,12 @@ fn suggest_action_bindings(
|
||||
actions: Res<ControllerActions>,
|
||||
mut bindings: EventWriter<OxrSuggestActionBinding>,
|
||||
) {
|
||||
bindings.send(OxrSuggestActionBinding {
|
||||
bindings.write(OxrSuggestActionBinding {
|
||||
action: actions.left.as_raw(),
|
||||
interaction_profile: "/interaction_profiles/oculus/touch_controller".into(),
|
||||
bindings: vec!["/user/hand/left/input/grip/pose".into()],
|
||||
});
|
||||
bindings.send(OxrSuggestActionBinding {
|
||||
bindings.write(OxrSuggestActionBinding {
|
||||
action: actions.right.as_raw(),
|
||||
interaction_profile: "/interaction_profiles/oculus/touch_controller".into(),
|
||||
bindings: vec!["/user/hand/right/input/grip/pose".into()],
|
||||
|
||||
@@ -32,23 +32,23 @@ fn handle_input(
|
||||
) {
|
||||
if keys.just_pressed(KeyCode::KeyE) {
|
||||
info!("sending end");
|
||||
end.send_default();
|
||||
end.write_default();
|
||||
}
|
||||
if keys.just_pressed(KeyCode::KeyC) {
|
||||
info!("sending create");
|
||||
create.send_default();
|
||||
create.write_default();
|
||||
}
|
||||
if keys.just_pressed(KeyCode::KeyD) {
|
||||
info!("sending destroy");
|
||||
destroy.send_default();
|
||||
destroy.write_default();
|
||||
}
|
||||
if keys.just_pressed(KeyCode::KeyB) {
|
||||
info!("sending begin");
|
||||
begin.send_default();
|
||||
begin.write_default();
|
||||
}
|
||||
if keys.just_pressed(KeyCode::KeyR) {
|
||||
info!("sending request exit");
|
||||
request_exit.send_default();
|
||||
request_exit.write_default();
|
||||
}
|
||||
if keys.just_pressed(KeyCode::KeyI) {
|
||||
info!("current state: {:?}", *state);
|
||||
|
||||
@@ -28,8 +28,8 @@ fn main() {
|
||||
send_recenter.after(XRUtilsActionSystemSet::SyncActionStates),
|
||||
)
|
||||
.insert_resource(AmbientLight {
|
||||
color: Default::default(),
|
||||
brightness: 500.0,
|
||||
..AmbientLight::default()
|
||||
})
|
||||
.run();
|
||||
}
|
||||
@@ -161,7 +161,7 @@ fn send_look_at_red_cube_event(
|
||||
info!("send facing");
|
||||
let quat = Transform::default()
|
||||
.looking_at(Transform::from_xyz(4.0, 0.0, 0.0).translation, Vec3::Y); //this is a transform facing the red cube from the center of the scene, you should use the HMD posision but I was lazy.
|
||||
event_writer.send(SnapToRotation(quat.rotation));
|
||||
event_writer.write(SnapToRotation(quat.rotation));
|
||||
}
|
||||
}
|
||||
XRUtilsActionState::Float(_) => (),
|
||||
@@ -185,7 +185,7 @@ fn send_recenter(
|
||||
if send {
|
||||
let center = Transform::default().translation;
|
||||
|
||||
event_writer.send(SnapToPosition(center));
|
||||
event_writer.write(SnapToPosition(center));
|
||||
}
|
||||
}
|
||||
XRUtilsActionState::Float(_) => (),
|
||||
|
||||
@@ -3,8 +3,8 @@ use std::ptr;
|
||||
|
||||
use bevy::ecs::schedule::ScheduleLabel;
|
||||
use bevy::ecs::system::RunSystemOnce;
|
||||
use bevy::platform::collections::HashMap;
|
||||
use bevy::prelude::*;
|
||||
use bevy::utils::HashMap;
|
||||
use bevy_mod_xr::session::XrSessionCreatedEvent;
|
||||
use openxr::sys::ActionSuggestedBinding;
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
use bevy::{
|
||||
ecs::system::Resource,
|
||||
prelude::{Deref, DerefMut},
|
||||
};
|
||||
use bevy::prelude::{Deref, DerefMut, Resource};
|
||||
use openxr::ExtensionSet;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Deref, DerefMut, Resource)]
|
||||
|
||||
@@ -110,7 +110,7 @@ fn clean_up_default_hands(
|
||||
) {
|
||||
for e in &query {
|
||||
debug!("removing default hand entity");
|
||||
cmds.entity(e).despawn_recursive();
|
||||
cmds.entity(e).despawn();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ impl Plugin for OxrOverlayPlugin {
|
||||
|
||||
fn handle_overlay_event(event: OxrEventIn, mut writer: EventWriter<OxrOverlaySessionEvent>) {
|
||||
if let Event::MainSessionVisibilityChangedEXTX(event) = *event {
|
||||
writer.send(OxrOverlaySessionEvent::MainSessionVisibilityChanged {
|
||||
writer.write(OxrOverlaySessionEvent::MainSessionVisibilityChanged {
|
||||
visible: event.visible(),
|
||||
flags: event.flags(),
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ use openxr::PassthroughCapabilityFlagsFB;
|
||||
use crate::layer_builder::PassthroughLayer;
|
||||
use crate::resources::*;
|
||||
use crate::session::OxrSession;
|
||||
use crate::types::*;
|
||||
use crate::types::Result as OxrResult;
|
||||
|
||||
pub struct OxrPassthroughPlugin;
|
||||
|
||||
@@ -73,7 +73,7 @@ pub fn create_passthrough(
|
||||
session: &OxrSession,
|
||||
flags: openxr::PassthroughFlagsFB,
|
||||
purpose: openxr::PassthroughLayerPurposeFB,
|
||||
) -> Result<(OxrPassthrough, OxrPassthroughLayer)> {
|
||||
) -> OxrResult<(OxrPassthrough, OxrPassthroughLayer)> {
|
||||
let passthrough = session.create_passthrough(flags)?;
|
||||
|
||||
let passthrough_layer = session.create_passthrough_layer(&passthrough, purpose)?;
|
||||
@@ -82,7 +82,10 @@ pub fn create_passthrough(
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn supports_passthrough(instance: &OxrInstance, system: OxrSystemId) -> Result<bool> {
|
||||
pub fn supports_passthrough(
|
||||
instance: &OxrInstance,
|
||||
system: OxrSystemId,
|
||||
) -> OxrResult<bool> {
|
||||
if instance.exts().fb_passthrough.is_none() {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
@@ -115,7 +115,6 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
||||
<Vulkan as Api>::Instance::desired_extensions(&vk_entry, VK_TARGET_VERSION_ASH, flags)?;
|
||||
let device_extensions = [
|
||||
ash::khr::swapchain::NAME,
|
||||
#[cfg(target_os = "android")]
|
||||
ash::khr::draw_indirect_count::NAME,
|
||||
ash::khr::timeline_semaphore::NAME,
|
||||
ash::khr::imageless_framebuffer::NAME,
|
||||
@@ -197,8 +196,7 @@ unsafe impl GraphicsExt for openxr::Vulkan {
|
||||
"Couldn't parse Android's ",
|
||||
"ro.build.version.sdk system property ({}): {}",
|
||||
),
|
||||
val,
|
||||
err,
|
||||
val, err,
|
||||
);
|
||||
0
|
||||
}
|
||||
@@ -652,6 +650,7 @@ fn wgpu_to_vulkan(format: wgpu::TextureFormat) -> Option<ash::vk::Format> {
|
||||
Tf::R32Uint => F::R32_UINT,
|
||||
Tf::R32Sint => F::R32_SINT,
|
||||
Tf::R32Float => F::R32_SFLOAT,
|
||||
Tf::R64Uint => F::R64_UINT,
|
||||
Tf::Rg16Uint => F::R16G16_UINT,
|
||||
Tf::Rg16Sint => F::R16G16_SINT,
|
||||
Tf::Rg16Float => F::R16G16_SFLOAT,
|
||||
|
||||
@@ -13,6 +13,7 @@ use bevy::render::settings::RenderCreation;
|
||||
use bevy::render::MainWorld;
|
||||
use bevy::render::Render;
|
||||
use bevy::render::RenderApp;
|
||||
use bevy::render::RenderDebugFlags;
|
||||
use bevy::render::RenderPlugin;
|
||||
use bevy::winit::UpdateMode;
|
||||
use bevy::winit::WinitSettings;
|
||||
@@ -24,11 +25,12 @@ use crate::graphics::*;
|
||||
use crate::resources::*;
|
||||
use crate::session::OxrSession;
|
||||
use crate::session::OxrSessionCreateNextChain;
|
||||
use crate::types::Result as OxrResult;
|
||||
use crate::types::*;
|
||||
|
||||
use super::exts::OxrEnabledExtensions;
|
||||
use super::poll_events::OxrEventIn;
|
||||
use super::poll_events::OxrEventHandlerExt;
|
||||
use super::poll_events::OxrEventIn;
|
||||
|
||||
pub fn session_started(started: Option<Res<OxrSessionStarted>>) -> bool {
|
||||
started.is_some_and(|started| started.0)
|
||||
@@ -62,6 +64,7 @@ pub struct OxrInitPlugin {
|
||||
pub resolutions: Option<Vec<UVec2>>,
|
||||
/// Passed into the render plugin when added to the app.
|
||||
pub synchronous_pipeline_compilation: bool,
|
||||
pub render_debug_flags: RenderDebugFlags,
|
||||
}
|
||||
impl Default for OxrInitPlugin {
|
||||
fn default() -> Self {
|
||||
@@ -73,11 +76,12 @@ impl Default for OxrInitPlugin {
|
||||
exts.enable_hand_tracking();
|
||||
exts
|
||||
},
|
||||
blend_modes: default(),
|
||||
blend_modes: Some(vec![openxr::EnvironmentBlendMode::OPAQUE]),
|
||||
backends: default(),
|
||||
formats: Some(vec![wgpu::TextureFormat::Rgba8UnormSrgb]),
|
||||
resolutions: default(),
|
||||
synchronous_pipeline_compilation: false,
|
||||
render_debug_flags: default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,6 +108,7 @@ impl Plugin for OxrInitPlugin {
|
||||
RenderInstance(Arc::new(WgpuWrapper::new(wgpu_instance))),
|
||||
),
|
||||
synchronous_pipeline_compilation: self.synchronous_pipeline_compilation,
|
||||
debug_flags: self.render_debug_flags,
|
||||
},
|
||||
ExtractResourcePlugin::<OxrSessionStarted>::default(),
|
||||
))
|
||||
@@ -197,7 +202,7 @@ fn detect_session_destroyed(
|
||||
let state = state.0.load(Ordering::Relaxed);
|
||||
if *last_state && !state {
|
||||
debug!("XrSession was fully destroyed!");
|
||||
sender.send_default();
|
||||
sender.write_default();
|
||||
cmds.insert_resource(XrState::Available);
|
||||
}
|
||||
*last_state = state;
|
||||
@@ -206,7 +211,7 @@ fn detect_session_destroyed(
|
||||
impl OxrInitPlugin {
|
||||
fn init_xr(
|
||||
&self,
|
||||
) -> Result<(
|
||||
) -> OxrResult<(
|
||||
OxrInstance,
|
||||
OxrSystemId,
|
||||
WgpuGraphics,
|
||||
@@ -326,14 +331,14 @@ pub fn handle_events(
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
changed_event.send(XrStateChanged(new_status));
|
||||
changed_event.write(XrStateChanged(new_status));
|
||||
*status = new_status;
|
||||
}
|
||||
InstanceLossPending(_) => {}
|
||||
EventsLost(e) => warn!("lost {} XR events", e.lost_event_count()),
|
||||
// we might want to check if this is the correct session?
|
||||
Event::InteractionProfileChanged(_) => {
|
||||
interaction_profile_changed_event.send_default();
|
||||
interaction_profile_changed_event.write_default();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -350,7 +355,7 @@ fn init_xr_session(
|
||||
resolutions,
|
||||
graphics_info,
|
||||
}: SessionConfigInfo,
|
||||
) -> Result<(
|
||||
) -> OxrResult<(
|
||||
OxrSession,
|
||||
OxrFrameWaiter,
|
||||
OxrFrameStream,
|
||||
@@ -456,7 +461,7 @@ fn init_xr_session(
|
||||
} else {
|
||||
available_blend_modes.first().copied()
|
||||
}
|
||||
.ok_or(OxrError::NoAvailableBackend)?;
|
||||
.ok_or(OxrError::NoAvailableBlendMode)?;
|
||||
|
||||
let graphics_info = OxrGraphicsInfo {
|
||||
blend_mode,
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::resources::*;
|
||||
use crate::spaces::OxrSpaceExt as _;
|
||||
|
||||
pub trait LayerProvider {
|
||||
fn get<'a>(&'a self, world: &'a World) -> Option<Box<dyn CompositionLayer + '_>>;
|
||||
fn get<'a>(&'a self, world: &'a World) -> Option<Box<dyn CompositionLayer<'a> + 'a>>;
|
||||
}
|
||||
|
||||
pub struct ProjectionLayer;
|
||||
@@ -63,7 +63,7 @@ impl LayerProvider for ProjectionLayer {
|
||||
}
|
||||
|
||||
impl LayerProvider for PassthroughLayer {
|
||||
fn get<'a>(&'a self, world: &'a World) -> Option<Box<dyn CompositionLayer + '_>> {
|
||||
fn get(&self, world: &World) -> Option<Box<dyn CompositionLayer>> {
|
||||
Some(Box::new(
|
||||
CompositionLayerPassthrough::new()
|
||||
.layer_handle(world.get_resource::<OxrPassthroughLayer>()?)
|
||||
@@ -117,7 +117,7 @@ impl<'a> SwapchainSubImage<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Default for SwapchainSubImage<'a> {
|
||||
impl Default for SwapchainSubImage<'_> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
@@ -165,11 +165,15 @@ impl<'a> CompositionLayerProjectionView<'a> {
|
||||
self
|
||||
}
|
||||
}
|
||||
impl<'a> Default for CompositionLayerProjectionView<'a> {
|
||||
impl Default for CompositionLayerProjectionView<'_> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
/// # Safety
|
||||
/// the header function must return a ref to a valid Composition Layer struct.
|
||||
/// it has to use `repr(C)` and it has to follow the shape of a Composition Layer struct from the
|
||||
/// OpenXR specification
|
||||
pub unsafe trait CompositionLayer<'a> {
|
||||
fn swapchain(&self) -> Option<&'a OxrSwapchain>;
|
||||
fn header(&self) -> &sys::CompositionLayerBaseHeader;
|
||||
@@ -227,7 +231,7 @@ unsafe impl<'a> CompositionLayer<'a> for CompositionLayerProjection<'a> {
|
||||
unsafe { mem::transmute(&self.inner) }
|
||||
}
|
||||
}
|
||||
impl<'a> Default for CompositionLayerProjection<'a> {
|
||||
impl Default for CompositionLayerProjection<'_> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use super::{openxr_session_available, resources::OxrInstance};
|
||||
use bevy::{ecs::system::SystemId, prelude::*};
|
||||
use bevy_mod_xr::session::{XrFirst, XrHandleEvents};
|
||||
use openxr::{Event, EventDataBuffer};
|
||||
@@ -30,7 +31,7 @@ pub fn poll_events(world: &mut World) {
|
||||
.iter()
|
||||
.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}");
|
||||
};
|
||||
}
|
||||
@@ -38,7 +39,6 @@ pub fn poll_events(world: &mut World) {
|
||||
world.insert_resource(handlers);
|
||||
}
|
||||
|
||||
use super::{openxr_session_available, resources::OxrInstance};
|
||||
#[derive(Resource, Debug, Default)]
|
||||
pub struct OxrEventHandlers(Vec<Entity>);
|
||||
pub trait OxrEventHandlerExt {
|
||||
|
||||
@@ -20,18 +20,10 @@ impl Default for OxrReferenceSpacePlugin {
|
||||
}
|
||||
}
|
||||
|
||||
/// Resource specifying what the type should be for [`OxrPrimaryReferenceSpace`]. Set through [`OxrReferenceSpacePlugin`].
|
||||
/// Resource specifying what the type should used be for the [`XrPrimaryReferenceSpace`]. Set through [`OxrReferenceSpacePlugin`].
|
||||
#[derive(Resource)]
|
||||
struct OxrDefaultPrimaryReferenceSpaceType(openxr::ReferenceSpaceType);
|
||||
|
||||
/// The Default Reference space used for locating things
|
||||
// #[derive(Resource, Deref, ExtrctResource, Clone)]
|
||||
// pub struct OxrPrimaryReferenceSpace(pub Arc<openxr::Space>);
|
||||
|
||||
/// The Reference space used for locating spaces on this entity
|
||||
#[derive(Component)]
|
||||
pub struct OxrReferenceSpace(pub openxr::Space);
|
||||
|
||||
impl Plugin for OxrReferenceSpacePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins(ExtractResourcePlugin::<XrPrimaryReferenceSpace>::default())
|
||||
|
||||
@@ -4,7 +4,7 @@ use bevy::{
|
||||
camera::{ManualTextureView, ManualTextureViewHandle, ManualTextureViews, RenderTarget},
|
||||
extract_resource::ExtractResourcePlugin,
|
||||
pipelined_rendering::PipelinedRenderingPlugin,
|
||||
view::ExtractedView,
|
||||
view::{ExtractedView, NoFrustumCulling},
|
||||
Render, RenderApp,
|
||||
},
|
||||
transform::TransformSystem,
|
||||
@@ -146,7 +146,7 @@ pub fn clean_views(
|
||||
) {
|
||||
for (e, cam) in &cam_query {
|
||||
manual_texture_views.remove(&ManualTextureViewHandle(XR_TEXTURE_INDEX + cam.0));
|
||||
commands.entity(e).despawn_recursive();
|
||||
commands.entity(e).despawn();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,6 +170,8 @@ pub fn init_views<const SPAWN_CAMERAS: bool>(
|
||||
..Default::default()
|
||||
},
|
||||
XrCamera(index),
|
||||
Projection::custom(XrProjection::default()),
|
||||
NoFrustumCulling,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -244,13 +246,17 @@ pub fn locate_views(
|
||||
}
|
||||
|
||||
pub fn update_views(
|
||||
mut query: Query<(&mut Transform, &mut XrProjection, &XrCamera)>,
|
||||
mut query: Query<(&mut Transform, &mut Projection, &XrCamera)>,
|
||||
views: ResMut<OxrViews>,
|
||||
) {
|
||||
for (mut transform, mut projection, camera) in query.iter_mut() {
|
||||
let Some(view) = views.get(camera.0 as usize) else {
|
||||
continue;
|
||||
};
|
||||
let projection = match projection.as_mut() {
|
||||
Projection::Custom(custom) => custom.get_mut::<XrProjection>().unwrap(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let projection_matrix = calculate_projection(
|
||||
projection.near,
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::error::OxrError;
|
||||
use crate::graphics::*;
|
||||
use crate::layer_builder::{CompositionLayer, LayerProvider};
|
||||
use crate::session::{OxrSession, OxrSessionCreateNextChain};
|
||||
use crate::types::Result as OxrResult;
|
||||
use crate::types::*;
|
||||
|
||||
/// Wrapper around an [`Entry`](openxr::Entry) with some methods overridden to use bevy types.
|
||||
@@ -15,7 +16,7 @@ pub struct OxrEntry(pub openxr::Entry);
|
||||
|
||||
impl OxrEntry {
|
||||
/// Enumerate available extensions for this OpenXR runtime.
|
||||
pub fn enumerate_extensions(&self) -> Result<OxrExtensions> {
|
||||
pub fn enumerate_extensions(&self) -> OxrResult<OxrExtensions> {
|
||||
Ok(self.0.enumerate_extensions().map(Into::into)?)
|
||||
}
|
||||
|
||||
@@ -28,7 +29,7 @@ impl OxrEntry {
|
||||
exts: OxrExtensions,
|
||||
layers: &[&str],
|
||||
backend: GraphicsBackend,
|
||||
) -> Result<OxrInstance> {
|
||||
) -> OxrResult<OxrInstance> {
|
||||
let available_exts = self.enumerate_extensions()?;
|
||||
|
||||
if !backend.is_available(&available_exts) {
|
||||
@@ -53,7 +54,7 @@ impl OxrEntry {
|
||||
}
|
||||
|
||||
/// 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) -> OxrResult<Vec<GraphicsBackend>> {
|
||||
Ok(GraphicsBackend::available_backends(
|
||||
&self.enumerate_extensions()?,
|
||||
))
|
||||
@@ -105,7 +106,7 @@ impl OxrInstance {
|
||||
pub fn init_graphics(
|
||||
&self,
|
||||
system_id: openxr::SystemId,
|
||||
) -> Result<(WgpuGraphics, SessionCreateInfo)> {
|
||||
) -> OxrResult<(WgpuGraphics, SessionCreateInfo)> {
|
||||
graphics_match!(
|
||||
self.1;
|
||||
_ => {
|
||||
@@ -128,9 +129,9 @@ impl OxrInstance {
|
||||
system_id: openxr::SystemId,
|
||||
info: SessionCreateInfo,
|
||||
chain: &mut OxrSessionCreateNextChain,
|
||||
) -> Result<(OxrSession, OxrFrameWaiter, OxrFrameStream)> {
|
||||
) -> OxrResult<(OxrSession, OxrFrameWaiter, OxrFrameStream)> {
|
||||
if !info.0.using_graphics_of_val(&self.1) {
|
||||
return Err(OxrError::GraphicsBackendMismatch {
|
||||
return OxrResult::Err(OxrError::GraphicsBackendMismatch {
|
||||
item: std::any::type_name::<SessionCreateInfo>(),
|
||||
backend: info.0.graphics_name(),
|
||||
expected_backend: self.1.graphics_name(),
|
||||
@@ -180,7 +181,7 @@ impl OxrFrameStream {
|
||||
display_time: openxr::Time,
|
||||
environment_blend_mode: openxr::EnvironmentBlendMode,
|
||||
layers: &[&dyn CompositionLayer],
|
||||
) -> Result<()> {
|
||||
) -> OxrResult<()> {
|
||||
graphics_match!(
|
||||
&mut self.0;
|
||||
stream => {
|
||||
@@ -233,7 +234,7 @@ impl OxrSwapchain {
|
||||
/// Determine the index of the next image to render to in the swapchain image array.
|
||||
///
|
||||
/// Calls [`acquire_image`](openxr::Swapchain::acquire_image) internally.
|
||||
pub fn acquire_image(&mut self) -> Result<u32> {
|
||||
pub fn acquire_image(&mut self) -> OxrResult<u32> {
|
||||
graphics_match!(
|
||||
&mut self.0;
|
||||
swap => Ok(swap.acquire_image()?)
|
||||
@@ -243,7 +244,7 @@ impl OxrSwapchain {
|
||||
/// Wait for the compositor to finish reading from the oldest unwaited acquired image.
|
||||
///
|
||||
/// 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) -> OxrResult<()> {
|
||||
graphics_match!(
|
||||
&mut self.0;
|
||||
swap => Ok(swap.wait_image(timeout)?)
|
||||
@@ -253,7 +254,7 @@ impl OxrSwapchain {
|
||||
/// Release the oldest acquired image.
|
||||
///
|
||||
/// Calls [`release_image`](openxr::Swapchain::release_image) internally.
|
||||
pub fn release_image(&mut self) -> Result<()> {
|
||||
pub fn release_image(&mut self) -> OxrResult<()> {
|
||||
graphics_match!(
|
||||
&mut self.0;
|
||||
swap => Ok(swap.release_image()?)
|
||||
@@ -268,7 +269,7 @@ impl OxrSwapchain {
|
||||
device: &wgpu::Device,
|
||||
format: wgpu::TextureFormat,
|
||||
resolution: UVec2,
|
||||
) -> Result<OxrSwapchainImages> {
|
||||
) -> OxrResult<OxrSwapchainImages> {
|
||||
graphics_match!(
|
||||
&self.0;
|
||||
swap => {
|
||||
@@ -288,10 +289,6 @@ impl OxrSwapchain {
|
||||
#[derive(Debug, Deref, Resource, Clone, Copy, ExtractResource)]
|
||||
pub struct OxrSwapchainImages(pub &'static [wgpu::Texture]);
|
||||
|
||||
/// Thread safe wrapper around [openxr::Space] representing the stage.
|
||||
// #[derive(Deref, Clone, Resource)]
|
||||
// pub struct OxrStage(pub Arc<openxr::Space>);
|
||||
|
||||
/// Stores the latest generated [OxrViews]
|
||||
#[derive(Clone, Resource, ExtractResource, Deref, DerefMut, Default)]
|
||||
pub struct OxrViews(pub Vec<openxr::View>);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{mem::MaybeUninit, ptr, sync::Mutex};
|
||||
|
||||
use bevy::{prelude::*, utils::hashbrown::HashSet};
|
||||
use bevy::{platform::collections::hash_set::HashSet, prelude::*};
|
||||
use bevy_mod_xr::{
|
||||
session::{XrFirst, XrHandleEvents},
|
||||
spaces::{
|
||||
|
||||
@@ -10,7 +10,7 @@ keywords = ["gamedev", "bevy", "Xr", "Vr"]
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bevy.workspace = true
|
||||
bevy = { workspace = true, features = ["bevy_log"] }
|
||||
|
||||
[lints.clippy]
|
||||
too_many_arguments = "allow"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::{any::TypeId, marker::PhantomData};
|
||||
|
||||
use bevy::app::{App, Plugin};
|
||||
use bevy::ecs::system::Resource;
|
||||
use bevy::math::Vec2;
|
||||
use bevy::prelude::Resource;
|
||||
|
||||
pub struct ActionPlugin<A: Action>(PhantomData<A>);
|
||||
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
use core::panic;
|
||||
|
||||
use bevy::app::{App, Plugin, PostUpdate};
|
||||
use bevy::app::{App, Plugin};
|
||||
use bevy::core_pipeline::core_3d::Camera3d;
|
||||
use bevy::ecs::component::{Component, StorageType};
|
||||
use bevy::ecs::reflect::ReflectComponent;
|
||||
use bevy::ecs::schedule::IntoSystemConfigs;
|
||||
use bevy::ecs::component::Component;
|
||||
use bevy::math::{Mat4, Vec3A, Vec4};
|
||||
use bevy::pbr::{PbrPlugin, PbrProjectionPlugin};
|
||||
use bevy::prelude::{Projection, SystemSet};
|
||||
use bevy::prelude::SystemSet;
|
||||
use bevy::reflect::std_traits::ReflectDefault;
|
||||
use bevy::reflect::Reflect;
|
||||
use bevy::render::camera::{CameraProjection, CameraProjectionPlugin};
|
||||
use bevy::render::camera::CameraProjection;
|
||||
use bevy::render::extract_component::{ExtractComponent, ExtractComponentPlugin};
|
||||
use bevy::render::view::{update_frusta, VisibilitySystems};
|
||||
use bevy::transform::TransformSystem;
|
||||
|
||||
use crate::session::XrTracker;
|
||||
|
||||
@@ -21,41 +16,19 @@ pub struct XrCameraPlugin;
|
||||
|
||||
impl Plugin for XrCameraPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins(CameraProjectionPlugin::<XrProjection>::default());
|
||||
app.add_systems(
|
||||
PostUpdate,
|
||||
update_frusta::<XrProjection>
|
||||
.after(TransformSystem::TransformPropagate)
|
||||
.before(VisibilitySystems::UpdateFrusta),
|
||||
);
|
||||
if app.is_plugin_added::<PbrPlugin>() {
|
||||
app.add_plugins(PbrProjectionPlugin::<XrProjection>::default());
|
||||
}
|
||||
app.add_plugins((
|
||||
ExtractComponentPlugin::<XrProjection>::default(),
|
||||
ExtractComponentPlugin::<XrCamera>::default(),
|
||||
));
|
||||
app.add_plugins(ExtractComponentPlugin::<XrCamera>::default());
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default, PartialEq, Eq, Debug, Hash, SystemSet)]
|
||||
pub struct XrViewInit;
|
||||
|
||||
#[derive(Debug, Clone, Reflect, ExtractComponent)]
|
||||
#[reflect(Component, Default)]
|
||||
#[derive(Debug, Clone, Reflect)]
|
||||
#[reflect(Default)]
|
||||
pub struct XrProjection {
|
||||
pub projection_matrix: Mat4,
|
||||
pub near: f32,
|
||||
}
|
||||
impl Component for XrProjection {
|
||||
const STORAGE_TYPE: StorageType = StorageType::Table;
|
||||
|
||||
fn register_component_hooks(hooks: &mut bevy::ecs::component::ComponentHooks) {
|
||||
hooks.on_add(|mut world, entity, _| {
|
||||
world.commands().entity(entity).remove::<Projection>();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for XrProjection {
|
||||
fn default() -> Self {
|
||||
@@ -68,7 +41,7 @@ impl Default for XrProjection {
|
||||
|
||||
/// Marker component for an XR view. It is the backends responsibility to update this.
|
||||
#[derive(Clone, Copy, Component, ExtractComponent, Debug, Default)]
|
||||
#[require(Camera3d, XrProjection, XrTracker)]
|
||||
#[require(Camera3d, XrTracker)]
|
||||
pub struct XrCamera(pub u32);
|
||||
|
||||
impl CameraProjection for XrProjection {
|
||||
@@ -132,7 +105,6 @@ pub fn calculate_projection(near_z: f32, fov: Fov) -> Mat4 {
|
||||
// let y_fov = (self.fov.angle_up.abs() + self.fov.angle_down.abs());
|
||||
// return Mat4::perspective_infinite_reverse_rh(y_fov, x_fov / y_fov, self.near);
|
||||
|
||||
let is_vulkan_api = false; // FIXME wgpu probably abstracts this
|
||||
let far_z = -1.; // use infinite proj
|
||||
// let far_z = self.far;
|
||||
|
||||
@@ -149,11 +121,7 @@ pub fn calculate_projection(near_z: f32, fov: Fov) -> Mat4 {
|
||||
// positive Y up (OpenGL / D3D / Metal).
|
||||
// const float tanAngleHeight =
|
||||
// graphicsApi == GRAPHICS_VULKAN ? (tanAngleDown - tanAngleUp) : (tanAngleUp - tanAngleDown);
|
||||
let tan_angle_height = if is_vulkan_api {
|
||||
tan_angle_down - tan_angle_up
|
||||
} else {
|
||||
tan_angle_up - tan_angle_down
|
||||
};
|
||||
let tan_angle_height = tan_angle_up - tan_angle_down;
|
||||
|
||||
// Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES).
|
||||
// Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal).
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use bevy::{
|
||||
ecs::{component::Component, entity::Entity, world::Command},
|
||||
ecs::{component::Component, entity::Entity},
|
||||
log::warn,
|
||||
math::bool,
|
||||
prelude::{Bundle, Commands, Deref, DerefMut, Resource, Transform, Visibility, World},
|
||||
prelude::{Bundle, Command, Commands, Deref, DerefMut, Resource, Transform, Visibility, World},
|
||||
};
|
||||
|
||||
use crate::{session::XrTracker, spaces::XrSpaceLocationFlags};
|
||||
pub const HAND_JOINT_COUNT: usize = 26;
|
||||
|
||||
@@ -182,7 +181,7 @@ pub struct SpawnHandTracker<B: Bundle> {
|
||||
}
|
||||
|
||||
impl<B: Bundle> Command for SpawnHandTracker<B> {
|
||||
fn apply(self, world: &mut bevy::prelude::World) {
|
||||
fn apply(self, world: &mut World) {
|
||||
let Some(executor) = world.remove_resource::<SpawnHandTrackerCommandExecutor>() else {
|
||||
warn!("no SpawnHandTracker executor defined, skipping handtracker creation");
|
||||
return;
|
||||
|
||||
@@ -3,8 +3,9 @@ use std::sync::atomic::AtomicBool;
|
||||
use std::sync::Arc;
|
||||
|
||||
use bevy::app::{AppExit, MainScheduleOrder};
|
||||
use bevy::ecs::component::StorageType;
|
||||
use bevy::ecs::component::HookContext;
|
||||
use bevy::ecs::schedule::ScheduleLabel;
|
||||
use bevy::ecs::world::DeferredWorld;
|
||||
use bevy::prelude::*;
|
||||
use bevy::render::extract_resource::{ExtractResource, ExtractResourcePlugin};
|
||||
use bevy::render::{Render, RenderApp, RenderSet};
|
||||
@@ -96,26 +97,21 @@ pub struct XrTrackingRoot;
|
||||
struct TrackingRootRes(Entity);
|
||||
|
||||
/// 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;
|
||||
impl Component for XrTracker {
|
||||
const STORAGE_TYPE: StorageType = StorageType::SparseSet;
|
||||
|
||||
fn register_component_hooks(hooks: &mut bevy::ecs::component::ComponentHooks) {
|
||||
hooks.on_add(|mut world, entity, _| {
|
||||
if world
|
||||
.entity(entity)
|
||||
.get_components::<Has<Parent>>()
|
||||
.is_some_and(identity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
let Some(root) = world.get_resource::<TrackingRootRes>().map(|r| r.0) else {
|
||||
return;
|
||||
};
|
||||
world.commands().entity(root).add_child(entity);
|
||||
});
|
||||
fn on_tracker_add(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {
|
||||
if world
|
||||
.entity(entity)
|
||||
.get_components::<Has<Children>>()
|
||||
.is_some_and(identity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
let Some(root) = world.get_resource::<TrackingRootRes>().map(|r| r.0) else {
|
||||
return;
|
||||
};
|
||||
world.commands().entity(root).add_child(entity);
|
||||
}
|
||||
|
||||
pub struct XrSessionPlugin {
|
||||
@@ -220,7 +216,7 @@ impl Plugin for XrSessionPlugin {
|
||||
}
|
||||
|
||||
fn exits_session_on_app_exit(mut request_exit: EventWriter<XrRequestExitEvent>) {
|
||||
request_exit.send_default();
|
||||
request_exit.write_default();
|
||||
}
|
||||
|
||||
/// Event sent by backends whenever [`XrState`] is changed.
|
||||
@@ -262,18 +258,18 @@ pub fn auto_handle_session(
|
||||
match state {
|
||||
XrState::Available => {
|
||||
if !*no_auto_restart {
|
||||
create_session.send_default();
|
||||
create_session.write_default();
|
||||
}
|
||||
}
|
||||
XrState::Ready => {
|
||||
begin_session.send_default();
|
||||
begin_session.write_default();
|
||||
}
|
||||
XrState::Stopping => {
|
||||
end_session.send_default();
|
||||
end_session.write_default();
|
||||
}
|
||||
XrState::Exiting { should_restart } => {
|
||||
*no_auto_restart = !should_restart;
|
||||
destroy_session.send_default();
|
||||
destroy_session.write_default();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@@ -284,7 +280,7 @@ pub fn update_root_transform(
|
||||
mut root_transform: ResMut<XrRootTransform>,
|
||||
root: Query<&GlobalTransform, With<XrTrackingRoot>>,
|
||||
) {
|
||||
let Ok(transform) = root.get_single() else {
|
||||
let Ok(transform) = root.single() else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ fn update_stage(
|
||||
root_query: Query<&Transform, (With<XrTrackingRoot>, Without<XrTrackedStage>)>,
|
||||
mut stage_query: Query<&mut Transform, (With<XrTrackedStage>, Without<XrTrackingRoot>)>,
|
||||
) {
|
||||
if let Ok(root) = root_query.get_single() {
|
||||
if let Ok(root) = root_query.single() {
|
||||
for mut transform in &mut stage_query {
|
||||
*transform = *root;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ fn update_view(
|
||||
mut head_query: Query<&mut Transform, (With<HeadXRSpace>, Without<XrTrackedView>)>,
|
||||
mut view_query: Query<&mut Transform, (With<XrTrackedView>, Without<HeadXRSpace>)>,
|
||||
) {
|
||||
let head_transform = head_query.get_single_mut();
|
||||
let head_transform = head_query.single_mut();
|
||||
if let Ok(root) = head_transform {
|
||||
for mut transform in &mut view_query {
|
||||
*transform = *root;
|
||||
@@ -142,7 +142,7 @@ fn update_local_floor_transforms(
|
||||
mut head_space: Query<&mut Transform, (With<HeadXRSpace>, Without<XrTrackedLocalFloor>)>,
|
||||
mut local_floor: Query<&mut Transform, (With<XrTrackedLocalFloor>, Without<HeadXRSpace>)>,
|
||||
) {
|
||||
let head_transform = head_space.get_single_mut();
|
||||
let head_transform = head_space.single_mut();
|
||||
if let Ok(head) = head_transform {
|
||||
let mut calc_floor = *head;
|
||||
calc_floor.translation.y = 0.0;
|
||||
@@ -164,7 +164,7 @@ fn update_left_grip(
|
||||
mut left_grip: Query<&mut Transform, (With<LeftGrip>, Without<XrTrackedLeftGrip>)>,
|
||||
mut tracked_left_grip: Query<&mut Transform, (With<XrTrackedLeftGrip>, Without<LeftGrip>)>,
|
||||
) {
|
||||
let head_transform = left_grip.get_single_mut();
|
||||
let head_transform = left_grip.single_mut();
|
||||
if let Ok(head) = head_transform {
|
||||
for mut transform in &mut tracked_left_grip {
|
||||
*transform = *head;
|
||||
@@ -180,7 +180,7 @@ fn update_right_grip(
|
||||
mut right_grip: Query<&mut Transform, (With<RightGrip>, Without<XrTrackedRightGrip>)>,
|
||||
mut tracked_right_grip: Query<&mut Transform, (With<XrTrackedRightGrip>, Without<RightGrip>)>,
|
||||
) {
|
||||
let head_transform = right_grip.get_single_mut();
|
||||
let head_transform = right_grip.single_mut();
|
||||
if let Ok(head) = head_transform {
|
||||
for mut transform in &mut tracked_right_grip {
|
||||
*transform = *head;
|
||||
@@ -229,12 +229,12 @@ pub fn suggest_action_bindings(
|
||||
actions: Res<ControllerActions>,
|
||||
mut bindings: EventWriter<OxrSuggestActionBinding>,
|
||||
) {
|
||||
bindings.send(OxrSuggestActionBinding {
|
||||
bindings.write(OxrSuggestActionBinding {
|
||||
action: actions.left.as_raw(),
|
||||
interaction_profile: "/interaction_profiles/oculus/touch_controller".into(),
|
||||
bindings: vec!["/user/hand/left/input/grip/pose".into()],
|
||||
});
|
||||
bindings.send(OxrSuggestActionBinding {
|
||||
bindings.write(OxrSuggestActionBinding {
|
||||
action: actions.right.as_raw(),
|
||||
interaction_profile: "/interaction_profiles/oculus/touch_controller".into(),
|
||||
bindings: vec!["/user/hand/right/input/grip/pose".into()],
|
||||
@@ -242,11 +242,11 @@ pub fn suggest_action_bindings(
|
||||
}
|
||||
|
||||
fn sync_actions(actions: Res<ControllerActions>, mut sync: EventWriter<OxrSyncActionSet>) {
|
||||
sync.send(OxrSyncActionSet(actions.set.clone()));
|
||||
sync.write(OxrSyncActionSet(actions.set.clone()));
|
||||
}
|
||||
|
||||
fn attach_set(actions: Res<ControllerActions>, mut attach: EventWriter<OxrAttachActionSet>) {
|
||||
attach.send(OxrAttachActionSet(actions.set.clone()));
|
||||
attach.write(OxrAttachActionSet(actions.set.clone()));
|
||||
}
|
||||
|
||||
fn create_actions(instance: Res<OxrInstance>, mut cmds: Commands) {
|
||||
|
||||
@@ -28,7 +28,7 @@ pub fn handle_transform_events(
|
||||
mut position_reader: EventReader<SnapToPosition>,
|
||||
mut rotation_reader: EventReader<SnapToRotation>,
|
||||
) {
|
||||
let result = root_query.get_single_mut();
|
||||
let result = root_query.single_mut();
|
||||
match result {
|
||||
Ok(mut root_transform) => {
|
||||
let view = views.first();
|
||||
@@ -45,7 +45,7 @@ pub fn handle_transform_events(
|
||||
}
|
||||
|
||||
//rotation
|
||||
let root_local = root_transform.translation.clone();
|
||||
let root_local = root_transform.translation;
|
||||
let hmd_global =
|
||||
root_transform.rotation.mul_vec3(view_translation) + root_local;
|
||||
let view_rot = view.pose.orientation.to_quat();
|
||||
|
||||
@@ -131,7 +131,7 @@ fn create_openxr_events(
|
||||
commands.entity(id).insert(oxr_action_set);
|
||||
|
||||
//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
|
||||
let (create_action, bindings) = actions_query.get(child).unwrap();
|
||||
//lets create dat action
|
||||
@@ -158,7 +158,7 @@ fn create_openxr_events(
|
||||
}),
|
||||
));
|
||||
//since we need actions for bindings lets go!!
|
||||
for &bind in bindings.iter() {
|
||||
for bind in bindings.iter() {
|
||||
//interaction profile
|
||||
//get the binding entity and stuff
|
||||
let create_binding = bindings_query.get(bind).unwrap();
|
||||
@@ -171,7 +171,7 @@ fn create_openxr_events(
|
||||
bindings: binding,
|
||||
};
|
||||
//finally send the suggestion
|
||||
binding_writer.send(sugestion);
|
||||
binding_writer.write(sugestion);
|
||||
}
|
||||
}
|
||||
bevy_mod_xr::actions::ActionType::Float => {
|
||||
@@ -197,7 +197,7 @@ fn create_openxr_events(
|
||||
}),
|
||||
));
|
||||
//since we need actions for bindings lets go!!
|
||||
for &bind in bindings.iter() {
|
||||
for bind in bindings.iter() {
|
||||
//interaction profile
|
||||
//get the binding entity and stuff
|
||||
let create_binding = bindings_query.get(bind).unwrap();
|
||||
@@ -210,7 +210,7 @@ fn create_openxr_events(
|
||||
bindings: binding,
|
||||
};
|
||||
//finally send the suggestion
|
||||
binding_writer.send(sugestion);
|
||||
binding_writer.write(sugestion);
|
||||
}
|
||||
}
|
||||
bevy_mod_xr::actions::ActionType::Vector => {
|
||||
@@ -236,7 +236,7 @@ fn create_openxr_events(
|
||||
}),
|
||||
));
|
||||
//since we need actions for bindings lets go!!
|
||||
for &bind in bindings.iter() {
|
||||
for bind in bindings.iter() {
|
||||
//interaction profile
|
||||
//get the binding entity and stuff
|
||||
let create_binding = bindings_query.get(bind).unwrap();
|
||||
@@ -249,13 +249,13 @@ fn create_openxr_events(
|
||||
bindings: binding,
|
||||
};
|
||||
//finally send the suggestion
|
||||
binding_writer.send(sugestion);
|
||||
binding_writer.write(sugestion);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
attach_writer.send(OxrAttachActionSet(action_set));
|
||||
attach_writer.write(OxrAttachActionSet(action_set));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ fn sync_active_action_sets(
|
||||
active_action_set_query: Query<&XRUtilsActionSetReference, With<ActiveSet>>,
|
||||
) {
|
||||
for set in &active_action_set_query {
|
||||
sync_set.send(OxrSyncActionSet(set.0.clone()));
|
||||
sync_set.write(OxrSyncActionSet(set.0.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user