mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-08-23 00:35:31 +00:00
Merge pull request #4 from Auruss/sdk_0.1.19_refactoring
OpenVR 0.1.19 + Refactoring
This commit is contained in:
549
Cargo.lock
generated
549
Cargo.lock
generated
@ -2,10 +2,559 @@
|
||||
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)",
|
||||
]
|
||||
|
||||
|
@ -6,6 +6,7 @@ authors = [
|
||||
"Erick Tryzelaar",
|
||||
"Rene Eichhorn"
|
||||
]
|
||||
build = "src/sys/build.rs"
|
||||
|
||||
[lib]
|
||||
name = "openvr"
|
||||
@ -13,3 +14,8 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies.openvr_sys]
|
||||
path = "src/sys/"
|
||||
|
||||
[dev_dependencies]
|
||||
glium = "0.14.0"
|
||||
num = "0.1.31"
|
||||
nalgebra = "0.8.2"
|
||||
|
70
Readme.md
70
Readme.md
@ -7,7 +7,7 @@ rust-openvr is a binding for openvr. It's still in progress. Tests are automatic
|
||||
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 version: OpenVR SDK 0.9.11 (will be updated soon to newest!)
|
||||
## Current sdk version: OpenVR SDK 0.9.19
|
||||
|
||||
Building
|
||||
--------
|
||||
@ -32,69 +32,23 @@ Using rust-openvr
|
||||
|
||||
extern crate openvr;
|
||||
|
||||
use openvr::{SensorCapabilities, Ovr};
|
||||
|
||||
fn main() {
|
||||
// Initalize the Oculus VR library
|
||||
let ovr = match Ovr::init() {
|
||||
Some(ovr) => ovr,
|
||||
None => {
|
||||
println!("Could not initialize OpenVR SDK");
|
||||
// Initialize system subsystem
|
||||
let system = match openvr::init() {
|
||||
Ok(sys) => sys,
|
||||
Err(err) => {
|
||||
println!("Could not initialize OpenVR SDK: \n\t{:?}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// get the first available HMD device, returns None
|
||||
// if no HMD device is currently plugged in
|
||||
let hmd = match ovr.first_hmd() {
|
||||
Some(hmd) => hmd,
|
||||
None => {
|
||||
println!("Could not get hmd");
|
||||
return;
|
||||
}
|
||||
};
|
||||
// accessing other sub systems
|
||||
let ext = openvr::extended_display();
|
||||
|
||||
// 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
|
||||
|
||||
The OpenVR SDK will handle most of the heavy lifting of the barrel distortion.
|
||||
|
||||
```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();
|
||||
}
|
||||
```
|
||||
# Examples
|
||||
For data collection examples/test.rs can be used.
|
||||
For an actual opengl implementation see examples/opengl.rs (WIP)
|
||||
|
299
examples/opengl.rs
Normal file
299
examples/opengl.rs
Normal 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, ¶ms).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, ¶ms).unwrap();
|
||||
right_eye_framebuffer.draw(&controller_vertex_buffer, &controller_index_buffer, &program, &right_uniforms, ¶ms).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();
|
||||
}
|
@ -16,7 +16,7 @@ fn print_matrix_4x3(offset: u32, mat: [[f32; 4]; 3]) {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let ivr = match openvr::IVRSystem::init() {
|
||||
let system = match openvr::init() {
|
||||
Ok(ivr) => ivr,
|
||||
Err(err) => {
|
||||
println!("Failed to create IVR subsystem {:?}", err);
|
||||
@ -24,27 +24,26 @@ fn main() {
|
||||
}
|
||||
};
|
||||
|
||||
println!("IVR was created");
|
||||
println!("\tbounds: {:?}", ivr.bounds());
|
||||
println!("\trecommended size: {:?}", ivr.recommended_render_target_size());
|
||||
println!("\teye output: {:?} {:?}", ivr.eye_viewport(openvr::Eye::Left), ivr.eye_viewport(openvr::Eye::Right));
|
||||
println!("\tvsync: {:?}", ivr.time_since_last_vsync());
|
||||
println!("IVRSystem was created");
|
||||
|
||||
println!("\trecommended size: {:?}", system.recommended_render_target_size());
|
||||
println!("\tvsync: {:?}", system.time_since_last_vsync());
|
||||
|
||||
print!("\tprojection matrix left ");
|
||||
print_matrix_4x4(31, ivr.projection_matrix(openvr::Eye::Left, 0.1, 100.));
|
||||
print_matrix_4x4(31, system.projection_matrix(openvr::Eye::Left, 0.1, 100.));
|
||||
print!("\tprojection matrix right ");
|
||||
print_matrix_4x4(31, ivr.projection_matrix(openvr::Eye::Right, 0.1, 100.));
|
||||
print_matrix_4x4(31, system.projection_matrix(openvr::Eye::Right, 0.1, 100.));
|
||||
|
||||
print!("\teye_to_head ");
|
||||
print_matrix_4x3(8+12, ivr.eye_to_head_transform(openvr::Eye::Left));
|
||||
print_matrix_4x3(8+12, system.eye_to_head_transform(openvr::Eye::Left));
|
||||
|
||||
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");
|
||||
for u in 0..2 {
|
||||
for v in 0..2 {
|
||||
let pos = ivr.compute_distortion(
|
||||
let pos = system.compute_distortion(
|
||||
openvr::Eye::Left,
|
||||
u as f32 / 4.,
|
||||
v as f32 / 4.,
|
||||
@ -54,18 +53,43 @@ fn main() {
|
||||
println!("");
|
||||
}
|
||||
|
||||
println!("Trying to create a compositor");
|
||||
match ivr.compositor() {
|
||||
Err(err) => println!("Could not create compositor {:?}", err),
|
||||
Ok(comp) => {
|
||||
println!("\tCreated one!");
|
||||
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());
|
||||
let ext = match openvr::extended_display() {
|
||||
Ok(ext) => ext,
|
||||
Err(err) => {
|
||||
println!("Failed to create IVRExtendedDisplay subsystem {:?}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
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/");
|
||||
|
||||
|
||||
|
2
openvr
2
openvr
Submodule openvr updated: 061cf411ee...a6c91ef973
5
scripts/binding.h
Normal file
5
scripts/binding.h
Normal 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"
|
144
scripts/gen.py
144
scripts/gen.py
@ -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
71
src/common.rs
Normal 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
73
src/compositor.rs
Normal 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
57
src/extended_display.rs
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
392
src/lib.rs
392
src/lib.rs
@ -1,361 +1,59 @@
|
||||
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 struct Size {
|
||||
pub width: u32,
|
||||
pub height: u32
|
||||
}
|
||||
pub use system::IVRSystem;
|
||||
pub use extended_display::IVRExtendedDisplay;
|
||||
pub use compositor::IVRCompositor;
|
||||
pub use render_models::IVRRenderModels;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Position {
|
||||
pub x: i32,
|
||||
pub y: i32
|
||||
}
|
||||
pub use subsystems::*;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Rectangle {
|
||||
pub position: Position,
|
||||
pub size: Size
|
||||
}
|
||||
pub use common::Eye;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct DistortionCoordinates {
|
||||
pub red: [f32; 2],
|
||||
pub green: [f32; 2],
|
||||
pub blue: [f32; 2],
|
||||
}
|
||||
/// Inits the open vr interface and returns the system
|
||||
pub fn init() -> Result<system::IVRSystem, openvr_sys::HmdError> {
|
||||
let mut err = EVRInitError_VRInitError_None;
|
||||
let app_type = EVRApplicationType_VRApplication_Scene;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Eye {
|
||||
Left, Right
|
||||
}
|
||||
// try to initialize base vr eco
|
||||
unsafe {
|
||||
openvr_sys::VR_InitInternal(&mut err, app_type);
|
||||
};
|
||||
|
||||
|
||||
impl Eye {
|
||||
/// Convert a eye to a HmdEye
|
||||
fn to_raw(&self) -> openvr_sys::Hmd_Eye {
|
||||
match self {
|
||||
&Eye::Left => openvr_sys::Hmd_Eye::Left,
|
||||
&Eye::Right => openvr_sys::Hmd_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 {
|
||||
/// 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
|
||||
// check for errors
|
||||
match err {
|
||||
EVRInitError_VRInitError_None => {
|
||||
// get system
|
||||
let result = system();
|
||||
match result {
|
||||
Ok(sys) => {
|
||||
return Ok(sys);
|
||||
},
|
||||
Err(err) => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
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 {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
println!("Trying to shutdown openvr");
|
||||
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)
|
||||
}
|
||||
/// Shutdowns all openvr related systems
|
||||
pub fn shutdown() {
|
||||
unsafe {
|
||||
openvr_sys::VR_ShutdownInternal();
|
||||
}
|
||||
}
|
||||
|
216
src/render_models.rs
Normal file
216
src/render_models.rs
Normal 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
89
src/subsystems.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
3776
src/sys/lib.rs
3776
src/sys/lib.rs
File diff suppressed because it is too large
Load Diff
112
src/system.rs
Normal file
112
src/system.rs
Normal 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
103
src/tracking.rs
Normal 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
|
||||
}
|
Reference in New Issue
Block a user