From a0241c2b24a5fcbd54138738ff891b5636274010 Mon Sep 17 00:00:00 2001 From: ExDe707 Date: Thu, 10 Oct 2024 18:03:53 +0200 Subject: [PATCH] Added xrBinder page with guide on installation and usage --- content/docs/fossvr/xrBinder/_index.md | 115 +++++++++++++++++++++++++ static/images/xrbinder_gui.png | Bin 0 -> 22873 bytes 2 files changed, 115 insertions(+) create mode 100644 content/docs/fossvr/xrBinder/_index.md create mode 100644 static/images/xrbinder_gui.png diff --git a/content/docs/fossvr/xrBinder/_index.md b/content/docs/fossvr/xrBinder/_index.md new file mode 100644 index 0000000..5747aed --- /dev/null +++ b/content/docs/fossvr/xrBinder/_index.md @@ -0,0 +1,115 @@ +--- +weight: 900 +title: xrBinder +--- + +# xrBinder +- [xrBinder GitLab repository](https://gitlab.com/mittorn/xrBinder) +- [xrBinder example_configs](https://gitlab.com/mittorn/xrBinder/-/tree/master/example_configs) + +> xrBinder is an OpenXR binding layer that is designed to manage key bindings for XR applications. It acts as a bridge between input actions and various VR/AR devices, providing a way to map specific hardware inputs to in-game actions. This is particularily useful for when the default mappings of an application may not align with your preferences or specific hardware capabilities. + +{{< hint danger >}} +**Warning** + +xrBinder is still considered alpha-quality and highly experimental. +Certain bindings may not work when they are hard coded to the application, such as the [Index Controller bindings in VRChat](https://docs.vrchat.com/docs/valve-index#binding-customization-notes) for `Jump`, `Mic Toggle`, `Gesture Toggle` and `Action Menu Left / Right`. +{{< /hint >}} + +## Building from source + +The project uses submodules to include dependencies such as imgui. They will need to be initialized and updated after cloning the repository. + +```bash +git clone https://gitlab.com/mittorn/xrBinder.git +cd xrBinder +git submodule update --init --recursive +``` + +It is recommended to create a build subdirectory: + +```bash +mkdir build +cd build +cmake .. +make +``` + +Once building is complete, the shared object (.so file) will be located in the `/XR_APILAYER_NOVENDOR_xr_binder` directory, alongside a few binaries and a `manifest.json`. + +## Importing as an implicit layer + +The [API Layer Interaction documentation for OpenXR](https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/main/specification/loader/api_layer.adoc) states that layers can be either implicit, where they are automatically enabled, and explicit, where they must be manually enabled. We will set this up as an implicit layer for convenience. + +This gives us a choice of directories to copy the contents of the `/XR_APILAYER_NOVENDOR_xr_binder` directory to, assuming the environment variable `XR_API_LAYER_PATH` is not set: + +``` +/usr/local/etc/openxr/1/api_layers/implicit.d +/usr/local/share/openxr/1/api_layers/implicit.d +/etc/openxr/1/api_layers/implicit.d +/usr/share/openxr/1/api_layers/implicit.d +$HOME/.local/share/openxr/1/api_layers/implicit.d +``` + +If the directory structure does not exist, it must be manually recreated. + +Once the files are copied over to the implicit.d directory, make sure to double-check the manifest.json so that it matches the **API Layer Manifest File Format** in the OpenXR API Layer documentation. + +### Example manifest.json + +```json +{ + "file_format_version": "1.0.0", + "api_layer": { + "name": "XR_APILAYER_NOVENDOR_xr_binder", + "disable_environment": "XR_APILAYER_NOVENDOR_xr_binder_DISABLE", + "api_version": "1.0", + "implementation_version": "1", + "description": "Advanced layer for binding actions'", + "library_path": "./libxrBinder_module.so" + } +} + +``` + +## Configuration + +xrBinder reads and stores its configuration in `$XDG_CONFIG_HOME/xrBinder` or `$HOME/.config/xrBinder`. If either directories do not exist, they must be manually created. + +Copy the [example_configs directory](https://gitlab.com/mittorn/xrBinder/-/tree/master/example_configs) from the xrBinder gitlab repository and place it and its contents in the xrBinder config directory. + +Depending on which controllers you use, pick the corresponding .ini template from the `source_templates` subdirectory and append its entire content into the `xrBinder.ini` file. + +## Usage + +To verify if the module was loaded, check your opencomposite logs or your system logs after you've launched your application. If xrBinder was loaded successfully, these two lines should be present as an example: + +``` +[2024-10-10 01:49:03.230] CreateOpenXRBackend:154 - Num layers available: 1 +[2024-10-10 01:49:03.230] CreateOpenXRBackend:162 - Layer: XR_APILAYER_NOVENDOR_xr_binder +``` + +If this is the case, we can begin using xrBinder. You may have noticed these two lines in `xrBinder.ini` which come by default: + +```bash +# UDP port for ipc +serverPort = 9011 +# run ipc_server and gui/cli client if set to bus mode or just client in server +ipcMode = bus +``` + +In this example, we are expected to run the `ipc_server` binary in the implicit.d directory we copied our files from the build into on port 9011 from the terminal. + +```bash +./ipc_server 9011 +``` + +With the server and the application where we want to edit our keybinds running in the Background, we can now use the xrBinder GUI by executing the `client_gui` binary. + +![xrBinder GUI](/images/xrbinder_gui.png "Example usage of xrBinder to bind gesture_toggle to the left A button") + +- Type in the port to connect to (9011 in our case) and hit Connect +- Under the "Windows" expander, click "Session". This will open a new window in the xrBinder GUI. +- Load the data in each tab of the session window +- Choose the action and source to dictate what action to bind the button to, then hit Apply. +- The binding should be applied immediately. You can hit "Update data" below to refresh the list of bindings that have been applied. diff --git a/static/images/xrbinder_gui.png b/static/images/xrbinder_gui.png new file mode 100644 index 0000000000000000000000000000000000000000..8e162c4c291cdf00ca4ef7063b1e313e6fe75a0a GIT binary patch literal 22873 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 Q!A4KxU8Xxze)u`?zwCD5p8x;= literal 0 HcmV?d00001