api changes
This commit is contained in:
@@ -3,11 +3,14 @@ name = "xr_api"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
[features]
|
||||||
|
default = ["linked"]
|
||||||
|
linked = ["openxr/linked"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3.29"
|
futures = "0.3.29"
|
||||||
thiserror = "1.0.51"
|
thiserror = "1.0.51"
|
||||||
|
wgpu = "0.18"
|
||||||
|
|
||||||
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
||||||
openxr = "0.17.1"
|
openxr = "0.17.1"
|
||||||
|
|||||||
@@ -6,6 +6,12 @@ use crate::prelude::*;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Entry(Rc<dyn EntryTrait>);
|
pub struct Entry(Rc<dyn EntryTrait>);
|
||||||
|
|
||||||
|
impl Entry {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Instance(Rc<dyn InstanceTrait>);
|
pub struct Instance(Rc<dyn InstanceTrait>);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use wgpu::{Adapter, AdapterInfo, Device, Queue, TextureView};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub trait EntryTrait {
|
pub trait EntryTrait {
|
||||||
@@ -19,21 +21,36 @@ pub trait InstanceTrait {
|
|||||||
pub trait SessionTrait {
|
pub trait SessionTrait {
|
||||||
/// Returns the [Instance] used to create this.
|
/// Returns the [Instance] used to create this.
|
||||||
fn instance(&self) -> &Instance;
|
fn instance(&self) -> &Instance;
|
||||||
|
/// Get render resources compatible with this session.
|
||||||
|
fn get_render_resources(&self)
|
||||||
|
-> Option<(Device, Queue, AdapterInfo, Adapter, wgpu::Instance)>;
|
||||||
/// Request input modules with the specified bindings.
|
/// Request input modules with the specified bindings.
|
||||||
fn create_input(&self, bindings: Bindings) -> Result<Input>;
|
fn create_input(&self, bindings: Bindings) -> Result<Input>;
|
||||||
/// Blocks until a rendering frame is available and then begins it.
|
/// Blocks until a rendering frame is available, then returns the texture views for the left and right eyes.
|
||||||
fn begin_frame(&self) -> Result<()>;
|
fn begin_frame(&self) -> Result<(TextureView, TextureView)>;
|
||||||
/// Submits rendering work for this frame.
|
/// Submits rendering work for this frame.
|
||||||
fn end_frame(&self) -> Result<()>;
|
fn end_frame(&self) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InputTrait {
|
pub trait InputTrait {
|
||||||
|
/// Get the haptic action at the specified path.
|
||||||
fn get_haptics(&self, path: ActionId) -> Result<Action<Haptic>>;
|
fn get_haptics(&self, path: ActionId) -> Result<Action<Haptic>>;
|
||||||
|
/// Get the pose action at the specified path.
|
||||||
fn get_pose(&self, path: ActionId) -> Result<Action<Pose>>;
|
fn get_pose(&self, path: ActionId) -> Result<Action<Pose>>;
|
||||||
|
/// Get the float action at the specified path.
|
||||||
fn get_float(&self, path: ActionId) -> Result<Action<f32>>;
|
fn get_float(&self, path: ActionId) -> Result<Action<f32>>;
|
||||||
|
/// Get the boolean action at the specified path.
|
||||||
fn get_bool(&self, path: ActionId) -> Result<Action<bool>>;
|
fn get_bool(&self, path: ActionId) -> Result<Action<bool>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This impl is moved outside of the trait to ensure that InputTrait stays object safe.
|
||||||
|
impl dyn InputTrait {
|
||||||
|
/// Get the action at the specified path.
|
||||||
|
pub fn get_action<A: ActionType>(&self, path: ActionId) -> Result<Action<A>> {
|
||||||
|
A::get(self, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ActionTrait {
|
pub trait ActionTrait {
|
||||||
fn id(&self) -> ActionId;
|
fn id(&self) -> ActionId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,15 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
pub struct OXrEntry(openxr::Entry);
|
pub struct OXrEntry(openxr::Entry);
|
||||||
|
|
||||||
|
impl OXrEntry {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
#[cfg(feature = "linked")]
|
||||||
|
return OXrEntry(openxr::Entry::linked());
|
||||||
|
#[cfg(not(feature = "linked"))]
|
||||||
|
return OXrEntry(unsafe { openxr::Entry::load().expect("Failed to load OpenXR runtime") });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EntryTrait for OXrEntry {
|
impl EntryTrait for OXrEntry {
|
||||||
fn available_extensions(&self) -> Result<ExtensionSet> {
|
fn available_extensions(&self) -> Result<ExtensionSet> {
|
||||||
// self.0.enumerate_extensions();
|
// self.0.enumerate_extensions();
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ use std::sync::{
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use wasm_bindgen::{closure::Closure, JsCast};
|
use wasm_bindgen::{closure::Closure, JsCast};
|
||||||
use web_sys::{js_sys, XrFrame, XrInputSource};
|
use wasm_bindgen_futures::js_sys;
|
||||||
|
use web_sys::{XrFrame, XrInputSource};
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
@@ -78,7 +79,7 @@ impl SessionTrait for WebXrSession {
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn begin_frame(&self) -> Result<()> {
|
fn begin_frame(&self) -> Result<(wgpu::TextureView, wgpu::TextureView)> {
|
||||||
let mut end_frame_sender = self.end_frame_sender.lock().unwrap();
|
let mut end_frame_sender = self.end_frame_sender.lock().unwrap();
|
||||||
if end_frame_sender.is_some() {
|
if end_frame_sender.is_some() {
|
||||||
Err(XrError::Placeholder)?
|
Err(XrError::Placeholder)?
|
||||||
@@ -87,7 +88,7 @@ impl SessionTrait for WebXrSession {
|
|||||||
let (tx_end, rx_end) = channel::<()>();
|
let (tx_end, rx_end) = channel::<()>();
|
||||||
*end_frame_sender = Some(tx_end);
|
*end_frame_sender = Some(tx_end);
|
||||||
let on_frame: Closure<dyn FnMut(f64, XrFrame)> =
|
let on_frame: Closure<dyn FnMut(f64, XrFrame)> =
|
||||||
Closure::new(move |time: f64, frame: XrFrame| {
|
Closure::new(move |_time: f64, _frame: XrFrame| {
|
||||||
tx.send(()).ok();
|
tx.send(()).ok();
|
||||||
rx_end.recv().ok();
|
rx_end.recv().ok();
|
||||||
});
|
});
|
||||||
@@ -96,7 +97,7 @@ impl SessionTrait for WebXrSession {
|
|||||||
.request_animation_frame(on_frame.as_ref().unchecked_ref());
|
.request_animation_frame(on_frame.as_ref().unchecked_ref());
|
||||||
|
|
||||||
rx.recv().ok();
|
rx.recv().ok();
|
||||||
Ok(())
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end_frame(&self) -> Result<()> {
|
fn end_frame(&self) -> Result<()> {
|
||||||
@@ -107,6 +108,18 @@ impl SessionTrait for WebXrSession {
|
|||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_render_resources(
|
||||||
|
&self,
|
||||||
|
) -> Option<(
|
||||||
|
wgpu::Device,
|
||||||
|
wgpu::Queue,
|
||||||
|
wgpu::AdapterInfo,
|
||||||
|
wgpu::Adapter,
|
||||||
|
wgpu::Instance,
|
||||||
|
)> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WebXrInput {
|
pub struct WebXrInput {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use wasm_bindgen::JsValue;
|
use wasm_bindgen::JsValue;
|
||||||
|
use wasm_bindgen_futures::js_sys::Promise;
|
||||||
use wasm_bindgen_futures::JsFuture;
|
use wasm_bindgen_futures::JsFuture;
|
||||||
use web_sys::js_sys::Promise;
|
|
||||||
|
|
||||||
pub trait PromiseRes {
|
pub trait PromiseRes {
|
||||||
fn resolve<T: From<JsValue>>(self) -> Result<T, JsValue>;
|
fn resolve<T: From<JsValue>>(self) -> Result<T, JsValue>;
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
pub mod api;
|
//! Abstracted API over WebXR and OpenXR
|
||||||
|
//!
|
||||||
|
//! This crate is intended to be used as a common API for cross platform projects. It was primarily
|
||||||
|
//! made for use in Bevy, but can be used elsewhere.
|
||||||
|
//!
|
||||||
|
//! To get started, create an [Entry] with [Entry](Entry#method.new)
|
||||||
|
|
||||||
|
mod api;
|
||||||
pub mod api_traits;
|
pub mod api_traits;
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
@@ -10,3 +17,5 @@ pub mod prelude {
|
|||||||
pub use super::error::*;
|
pub use super::error::*;
|
||||||
pub use super::types::*;
|
pub use super::types::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use api::*;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::api_traits::{ActionInputTrait, HapticTrait};
|
use crate::api::Action;
|
||||||
|
use crate::api_traits::{ActionInputTrait, HapticTrait, InputTrait};
|
||||||
|
use crate::error::Result;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||||
pub struct ExtensionSet {}
|
pub struct ExtensionSet {}
|
||||||
@@ -12,7 +14,7 @@ pub struct Bindings {}
|
|||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub struct ActionId {
|
pub struct ActionId {
|
||||||
pub handedness: Handedness,
|
pub handedness: Handedness,
|
||||||
pub device: Device,
|
pub device: XrDevice,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
@@ -23,29 +25,47 @@ pub enum Handedness {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum Device {
|
pub enum XrDevice {
|
||||||
Controller,
|
Controller,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Haptic;
|
pub struct Haptic;
|
||||||
pub struct Pose;
|
pub struct Pose;
|
||||||
|
|
||||||
pub trait ActionType {
|
pub trait ActionType: Sized {
|
||||||
type Inner;
|
type Inner;
|
||||||
|
|
||||||
|
fn get(input: &dyn InputTrait, path: ActionId) -> Result<Action<Self>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActionType for Haptic {
|
impl ActionType for Haptic {
|
||||||
type Inner = Rc<dyn HapticTrait>;
|
type Inner = Rc<dyn HapticTrait>;
|
||||||
|
|
||||||
|
fn get(input: &dyn InputTrait, path: ActionId) -> Result<Action<Self>> {
|
||||||
|
input.get_haptics(path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActionType for Pose {
|
impl ActionType for Pose {
|
||||||
type Inner = Rc<dyn ActionInputTrait<Pose>>;
|
type Inner = Rc<dyn ActionInputTrait<Pose>>;
|
||||||
|
|
||||||
|
fn get(input: &dyn InputTrait, path: ActionId) -> Result<Action<Self>> {
|
||||||
|
input.get_pose(path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActionType for f32 {
|
impl ActionType for f32 {
|
||||||
type Inner = Rc<dyn ActionInputTrait<f32>>;
|
type Inner = Rc<dyn ActionInputTrait<f32>>;
|
||||||
|
|
||||||
|
fn get(input: &dyn InputTrait, path: ActionId) -> Result<Action<Self>> {
|
||||||
|
input.get_float(path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActionType for bool {
|
impl ActionType for bool {
|
||||||
type Inner = Rc<dyn ActionInputTrait<bool>>;
|
type Inner = Rc<dyn ActionInputTrait<bool>>;
|
||||||
|
|
||||||
|
fn get(input: &dyn InputTrait, path: ActionId) -> Result<Action<Self>> {
|
||||||
|
input.get_bool(path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user