diff --git a/Cargo.toml b/Cargo.toml index 094811e..80462ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ edition = "2021" anyhow = "1.0.75" ash = "0.37.3" bevy = { git = "https://github.com/awtterpip/bevy", default-features = false, features = ["bevy_render"] } -openxr = "0.17.1" +openxr = {version = "0.17.1" } wgpu = "0.16.0" wgpu-core = "0.16.0" wgpu-hal = "0.16.0" diff --git a/examples/xr.rs b/examples/xr.rs index 57868bf..1bac15f 100644 --- a/examples/xr.rs +++ b/examples/xr.rs @@ -1,14 +1,27 @@ //! A simple 3D scene with light shining over a cube sitting on a plane. use bevy_openxr::{DefaultXrPlugins, LEFT_XR_TEXTURE_HANDLE, RIGHT_XR_TEXTURE_HANDLE}; use bevy::{prelude::*, render::camera::RenderTarget}; +use bevy::prelude::Component; +use bevy::render::camera::Viewport; +use bevy_openxr::input::XrInput; +use bevy_openxr::resources::{XrInstance, XrSession, XrViews}; fn main() { App::new() .add_plugins(DefaultXrPlugins) .add_systems(Startup, setup) + .add_systems(Update, head_movement) .run(); } +#[derive(Component)] +enum CameraType { + Left, + Right, + Middle, +} + + /// set up a simple 3D scene fn setup( mut commands: Commands, @@ -39,27 +52,119 @@ fn setup( ..default() }); // camera - commands.spawn(Camera3dBundle { + commands.spawn((Camera3dBundle { transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y), ..default() - }); + }, CameraType::Middle)); - commands.spawn(Camera3dBundle { + // let viewport = Viewport{ + // physical_position: Default::default(), + // physical_size: UVec2::splat(2000), + // depth: 0.0..1.0, + // }; + + commands.spawn((Camera3dBundle { transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y), camera: Camera { order: -1, target: RenderTarget::TextureView(LEFT_XR_TEXTURE_HANDLE), + viewport: None, ..default() }, ..default() - }); - commands.spawn(Camera3dBundle { + }, CameraType::Left)); + commands.spawn((Camera3dBundle { transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y), camera: Camera { order: -1, target: RenderTarget::TextureView(RIGHT_XR_TEXTURE_HANDLE), + viewport: None, ..default() }, ..default() - }); + }, CameraType::Right)); } +fn head_movement(views: ResMut, mut query: Query<(&mut Transform, &Camera, &CameraType)>) { + let views = views.lock().unwrap(); + let mut f = || -> Option<()> { + let midpoint = (views.get(0)?.pose.position.to_vec3() + + views.get(1)?.pose.position.to_vec3()) + / 2.; + for (mut t, _, camera_type) in query.iter_mut() { + match camera_type { + CameraType::Left => { + t.translation = views.get(0)?.pose.position.to_vec3() + }, + CameraType::Right => { + t.translation = views.get(1)?.pose.position.to_vec3() + }, + CameraType::Middle => { + t.translation = midpoint; + }, + } + } + let left_rot = views.get(0).unwrap().pose.orientation.to_quat(); + let right_rot = views.get(1).unwrap().pose.orientation.to_quat(); + let mid_rot = if left_rot.dot(right_rot) >= 0. { + left_rot.slerp(right_rot, 0.5) + } else { + right_rot.slerp(left_rot, 0.5) + }; + for (mut t, _, camera_type) in query.iter_mut() { + match camera_type { + CameraType::Left => { + t.rotation = left_rot + }, + CameraType::Right => { + t.rotation = right_rot + }, + CameraType::Middle => { + t.rotation = mid_rot; + }, + } + } + + + // for (mut projection, mut transform, eye) in cam.iter_mut() { + // let view_idx = match eye { + // Eye::Left => 0, + // Eye::Right => 1, + // }; + // let view = views.get(view_idx).unwrap(); + // + // projection.fov = view.fov; + // + // transform.rotation = view.pose.orientation.to_quat(); + // let pos = view.pose.position; + // transform.translation = pos.to_vec3(); + // } + + Some(()) + }; + f(); +} +pub trait Vec3Conv { + fn to_vec3(&self) -> Vec3; +} + +impl Vec3Conv for openxr::Vector3f { + fn to_vec3(&self) -> Vec3 { + Vec3::new(self.x, self.y, self.z) + } +} +pub trait QuatConv { + fn to_quat(&self) -> Quat; +} + +impl QuatConv for openxr::Quaternionf { + fn to_quat(&self) -> Quat { + Quat::from_xyzw(self.x, self.y, self.z, self.w) + } +} + +// fn head_movement(right_camera: Query<(&mut Transform, &RightCamera), Without>, left_camera: Query<(&mut Transform, &LeftCamera), Without>, xr_input: Res, instance: Res, session: Res) { +// +// // let stage = +// // session.create_reference_space(openxr::ReferenceSpaceType::VIEW, openxr::Posef::IDENTITY).unwrap(); +// // eprintln!("a: {:#?}", stage.locate(&xr_input.stage, xr_input.action_set.).unwrap().pose); +// } \ No newline at end of file diff --git a/src/graphics/vulkan.rs b/src/graphics/vulkan.rs index 99fcb90..9b77667 100644 --- a/src/graphics/vulkan.rs +++ b/src/graphics/vulkan.rs @@ -77,8 +77,8 @@ pub fn initialize_xr_graphics(window: Option) -> anyhow::Resul let blend_mode = xr_instance.enumerate_environment_blend_modes(xr_system_id, VIEW_TYPE)?[0]; - let vk_target_version = vk::make_api_version(0, 1, 1, 0); - let vk_target_version_xr = xr::Version::new(1, 1, 0); + let vk_target_version = vk::make_api_version(0, 1, 2, 0); + let vk_target_version_xr = xr::Version::new(1, 2, 0); let reqs = xr_instance.graphics_requirements::(xr_system_id)?; if vk_target_version_xr < reqs.min_api_version_supported || vk_target_version_xr.major() > reqs.max_api_version_supported.major()