Giter Site home page Giter Site logo

rust-webvr's Introduction

rust-webvr

Safe rust API that provides a way to interact with Virtual Reality headsets and integration with vendor specific SDKs like OpenVR, Oculus and GoogleVR (Daydream). The API is inspired on the easy to use WebVR API but adapted to Rust design patterns.

It's used in the WebVR Core implementation for Servo browser. This module can be tested outside of Servo and even be used on any vanilla Rust app.

Room Scale example:

Just run this command in examples/room folder

cargo run

Run room scale demo on android:

./run_android.sh

OpenVR tips:

In order to run with openvr on windows, openvr_api.dll must be available. Please make it either accessible in your path, or copy it into the examples/room folder.

Refer to The ValveSoftware openvr repository and head over to the releases section for more information.

rust-webvr's People

Contributors

bors-servo avatar eijebong avatar emilio avatar jdm avatar jhwgh1968 avatar manishearth avatar mortimergoro avatar nox avatar o0ignition0o avatar paulrouget avatar simonsapin avatar trevordev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-webvr's Issues

Getting eye parameters requires memory allocation

One of the webvr issues in Servo is that we freeze the eye parameters for a VRDisplay when the object is created, so if they change then the changes don't get seen by JS. servo/servo#22758

The obvious fix for this is to get the eye parameters from rust-webvr, but unfortunately the API for that is to get the VRDisplayData

/// Returns the current display data.
fn data(&self) -> VRDisplayData;

and the display data includes the display_name as a String

pub struct VRDisplayData {
pub display_id: u32,
pub display_name: String,
pub connected: bool,
pub capabilities: VRDisplayCapabilities,
pub stage_parameters: Option<VRStageParameters>,
pub left_eye_parameters: VREyeParameters,
pub right_eye_parameters: VREyeParameters,
}

Since the name is a String, it has to be freshly allocated each time the display data is accessed, which is wasteful.

Possible fixes: separate out the eye parameters from the display data, or make the display_name a &'static str or Cow<'static, str> rather than a String.

No support for 32-bit applications?

Tried to compile this for stable-i686-pc-windows-msvc, and got the following error:

error[E0512]: transmute called with types of different sizes
   --> C:\Users\Sgeo\.cargo\registry\src\github.com-1ecc6299db9ec823\rust-webvr-0.9.10\src\api\openvr\display.rs:152:46
    |
152 |         self.frame_texture.handle = unsafe { mem::transmute(layer.texture_id as u64) };
    |                                              ^^^^^^^^^^^^^^
    |
    = note: source type: u64 (64 bits)
    = note: target type: *mut std::os::raw::c_void (32 bits)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0512`.
error: Could not compile `rust-webvr`.

I assume that this is because I'm compiling for 32-bit.

Room example fails to compile

   Compiling core-graphics v0.3.2                                                                                                                                                                                     
error: type `color_space::__CGColorSpace` is private                                                                                                                                                                  
  --> /Users/ajeffrey/.cargo/registry/src/github.com-1ecc6299db9ec823/core-graphics-0.3.2/src/context.rs:86:26                                                                                                        
   |                                                                                                                                                                                                                  
86 |             let result = CGBitmapContextCreate(ptr::null_mut(),                                                                                                                                                  
   |                          ^^^^^^^^^^^^^^^^^^^^^                                                                                                                                                                   

Looking at the output of cargo tree:

├── glutin v0.7.5 (https://github.com/MortimerGoro/glutin/?branch=android_fixes#ebbaaaf8)
...
│   ├── core-foundation v0.2.3 (*)
│   ├── core-graphics v0.3.2 (*)

So it looks like we should update glutin.

No support for desktop Oculus API?

Looking through the code, it looks like the Oculus SDK for Desktop isn't supported, only Oculus SDK for mobile (and Oculus SDK for Desktop indirectly through OpenVR).

Is this intended? Some Oculus Rift users would prefer applications to use the Oculus SDK directly if possible.

`VRServiceManager` isn't `Send`

Trying to share a ServiceManager between threads:

   |
81 |             .spawn(move || {
   |              ^^^^^ `std::cell::RefCell<(dyn rust_webvr_api::vr_display::VRDisplay + 'static)>` cannot be shared between threads safely
   |
   = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<(dyn rust_webvr_api::vr_display::VRDisplay + 'static)>`
   = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::cell::RefCell<(dyn rust_webvr_api::vr_display::VRDisplay + 'static)>>`
   = note: required because it appears within the type `(u32, std::sync::Arc<std::cell::RefCell<(dyn rust_webvr_api::vr_display::VRDisplay + 'static)>>)`
   = note: required because it appears within the type `std::marker::PhantomData<(u32, std::sync::Arc<std::cell::RefCell<(dyn rust_webvr_api::vr_display::VRDisplay + 'static)>>)>`
   = note: required because it appears within the type `std::collections::hash::table::RawTable<u32, std::sync::Arc<std::cell::RefCell<(dyn rust_webvr_api::vr_display::VRDisplay + 'static)>>>`
   = note: required because it appears within the type `std::collections::HashMap<u32, std::sync::Arc<std::cell::RefCell<(dyn rust_webvr_api::vr_display::VRDisplay + 'static)>>>`
   = note: required because it appears within the type `rust_webvr::vr_manager::VRServiceManager`
...

Since VRServiceManager is !Send, it can't be shared, even in a Arc<Mutex<VRServiceManager>>.

The VRDisplay is not provided with a Gl instance

When the VRDisplay is presenting, it does so (at least in Servo) in the context of a WebGL thread, that has access to an Rc<Gl> object, which provides GL bindings. This Rc<Gl> object is not provided to the VRDisplay, so if it wants to call any GL functions, it has to create its own GL bindings.

Deprecate some APIs

We should deprecate:

  • sync_poses(), synced_frame_data() and presented_by_browser in favour of future_frame_data()
  • render_layer() and submit_frame() in favour of submit_layer()

Then remove them in a breaking change.

We should have a way to get gamepad state asynchronously

Ideally, make it a variant of future_frame_data that gets you both the frame data and gamepads.

Currently we only have one async implementor of future_frame_data (GLWindow) and that has no gamepads, so it's not 100% necessary yet, but we may need it in the future.

cc @asajeffrey

VRViewport coordinates are ints or floats?

According to the docs, VRViewport coordinates are given as floats.

/// UVs defining the texture bounds to present to the eye in UV space: [x,y,w,h]
/// Defaults to [0.0, 0.0, 0.5, 1.0]
pub viewport: VRViewport,

According to the implementation, they're ints.

pub struct VRViewport {
pub x: i32,
pub y: i32,
pub width: i32,
pub height: i32,
}

Any chance of a tutorial?

I'd love to write some VR in Rust. But this API is very technical (and OpenVR isn't any better), so a tutorial would be very, very welcome :)

Can we avoid blocking the WebVR render thread?

Currently, sync_poses is a blocking function, which blocks the WebVR render thread until the next animation frame. This means the render thread can't perform other useful work while waiting for the next animation frame. In Servo, the WebVR render thread is the same as the WebGL thread, so the WebGL thread is blocked, leading to issues such as servo/servo#22914, where webrender is blocked waiting on the WebGL thread.

Why is `register_vrexternal` safe?

There's a safe function VRServiceManager.::register_vrexternal (https://docs.rs/rust-webvr/0.10.0/rust_webvr/struct.VRServiceManager.html#method.register_vrexternal) which takes a VRExternalShmemPtr argumen, which can be constructed using the safe function VRExternalShmemPtr::new (https://docs.rs/rust-webvr/0.10.0/rust_webvr/api/struct.VRExternalShmemPtr.html#method.new).

Now currently this is all unimplemented!() but it's not obvious how this can be safe once the service manager does something with its VRExternalShmemPtr. Am I missing something?

Example doesn't work

pwd
$HOME/rust-webvr/examples/room

cargo run --example room

Updating registry `https://github.com/rust-lang/crates.io-index`
    Updating git repository `https://github.com/MortimerGoro/glutin/`           
error: failed to load source for a dependency on `rust-svr`                     

Caused by:
  Unable to update file:///$HOME/rust-svr

Caused by:
  failed to read `/$HOME/rust-svr/Cargo.toml`

Caused by:
  No such file or directory (os error 2)

Using openvr on windows leads to TrackedDevicePose_t uninitilized error

Hi,

i am using the HTC Vive on windows, with OpenVR.
If i start use the device like in the example, i get an error, TrackedDevicePose_t uninitilized.
The stacktrace leads to:
https://github.com/servo/rust-webvr/blob/master/rust-webvr/src/api/openvr/display.rs#L118

At first i tought i did setup the device wrong, but seeing the code two lines above. Can it be, that indeed struct should be initilized?

Rust Version:
nightly-x86_64-pc-windows-msvc (default)
rustc 1.53.0-nightly (07e0e2ec2 2021-03-24)

' panicked at 'attempted to leave type `api::openvr::binding::TrackedDevicePose_t` uninitialized, which is invalid', C:\Users\gojira\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\mem\mod.rs:660:9
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/07e0e2ec268c140e607e1ac7f49f145612d0f597\/library\std\src\panicking.rs:493
   1: core::panicking::panic_fmt
             at /rustc/07e0e2ec268c140e607e1ac7f49f145612d0f597\/library\core\src\panicking.rs:92
   2: core::panicking::panic
             at /rustc/07e0e2ec268c140e607e1ac7f49f145612d0f597\/library\core\src\panicking.rs:50
   3: core::mem::uninitialized
             at C:\Users\gojira\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\mem\mod.rs:660
   4: rust_webvr::api::openvr::display::{{impl}}::synced_frame_data
             at C:\Users\gojira\.cargo\registry\src\github.com-1ecc6299db9ec823\rust-webvr-0.19.0\src\api\openvr\display.rs:118
   5: shadow_of_truth::vr::VirtualReality::sync_data

VREyeParameters API incompatible with canted displays

I have a Pimax headset with canted displays. The matrices produced by GetEyeToHeadTransform thus contain a rotation. Not only does openvr/display.rs discard that data in fetch_eye_parameters, there's nowhere to put it in VREyeParameters. This will need to be fixed, and maybe not just for wide field of view headsets; the Valve Index also has canted optics.

Why is `VRDisplay` marked `Send` and `Sync`?

I understand why the VRService has to be Send and Sync, because it may be created on a different thread than its used (e.g. created on the main thread, used on the WebVR thread). I don't understand why a VRDisplay has to be. Why not query the VRService for its displays on one thread and then just leave it on that thread?

Use euclid for matrices?

At the moment the API uses raw float arrays to represent matrices, which means we can't use matrix operations (subtraction, multiplication, etc) and there is no record in the types of units.

Supporting devices that require code to run on the main thread

Currently the API has no concept of the "main thread" of an application, and assumes that VRServiceManager::new() and VRServiceManager::register_defaults() can be safely called from any thread (in servo, they're called from the WebVRThread). This has a mismatch with devices (such as MagicLeap) which have a main thread, and where the APIs to access the device capabilities aren't thread-safe.

Redesign the main API of this crate to be XR-focused

The WebVR API is deprecated, and I'm hitting roadblocks implementing stuff in WebXR since WebXR in many cases is more powerful than WebVR. Furthermore, it's tricky to work around this because most of the uses of this crate in Servo have nuanced soundness issues (#18) and I don't know how to avoid breaking those. For example, one of the issues I'm hitting is that WebXR expects gamepad information to stay up to date (unlike the Gamepad) API, and it's pretty hard to work that into the current model.

Some differences between WebVR and WebXR:

  • WebXR supports inline immersive sessions, where there is no "display" but there is position and orientation information
  • WebXR operates directly on pose matrices as opposed to view matrices
  • WebXR treats gamepads as being attached to a session (display) and automatically kept up to date, WebVR thinks of gamepads as a wholly separate deal.
  • The lifecycle model is somewhat different for the session

It might be worth finding an API that is a good middle ground between the two, as opposed to being primarily webvr-focused.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.