mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-04-19 19:14:53 +00:00
Merge branch 'main' into feat/stardust
This commit is contained in:
commit
348dc13614
18 changed files with 197 additions and 59 deletions
|
@ -22,8 +22,8 @@ cargo:test:
|
|||
script:
|
||||
- echo 'deb http://deb.debian.org/debian experimental main' > /etc/apt/sources.list.d/experimental.list
|
||||
- apt-get update
|
||||
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev -y
|
||||
- apt-get install meson ninja-build git desktop-file-utils gettext libjxl-dev file libusb-dev libusb-1.0-0-dev curl -y
|
||||
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev libjxl-dev -y
|
||||
- apt-get install meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y
|
||||
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
|
||||
- chmod +x /tmp/rustup.sh
|
||||
- /tmp/rustup.sh -y
|
||||
|
@ -41,8 +41,8 @@ appimage:
|
|||
script:
|
||||
- echo 'deb http://deb.debian.org/debian experimental main' > /etc/apt/sources.list.d/experimental.list
|
||||
- apt-get update
|
||||
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev -y
|
||||
- apt-get install meson ninja-build git desktop-file-utils gettext libjxl-dev file libusb-dev libusb-1.0-0-dev curl -y
|
||||
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev libjxl-dev -y
|
||||
- apt-get install meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y
|
||||
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
|
||||
- chmod +x /tmp/rustup.sh
|
||||
- /tmp/rustup.sh -y
|
||||
|
|
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1068,7 +1068,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "libmonado-rs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/technobaboo/libmonado-rs#3b3f098cb131843ee90f078e26362fcefe02b822"
|
||||
source = "git+https://github.com/technobaboo/libmonado-rs#d79d5bf11586b8010d8aa016097ebdb07f683c64"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cmake",
|
||||
|
|
|
@ -33,14 +33,6 @@ cd envision
|
|||
./dist/appimage/build_appimage.sh
|
||||
```
|
||||
|
||||
<!-- no feature flags for now :)
|
||||
# Feature flags
|
||||
|
||||
|Env var|Values|Default|
|
||||
|---|---|---|
|
||||
|`ENVISION_FF_USE_LIBMONADO`|`1`: enabled; `0`: disabled|`0`|
|
||||
-->
|
||||
|
||||
# Common issues
|
||||
|
||||
## NOSUID with systemd-homed
|
||||
|
|
|
@ -61,6 +61,7 @@ meson.add_dist_script(
|
|||
|
||||
global_conf = configuration_data()
|
||||
global_conf.set('APP_ID', application_id)
|
||||
global_conf.set('RESOURCES_BASE_PATH', '/' + base_id.replace('.', '/'))
|
||||
global_conf.set('PKGDATADIR', pkgdatadir)
|
||||
global_conf.set('PROFILE', profile)
|
||||
global_conf.set('VERSION', version + version_suffix)
|
||||
|
|
|
@ -30,6 +30,7 @@ pub fn get_build_libsurvive_jobs(profile: &Profile, clean_build: bool) -> VecDeq
|
|||
let mut cmake_vars: HashMap<String, String> = HashMap::new();
|
||||
cmake_vars.insert("CMAKE_BUILD_TYPE".into(), "Release".into());
|
||||
cmake_vars.insert("ENABLE_api_example".into(), "OFF".into());
|
||||
cmake_vars.insert("USE_HIDAPI".into(), "ON".into());
|
||||
cmake_vars.insert("CMAKE_SKIP_INSTALL_RPATH".into(), "YES".into());
|
||||
cmake_vars.insert("CMAKE_INSTALL_PREFIX".into(), profile.prefix.clone());
|
||||
cmake_vars.insert(
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::paths::get_exec_prefix;
|
|||
|
||||
pub const APP_NAME: &str = "@PRETTY_NAME@";
|
||||
pub const APP_ID: &str = "@APP_ID@";
|
||||
pub const RESOURCES_BASE_PATH: &str = "@RESOURCES_BASE_PATH@";
|
||||
pub const PKG_DATA_DIR: &str = "@PKGDATADIR@";
|
||||
pub const RESOURCES: &str = concat!("@PKGDATADIR@", "/resources.gresource");
|
||||
pub const CMD_NAME: &str = "@CMD_NAME@";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::file_utils::get_writer;
|
||||
use crate::{constants::APP_ID, file_utils::get_writer};
|
||||
use reqwest::{
|
||||
header::{HeaderMap, USER_AGENT},
|
||||
Method,
|
||||
|
@ -11,7 +11,7 @@ const CHUNK_SIZE: usize = 1024;
|
|||
|
||||
fn headers() -> HeaderMap {
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(USER_AGENT, "org.gabmus.envision/1.0".parse().unwrap());
|
||||
headers.insert(USER_AGENT, format!("{}/1.0", APP_ID).parse().unwrap());
|
||||
headers
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ pub static ENV_VAR_DESCRIPTIONS: Map<&str, &str> = phf_map! {
|
|||
pub fn env_var_descriptions_as_paragraph() -> String {
|
||||
ENV_VAR_DESCRIPTIONS
|
||||
.into_iter()
|
||||
.map(|(k, v)| format!("{}: {}", k, v))
|
||||
.map(|(k, v)| format!(" \u{2022} <b>{}</b>: {}", k, v))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n\n")
|
||||
}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
use std::env;
|
||||
|
||||
use anyhow::Result;
|
||||
use constants::{resources, APP_ID, APP_NAME, GETTEXT_PACKAGE, LOCALE_DIR};
|
||||
use constants::{resources, APP_ID, APP_NAME, GETTEXT_PACKAGE, LOCALE_DIR, RESOURCES_BASE_PATH};
|
||||
use file_builders::{
|
||||
active_runtime_json::{get_current_active_runtime, set_current_active_runtime_to_steam},
|
||||
openvrpaths_vrpath::{get_current_openvrpaths, set_current_openvrpaths_to_steam},
|
||||
};
|
||||
use gettextrs::LocaleCategory;
|
||||
use gtk::prelude::ObjectExt;
|
||||
use relm4::{
|
||||
adw,
|
||||
gtk::{self, gdk, gio, glib},
|
||||
|
@ -83,7 +80,7 @@ fn main() -> Result<()> {
|
|||
}
|
||||
|
||||
let provider = gtk::CssProvider::new();
|
||||
provider.load_from_resource("/org/gabmus/envision/style.css");
|
||||
provider.load_from_resource(&format!("{}/style.css", RESOURCES_BASE_PATH));
|
||||
if let Some(display) = gdk::Display::default() {
|
||||
gtk::style_context_add_provider_for_display(
|
||||
&display,
|
||||
|
|
|
@ -236,26 +236,45 @@ impl Display for Profile {
|
|||
|
||||
impl Default for Profile {
|
||||
fn default() -> Self {
|
||||
let uuid = Uuid::new_v4().to_string();
|
||||
let profile_dir = format!("{}/{}", get_data_dir(), uuid);
|
||||
Self {
|
||||
uuid: Uuid::new_v4().to_string(),
|
||||
name: "Default profile name".into(),
|
||||
xrservice_path: data_monado_path(),
|
||||
xrservice_path: format!("{}/xrservice", profile_dir),
|
||||
xrservice_type: XRServiceType::Monado,
|
||||
xrservice_repo: None,
|
||||
xrservice_cmake_flags: HashMap::<String, String>::default(),
|
||||
opencomposite_path: data_opencomposite_path(),
|
||||
features: ProfileFeatures::default(),
|
||||
features: ProfileFeatures {
|
||||
libsurvive: ProfileFeature {
|
||||
enabled: false,
|
||||
path: Some(format!("{}/libsurvive", profile_dir)),
|
||||
repo: None,
|
||||
feature_type: ProfileFeatureType::Libsurvive,
|
||||
},
|
||||
basalt: ProfileFeature {
|
||||
enabled: false,
|
||||
path: Some(format!("{}/basalt", profile_dir)),
|
||||
repo: None,
|
||||
feature_type: ProfileFeatureType::Basalt,
|
||||
},
|
||||
openhmd: ProfileFeature {
|
||||
enabled: false,
|
||||
path: Some(format!("{}/openhmd", profile_dir)),
|
||||
repo: None,
|
||||
feature_type: ProfileFeatureType::OpenHmd,
|
||||
},
|
||||
mercury_enabled: false,
|
||||
},
|
||||
environment: HashMap::new(),
|
||||
prefix: format!(
|
||||
"{data}/prefixes/default_profile_prefix",
|
||||
data = get_data_dir()
|
||||
),
|
||||
prefix: format!("{}/prefixes/{}", get_data_dir(), uuid),
|
||||
can_be_built: true,
|
||||
pull_on_build: true,
|
||||
opencomposite_repo: None,
|
||||
opencomposite_path: format!("{}/opencomposite", profile_dir),
|
||||
editable: true,
|
||||
lighthouse_driver: LighthouseDriver::default(),
|
||||
xrservice_launch_options: String::default(),
|
||||
uuid,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -307,10 +326,30 @@ impl Profile {
|
|||
}
|
||||
|
||||
pub fn create_duplicate(&self) -> Self {
|
||||
let mut dup = self.clone();
|
||||
dup.uuid = Uuid::new_v4().to_string();
|
||||
dup.editable = true;
|
||||
dup.name = format!("Duplicate of {}", dup.name);
|
||||
if !self.can_be_built {
|
||||
let mut dup = self.clone();
|
||||
dup.uuid = Uuid::new_v4().to_string();
|
||||
dup.name = format!("Duplicate of {}", dup.name);
|
||||
dup.editable = true;
|
||||
return dup;
|
||||
}
|
||||
let mut dup = Self::default();
|
||||
dup.name = format!("Duplicate of {}", self.name);
|
||||
dup.xrservice_type = self.xrservice_type.clone();
|
||||
dup.xrservice_repo = self.xrservice_repo.clone();
|
||||
dup.xrservice_cmake_flags = self.xrservice_cmake_flags.clone();
|
||||
dup.features.libsurvive.enabled = self.features.libsurvive.enabled;
|
||||
dup.features.libsurvive.repo = self.features.libsurvive.repo.clone();
|
||||
dup.features.basalt.enabled = self.features.basalt.enabled;
|
||||
dup.features.basalt.repo = self.features.basalt.repo.clone();
|
||||
dup.features.openhmd.enabled = self.features.openhmd.enabled;
|
||||
dup.features.openhmd.repo = self.features.openhmd.repo.clone();
|
||||
dup.features.mercury_enabled = self.features.mercury_enabled;
|
||||
dup.environment = self.environment.clone();
|
||||
dup.pull_on_build = self.pull_on_build;
|
||||
dup.opencomposite_repo = self.opencomposite_repo.clone();
|
||||
dup.lighthouse_driver = self.lighthouse_driver;
|
||||
dup.xrservice_launch_options = self.xrservice_launch_options.clone();
|
||||
dup
|
||||
}
|
||||
|
||||
|
@ -347,10 +386,14 @@ impl Profile {
|
|||
}
|
||||
|
||||
pub fn xrservice_binary(&self) -> String {
|
||||
match self.xrservice_type {
|
||||
XRServiceType::Monado => format!("{pfx}/bin/monado-service", pfx = self.prefix),
|
||||
XRServiceType::Wivrn => format!("{pfx}/bin/wivrn-server", pfx = self.prefix),
|
||||
}
|
||||
format!(
|
||||
"{}/bin/{}",
|
||||
self.prefix,
|
||||
match self.xrservice_type {
|
||||
XRServiceType::Monado => "monado-service",
|
||||
XRServiceType::Wivrn => "wivrn-server",
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
pub fn can_start(&self) -> bool {
|
||||
|
|
|
@ -61,7 +61,7 @@ impl SimpleComponent for DebugView {
|
|||
menu! {
|
||||
debug_menu: {
|
||||
section! {
|
||||
"Open Envision _Data Folder" => DebugOpenDataAction,
|
||||
"Open _Data Folder" => DebugOpenDataAction,
|
||||
"Open _Prefix Folder" => DebugOpenPrefixAction,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
use lazy_static::lazy_static;
|
||||
use std::env;
|
||||
|
||||
fn get_ff_libmonado_device_enumeration_enabled() -> bool {
|
||||
env::var("ENVISION_FF_USE_LIBMONADO").unwrap_or_default() == "1"
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref FF_LIBMONADO_DEVICE_ENUMERATION_ENABLED: bool =
|
||||
get_ff_libmonado_device_enumeration_enabled();
|
||||
}
|
|
@ -228,7 +228,7 @@ impl SimpleComponent for MainView {
|
|||
set_label: concat!(
|
||||
"Your current prefix is inside a partition ",
|
||||
"mounted with the nosuid option. This will prevent ",
|
||||
"the Envision runtime from acquiring certain privileges ",
|
||||
"the XR runtime from acquiring certain privileges ",
|
||||
"and will cause noticeable stutter when running XR ",
|
||||
"applications."
|
||||
),
|
||||
|
|
|
@ -6,7 +6,6 @@ pub mod debug_view;
|
|||
pub mod devices_box;
|
||||
pub mod factories;
|
||||
pub mod fbt_config_editor;
|
||||
pub mod feature_flags;
|
||||
pub mod install_wivrn_box;
|
||||
pub mod job_worker;
|
||||
pub mod libsurvive_setup_window;
|
||||
|
|
|
@ -179,6 +179,7 @@ pub fn path_row<F: Fn(Option<String>) + 'static + Clone>(
|
|||
None => "(None)",
|
||||
Some(p) => p.as_str(),
|
||||
})
|
||||
.wrap(true)
|
||||
.build();
|
||||
row.add_suffix(path_label);
|
||||
|
||||
|
|
|
@ -146,9 +146,9 @@ impl SimpleComponent for ProfileEditor {
|
|||
"Lighthouse Driver",
|
||||
Some(concat!(
|
||||
"Driver for lighhouse tracked XR devices (ie: Valve Index, HTC Vive...). Only applicable for Monado.\n\n",
|
||||
"Vive: 3DOF tracking\n\n",
|
||||
"Survive: 6DOF reverse engineered lighthouse tracking provided by Libsurvive\n\n",
|
||||
"SteamVR: 6DOF lighthouse tracking using the proprietary SteamVR driver",
|
||||
" \u{2022} Vive: 3DOF tracking\n",
|
||||
" \u{2022} Survive: 6DOF reverse engineered lighthouse tracking provided by Libsurvive\n",
|
||||
" \u{2022} SteamVR: 6DOF lighthouse tracking using the proprietary SteamVR driver",
|
||||
)),
|
||||
model.profile.borrow().lighthouse_driver.to_string().as_str(),
|
||||
LighthouseDriver::iter()
|
||||
|
|
|
@ -69,11 +69,11 @@ impl SimpleComponent for SteamVrCalibrationBox {
|
|||
set_hexpand: true,
|
||||
set_label: concat!(
|
||||
"Run a quick SteamVR calibration.\n\n",
|
||||
"\u{2022} Plug in your HMD and place it on the floor, ",
|
||||
" \u{2022} Plug in your HMD and place it on the floor, ",
|
||||
"approximately in the middle of your play area\n",
|
||||
"\u{2022} Make sure your controllers and other VR devices ",
|
||||
" \u{2022} Make sure your controllers and other VR devices ",
|
||||
"are turned off\n",
|
||||
"\u{2022} Click the Calibrate button and wait for the ",
|
||||
" \u{2022} Click the Calibrate button and wait for the ",
|
||||
"process to finish\n\n",
|
||||
"Note that the orientation of your HMD during this process ",
|
||||
"will dictate the forward direction of your play area.",
|
||||
|
|
|
@ -11,6 +11,21 @@ pub enum XRDeviceRole {
|
|||
Eyes,
|
||||
HandTrackingLeft,
|
||||
HandTrackingRight,
|
||||
|
||||
HandheldObject,
|
||||
LeftFoot,
|
||||
RightFoot,
|
||||
LeftShoulder,
|
||||
RightShoulder,
|
||||
LeftElbow,
|
||||
RightElbow,
|
||||
LeftKnee,
|
||||
RightKnee,
|
||||
Waist,
|
||||
Chest,
|
||||
Camera,
|
||||
Keyboard,
|
||||
|
||||
GenericTracker,
|
||||
/**
|
||||
* Devices with no role
|
||||
|
@ -34,6 +49,21 @@ impl Display for XRDeviceRole {
|
|||
Self::Eyes => "Eye Tracking",
|
||||
Self::HandTrackingLeft => "Hand tracking left",
|
||||
Self::HandTrackingRight => "Hand tracking right",
|
||||
|
||||
Self::HandheldObject => "Handheld object",
|
||||
Self::LeftFoot => "Left foot",
|
||||
Self::RightFoot => "Right foot",
|
||||
Self::LeftShoulder => "Left shoulder",
|
||||
Self::RightShoulder => "Right shoulder",
|
||||
Self::LeftElbow => "Left elbow",
|
||||
Self::RightElbow => "Right elbow",
|
||||
Self::LeftKnee => "Left knee",
|
||||
Self::RightKnee => "Right knee",
|
||||
Self::Waist => "Waist",
|
||||
Self::Chest => "Chest",
|
||||
Self::Camera => "Camera",
|
||||
Self::Keyboard => "Keyboard",
|
||||
|
||||
Self::GenericTracker => "Generic tracker",
|
||||
Self::Other => "",
|
||||
})
|
||||
|
@ -62,6 +92,19 @@ impl XRDeviceRole {
|
|||
Self::Eyes,
|
||||
Self::HandTrackingLeft,
|
||||
Self::HandTrackingRight,
|
||||
Self::HandheldObject,
|
||||
Self::LeftFoot,
|
||||
Self::RightFoot,
|
||||
Self::LeftShoulder,
|
||||
Self::RightShoulder,
|
||||
Self::LeftElbow,
|
||||
Self::RightElbow,
|
||||
Self::LeftKnee,
|
||||
Self::RightKnee,
|
||||
Self::Waist,
|
||||
Self::Chest,
|
||||
Self::Camera,
|
||||
Self::Keyboard,
|
||||
Self::GenericTracker,
|
||||
]
|
||||
.iter()
|
||||
|
@ -76,6 +119,21 @@ impl XRDeviceRole {
|
|||
Self::Eyes => "eyes",
|
||||
Self::HandTrackingLeft => "hand-tracking-left",
|
||||
Self::HandTrackingRight => "hand-tracking-right",
|
||||
|
||||
Self::HandheldObject => "handheld-object",
|
||||
Self::LeftFoot => "left-foot",
|
||||
Self::RightFoot => "right-foot",
|
||||
Self::LeftShoulder => "left-shoulder",
|
||||
Self::RightShoulder => "right-shoulder",
|
||||
Self::LeftElbow => "left-elbow",
|
||||
Self::RightElbow => "right-elbow",
|
||||
Self::LeftKnee => "left-knee",
|
||||
Self::RightKnee => "right-knee",
|
||||
Self::Waist => "waist",
|
||||
Self::Chest => "chest",
|
||||
Self::Camera => "camera",
|
||||
Self::Keyboard => "keyboard",
|
||||
|
||||
Self::GenericTracker => "generic-tracker", // not actually in monado
|
||||
Self::Other => "other", // not actually in monado
|
||||
}
|
||||
|
@ -90,8 +148,23 @@ impl XRDeviceRole {
|
|||
Self::Eyes => 4,
|
||||
Self::HandTrackingLeft => 5,
|
||||
Self::HandTrackingRight => 6,
|
||||
Self::GenericTracker => 7,
|
||||
Self::Other => 8,
|
||||
|
||||
Self::HandheldObject => 7,
|
||||
Self::LeftFoot => 8,
|
||||
Self::RightFoot => 9,
|
||||
Self::LeftShoulder => 10,
|
||||
Self::RightShoulder => 11,
|
||||
Self::LeftElbow => 12,
|
||||
Self::RightElbow => 13,
|
||||
Self::LeftKnee => 14,
|
||||
Self::RightKnee => 15,
|
||||
Self::Waist => 16,
|
||||
Self::Chest => 17,
|
||||
Self::Camera => 18,
|
||||
Self::Keyboard => 19,
|
||||
|
||||
Self::GenericTracker => 20,
|
||||
Self::Other => 21,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,6 +177,19 @@ impl XRDeviceRole {
|
|||
"eyes" => Some(Self::Eyes),
|
||||
"hand-tracking-left" => Some(Self::HandTrackingLeft),
|
||||
"hand-tracking-right" => Some(Self::HandTrackingRight),
|
||||
"handheld-object" => Some(Self::HandheldObject),
|
||||
"left-foot" => Some(Self::LeftFoot),
|
||||
"right-foot" => Some(Self::RightFoot),
|
||||
"left-shoulder" => Some(Self::LeftShoulder),
|
||||
"right-shoulder" => Some(Self::RightShoulder),
|
||||
"left-elbow" => Some(Self::LeftElbow),
|
||||
"right-elbow" => Some(Self::RightElbow),
|
||||
"left-knee" => Some(Self::LeftKnee),
|
||||
"right-knee" => Some(Self::RightKnee),
|
||||
"waist" => Some(Self::Waist),
|
||||
"chest" => Some(Self::Chest),
|
||||
"camera" => Some(Self::Camera),
|
||||
"keyboard" => Some(Self::Keyboard),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +203,21 @@ impl XRDeviceRole {
|
|||
"Eye Tracking" => Self::Eyes,
|
||||
"Hand tracking left" => Self::HandTrackingLeft,
|
||||
"Hand tracking right" => Self::HandTrackingRight,
|
||||
|
||||
"Handheld object" => Self::HandheldObject,
|
||||
"Left foot" => Self::LeftFoot,
|
||||
"Right foot" => Self::RightFoot,
|
||||
"Left shoulder" => Self::LeftShoulder,
|
||||
"Right shoulder" => Self::RightShoulder,
|
||||
"Left elbow" => Self::LeftElbow,
|
||||
"Right elbow" => Self::RightElbow,
|
||||
"Left knee" => Self::LeftKnee,
|
||||
"Right knee" => Self::RightKnee,
|
||||
"Waist" => Self::Waist,
|
||||
"Chest" => Self::Chest,
|
||||
"Camera" => Self::Camera,
|
||||
"Keyboard" => Self::Keyboard,
|
||||
|
||||
"Generic tracker" => Self::GenericTracker,
|
||||
_ => Self::GenericTracker,
|
||||
}
|
||||
|
@ -179,6 +280,19 @@ impl XRDevice {
|
|||
XRDeviceRole::Right,
|
||||
XRDeviceRole::HandTrackingLeft,
|
||||
XRDeviceRole::HandTrackingRight,
|
||||
XRDeviceRole::HandheldObject,
|
||||
XRDeviceRole::LeftFoot,
|
||||
XRDeviceRole::RightFoot,
|
||||
XRDeviceRole::LeftShoulder,
|
||||
XRDeviceRole::RightShoulder,
|
||||
XRDeviceRole::LeftElbow,
|
||||
XRDeviceRole::RightElbow,
|
||||
XRDeviceRole::LeftKnee,
|
||||
XRDeviceRole::RightKnee,
|
||||
XRDeviceRole::Waist,
|
||||
XRDeviceRole::Chest,
|
||||
XRDeviceRole::Camera,
|
||||
XRDeviceRole::Keyboard,
|
||||
XRDeviceRole::Gamepad,
|
||||
XRDeviceRole::Eyes,
|
||||
]
|
||||
|
|
Loading…
Add table
Reference in a new issue