Merge pull request #11 from Auruss/stable

Update to 0.1.19 and refactoring
This commit is contained in:
Rene Eichhorn
2016-05-06 16:23:34 +02:00
21 changed files with 4405 additions and 1708 deletions

2
.gitignore vendored
View File

@ -5,3 +5,5 @@
/modules/oculus_sdk_mac/LibOVR/Lib/Mac/Xcode/Release/ /modules/oculus_sdk_mac/LibOVR/Lib/Mac/Xcode/Release/
/target /target
*.py[co] *.py[co]
/src/sys/target/
*.lock

View File

@ -1,7 +1,16 @@
language: rust language: rust
install: rust:
- sudo apt-get update - stable
- sudo apt-get install libudev-dev libxrandr-dev - beta
script: - nightly
- cargo build after_success: |
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
cargo doc &&
echo "<meta http-equiv=refresh content=0;url=`echo $TRAVIS_REPO_SLUG | cut -d '/' -f 2`/index.html>" > target/doc/index.html &&
sudo pip install ghp-import &&
ghp-import -n target/doc &&
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
env:
global:
secure: EWhZMkAWuLzClX2ccFavodnxIlthv/Xc/n2oP9lmddvhqVlHC9MeVKZj/9rLYYhDA6AWNPv9m79aRZJ3PNf/iuIuf1jC1VNDIuD4teCbFMrX3C1QcUN37llEIu4n8YlPRFa2gLYRVqyh5rWS+zde/RM/3b8cw0i8/k/yux/ehqbFUSYcRVuZWNtBwUJw0Nmzii/nzzz6zTdPWqsOkoIjDbexQnceZ7TzrZbJBfJeU8xyiGLaZDTUSOsvQWw157uwX1nq9XOLutth0dbbCixFALa6ALU7n+x5XMDZGdo+F61ul3qHX8ZnPZ4Wl2DEzC9zVyB/ECG9TdUUiGHshEhLXa/FBKqTG6D9NSAsrEhcqlQ/ZIIuCS9PQEQCILJqaZbykx0AUi1W237AGUb2sKOCXHqPn7SiiYTtIMNPk8RumeNtxOGp+AAC/50epGocDOXglCEM6EcdwYtp6nSi9dqmRoBkNMJwWYjddx/OA/cU8tBMEVXpgRUe/vLj+gUqNcCGFvQ1Yd+wsBAklvwzn3fuVDgyWo/hIhJy8wpAEoiv+wJbzjnaseGoMRUDEwLHChzMUNbFmVdfve/oZlHyvpHlkwmuwy5B8BsppcJr6CoQ85DD1k4tM3dDGeZ3XSFAd33n5adsrLtx6nQlGfbzTaXZp9u0n7Hv6vBNz9DEreBifa0=

560
Cargo.lock generated Normal file
View File

@ -0,0 +1,560 @@
[root]
name = "openvr"
version = "0.2.0"
dependencies = [
"glium 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nalgebra 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"openvr_sys 0.1.0",
]
[[package]]
name = "android_glue"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "backtrace"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"debug-builders 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "backtrace-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cgl"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gleam 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cocoa"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "core-foundation"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "core-foundation-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "core-graphics"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "dbghelp-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "debug-builders"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "dlib"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libloading 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dlib"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libloading 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dwmapi-sys"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dylib"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fs2"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gcc"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "gdi32-sys"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gl_generator"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"xml-rs 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gleam"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gl_generator 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glium"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"gl_generator 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glutin"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"android_glue 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cgl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cocoa 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gl_generator 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"osmesa-sys 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"shared_library 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-kbd 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-window 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"x11-dl 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "khronos_api"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libloading"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "malloc_buf"
version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memmap"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fs2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nalgebra"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-bigint 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-complex 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-rational 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-bigint"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-complex"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-iter"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-rational"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-bigint 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "objc"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openvr_sys"
version = "0.1.0"
[[package]]
name = "osmesa-sys"
version = "0.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"shared_library 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-serialize"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc_version"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "shared_library"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "shell32-sys"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "smallvec"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "tempfile"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "user32-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wayland-client"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"dlib 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-scanner 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-sys 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wayland-kbd"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wayland-scanner"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"xml-rs 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wayland-sys"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wayland-window"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "x11-dl"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dylib 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "xml-rs"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "xml-rs"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

View File

@ -1,14 +1,21 @@
[package] [package]
name = "vr" name = "openvr"
version = "0.1.0" version = "0.2.0"
authors = [ authors = [
"Colin Sherratt", "Colin Sherratt",
"Erick Tryzelaar" "Erick Tryzelaar",
"Rene Eichhorn"
] ]
build = "src/sys/build.rs"
[lib] [lib]
name = "vr" name = "openvr"
path = "src/lib.rs" path = "src/lib.rs"
[dependencies.openvr_sys] [dependencies.openvr_sys]
path = "src/sys/" path = "src/sys/"
[dev_dependencies]
glium = "0.14.0"
num = "0.1.31"
nalgebra = "0.8.2"

8
LICENSE.md Normal file
View File

@ -0,0 +1,8 @@
The MIT License (MIT)
Copyright (c) 2016 Colin Sherratt, Erick Tryzelaar, Rene Eichhorn
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,95 +1,54 @@
VR-RS rust-openvr
===== =====
[![Build Status](https://travis-ci.org/csherratt/vr-rs.svg?branch=master)](https://travis-ci.org/csherratt/vr-rs) [![Build Status](https://travis-ci.org/Auruss/rust-openvr.svg?branch=master)](https://travis-ci.org/Auruss/rust-openvr)
VR-RS providers bindings for the Oculus's libovr. Currently it only provides bindings for 0.3.2c. rust-openvr is a binding for openvr. It's still in progress. Tests are automatically ran by travis.
Also my private jenkins is running these test on Ubuntu 14.04 as well, every successful build will be pushed to its branch (stable, nightly, beta). For good practice always use either stable, beta or nightly instead of master!
## [Link to the documentation](http://auruss.github.io/rust-openvr/openvr/index.html)
## Current sdk version: OpenVR SDK 0.9.19
Building Building
-------- --------
vr-rs is fully cargoized. to Compile rust-openvr is fully cargoized. to Compile
cargo build cargo build
To add as a dependency using cargo Cargo add the following to your `Cargo.toml` To add as a dependency using cargo Cargo add the following to your `Cargo.toml`. Will be added to crates.io once we've a stable version. For nightly/beta use nightly/beta branch instead.
[dependencies.ovr] [dependencies.openvr]
git = "https://github.com/csherratt/vr-rs.git" git = "https://github.com/auruss/rust-openvr.git"
branch = "stable"
Using VR-RS Using rust-openvr
----------- -----------
# Initializing # Initializing
```rust ```rust
extern crate ovr = "oculus-vr"; extern crate openvr;
use ovr::{SensorCapabilities, Ovr};
fn main() { fn main() {
// Initalize the Oculus VR library // Initialize system subsystem
let ovr = match Ovr::init() { let system = match openvr::init() {
Some(ovr) => ovr, Ok(sys) => sys,
None => { Err(err) => {
println!("Could not initialize Oculus SDK"); println!("Could not initialize OpenVR SDK: \n\t{:?}", err);
return; return;
} }
}; };
// get the first available HMD device, returns None // accessing other sub systems
// if no HMD device is currently plugged in let ext = openvr::extended_display();
let hmd = match ovr.first_hmd() {
Some(hmd) => hmd,
None => {
println!("Could not get hmd");
return;
}
};
// start the sensor recording, Require orientation tracking // ..
let started = hmd.start_sensor(SensorCapabilities::new().set_orientation(true),
SensorCapabilities::new().set_orientation(true));
if !started {
println!("Could not start sensor");
return;
}
} }
``` ```
# Render loop # Examples
For data collection examples/test.rs can be used.
The Oculus SDK will handle most of the heavy lifting of the barrel distortion. For an actual opengl implementation see examples/opengl.rs (WIP)
```rust
fn render(frame_index: uint, hmd: &ovr::Hmd, base_view: &Matrix4<f32>) {
// start a new frame, the frame_index should increment each frame
let frame_timing = hmd.begin_frame(frame_index);
let desc = hmd.get_description();
for &eye in [ovr::EyeLeft, ovr::EyeRight].iter() {
// start rendering a new eye, this will give the most current
// copy of the pose from the HMD tracking sensor
let pose = self.window.get_hmd().begin_eye_render(eye);
// base_view * pose * eye_view_adjustment
let view = base_view.mul_m(&pose.orientation.to_matrix4())
.mul_m(&Matrix4::translate(&eye.view_adjust));
let projection = desc.eye_fovs.eye(eye).default_eye_fov;
// render to texture
render();
let texture = ovr::Texture(width, height,
viewport_offset_x, viewport_offset_y,
viewport_width, viewport_height,
opengl_texture_id);
hmd.end_eye_render(eye, pose, &texture);
}
// this will swap the buffers and frame sync
hmd.end_frame();
}
```

299
examples/opengl.rs Normal file
View File

@ -0,0 +1,299 @@
extern crate openvr;
extern crate nalgebra;
#[macro_use]
extern crate glium;
use std::convert::From;
use nalgebra::Inverse;
use glium::framebuffer::ToColorAttachment;
use glium::framebuffer::ToDepthAttachment;
use glium::GlObject;
#[derive(Copy, Clone)]
struct Vertex {
position: [f32; 3],
normal: [f32; 3],
texcoord: [f32; 2]
}
implement_vertex!(Vertex, position, normal, texcoord);
pub fn main() {
{
// init vr system
let system = match openvr::init() {
Ok(ivr) => ivr,
Err(err) => {
println!("Failed to create IVR subsystem {:?}", err);
return;
}
};
// init render model subsystem
let models = match openvr::render_models() {
Ok(ext) => ext,
Err(err) => {
println!("Failed to create IVRRenderModels subsystem {:?}", err);
return;
}
};
for device in system.tracked_devices(0.0).connected_iter() {
println!("device found :) -> {}",
device.get_property_string(openvr::ETrackedDeviceProperty_Prop_RenderModelName_String).unwrap_or_else(|_| { panic!("No render model")} ));
println!("\t{:?}", device);
println!("\t{:?}", device.device_class());
}
// init compositor subsystem
let comp = match openvr::compositor() {
Ok(ext) => ext,
Err(err) => {
println!("Failed to create IVRCompositor subsystem {:?}", err);
return;
}
};
// create glium window and context
use glium::{DisplayBuild, Surface};
let display = glium::glutin::WindowBuilder::new()
.with_depth_buffer(24)
.build_glium()
.unwrap();
// create frame buffer for hmd
let texture_size = system.recommended_render_target_size();
let left_eye_depth = glium::framebuffer::DepthRenderBuffer::new(
&display,
glium::texture::DepthFormat::I24,
texture_size.width,
texture_size.height).unwrap();
let left_eye_texture = glium::framebuffer::RenderBuffer::new(
&display,
glium::texture::UncompressedFloatFormat::U8U8U8U8,
texture_size.width,
texture_size.height).unwrap();
let mut left_eye_framebuffer = glium::framebuffer::SimpleFrameBuffer::with_depth_buffer
(
&display, left_eye_texture.to_color_attachment(), left_eye_depth.to_depth_attachment()
).unwrap();
let right_eye_depth = glium::framebuffer::DepthRenderBuffer::new(
&display,
glium::texture::DepthFormat::I24,
texture_size.width,
texture_size.height).unwrap();
let right_eye_texture = glium::framebuffer::RenderBuffer::new(
&display,
glium::texture::UncompressedFloatFormat::U8U8U8U8,
texture_size.width,
texture_size.height).unwrap();
let mut right_eye_framebuffer = glium::framebuffer::SimpleFrameBuffer::with_depth_buffer
(
&display, right_eye_texture.to_color_attachment(), right_eye_depth.to_depth_attachment()
).unwrap();
// prepare shader
let vertex_shader_src = r#"
#version 140
in vec3 position;
in vec3 normal;
in vec2 texcoord;
out vec3 v_normal;
out vec2 v_texcoord;
uniform mat4 matrix;
void main() {
v_normal = normal;
v_texcoord = texcoord;
gl_Position = matrix * vec4(position, 1.0);
}
"#;
let fragment_shader_src = r#"
#version 140
uniform sampler2D diffuse;
in vec3 v_normal;
in vec2 v_texcoord;
out vec4 color;
void main() {
color = texture(diffuse, v_texcoord);
}
"#;
let program = glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None).unwrap();
// load controller models
let controller = models.load(String::from("lh_basestation_vive")).unwrap_or_else(|err| {
openvr::shutdown(); panic!("controller render model not found: {:?}", err) });
let mut controller_vertices: Vec<Vertex> = Vec::new();
let mut controller_indices: Vec<u16> = Vec::new();
for vertex in controller.vertex_iter() {
controller_vertices.push(Vertex {
position: [vertex.vPosition.v[0] as f32, vertex.vPosition.v[1] as f32, vertex.vPosition.v[2] as f32],
normal: [vertex.vNormal.v[0] as f32, vertex.vNormal.v[1] as f32, vertex.vNormal.v[2] as f32],
texcoord: [vertex.rfTextureCoord[0] as f32, vertex.rfTextureCoord[1] as f32],
});
}
for index in controller.index_iter() {
controller_indices.push(*index);
}
let controller_vertex_buffer = glium::VertexBuffer::new(&display, &controller_vertices).unwrap();
let controller_index_buffer = glium::IndexBuffer::new(&display, glium::index::PrimitiveType::TrianglesList, &controller_indices).unwrap();
let controller_texture_response = controller.load_texture().unwrap();
let dimension = (controller_texture_response.dimension().0 as u32, controller_texture_response.dimension().1 as u32);
let image = glium::texture::RawImage2d::from_raw_rgba(controller_texture_response.to_vec(), dimension);
let controller_texture = glium::texture::Texture2d::new(&display, image).unwrap();
// get static jmatrices
let left_projection = {
let raw = system.projection_matrix(openvr::Eye::Left, 0.01, 1000.0);
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[0][1], raw[0][2], raw[0][3],
raw[1][0], raw[1][1], raw[1][2], raw[1][3],
raw[2][0], raw[2][1], raw[2][2], raw[2][3],
raw[3][0], raw[3][1], raw[3][2], raw[3][3]);
mat
};
let left_eye_transform = {
let raw = system.eye_to_head_transform(openvr::Eye::Left);
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[1][0], raw[2][0], 0.0,
raw[0][1], raw[1][1], raw[2][1], 0.0,
raw[0][2], raw[1][2], raw[2][2], 0.0,
raw[0][3], raw[1][3], raw[2][3], 1.0);
mat.inverse().unwrap()
};
let right_projection = {
let raw = system.projection_matrix(openvr::Eye::Right, 0.01, 1000.0);
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[0][1], raw[0][2], raw[0][3],
raw[1][0], raw[1][1], raw[1][2], raw[1][3],
raw[2][0], raw[2][1], raw[2][2], raw[2][3],
raw[3][0], raw[3][1], raw[3][2], raw[3][3]);
mat
};
let right_eye_transform = {
let raw = system.eye_to_head_transform(openvr::Eye::Right);
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[1][0], raw[2][0], 0.0,
raw[0][1], raw[1][1], raw[2][1], 0.0,
raw[0][2], raw[1][2], raw[2][2], 0.0,
raw[0][3], raw[1][3], raw[2][3], 1.0);
mat.inverse().unwrap()
};
'render: loop {
// this is important to make sure frames are synced correctly
let tracked_devices = comp.wait_get_poses();
let mut left_matrix = left_projection * left_eye_transform;
let mut right_matrix = right_projection * right_eye_transform;
let mut once = false;
for device in tracked_devices.connected_iter() {
match device.device_class() {
openvr::ETrackedDeviceClass_TrackedDeviceClass_HMD => {
let matrix = {
let raw = device.to_device;
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[0][1], raw[0][2], raw[0][3],
raw[1][0], raw[1][1], raw[1][2], raw[1][3],
raw[2][0], raw[2][1], raw[2][2], raw[2][3],
0.0, 0.0, 0.0, 1.0);
mat.inverse().unwrap()
};
left_matrix *= matrix;
right_matrix *= matrix;
},
openvr::ETrackedDeviceClass_TrackedDeviceClass_TrackingReference => {
if once { continue; }
once = true;
let matrix = {
let raw = device.to_device;
let mat = nalgebra::Matrix4::new(
raw[0][0], raw[0][1], raw[0][2], raw[0][3],
raw[1][0], raw[1][1], raw[1][2], raw[1][3],
raw[2][0], raw[2][1], raw[2][2], raw[2][3],
0.0, 0.0, 0.0, 1.0);
mat
};
left_matrix *= matrix;
right_matrix *= matrix;
},
_ => { }
};
}
let mut target = display.draw();
target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
let left_uniforms = uniform! {
matrix: *left_matrix.as_ref(),
diffuse: &controller_texture
};
let right_uniforms = uniform! {
matrix: *right_matrix.as_ref(),
diffuse: &controller_texture
};
let params = glium::DrawParameters {
depth: glium::Depth {
test: glium::draw_parameters::DepthTest::IfLess,
write: true,
.. Default::default()
},
backface_culling: glium::draw_parameters::BackfaceCullingMode::CullClockwise,
.. Default::default()
};
// render 2d display output
target.draw(&controller_vertex_buffer, &controller_index_buffer, &program, &left_uniforms, &params).unwrap();
// render hmd eye outputs
left_eye_framebuffer.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
right_eye_framebuffer.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);
left_eye_framebuffer.draw(&controller_vertex_buffer, &controller_index_buffer, &program, &left_uniforms, &params).unwrap();
right_eye_framebuffer.draw(&controller_vertex_buffer, &controller_index_buffer, &program, &right_uniforms, &params).unwrap();
// finish all rendering
target.finish().unwrap();
// submit to hmd
comp.submit(openvr::Eye::Left, left_eye_texture.get_id() as usize, openvr::common::TextureBounds::new((0.0, 1.0), (0.0, 1.0)));
comp.submit(openvr::Eye::Right, right_eye_texture.get_id() as usize, openvr::common::TextureBounds::new((0.0, 1.0), (0.0, 1.0)));
// handle window events
for ev in display.poll_events() {
match ev {
glium::glutin::Event::Closed => break 'render, // the window has been closed by the user
_ => ()
}
}
}
}
// free openvr
openvr::shutdown();
}

View File

@ -1,4 +1,4 @@
extern crate vr; extern crate openvr;
fn print_matrix_4x4(offset: u32, mat: [[f32; 4]; 4]) { fn print_matrix_4x4(offset: u32, mat: [[f32; 4]; 4]) {
let off: String = (0..offset).map(|_| ' ').collect(); let off: String = (0..offset).map(|_| ' ').collect();
@ -16,7 +16,7 @@ fn print_matrix_4x3(offset: u32, mat: [[f32; 4]; 3]) {
} }
fn main() { fn main() {
let ivr = match vr::IVRSystem::init() { let system = match openvr::init() {
Ok(ivr) => ivr, Ok(ivr) => ivr,
Err(err) => { Err(err) => {
println!("Failed to create IVR subsystem {:?}", err); println!("Failed to create IVR subsystem {:?}", err);
@ -24,28 +24,27 @@ fn main() {
} }
}; };
println!("IVR was created"); println!("IVRSystem was created");
println!("\tbounds: {:?}", ivr.bounds());
println!("\trecommended size: {:?}", ivr.recommended_render_target_size()); println!("\trecommended size: {:?}", system.recommended_render_target_size());
println!("\teye output: {:?} {:?}", ivr.eye_viewport(vr::Eye::Left), ivr.eye_viewport(vr::Eye::Right)); println!("\tvsync: {:?}", system.time_since_last_vsync());
println!("\tvsync: {:?}", ivr.time_since_last_vsync());
print!("\tprojection matrix left "); print!("\tprojection matrix left ");
print_matrix_4x4(31, ivr.projection_matrix(vr::Eye::Left, 0.1, 100.)); print_matrix_4x4(31, system.projection_matrix(openvr::Eye::Left, 0.1, 100.));
print!("\tprojection matrix right "); print!("\tprojection matrix right ");
print_matrix_4x4(31, ivr.projection_matrix(vr::Eye::Right, 0.1, 100.)); print_matrix_4x4(31, system.projection_matrix(openvr::Eye::Right, 0.1, 100.));
print!("\teye_to_head "); print!("\teye_to_head ");
print_matrix_4x3(8+12, ivr.eye_to_head_transform(vr::Eye::Left)); print_matrix_4x3(8+12, system.eye_to_head_transform(openvr::Eye::Left));
print!("\tposes "); print!("\tposes ");
print_matrix_4x3(8+6, ivr.tracked_devices(0.).as_slice()[0].to_device); print_matrix_4x3(8+6, system.tracked_devices(0.).as_slice()[0].to_device);
println!("Distortion example"); println!("Distortion example");
for u in 0..2 { for u in 0..2 {
for v in 0..2 { for v in 0..2 {
let pos = ivr.compute_distortion( let pos = system.compute_distortion(
vr::Eye::Left, openvr::Eye::Left,
u as f32 / 4., u as f32 / 4.,
v as f32 / 4., v as f32 / 4.,
); );
@ -54,18 +53,43 @@ fn main() {
println!(""); println!("");
} }
println!("Trying to create a compositor"); let ext = match openvr::extended_display() {
match ivr.compositor() { Ok(ext) => ext,
Err(err) => println!("Could not create compositor {:?}", err), Err(err) => {
Ok(comp) => { println!("Failed to create IVRExtendedDisplay subsystem {:?}", err);
println!("\tCreated one!"); return;
println!("\tis fullscreen = {}", comp.is_fullscreen());
println!("\tis vsync = {}", comp.get_vsync());
println!("\tcan render scene = {}", comp.can_render_scene());
println!("\tgamma value = {}", comp.get_gamma());
} }
};
println!("\nIVRExtendedDisplay was created");
println!("\tbounds: {:?}", ext.window_bounds());
println!("\teye output: {:?} {:?}", ext.eye_viewport(openvr::Eye::Left), ext.eye_viewport(openvr::Eye::Right));
let comp = match openvr::compositor() {
Ok(ext) => ext,
Err(err) => {
println!("Failed to create IVRCompositor subsystem {:?}", err);
return;
}
};
println!("\nIVRCompositor was created");
println!("\tis fullscreen = {}", comp.is_fullscreen());
println!("\tcan render scene = {}", comp.can_render_scene());
let model = match openvr::render_models() {
Ok(ext) => ext,
Err(err) => {
println!("Failed to create IVRRenderModels subsystem {:?}", err);
return;
}
};
println!("\nIVRRenderModels was created\n Count: {}", model.get_count());
for i in 0..model.get_count() {
println!("\t{}", model.get_name(i));
} }
openvr::shutdown();
println!("Done! \\o/"); println!("Done! \\o/");

2
openvr

Submodule openvr updated: 061cf411ee...a6c91ef973

5
scripts/binding.h Normal file
View File

@ -0,0 +1,5 @@
// This header is used for bindgen to automatically generate the openvr c binding
// bindgen -match openvr_capi.h scripts/binding.h -o binding.rs
#include <stdbool.h>
#include "../openvr/headers/openvr_capi.h"

View File

@ -1,144 +0,0 @@
import json
import re
array = re.compile(r"(.+)\[([0-9]+)\]")
data = {}
with open("openvr/headers/openvr_api.json") as f:
data = json.loads(f.read())
type_mapping = {
'int': 'i32',
'uint64_t': 'u64',
'uint32_t': 'u32',
'uint16_t': 'u16',
'uint8_t': 'u8',
'int64_t': 'i64',
'int32_t': 'i32',
'int16_t': 'i16',
'int8_t': 'i8',
'double': 'f64',
'float': 'f32',
'_Bool': 'bool',
'unsigned short': 'u16',
'const char': 'u8',
'void': '()',
# I'm lazy
'unsigned char *': '*const u8',
'char *': '*const u8',
'char **': '*const *const u8',
'const uint16_t *': '*const u16',
'const uint8_t *': '*const u8',
'const struct vr::HmdVector2_t *': '*const HmdVector2_t',
'const struct vr::RenderModel_Vertex_t *': '*const RenderModel_Vertex_t',
'float [3][4]': '[[f32; 4]; 3]',
'float [16]': '[f32; 16]',
'float [4]': '[f32; 4]',
'float [3]': '[f32; 3]',
'float [2]': '[f32; 2]',
'double [3]': '[f64; 3]',
'union VREvent_Data_t': '[u8; 16]'
}
def parse_type(s):
if s.startswith("struct"):
return parse_type(s[7:])
elif s.startswith("vr::"):
return parse_type(s[4:])
elif s.startswith('enum'):
return parse_type(s.split()[1])
elif s.startswith("const "):
return parse_type(s[6:])
elif s in type_mapping:
return type_mapping[s]
elif s[-2:] == ' *':
return "*mut " + parse_type(s[:-2])
elif s[-2:] == ' &':
return "*const " + parse_type(s[:-2])
elif array.match(s):
m = array.match(s)
return "[%s; %s]" % (parse_type(m.group(1)), m.group(2))
return s
def parse_class(s):
if s.startswith("vr::"):
return 'VR_' + s[4:]
return s
def shorten_enum(parent, name):
split = name.split('_')
if len(split) == 2:
return split[-1]
elif len(split) > 2:
return '_'.join(split[1:])
return name
print """
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(improper_ctypes)]
#[link(name = "openvr_api")]
extern {}
extern "C" {
pub fn VR_Init(err: *mut HmdError) -> *const ();
pub fn VR_Shutdown();
pub fn VR_IsHmdPresent() -> bool;
pub fn VR_GetStringForHmdError(err: HmdError) -> *const u8;
pub fn VR_GetGenericInterface(name: *const u8, err: *mut HmdError) -> *const ();
}
"""
for d in data['typedefs']:
if parse_type(d['typedef']) == parse_type(d['type']):
continue
print "pub type %s = %s;" % (parse_type(d['typedef']), parse_type(d['type']))
for d in data['enums']:
found = set()
print "#[repr(C)]\n#[derive(Debug)]\npub enum %s {" % parse_type(d['enumname'])
for v in d['values']:
if v['value'] in found:
continue
found.add(v['value'])
print "\t%s = %s," % (shorten_enum(d['enumname'], v['name']), v['value'])
print "}\n"
for s in data['structs']:
if s['struct'] == "vr::(anonymous)":
continue
print "#[repr(C)]\npub struct %s {" % parse_type(s['struct'])
for f in s['fields']:
print "\t//%s" % f['fieldtype']
print "\tpub %s: %s," % (f['fieldname'], parse_type(f['fieldtype']))
print "}"
print "extern \"C\" {"
for m in data['methods']:
print '\tpub fn ' + parse_class(m['classname']) + '_' + m['methodname'] + "(ptr: *const (),",
s = []
for p in m.get('params', []):
if p['paramname'] == 'type':
p['paramname'] = '_type'
s += ["%s: %s" % (p['paramname'], parse_type(p['paramtype']))]
print "%s)" % (', '.join(s)),
if 'returntype' in m and m['returntype'] == 'void':
print ";"
elif 'returntype' in m:
print "-> %s;" % parse_type(m['returntype'])
else:
print ";"
print "}"

71
src/common.rs Normal file
View File

@ -0,0 +1,71 @@
use openvr_sys;
use openvr_sys::Enum_EVREye::*;
#[derive(Debug, Copy, Clone)]
pub struct Size {
pub width: u32,
pub height: u32
}
#[derive(Debug, Copy, Clone)]
pub struct Position {
pub x: i32,
pub y: i32
}
#[derive(Debug, Copy, Clone)]
pub struct Rectangle {
pub position: Position,
pub size: Size
}
#[derive(Debug, Copy, Clone)]
pub struct DistortionCoordinates {
pub red: [f32; 2],
pub green: [f32; 2],
pub blue: [f32; 2],
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Eye {
Left, Right
}
impl Eye {
/// Convert a eye to a HmdEye
pub fn to_raw(&self) -> openvr_sys::EVREye {
match self {
&Eye::Left => EVREye_Eye_Left,
&Eye::Right => EVREye_Eye_Right,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct TextureBounds {
pub u_min: f32,
pub u_max: f32,
pub v_min: f32,
pub v_max: f32
}
impl TextureBounds {
pub fn new(u: (f32, f32), v: (f32, f32)) -> Self {
TextureBounds {
u_min: u.0,
u_max: u.1,
v_min: v.0,
v_max: v.1
}
}
/// Convert a bounds to a openvr_bounds
pub fn to_raw(self) -> openvr_sys::VRTextureBounds_t {
openvr_sys::VRTextureBounds_t{
uMin: self.u_min,
uMax: self.u_max,
vMin: self.v_min,
vMax: self.v_max
}
}
}

73
src/compositor.rs Normal file
View File

@ -0,0 +1,73 @@
use openvr_sys;
use openvr_sys::Enum_EGraphicsAPIConvention::*;
use openvr_sys::Enum_EVRSubmitFlags::*;
use openvr_sys::Enum_EColorSpace::*;
use common::*;
use tracking::*;
/// A VR compositor
pub struct IVRCompositor(*const ());
impl IVRCompositor {
pub unsafe fn from_raw(ptr: *const ()) -> Self {
IVRCompositor(ptr as *mut ())
}
/// Check to see if the compositor is fullscreen
pub fn is_fullscreen(&self) -> bool {
unsafe {
let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable };
comp.IsFullscreen.unwrap()() > 0
}
}
/// Check if compositor can render a scene
pub fn can_render_scene(&self) -> bool {
unsafe {
let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable };
comp.CanRenderScene.unwrap()() > 0
}
}
/// Submits an opengl framebuffer as an eye to the render
pub fn submit(&self, eye: Eye, texture: usize, bounds: TextureBounds) {
let mut b = bounds.to_raw();
let e = eye.to_raw();
unsafe {
use std;
let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable };
let mut t = openvr_sys::Texture_t {
eType: EGraphicsAPIConvention_API_OpenGL,
eColorSpace: EColorSpace_ColorSpace_Auto,
handle: texture as *mut std::os::raw::c_void,
};
comp.Submit.unwrap()(
e,
&mut t,
&mut b as *mut openvr_sys::VRTextureBounds_t,
EVRSubmitFlags_Submit_GlRenderBuffer
);
}
}
/// Get the poses
pub fn wait_get_poses(&self) -> TrackedDevicePoses {
use std;
unsafe {
let comp = * { self.0 as *mut openvr_sys::Struct_VR_IVRCompositor_FnTable };
let mut data: [openvr_sys::TrackedDevicePose_t; 16] = std::mem::zeroed();
comp.WaitGetPoses.unwrap()(
&mut data[0],
16,
std::ptr::null_mut(),
0
);
to_tracked(data)
}
}
}

57
src/extended_display.rs Normal file
View File

@ -0,0 +1,57 @@
use openvr_sys;
use common::*;
pub struct IVRExtendedDisplay(*const ());
impl IVRExtendedDisplay {
pub unsafe fn from_raw(ptr: *const ()) -> Self {
IVRExtendedDisplay(ptr as *mut ())
}
/// Get the window bounds
pub fn window_bounds(&self) -> Rectangle {
unsafe {
let ext = * { self.0 as *mut openvr_sys::Struct_VR_IVRExtendedDisplay_FnTable };
let mut size = Size{width: 0, height: 0};
let mut pos = Position{x: 0, y: 0};
ext.GetWindowBounds.unwrap()(
&mut pos.x,
&mut pos.y,
&mut size.width,
&mut size.height
);
Rectangle {
position: pos,
size: size
}
}
}
/// Get eye viewport size
pub fn eye_viewport(&self, eye: Eye) -> Rectangle {
use std::mem;
unsafe {
let ext = * { self.0 as *mut openvr_sys::Struct_VR_IVRExtendedDisplay_FnTable };
let mut size = Size{width: 0, height: 0};
let mut pos = Position{x: 0, y: 0};
ext.GetEyeOutputViewport.unwrap()(
eye.to_raw(),
mem::transmute(&mut pos.x),
mem::transmute(&mut pos.y),
&mut size.width,
&mut size.height
);
Rectangle {
position: pos,
size: size
}
}
}
}

View File

@ -1,363 +1,59 @@
extern crate openvr_sys; extern crate openvr_sys;
pub use openvr_sys::Enum_EVRInitError::*;
pub use openvr_sys::Enum_EVRApplicationType::*;
pub use openvr_sys::Enum_ETrackedDeviceProperty::*;
pub use openvr_sys::Enum_ETrackedDeviceClass::*;
pub struct IVRSystem(*const ()); pub mod common;
pub mod tracking;
pub mod system;
pub mod extended_display;
pub mod compositor;
pub mod render_models;
pub mod subsystems;
#[derive(Debug, Copy, Clone)] pub use system::IVRSystem;
pub struct Size { pub use extended_display::IVRExtendedDisplay;
pub width: u32, pub use compositor::IVRCompositor;
pub height: u32 pub use render_models::IVRRenderModels;
}
#[derive(Debug, Copy, Clone)] pub use subsystems::*;
pub struct Position {
pub x: i32,
pub y: i32
}
#[derive(Debug, Copy, Clone)] pub use common::Eye;
pub struct Rectangle {
pub position: Position,
pub size: Size
}
#[derive(Debug, Copy, Clone)] /// Inits the open vr interface and returns the system
pub struct DistortionCoordinates { pub fn init() -> Result<system::IVRSystem, openvr_sys::HmdError> {
pub red: [f32; 2], let mut err = EVRInitError_VRInitError_None;
pub green: [f32; 2], let app_type = EVRApplicationType_VRApplication_Scene;
pub blue: [f32; 2],
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)] // try to initialize base vr eco
pub enum Eye { unsafe {
Left, Right openvr_sys::VR_InitInternal(&mut err, app_type);
} };
// check for errors
impl Eye { match err {
/// Convert a eye to a HmdEye EVRInitError_VRInitError_None => {
fn to_raw(&self) -> openvr_sys::Hmd_Eye { // get system
match self { let result = system();
&Eye::Left => openvr_sys::Hmd_Eye::Left, match result {
&Eye::Right => openvr_sys::Hmd_Eye::Right, Ok(sys) => {
} return Ok(sys);
} },
} Err(err) => {
return Err(err);
#[derive(Debug, Copy, Clone, PartialEq)] }
pub struct TextureBounds {
pub u_min: f32,
pub u_max: f32,
pub v_min: f32,
pub v_max: f32
}
impl TextureBounds {
/// Convert a bounds to a openvr_bounds
fn to_raw(self) -> openvr_sys::VRTextureBounds_t {
openvr_sys::VRTextureBounds_t{
uMin: self.u_min,
uMax: self.u_max,
vMin: self.v_min,
vMax: self.v_max
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct TrackedDevicePose {
pub to_device: [[f32; 4]; 3],
pub velocity: [f32; 3],
pub angular_velocity: [f32; 3],
pub is_valid: bool,
pub is_connected: bool,
}
#[derive(Debug, Copy, Clone)]
pub struct TrackedDevicePoses {
pub count: usize,
pub poses: [TrackedDevicePose; 16],
}
impl TrackedDevicePoses {
pub fn as_slice(&self) -> &[TrackedDevicePose] {
&self.poses[0..self.count]
}
}
unsafe fn to_tracked(data: [openvr_sys::TrackedDevicePose_t; 16]) -> TrackedDevicePoses {
let mut out: TrackedDevicePoses = std::mem::zeroed();
for (i, d) in data.iter().enumerate() {
if d.bDeviceIsConnected {
out.count = i + 1;
}
out.poses[i].is_connected = d.bDeviceIsConnected;
out.poses[i].is_valid = d.bPoseIsValid;
out.poses[i].to_device = d.mDeviceToAbsoluteTracking.m;
out.poses[i].velocity = d.vVelocity.v;
out.poses[i].angular_velocity = d.vAngularVelocity.v;
}
out
}
impl IVRSystem {
/// Initialize the IVR System
pub fn init() -> Result<IVRSystem, openvr_sys::HmdError> {
let mut err = openvr_sys::HmdError::None;
let ptr = unsafe {
openvr_sys::VR_Init(&mut err as *mut openvr_sys::HmdError)
};
if ptr.is_null() {
Err(err)
} else {
Ok(IVRSystem(ptr))
}
}
/// Get the window bounds
pub fn bounds(&self) -> Rectangle {
unsafe {
let mut size = Size{width: 0, height: 0};
let mut pos = Position{x: 0, y: 0};
openvr_sys::VR_IVRSystem_GetWindowBounds(
self.0,
&mut pos.x,
&mut pos.y,
&mut size.width,
&mut size.height
);
Rectangle {
position: pos,
size: size
} }
},
_ => {
return Err(err);
} }
} };
/// Get the recommended render target size
pub fn recommended_render_target_size(&self) -> Size {
unsafe {
let mut size = Size{width: 0, height: 0};
openvr_sys::VR_IVRSystem_GetRecommendedRenderTargetSize(
self.0,
&mut size.width,
&mut size.height
);
size
}
}
/// Get eye viewport size
pub fn eye_viewport(&self, eye: Eye) -> Rectangle {
use std::mem;
unsafe {
let mut size = Size{width: 0, height: 0};
let mut pos = Position{x: 0, y: 0};
openvr_sys::VR_IVRSystem_GetEyeOutputViewport(
self.0,
eye.to_raw(),
mem::transmute(&mut pos.x),
mem::transmute(&mut pos.y),
&mut size.width,
&mut size.height
);
Rectangle {
position: pos,
size: size
}
}
}
/// Get the projection matrix for an eye
/// supply the near and the far position
/// assumes opengl conventions
pub fn projection_matrix(&self, eye: Eye, near: f32, far: f32) -> [[f32; 4]; 4] {
unsafe {
let mat = openvr_sys::VR_IVRSystem_GetProjectionMatrix(
self.0,
eye.to_raw(),
near,
far,
openvr_sys::GraphicsAPIConvention::OpenGL
);
mat.m
}
}
/// Computes the distortion caused by the optics
pub fn compute_distortion(&self, eye: Eye, u: f32, v: f32) -> DistortionCoordinates {
unsafe {
let coord = openvr_sys::VR_IVRSystem_ComputeDistortion(
self.0,
eye.to_raw(),
u, v
);
DistortionCoordinates {
red: coord.rfRed,
blue: coord.rfBlue,
green: coord.rfGreen
}
}
}
/// Computes the distortion caused by the optics
pub fn eye_to_head_transform(&self, eye: Eye) -> [[f32; 4]; 3] {
unsafe {
let mat = openvr_sys::VR_IVRSystem_GetEyeToHeadTransform(
self.0,
eye.to_raw(),
);
mat.m
}
}
/// Computes the distortion caused by the optics
pub fn time_since_last_vsync(&self) -> Option<(f32, u64)> {
unsafe {
let mut frame = 0;
let mut sync = 0.;
let found = openvr_sys::VR_IVRSystem_GetTimeSinceLastVsync(
self.0,
&mut sync,
&mut frame
);
if found {
Some((sync, frame))
} else {
None
}
}
}
/// Fetch the tracked results from the HMD
pub fn tracked_devices(&self, time: f32) -> TrackedDevicePoses {
unsafe {
let mut data: [openvr_sys::TrackedDevicePose_t; 16] = std::mem::zeroed();
openvr_sys::VR_IVRSystem_GetDeviceToAbsoluteTrackingPose(
self.0,
openvr_sys::TrackingUniverseOrigin::TrackingUniverseSeated,
time,
&mut data[0],
16
);
to_tracked(data)
}
}
/// If the device supports a compositor return a instance
pub fn compositor(&self) -> Result<Compositor, openvr_sys::HmdError> {
unsafe {
let mut err = openvr_sys::HmdError::None;
let name = std::ffi::CString::new("IVRCompositor_006").unwrap();
let ptr = openvr_sys::VR_GetGenericInterface(name.as_ptr() as *const u8, &mut err as *mut openvr_sys::HmdError);
match err {
openvr_sys::HmdError::None => Ok(Compositor(ptr)),
err => Err(err)
}
}
}
/// get frequency of hmd in hz
pub fn display_frequency(&self) -> f32 {
unsafe {
openvr_sys::VR_IVRSystem_GetFloatTrackedDeviceProperty(
self.0,
0,
openvr_sys::TrackedDeviceProperty::DisplayFrequency_Float,
std::ptr::null_mut()
)
}
}
/// get the time vsync to phonts
pub fn vsync_to_photons(&self) -> f32 {
unsafe {
openvr_sys::VR_IVRSystem_GetFloatTrackedDeviceProperty(
self.0,
0,
openvr_sys::TrackedDeviceProperty::SecondsFromVsyncToPhotons_Float,
std::ptr::null_mut()
)
}
}
} }
impl Drop for IVRSystem { /// Shutdowns all openvr related systems
fn drop(&mut self) { pub fn shutdown() {
unsafe { unsafe {
println!("Trying to shutdown openvr"); openvr_sys::VR_ShutdownInternal();
openvr_sys::VR_Shutdown();
println!("Should be done now.");
}
}
}
/// A VR compositor
pub struct Compositor(*const ());
impl Compositor {
/// Check to see if the compositor is fullscreen
pub fn is_fullscreen(&self) -> bool {
unsafe { openvr_sys::VR_IVRCompositor_IsFullscreen(self.0) }
}
/// Check if vsync in enabled
pub fn get_vsync(&self) -> bool {
unsafe { openvr_sys::VR_IVRCompositor_GetVSync(self.0) }
}
/// Set the vsync value
pub fn set_vsync(&self, v: bool) {
unsafe { openvr_sys::VR_IVRCompositor_SetVSync(self.0, v) }
}
/// Check if vsync in enabled
pub fn can_render_scene(&self) -> bool {
unsafe { openvr_sys::VR_IVRCompositor_CanRenderScene(self.0) }
}
/// Get the gamma value
pub fn get_gamma(&self) -> f32 {
unsafe { openvr_sys::VR_IVRCompositor_GetGamma(self.0) }
}
/// Get the gamma value
pub fn set_gamma(&self, v: f32) {
unsafe { openvr_sys::VR_IVRCompositor_SetGamma(self.0, v) }
}
/// Submit an eye to the render
pub fn submit(&self, eye: Eye, texture: usize, bounds: TextureBounds) {
let mut b = bounds.to_raw();
let e = eye.to_raw();
unsafe {
use std::mem;
let t = mem::transmute(texture);
openvr_sys::VR_IVRCompositor_Submit(
self.0,
e,
openvr_sys::GraphicsAPIConvention::OpenGL,
t,
&mut b as *mut openvr_sys::VRTextureBounds_t,
openvr_sys::VRSubmitFlags_t::Default
);
}
}
/// Get the poses
pub fn wait_get_poses(&self) -> TrackedDevicePoses {
unsafe {
let mut data: [openvr_sys::TrackedDevicePose_t; 16] = std::mem::zeroed();
openvr_sys::VR_IVRCompositor_WaitGetPoses(
self.0,
&mut data[0],
16,
std::ptr::null_mut(),
0
);
to_tracked(data)
}
} }
} }

216
src/render_models.rs Normal file
View File

@ -0,0 +1,216 @@
use openvr_sys;
use openvr_sys::Enum_EVRRenderModelError::*;
use std::string::String;
use std::ptr::null_mut;
use std::slice;
use subsystems::render_models;
pub struct IVRRenderModels(*const ());
pub struct RenderModel(*mut openvr_sys::RenderModel_t);
pub struct RenderModelTexture(*mut openvr_sys::RenderModel_TextureMap_t);
impl Drop for RenderModel {
/// will inform openvr that the memory for the render model is no longer required
fn drop (&mut self) {
unsafe {
let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
models.FreeRenderModel.unwrap()(
self.0
);
}
}
}
impl Drop for RenderModelTexture {
/// will inform openvr that the memory for the render model is no longer required
fn drop (&mut self) {
unsafe {
let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
models.FreeTexture.unwrap()(
self.0
);
}
}
}
impl RenderModel {
/// Returns an iterator that iterates over vertices
pub fn vertex_iter(&self) -> slice::Iter<openvr_sys::RenderModel_Vertex_t> {
unsafe {
let slice = slice::from_raw_parts((*self.0).rVertexData, (*self.0).unVertexCount as usize);
slice.iter()
}
}
/// Returns an iterator that iterates over indices
pub fn index_iter(&self) -> slice::Iter<u16> {
unsafe {
let slice = slice::from_raw_parts((*self.0).rIndexData, (*self.0).unTriangleCount as usize * 3);
slice.iter()
}
}
/// asynchronosly loads the texture for the current render model
/// see IVRRenderModels::load_async for info how openvr async work
pub fn load_texture_async(&self) -> Result<RenderModelTexture, openvr_sys::Enum_EVRRenderModelError> {
unsafe {
let models = * { render_models().unwrap().0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
let mut resp: *mut openvr_sys::RenderModel_TextureMap_t = null_mut();
let err = models.LoadTexture_Async.unwrap()(
(*self.0).diffuseTextureId,
&mut resp
);
match err {
EVRRenderModelError_VRRenderModelError_None => {
Ok(RenderModelTexture (resp))
},
_ => {
Err(err)
}
}
}
}
/// loads the texture for current model
pub fn load_texture(&self) -> Result<RenderModelTexture, openvr_sys::Enum_EVRRenderModelError> {
use std;
loop {
let result = self.load_texture_async();
match result {
Ok(texture) => {
return Ok(texture);
},
Err(err) => {
match err {
EVRRenderModelError_VRRenderModelError_Loading => {
// ask again later
},
_ => {
return Err(err);
}
}
}
}
std::thread::sleep(std::time::Duration::from_millis(10));
}
}
}
impl RenderModelTexture {
/// Returns the dimension from the texture (width, height)
pub fn dimension(&self) -> (usize, usize) {
unsafe {
((*self.0).unWidth as usize, (*self.0).unHeight as usize)
}
}
/// Creates a 1 dimensional vector of pixels, format: rgba@32
pub fn to_vec(&self) -> Vec<u8> {
unsafe {
let dimension = self.dimension();
let slice = slice::from_raw_parts((*self.0).rubTextureMapData, dimension.0 * dimension.1 * 4);
let mut vec = Vec::new();
vec.extend_from_slice(slice);
vec
}
}
}
impl IVRRenderModels {
pub unsafe fn from_raw(ptr: *const ()) -> Self {
IVRRenderModels(ptr as *mut ())
}
/// Returns the amount of render models available
pub fn get_count(&self) -> u32 {
unsafe {
let models = * { self.0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
models.GetRenderModelCount.unwrap()()
}
}
/// Returns the name of an available render model
pub fn get_name(&self, index: u32) -> String {
unsafe {
let models = * { self.0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
let name_out = String::with_capacity(256);
let size = models.GetRenderModelName.unwrap()(
index,
name_out.as_ptr() as *mut i8,
256
);
if size > 0 {
return String::from_raw_parts(name_out.as_ptr() as *mut _, (size - 1) as usize, (size - 1) as usize);
} else {
return String::from("");
}
};
}
/// Loads an render model into local memory
/// blocks the thread and waits until driver responds with model
pub fn load(&self, name: String) -> Result<RenderModel, openvr_sys::EVRRenderModelError> {
use std;
loop {
let result = self.load_async(name.clone());
match result {
Ok(model) => {
return Ok(model);
},
Err(err) => {
match err {
EVRRenderModelError_VRRenderModelError_Loading => {
// ask again later
},
_ => {
return Err(err);
}
}
}
}
std::thread::sleep(std::time::Duration::from_millis(10));
}
}
/// Loads an render model into local memory
/// When called for the first time openvr will start to load the model into memory
/// In the mean time this call will respond with EVRRenderModelError_VRRenderModelError_Loading
/// It is designed to be used wihtin the render loop as it won't block the user, for sync usage use load()
pub fn load_async(&self, name: String) -> Result<RenderModel, openvr_sys::EVRRenderModelError> {
use std;
unsafe {
let models = * { self.0 as *mut openvr_sys::Struct_VR_IVRRenderModels_FnTable};
let mut resp: *mut openvr_sys::RenderModel_t = null_mut();
let cname = std::ffi::CString::new(name.as_str()).unwrap();
let rawname = cname.into_raw();
let err = models.LoadRenderModel_Async.unwrap()(
rawname,
&mut resp
);
let _ = std::ffi::CString::from_raw(rawname);
match err {
EVRRenderModelError_VRRenderModelError_None => {
Ok(RenderModel ( resp ))
},
_ => {
Err(err)
}
}
}
}
}

89
src/subsystems.rs Normal file
View File

@ -0,0 +1,89 @@
extern crate openvr_sys;
use openvr_sys::Enum_EVRInitError::*;
use system::IVRSystem;
use extended_display::IVRExtendedDisplay;
use compositor::IVRCompositor;
use render_models::IVRRenderModels;
use std;
/// gets the current vr system interface (initialization is required beforehand)
pub fn system() -> Result<IVRSystem, openvr_sys::HmdError> {
let mut err = EVRInitError_VRInitError_None;
let name = std::ffi::CString::new("FnTable:IVRSystem_012").unwrap();
let ptr = unsafe {
openvr_sys::VR_GetGenericInterface(name.as_ptr(), &mut err)
};
match err {
EVRInitError_VRInitError_None => {
unsafe {
return Ok(IVRSystem::from_raw(ptr as *const ()));
}
},
_ => {
return Err(err);
}
}
}
/// gets the current vr extended display interface (initialization is required beforehand)
pub fn extended_display() -> Result<IVRExtendedDisplay, openvr_sys::HmdError> {
let mut err = EVRInitError_VRInitError_None;
let name = std::ffi::CString::new("FnTable:IVRExtendedDisplay_001").unwrap();
let ptr = unsafe {
openvr_sys::VR_GetGenericInterface(name.as_ptr(), &mut err)
};
match err {
EVRInitError_VRInitError_None => {
unsafe {
return Ok(IVRExtendedDisplay::from_raw(ptr as *const ()));
}
},
_ => {
return Err(err);
}
}
}
/// gets the current vr extended display interface (initialization is required beforehand)
pub fn compositor() -> Result<IVRCompositor, openvr_sys::HmdError> {
let mut err = EVRInitError_VRInitError_None;
let name = std::ffi::CString::new("FnTable:IVRCompositor_013").unwrap();
let ptr = unsafe {
openvr_sys::VR_GetGenericInterface(name.as_ptr(), &mut err)
};
match err {
EVRInitError_VRInitError_None => {
unsafe {
return Ok(IVRCompositor::from_raw(ptr as *const ()));
}
},
_ => {
return Err(err);
}
}
}
/// gets the current vr extended display interface (initialization is required beforehand)
pub fn render_models() -> Result<IVRRenderModels, openvr_sys::HmdError> {
let mut err = EVRInitError_VRInitError_None;
let name = std::ffi::CString::new("FnTable:IVRRenderModels_005").unwrap();
let ptr = unsafe {
openvr_sys::VR_GetGenericInterface(name.as_ptr(), &mut err)
};
match err {
EVRInitError_VRInitError_None => {
unsafe {
return Ok(IVRRenderModels::from_raw(ptr as *const ()));
}
},
_ => {
return Err(err);
}
}
}

View File

@ -2,15 +2,18 @@
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
fn main() { fn main() {
println!("cargo:rustc-link-search={}/../../openvr/lib/osx32", env!("CARGO_MANIFEST_DIR"));
println!("cargo:rustc-link-search={}/../../openvr/bin/osx32", env!("CARGO_MANIFEST_DIR")); println!("cargo:rustc-link-search={}/../../openvr/bin/osx32", env!("CARGO_MANIFEST_DIR"));
} }
#[cfg(target_os="linux")] #[cfg(target_os="linux")]
fn main() { fn main() {
println!("cargo:rustc-link-search={}/../../openvr/lib/linux64", env!("CARGO_MANIFEST_DIR"));
println!("cargo:rustc-link-search={}/../../openvr/bin/linux64", env!("CARGO_MANIFEST_DIR")); println!("cargo:rustc-link-search={}/../../openvr/bin/linux64", env!("CARGO_MANIFEST_DIR"));
} }
#[cfg(target_os="windows")] #[cfg(target_os="windows")]
fn main() { fn main() {
println!("cargo:rustc-link-search={}\\..\\..\\openvr\\lib\\win64", env!("CARGO_MANIFEST_DIR"));
println!("cargo:rustc-link-search={}\\..\\..\\openvr\\bin\\win64", env!("CARGO_MANIFEST_DIR")); println!("cargo:rustc-link-search={}\\..\\..\\openvr\\bin\\win64", env!("CARGO_MANIFEST_DIR"));
} }

File diff suppressed because it is too large Load Diff

112
src/system.rs Normal file
View File

@ -0,0 +1,112 @@
use openvr_sys;
use openvr_sys::Enum_EGraphicsAPIConvention::*;
use openvr_sys::Enum_ETrackingUniverseOrigin::*;
use common::*;
use tracking::*;
pub struct IVRSystem(pub *const ());
impl IVRSystem {
pub unsafe fn from_raw(ptr: *const ()) -> Self {
IVRSystem(ptr as *mut ())
}
/// Get the recommended render target size
pub fn recommended_render_target_size(&self) -> Size {
unsafe {
let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable };
let mut size = Size{width: 0, height: 0};
system.GetRecommendedRenderTargetSize.unwrap()(
&mut size.width,
&mut size.height
);
size
}
}
/// Get the projection matrix for an eye
/// supply the near and the far position
/// assumes opengl conventions
pub fn projection_matrix(&self, eye: Eye, near: f32, far: f32) -> [[f32; 4]; 4] {
unsafe {
let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable };
let mat = system.GetProjectionMatrix.unwrap()(
eye.to_raw(),
near,
far,
EGraphicsAPIConvention_API_OpenGL
);
mat.m
}
}
/// Computes the distortion caused by the optics
pub fn compute_distortion(&self, eye: Eye, u: f32, v: f32) -> DistortionCoordinates {
unsafe {
let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable };
let coord = system.ComputeDistortion.unwrap()(
eye.to_raw(),
u, v
);
DistortionCoordinates {
red: coord.rfRed,
blue: coord.rfBlue,
green: coord.rfGreen
}
}
}
/// Computes the distortion caused by the optics
pub fn eye_to_head_transform(&self, eye: Eye) -> [[f32; 4]; 3] {
unsafe {
let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable };
let mat = system.GetEyeToHeadTransform.unwrap()(
eye.to_raw(),
);
mat.m
}
}
/// Computes the distortion caused by the optics
pub fn time_since_last_vsync(&self) -> Option<(f32, u64)> {
unsafe {
let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable };
let mut frame = 0;
let mut sync = 0.;
let found = system.GetTimeSinceLastVsync.unwrap()(
&mut sync,
&mut frame
);
if found > 0 {
Some((sync, frame))
} else {
None
}
}
}
/// Fetch the tracked results from the HMD
/// when time is bigger than 0, it will give you the predicted poses for that time
/// Time is counted in photons, see https://github.com/ValveSoftware/openvr/wiki/IVRSystem::GetDeviceToAbsoluteTrackingPose
/// for time to photons conversion
pub fn tracked_devices(&self, time: f32) -> TrackedDevicePoses {
use std;
unsafe {
let system = * { self.0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable };
let mut data: [openvr_sys::TrackedDevicePose_t; 16] = std::mem::zeroed();
system.GetDeviceToAbsoluteTrackingPose.unwrap()(
ETrackingUniverseOrigin_TrackingUniverseSeated,
time,
&mut data[0],
16
);
to_tracked(data)
}
}
}

103
src/tracking.rs Normal file
View File

@ -0,0 +1,103 @@
use openvr_sys;
use openvr_sys::Enum_ETrackedPropertyError::*;
use subsystems::*;
#[derive(Debug, Copy, Clone)]
pub struct TrackedDevicePose {
pub index: usize,
pub to_device: [[f32; 4]; 3],
pub velocity: [f32; 3],
pub angular_velocity: [f32; 3],
pub is_valid: bool,
pub is_connected: bool,
}
impl TrackedDevicePose {
// returns the device class of the tracked object
pub fn device_class(&self) -> openvr_sys::Enum_ETrackedDeviceClass {
unsafe {
let system = * { system().unwrap().0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable};
system.GetTrackedDeviceClass.unwrap()(self.index as u32)
}
}
/// gets a propery as a string
pub fn get_property_string(&self, property: openvr_sys::Enum_ETrackedDeviceProperty) -> Result<String, openvr_sys::Enum_ETrackedPropertyError> {
unsafe {
let system = * { system().unwrap().0 as *mut openvr_sys::Struct_VR_IVRSystem_FnTable};
let val_out = String::with_capacity(256);
let mut err = ETrackedPropertyError_TrackedProp_Success;
let size = system.GetStringTrackedDeviceProperty.unwrap()(
self.index as u32,
property,
val_out.as_ptr() as *mut i8,
256,
&mut err
);
if size > 0 {
return Ok(String::from_raw_parts(val_out.as_ptr() as *mut _, (size - 1) as usize, (size - 1) as usize));
} else {
return Err(err);
}
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct TrackedDevicePoses {
pub count: usize,
pub poses: [TrackedDevicePose; 16],
}
pub struct TrackedDevicePosesIterator<'a> {
pub target: &'a TrackedDevicePoses,
pub index: usize
}
impl TrackedDevicePoses {
pub fn as_slice(&self) -> &[TrackedDevicePose] {
&self.poses[0..self.count]
}
/// creates an iterator that will iterate over all connected devices
pub fn connected_iter(&self) -> TrackedDevicePosesIterator {
TrackedDevicePosesIterator { target: self, index: 0 }
}
}
impl<'a> Iterator for TrackedDevicePosesIterator<'a> {
type Item = &'a TrackedDevicePose;
fn next(&mut self) -> Option<&'a TrackedDevicePose> {
// end reached
if self.index == self.target.count {
return None;
}
let res = &self.target.poses[self.index];
self.index += 1;
Some(res)
}
}
pub unsafe fn to_tracked(data: [openvr_sys::TrackedDevicePose_t; 16]) -> TrackedDevicePoses {
use std;
let mut out: TrackedDevicePoses = std::mem::zeroed();
for (i, d) in data.iter().enumerate() {
if d.bDeviceIsConnected > 0 {
out.count = i + 1;
}
out.poses[i].index = i;
out.poses[i].is_connected = d.bDeviceIsConnected > 0;
out.poses[i].is_valid = d.bPoseIsValid > 0;
out.poses[i].to_device = d.mDeviceToAbsoluteTracking.m;
out.poses[i].velocity = d.vVelocity.v;
out.poses[i].angular_velocity = d.vAngularVelocity.v;
}
out
}