├── .gitignore ├── Binary ├── Release_openvr1.1.3.zip ├── Release_openvr1.14.15.zip ├── Release_openvr1.3.22.zip └── Release_openvr1.9.16.zip ├── LICENSE ├── OpenVR Tracking Example ├── OpenVR Tracking Example.vcxproj ├── OpenVR Tracking Example.vcxproj.filters ├── OpenVR Tracking Example.vcxproj.user ├── OpenVRTrackingExample.cpp ├── OpenVRTrackingExample.h ├── framework.h ├── main.cpp ├── pathtools_excerpt.cpp ├── pch.cpp ├── pch.h └── targetver.h ├── OpenVRTrackingExample.sln ├── README.md └── openvr-binding-files ├── openvr_tracking_example_actions.json ├── openvr_tracking_example_bindings_knuckles.json ├── openvr_tracking_example_bindings_vive.json ├── openvr_tracking_example_bindings_vive_controller.json └── openvr_tracking_example_bindings_vive_pro.json /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 298 | *.vbp 299 | 300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 301 | *.dsw 302 | *.dsp 303 | 304 | # Visual Studio 6 technical files 305 | *.ncb 306 | *.aps 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # Visual Studio History (VSHistory) files 365 | .vshistory/ 366 | 367 | # BeatPulse healthcheck temp database 368 | healthchecksdb 369 | 370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 371 | MigrationBackup/ 372 | 373 | # Ionide (cross platform F# VS Code tools) working folder 374 | .ionide/ 375 | 376 | # Fody - auto-generated XML schema 377 | FodyWeavers.xsd 378 | 379 | # VS Code files for those working on multiple tools 380 | .vscode/* 381 | !.vscode/settings.json 382 | !.vscode/tasks.json 383 | !.vscode/launch.json 384 | !.vscode/extensions.json 385 | *.code-workspace 386 | 387 | # Local History for Visual Studio Code 388 | .history/ 389 | 390 | # Windows Installer files from build outputs 391 | *.cab 392 | *.msi 393 | *.msix 394 | *.msm 395 | *.msp 396 | 397 | # JetBrains Rider 398 | *.sln.iml 399 | 400 | # OpenVR Tracking Example 401 | Binary/Release*.zip 402 | -------------------------------------------------------------------------------- /Binary/Release_openvr1.1.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omnifinity/OpenVR-Tracking-Example/e409b6936a63e5cb430151abad1d349d803382fe/Binary/Release_openvr1.1.3.zip -------------------------------------------------------------------------------- /Binary/Release_openvr1.14.15.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omnifinity/OpenVR-Tracking-Example/e409b6936a63e5cb430151abad1d349d803382fe/Binary/Release_openvr1.14.15.zip -------------------------------------------------------------------------------- /Binary/Release_openvr1.3.22.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omnifinity/OpenVR-Tracking-Example/e409b6936a63e5cb430151abad1d349d803382fe/Binary/Release_openvr1.3.22.zip -------------------------------------------------------------------------------- /Binary/Release_openvr1.9.16.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Omnifinity/OpenVR-Tracking-Example/e409b6936a63e5cb430151abad1d349d803382fe/Binary/Release_openvr1.9.16.zip -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, Omnifinity 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /OpenVR Tracking Example/OpenVR Tracking Example.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {1C0BD20F-3476-41E0-AD62-8A54E2A51565} 23 | Win32Proj 24 | HTCLighthouseTrackingExample 25 | 10.0 26 | OpenVRTrackingExample 27 | 28 | 29 | 30 | Application 31 | true 32 | v143 33 | MultiByte 34 | 35 | 36 | Application 37 | true 38 | v143 39 | MultiByte 40 | 41 | 42 | Application 43 | false 44 | v143 45 | true 46 | MultiByte 47 | 48 | 49 | Application 50 | false 51 | v143 52 | true 53 | MultiByte 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | true 73 | 74 | 75 | true 76 | openvr_tracking_example 77 | $(Platform)\$(Configuration)\ 78 | 79 | 80 | false 81 | openvr_tracking_example 82 | false 83 | $(SolutionDir)$(Platform)\$(Configuration)\ 84 | $(Platform)\$(Configuration)\ 85 | 86 | 87 | false 88 | openvr_tracking_example 89 | false 90 | $(Platform)\$(Configuration)\ 91 | 92 | 93 | 94 | Use 95 | Level3 96 | Disabled 97 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 98 | true 99 | C:\Users\pt\Documents\Visual Studio 2013\Projects\openvr;C:\Users\pt\Documents\Visual Studio 2013\Projects\openvr\headers;%(AdditionalIncludeDirectories) 100 | 101 | 102 | Console 103 | true 104 | C:\Users\pt\Documents\Visual Studio 2013\Projects\openvr\lib\win32;%(AdditionalLibraryDirectories) 105 | openvr_api.lib;%(AdditionalDependencies) 106 | 107 | 108 | 109 | 110 | NotUsing 111 | Level3 112 | Disabled 113 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 114 | true 115 | $(openvr);$(openvr)\headers;%(AdditionalIncludeDirectories) 116 | pch.h 117 | 118 | 119 | Console 120 | true 121 | $(openvr)\lib\win64;%(AdditionalLibraryDirectories) 122 | openvr_api.lib;%(AdditionalDependencies) 123 | 124 | 125 | 126 | 127 | Level3 128 | Use 129 | MaxSpeed 130 | true 131 | true 132 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 133 | true 134 | C:\Users\pt\Documents\source\repos\openvr;C:\Users\pt\Documents\source\repos\openvr\headers;%(AdditionalIncludeDirectories) 135 | pch.h 136 | 137 | 138 | Console 139 | true 140 | true 141 | true 142 | openvr_api.lib;%(AdditionalDependencies) 143 | C:\Users\pt\Documents\source\repos\openvr\lib\win32;%(AdditionalLibraryDirectories) 144 | 145 | 146 | REM copy /Y "$(TargetPath)" "\\192.168.1.51\Users\Public\dev\R8_v2.3.2-Beta-dev\vive_debugger\$(TargetName)$(TargetExt)" 147 | copy /Y "$(TargetPath)" "\\DESKTOP-GH45UK8\Omnifinity\vive_debugger\$(TargetName)$(TargetExt)" 148 | 149 | 150 | 151 | Copying vive_debugger to alpha directory 152 | 153 | 154 | 155 | 156 | Level3 157 | NotUsing 158 | MaxSpeed 159 | true 160 | true 161 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 162 | true 163 | $(openvr);$(openvr)\headers;%(AdditionalIncludeDirectories) 164 | pch.h 165 | 166 | 167 | Console 168 | true 169 | true 170 | true 171 | openvr_api.lib;%(AdditionalDependencies) 172 | $(openvr)\lib\win64;%(AdditionalLibraryDirectories) 173 | 174 | 175 | REM copy /Y "$(TargetPath)" "\\192.168.1.51\Users\Public\dev\R8_v2.3.2-Beta-dev\vive_debugger\$(TargetName)$(TargetExt)" 176 | copy /Y "$(TargetPath)" "\\DESKTOP-GH45UK8\Omnifinity\vive_debugger\$(TargetName)$(TargetExt)" 177 | 178 | 179 | 180 | Copying vive_debugger to alpha directory 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | -------------------------------------------------------------------------------- /OpenVR Tracking Example/OpenVR Tracking Example.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {fef05b27-6878-4627-bbb5-96585ba14d2f} 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | 49 | 50 | openvr-binding-files 51 | 52 | 53 | openvr-binding-files 54 | 55 | 56 | openvr-binding-files 57 | 58 | 59 | openvr-binding-files 60 | 61 | 62 | openvr-binding-files 63 | 64 | 65 | -------------------------------------------------------------------------------- /OpenVR Tracking Example/OpenVR Tracking Example.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /OpenVR Tracking Example/OpenVRTrackingExample.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | OpenVR-Tracking-Example Copyright 2016-2022 Omnifinity 3 | Example on how to access tracking data from OpenVR 4 | 5 | OpenVR Copyright (c) 2015, Valve Corporation 6 | 7 | All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without modification, 10 | are permitted provided that the following conditions are met : 11 | 12 | 1. Redistributions of source code must retain the above copyright notice, this 13 | list of conditions and the following disclaimer. 14 | 15 | 2. Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation and / or 17 | other materials provided with the distribution. 18 | 19 | 3. Neither the name of the copyright holder nor the names of its contributors 20 | may be used to endorse or promote products derived from this software without 21 | specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 27 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 30 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | #include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier 36 | 37 | #include 38 | 39 | #include "OpenVRTrackingExample.h" 40 | 41 | inline bool fileExists(const std::string& fileName) { 42 | struct stat buff; 43 | return (stat(fileName.c_str(), &buff) == 0); 44 | } 45 | 46 | // Destructor 47 | OpenVRTrackingExample::~OpenVRTrackingExample() { 48 | if (m_pHMD != NULL) 49 | { 50 | vr::VR_Shutdown(); 51 | m_pHMD = NULL; 52 | } 53 | } 54 | 55 | // Constructor 56 | OpenVRTrackingExample::OpenVRTrackingExample() { 57 | 58 | // try to connect with openvr as an background application 59 | vr::EVRInitError eError = vr::VRInitError_None; 60 | m_pHMD = vr::VR_Init(&eError, vr::VRApplication_Background); 61 | char buf[1024]; 62 | 63 | if (eError != vr::VRInitError_None) 64 | { 65 | m_pHMD = NULL; 66 | sprintf_s(buf, sizeof(buf), "Unable to init VR runtime: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError)); 67 | printf_s(buf); 68 | exit(EXIT_FAILURE); 69 | } 70 | 71 | // Ensure VR Compositor is avail, otherwise getting poses causes a crash (openvr v1.3.22) 72 | if (!BInitCompositor()) { 73 | //printf("%s - Failed to initialize VR Compositor!\n", __FUNCTION__); 74 | sprintf_s(buf, sizeof(buf), "%s - Failed to initialize VR Compositor!", __FUNCTION__); 75 | printf_s(buf); 76 | exit(EXIT_FAILURE); 77 | } 78 | else { 79 | sprintf_s(buf, sizeof(buf), "Successfully initialized VR Compositor\n"); 80 | printf_s(buf); 81 | } 82 | 83 | // Prepare manifest file 84 | // TODO: OBSERVE THAT THIS IS HOW THIS UNIQUE PROJECT IS SETUP. 85 | // MAKE SURE THAT YOU SET YOUR PATH RELATIVE TO YOUR EXECUTABLE 86 | const char *manifestPath = "../../openvr-binding-files/openvr_tracking_example_actions.json"; 87 | std::string manifestFileName = Path_MakeAbsolute(manifestPath, Path_StripFilename(Path_GetExecutablePath())); 88 | 89 | // check if file exists before continue 90 | if (!fileExists(manifestFileName)) { 91 | sprintf_s(buf, sizeof(buf), "\nFatal Error: Manifest file does not exist. Tried to load:\n%s\n\n", manifestFileName.c_str()); 92 | printf_s(buf); 93 | exit(EXIT_FAILURE); 94 | } 95 | 96 | vr::EVRInputError inputError = vr::VRInput()->SetActionManifestPath(manifestFileName.c_str()); 97 | if (inputError != vr::VRInputError_None) { 98 | sprintf_s(buf, sizeof(buf), "Error: Unable to set manifest path: %d\n", inputError); 99 | printf_s(buf); 100 | } 101 | else { 102 | sprintf_s(buf, sizeof(buf), "Successfully using manifest path: %s\n", manifestFileName.c_str()); 103 | printf_s(buf); 104 | } 105 | 106 | // Handles for the new IVRInput 107 | inputError = vr::VRInput()->GetActionSetHandle(actionSetDemoPath, &m_actionSetDemo); 108 | if (inputError != vr::VRInputError_None) { 109 | sprintf_s(buf, sizeof(buf), "Error: Unable to get action set handle: %d\n", inputError); 110 | printf_s(buf); 111 | } 112 | else { 113 | sprintf_s(buf, sizeof(buf), "Successfully got %s action set handle: %d\n", actionSetDemoPath, (int)m_actionSetDemo); 114 | printf_s(buf); 115 | } 116 | 117 | // handle for left controller pose 118 | inputError = vr::VRInput()->GetActionHandle(actionDemoHandLeftPath, &m_actionDemoHandLeft); 119 | if (inputError != vr::VRInputError_None) { 120 | sprintf_s(buf, sizeof(buf), "Error: Unable to get action handle: %d\n", inputError); 121 | printf_s(buf); 122 | } 123 | else { 124 | sprintf_s(buf, sizeof(buf), "Successfully got %s handle: %d\n", actionDemoHandLeftPath, (int)m_actionDemoHandLeft); 125 | printf_s(buf); 126 | } 127 | 128 | // handle for right controller pose 129 | inputError = vr::VRInput()->GetActionHandle(actionDemoHandRightPath, &m_actionDemoHandRight); 130 | if (inputError != vr::VRInputError_None) { 131 | sprintf_s(buf, sizeof(buf), "Error: Unable to get action handle: %d\n", inputError); 132 | printf_s(buf); 133 | } 134 | else { 135 | sprintf_s(buf, sizeof(buf), "Successfully got %s handle: %d\n", actionDemoHandRightPath, (int)m_actionDemoHandRight); 136 | printf_s(buf); 137 | } 138 | 139 | // handle for analog trackpad action 140 | inputError = vr::VRInput()->GetActionHandle(actionDemoAnalogInputPath, &m_actionAnalogInput); 141 | if (inputError != vr::VRInputError_None) { 142 | sprintf_s(buf, sizeof(buf), "Error: Unable to get action handle: %d\n", inputError); 143 | printf_s(buf); 144 | } 145 | else { 146 | sprintf_s(buf, sizeof(buf), "Successfully got %s handle: %d\n", actionDemoAnalogInputPath, (int)m_actionAnalogInput); 147 | printf_s(buf); 148 | } 149 | 150 | // handle for a hide cube action 151 | inputError = vr::VRInput()->GetActionHandle(actionDemoHideCubesPath, &m_actionHideCubes); 152 | if (inputError != vr::VRInputError_None) { 153 | sprintf_s(buf, sizeof(buf), "Error: Unable to get action handle: %d\n", inputError); 154 | printf_s(buf); 155 | } 156 | else { 157 | sprintf_s(buf, sizeof(buf), "Successfully got %s handle: %d\n", actionDemoHideCubesPath, (int)m_actionHideCubes); 158 | printf_s(buf); 159 | } 160 | 161 | // handle for a touch action 162 | inputError = vr::VRInput()->GetActionHandle(actionDemoTouchPath, &m_actionTouch); 163 | if (inputError != vr::VRInputError_None) { 164 | sprintf_s(buf, sizeof(buf), "Error: Unable to get action handle: %d\n", inputError); 165 | printf_s(buf); 166 | } 167 | else { 168 | sprintf_s(buf, sizeof(buf), "Successfully got %s handle: %d\n", actionDemoTouchPath, (int)m_actionTouch); 169 | printf_s(buf); 170 | } 171 | 172 | // handle for a click action 173 | inputError = vr::VRInput()->GetActionHandle(actionDemoClickPath, &m_actionClick); 174 | if (inputError != vr::VRInputError_None) { 175 | sprintf_s(buf, sizeof(buf), "Error: Unable to get action handle: %d\n", inputError); 176 | printf_s(buf); 177 | } 178 | else { 179 | sprintf_s(buf, sizeof(buf), "Successfully got %s handle: %d\n", actionDemoClickPath, (int)m_actionClick); 180 | printf_s(buf); 181 | } 182 | 183 | // handle for controller pose source - not used atm 184 | inputError = vr::VRInput()->GetInputSourceHandle(inputHandLeftPath, &m_inputHandLeftPath); 185 | if (inputError != vr::VRInputError_None) { 186 | sprintf_s(buf, sizeof(buf), "Error: Unable to get input handle: %d\n", inputError); 187 | printf_s(buf); 188 | } 189 | else { 190 | sprintf_s(buf, sizeof(buf), "Successfully got %s input handle: %d\n", inputHandLeftPath, (int)m_inputHandLeftPath); 191 | printf_s(buf); 192 | } 193 | 194 | inputError = vr::VRInput()->GetInputSourceHandle(inputHandRightPath, &m_inputHandRightPath); 195 | if (inputError != vr::VRInputError_None) { 196 | sprintf_s(buf, sizeof(buf), "Error: Unable to get input handle: %d\n", inputError); 197 | printf_s(buf); 198 | } 199 | else { 200 | sprintf_s(buf, sizeof(buf), "Successfully got %s input handle: %d\n", inputHandRightPath, (int)m_inputHandRightPath); 201 | printf_s(buf); 202 | } 203 | } 204 | 205 | //----------------------------------------------------------------------------- 206 | // Purpose: Initialize Compositor. Returns true if the compositor was 207 | // successfully initialized, false otherwise. 208 | //----------------------------------------------------------------------------- 209 | bool OpenVRTrackingExample::BInitCompositor() 210 | { 211 | vr::EVRInitError peError = vr::VRInitError_None; 212 | 213 | if (!vr::VRCompositor()) 214 | { 215 | printf("Compositor initialization failed. See log file for details\n"); 216 | return false; 217 | } 218 | 219 | return true; 220 | } 221 | 222 | /* 223 | * Loop-listen for events then parses them (e.g. prints the to user) 224 | * Supply a filterIndex other than -1 to show only info for that device in question. e.g. 0 is always the hmd. 225 | * Returns true if success or false if openvr has quit 226 | */ 227 | bool OpenVRTrackingExample::RunProcedure(bool bWaitForEvents, int filterIndex = -1) { 228 | 229 | 230 | // check if HMD is connected or not 231 | if (!m_pHMD->IsTrackedDeviceConnected(0)) { 232 | char buf[1024]; 233 | sprintf_s(buf, sizeof(buf), "(OpenVR) HMD Not Connected\n"); 234 | printf_s(buf); 235 | return false; 236 | } 237 | 238 | // Either A) wait for events, such as hand controller button press, before parsing... 239 | if (bWaitForEvents) { 240 | // Process VREvent 241 | vr::VREvent_t event; 242 | while (m_pHMD->PollNextEvent(&event, sizeof(event))) 243 | { 244 | // Process event 245 | if (!ProcessVREvent(event, filterIndex)) { 246 | char buf[1024]; 247 | sprintf_s(buf, sizeof(buf), "\n\n(OpenVR) service quit?\n"); 248 | printf_s(buf); 249 | //return false; 250 | } 251 | 252 | // parse a frame 253 | //ParseTrackingFrame(filterIndex); 254 | } 255 | } 256 | else { 257 | // ... or B) continous parsint of tracking data irrespective of events 258 | //std::cout << std::endl << "Parsing next frame..."; 259 | 260 | ParseTrackingFrame(filterIndex); 261 | } 262 | 263 | return true; 264 | } 265 | 266 | //----------------------------------------------------------------------------- 267 | // Purpose: Processes a single VR event 268 | //----------------------------------------------------------------------------- 269 | 270 | bool OpenVRTrackingExample::ProcessVREvent(const vr::VREvent_t & event, int filterOutIndex = -1) 271 | { 272 | // if user supplied a device filter index only show events for that device 273 | if (filterOutIndex != -1) 274 | if (event.trackedDeviceIndex == filterOutIndex) 275 | return true; 276 | 277 | // print stuff for various events (this is not a complete list). Add/remove upon your own desire... 278 | switch (event.eventType) 279 | { 280 | case vr::VREvent_TrackedDeviceActivated: 281 | { 282 | //SetupRenderModelForTrackedDevice(event.trackedDeviceIndex); 283 | char buf[1024]; 284 | sprintf_s(buf, sizeof(buf), "(OpenVR) Device : %d attached\n", event.trackedDeviceIndex); 285 | printf_s(buf); 286 | } 287 | break; 288 | 289 | case vr::VREvent_TrackedDeviceDeactivated: 290 | { 291 | char buf[1024]; 292 | sprintf_s(buf, sizeof(buf), "(OpenVR) Device : %d detached\n", event.trackedDeviceIndex); 293 | printf_s(buf); 294 | } 295 | break; 296 | 297 | case vr::VREvent_TrackedDeviceUpdated: 298 | { 299 | char buf[1024]; 300 | sprintf_s(buf, sizeof(buf), "(OpenVR) Device : %d updated\n", event.trackedDeviceIndex); 301 | printf_s(buf); 302 | } 303 | break; 304 | 305 | case (vr::VREvent_DashboardActivated) : 306 | { 307 | char buf[1024]; 308 | sprintf_s(buf, sizeof(buf), "(OpenVR) Dashboard activated\n"); 309 | printf_s(buf); 310 | } 311 | break; 312 | 313 | case (vr::VREvent_DashboardDeactivated) : 314 | { 315 | char buf[1024]; 316 | sprintf_s(buf, sizeof(buf), "(OpenVR) Dashboard deactivated\n"); 317 | printf_s(buf); 318 | 319 | } 320 | break; 321 | 322 | case (vr::VREvent_ChaperoneDataHasChanged) : 323 | { 324 | char buf[1024]; 325 | sprintf_s(buf, sizeof(buf), "(OpenVR) Chaperone data has changed\n"); 326 | printf_s(buf); 327 | 328 | } 329 | break; 330 | 331 | case (vr::VREvent_ChaperoneSettingsHaveChanged) : 332 | { 333 | char buf[1024]; 334 | sprintf_s(buf, sizeof(buf), "(OpenVR) Chaperone settings have changed\n"); 335 | printf_s(buf); 336 | } 337 | break; 338 | 339 | case (vr::VREvent_ChaperoneUniverseHasChanged) : 340 | { 341 | char buf[1024]; 342 | sprintf_s(buf, sizeof(buf), "(OpenVR) Chaperone universe has changed\n"); 343 | printf_s(buf); 344 | 345 | } 346 | break; 347 | 348 | case (vr::VREvent_Quit) : 349 | { 350 | char buf[1024]; 351 | sprintf_s(buf, sizeof(buf), "(OpenVR) VREvent_Quit\n"); 352 | printf_s(buf); 353 | 354 | return false; 355 | } 356 | break; 357 | 358 | case (vr::VREvent_ProcessQuit) : 359 | { 360 | char buf[1024]; 361 | sprintf_s(buf, sizeof(buf), "(OpenVR) VREvent_ProcessQuit\n"); 362 | printf_s(buf); 363 | 364 | return false; 365 | } 366 | break; 367 | 368 | case (vr::VREvent_QuitAcknowledged) : 369 | { 370 | char buf[1024]; 371 | sprintf_s(buf, sizeof(buf), "(OpenVR) QuitAcknowledged\n"); 372 | printf_s(buf); 373 | 374 | return false; 375 | } 376 | break; 377 | 378 | case (vr::VREvent_TrackedDeviceRoleChanged) : 379 | { 380 | 381 | char buf[1024]; 382 | sprintf_s(buf, sizeof(buf), "(OpenVR) TrackedDeviceRoleChanged: %d\n", event.trackedDeviceIndex); 383 | printf_s(buf); 384 | } 385 | break; 386 | 387 | case (vr::VREvent_TrackedDeviceUserInteractionStarted) : 388 | { 389 | char buf[1024]; 390 | sprintf_s(buf, sizeof(buf), "(OpenVR) TrackedDeviceUserInteractionStarted: %d\n", event.trackedDeviceIndex); 391 | printf_s(buf); 392 | } 393 | break; 394 | 395 | // various events not handled/moved yet into the previous switch chunk. 396 | default: { 397 | char buf[1024]; 398 | switch (event.eventType) { 399 | case vr::EVREventType::VREvent_ButtonTouch: 400 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Touch Device: %d\n", event.trackedDeviceIndex); 401 | printf_s(buf); 402 | break; 403 | case vr::EVREventType::VREvent_ButtonUntouch: 404 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Untouch Device: %d\n", event.trackedDeviceIndex); 405 | printf_s(buf); 406 | break; 407 | case vr::EVREventType::VREvent_ButtonPress: { 408 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Press Device: %d\n", event.trackedDeviceIndex); 409 | printf_s(buf); 410 | 411 | vr::VREvent_Data_t vrevent_data = event.data; 412 | vr::VREvent_Controller_t vrevent_controller = vrevent_data.controller; 413 | sprintf_s(buf, sizeof(buf), "(OpenVR) controller button: %d\n", vrevent_controller.button); 414 | printf_s(buf); 415 | } 416 | break; 417 | case vr::EVREventType::VREvent_ButtonUnpress: 418 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Release Device: %d\n", event.trackedDeviceIndex); 419 | printf_s(buf); 420 | break; 421 | case vr::EVREventType::VREvent_EnterStandbyMode: 422 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Enter StandbyMode: %d\n", event.trackedDeviceIndex); 423 | printf_s(buf); 424 | break; 425 | case vr::EVREventType::VREvent_LeaveStandbyMode: 426 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Leave StandbyMode: %d\n", event.trackedDeviceIndex); 427 | printf_s(buf); 428 | break; 429 | case vr::EVREventType::VREvent_StatusUpdate: 430 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Status Update: %d\n", event.trackedDeviceIndex); 431 | printf_s(buf); 432 | break; 433 | case vr::EVREventType::VREvent_PropertyChanged: 434 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Property Changed Device: %d\n", event.trackedDeviceIndex); 435 | printf_s(buf); 436 | break; 437 | 438 | case vr::EVREventType::VREvent_SceneApplicationChanged: 439 | { 440 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Scene Application Changed\n"); 441 | printf_s(buf); 442 | 443 | sprintf_s(buf, sizeof(buf), "(OpenVR) old pid: %d new pid: %d\n", event.data.process.oldPid, event.data.process.pid); 444 | printf_s(buf); 445 | 446 | // Another way of getting the current scene application (can be called anytime) 447 | uint32_t pid = vr::VRApplications()->GetCurrentSceneProcessId(); 448 | sprintf_s(buf, sizeof(buf), "(OpenVR) vr::VRApplications()->GetCurrentSceneProcessId() pid: %d\n", pid); 449 | printf_s(buf); 450 | 451 | // Request and show its steam app key 452 | vr::EVRApplicationError eError = vr::VRApplications()->GetApplicationKeyByProcessId(pid, applicationKey, vr::k_unMaxApplicationKeyLength); 453 | sprintf_s(buf, sizeof(buf), "(OpenVR) vr::VRApplications()->GetApplicationKeyByProcessId() key: %s\n", applicationKey); 454 | printf_s(buf); 455 | 456 | } 457 | break; 458 | 459 | case vr::EVREventType::VREvent_SceneFocusChanged: 460 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Scene Focus Changed\n"); 461 | printf_s(buf); 462 | 463 | sprintf_s(buf, sizeof(buf), "(OpenVR) old pid: %d new pid: %d\n", event.data.process.oldPid, event.data.process.pid); 464 | printf_s(buf); 465 | break; 466 | 467 | case vr::EVREventType::VREvent_TrackedDeviceUserInteractionStarted: 468 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Tracked Device User Interaction Started Device: %d\n", event.trackedDeviceIndex); 469 | printf_s(buf); 470 | break; 471 | case vr::EVREventType::VREvent_TrackedDeviceUserInteractionEnded: 472 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Tracked Device User Interaction Ended Device: %d\n", event.trackedDeviceIndex); 473 | printf_s(buf); 474 | break; 475 | 476 | case vr::EVREventType::VREvent_ProcessDisconnected: 477 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: A process was disconnected\n"); 478 | printf_s(buf); 479 | break; 480 | case vr::EVREventType::VREvent_ProcessConnected: 481 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: A process was connected\n"); 482 | printf_s(buf); 483 | break; 484 | 485 | case vr::VREvent_Compositor_ApplicationNotResponding: 486 | sprintf_s(buf, sizeof(buf), "(OpenVR) Compositor: Application Not Responding\n"); 487 | printf_s(buf); 488 | break; 489 | case vr::VREvent_Compositor_ApplicationResumed: 490 | sprintf_s(buf, sizeof(buf), "(OpenVR) Compositor: Application Resumed\n"); 491 | printf_s(buf); 492 | break; 493 | case vr::VRInitError_Compositor_FirmwareRequiresUpdate: 494 | sprintf_s(buf, sizeof(buf), "(OpenVR) Compositor: Firmware Requires Update\n"); 495 | printf_s(buf); 496 | break; 497 | case vr::VRInitError_Compositor_SettingsInterfaceIsNull: 498 | sprintf_s(buf, sizeof(buf), "(OpenVR) Compositor: Settings Interface Is Null\n"); 499 | printf_s(buf); 500 | break; 501 | case vr::VRInitError_Compositor_MessageOverlaySharedStateInitFailure: 502 | sprintf_s(buf, sizeof(buf), "(OpenVR) Compositor: Message Overlay Shared State Init Failure\n"); 503 | printf_s(buf); 504 | break; 505 | 506 | case vr::VREvent_Input_BindingLoadFailed: 507 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Input: Binding Load Failed\n"); 508 | printf_s(buf); 509 | break; 510 | case vr::VREvent_Input_BindingLoadSuccessful: 511 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Input: Binding Load Sucessful\n"); 512 | printf_s(buf); 513 | break; 514 | case vr::VREvent_Input_ActionManifestReloaded: 515 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Input: Action Manifest Reloaded\n"); 516 | printf_s(buf); 517 | break; 518 | 519 | case vr::VREvent_Input_HapticVibration: 520 | sprintf_s(buf, sizeof(buf), "(OpenVR) Event: Input: Haptic Vibration. Component Handle: %d Container Handle: %d Duration: %f Amplitude: %f Frequency: %f\n", (int)event.data.hapticVibration.componentHandle, (int)event.data.hapticVibration.containerHandle, event.data.hapticVibration.fDurationSeconds, event.data.hapticVibration.fAmplitude, event.data.hapticVibration.fFrequency); 521 | printf_s(buf); 522 | break; 523 | 524 | default: 525 | sprintf_s(buf, sizeof(buf), "(OpenVR) Unmanaged Event: %d Device: %d\n", event.eventType, event.trackedDeviceIndex); 526 | printf_s(buf); 527 | break; 528 | } 529 | } 530 | break; 531 | } 532 | 533 | return true; 534 | } 535 | 536 | 537 | // Get the quaternion representing the rotation 538 | vr::HmdQuaternion_t OpenVRTrackingExample::GetRotation(vr::HmdMatrix34_t matrix) { 539 | vr::HmdQuaternion_t q; 540 | 541 | q.w = sqrt(fmax(0, 1 + matrix.m[0][0] + matrix.m[1][1] + matrix.m[2][2])) / 2; 542 | q.x = sqrt(fmax(0, 1 + matrix.m[0][0] - matrix.m[1][1] - matrix.m[2][2])) / 2; 543 | q.y = sqrt(fmax(0, 1 - matrix.m[0][0] + matrix.m[1][1] - matrix.m[2][2])) / 2; 544 | q.z = sqrt(fmax(0, 1 - matrix.m[0][0] - matrix.m[1][1] + matrix.m[2][2])) / 2; 545 | q.x = copysign(q.x, matrix.m[2][1] - matrix.m[1][2]); 546 | q.y = copysign(q.y, matrix.m[0][2] - matrix.m[2][0]); 547 | q.z = copysign(q.z, matrix.m[1][0] - matrix.m[0][1]); 548 | return q; 549 | } 550 | 551 | // Get the vector representing the position 552 | vr::HmdVector3_t OpenVRTrackingExample::GetPosition(vr::HmdMatrix34_t matrix) { 553 | vr::HmdVector3_t vector; 554 | 555 | vector.v[0] = matrix.m[0][3]; 556 | vector.v[1] = matrix.m[1][3]; 557 | vector.v[2] = matrix.m[2][3]; 558 | 559 | return vector; 560 | } 561 | 562 | void OpenVRTrackingExample::StoreLeftControllerPosition(vr::HmdVector3_t vector) { 563 | m_vecLeftController.v[0] = vector.v[0]; 564 | m_vecLeftController.v[1] = vector.v[1]; 565 | m_vecLeftController.v[2] = vector.v[2]; 566 | } 567 | 568 | void OpenVRTrackingExample::StoreRightControllerPosition(vr::HmdVector3_t vector) { 569 | m_vecRightController.v[0] = vector.v[0]; 570 | m_vecRightController.v[1] = vector.v[1]; 571 | m_vecRightController.v[2] = vector.v[2]; 572 | } 573 | 574 | vr::HmdVector3_t OpenVRTrackingExample::GetLeftControllerPosition() { 575 | return m_vecLeftController; 576 | } 577 | 578 | vr::HmdVector3_t OpenVRTrackingExample::GetRightControllerPosition() { 579 | return m_vecRightController; 580 | } 581 | 582 | 583 | vr::HmdVector3_t OpenVRTrackingExample::GetControllerPositionDelta() { 584 | vr::HmdVector3_t vecDiff; 585 | vecDiff.v[0] = m_vecLeftController.v[0] - m_vecRightController.v[0]; 586 | vecDiff.v[1] = m_vecLeftController.v[1] - m_vecRightController.v[1]; 587 | vecDiff.v[2] = m_vecLeftController.v[2] - m_vecRightController.v[2]; 588 | return vecDiff; 589 | } 590 | 591 | /* 592 | * Parse a Frame with data from the tracking system 593 | * 594 | * Handy reference: 595 | * https://github.com/TomorrowTodayLabs/NewtonVR/blob/master/Assets/SteamVR/Scripts/SteamVR_Utils.cs 596 | * 597 | * Also: 598 | * Open VR Convention (same as OpenGL) 599 | * right-handed system 600 | * +y is up 601 | * +x is to the right 602 | * -z is going away from you 603 | * http://www.3dgep.com/understanding-the-view-matrix/ 604 | * 605 | */ 606 | void OpenVRTrackingExample::ParseTrackingFrame(int filterIndex) { 607 | 608 | char buf[1024]; 609 | vr::EVRInputError inputError; 610 | 611 | sprintf_s(buf, sizeof(buf), "\n"); 612 | printf_s(buf); 613 | 614 | // Process SteamVR action state 615 | // UpdateActionState is called each frame to update the state of the actions themselves. The application 616 | // controls which action sets are active with the provided array of VRActiveActionSet_t structs. 617 | vr::VRActiveActionSet_t actionSet = { 0 }; 618 | actionSet.ulActionSet = m_actionSetDemo; 619 | inputError = vr::VRInput()->UpdateActionState(&actionSet, sizeof(actionSet), 1); 620 | if (inputError == vr::VRInputError_None) { 621 | sprintf_s(buf, sizeof(buf), "%s | UpdateActionState(): Ok\n", actionSetDemoPath); 622 | printf_s(buf); 623 | } 624 | else { 625 | sprintf_s(buf, sizeof(buf), "%s | UpdateActionState(): Error: %d\n", actionSetDemoPath, inputError); 626 | printf_s(buf); 627 | } 628 | 629 | // Get analog data 630 | vr::InputAnalogActionData_t analogData; 631 | inputError = vr::VRInput()->GetAnalogActionData(m_actionAnalogInput, &analogData, sizeof(analogData), vr::k_ulInvalidInputValueHandle); 632 | if (inputError == vr::VRInputError_None) 633 | { 634 | sprintf_s(buf, sizeof(buf), "%s | GetAnalogActionData() Ok\n", actionDemoAnalogInputPath); 635 | printf_s(buf); 636 | 637 | if (analogData.bActive) { 638 | float m_vAnalogValue0 = analogData.x; 639 | float m_vAnalogValue1 = analogData.y; 640 | sprintf_s(buf, sizeof(buf), "%s | x: %f y:%f\n", actionDemoAnalogInputPath, m_vAnalogValue0, m_vAnalogValue1); 641 | printf_s(buf); 642 | } 643 | else { 644 | sprintf_s(buf, sizeof(buf), "%s | action not avail to be bound\n", actionDemoAnalogInputPath); 645 | printf_s(buf); 646 | } 647 | } 648 | else { 649 | sprintf_s(buf, sizeof(buf), "%s | GetAnalogActionData() Not Ok. Error: %d\n", actionDemoAnalogInputPath, inputError); 650 | printf_s(buf); 651 | } 652 | 653 | 654 | // Get digital data 655 | vr::InputDigitalActionData_t digitalData; 656 | inputError = vr::VRInput()->GetDigitalActionData(m_actionHideCubes, &digitalData, sizeof(digitalData), vr::k_ulInvalidInputValueHandle); 657 | if (inputError == vr::VRInputError_None) 658 | { 659 | sprintf_s(buf, sizeof(buf), "%s | GetDigitalActionData() Ok\n", actionDemoHideCubesPath); 660 | printf_s(buf); 661 | 662 | if (digitalData.bActive) { 663 | bool m_vDigitalValue0 = digitalData.bState; 664 | sprintf_s(buf, sizeof(buf), "%s | State: %d\n", actionDemoHideCubesPath, m_vDigitalValue0); 665 | printf_s(buf); 666 | 667 | // check from which device the action came 668 | vr::InputOriginInfo_t originInfo; 669 | if (vr::VRInputError_None == vr::VRInput()->GetOriginTrackedDeviceInfo(digitalData.activeOrigin, &originInfo, sizeof(originInfo))) 670 | { 671 | if (originInfo.devicePath == m_inputHandLeftPath) { 672 | sprintf_s(buf, sizeof(buf), "Action comes from left hand\n"); 673 | printf_s(buf); 674 | } else if (originInfo.devicePath == m_inputHandRightPath) { 675 | sprintf_s(buf, sizeof(buf), "Action comes from right hand\n"); 676 | printf_s(buf); 677 | } 678 | } 679 | 680 | } 681 | else { 682 | sprintf_s(buf, sizeof(buf), "%s | action not avail to be bound\n", actionDemoHideCubesPath); 683 | printf_s(buf); 684 | } 685 | } 686 | else { 687 | sprintf_s(buf, sizeof(buf), "%s | GetDigitalActionData() Not Ok. Error: %d\n", actionDemoHideCubesPath, inputError); 688 | printf_s(buf); 689 | } 690 | 691 | // Get digital data of a "Touch Action" 692 | vr::InputDigitalActionData_t digitalDataTouch; 693 | inputError = vr::VRInput()->GetDigitalActionData(m_actionTouch, &digitalDataTouch, sizeof(digitalDataTouch), vr::k_ulInvalidInputValueHandle); 694 | if (inputError == vr::VRInputError_None) 695 | { 696 | sprintf_s(buf, sizeof(buf), "%s | GetDigitalActionData() Ok\n", actionDemoTouchPath); 697 | printf_s(buf); 698 | 699 | if (digitalDataTouch.bActive) { 700 | bool m_vDigitalValue0 = digitalDataTouch.bState; 701 | sprintf_s(buf, sizeof(buf), "%s | State: %d\n", actionDemoTouchPath, m_vDigitalValue0); 702 | printf_s(buf); 703 | 704 | // check from which device the action came 705 | vr::InputOriginInfo_t originInfo; 706 | if (vr::VRInputError_None == vr::VRInput()->GetOriginTrackedDeviceInfo(digitalDataTouch.activeOrigin, &originInfo, sizeof(originInfo))) 707 | { 708 | if (originInfo.devicePath == m_inputHandLeftPath) { 709 | sprintf_s(buf, sizeof(buf), "Action comes from left hand\n"); 710 | printf_s(buf); 711 | } 712 | else if (originInfo.devicePath == m_inputHandRightPath) { 713 | sprintf_s(buf, sizeof(buf), "Action comes from right hand\n"); 714 | printf_s(buf); 715 | } 716 | } 717 | 718 | } 719 | else { 720 | sprintf_s(buf, sizeof(buf), "%s | action not avail to be bound\n", actionDemoTouchPath); 721 | printf_s(buf); 722 | } 723 | } 724 | else { 725 | sprintf_s(buf, sizeof(buf), "%s | GetDigitalActionData() Not Ok. Error: %d\n", actionDemoTouchPath, inputError); 726 | printf_s(buf); 727 | } 728 | 729 | // Get digital data of a "Click Action" 730 | vr::InputDigitalActionData_t digitalDataClick; 731 | inputError = vr::VRInput()->GetDigitalActionData(m_actionClick, &digitalDataClick, sizeof(digitalDataClick), vr::k_ulInvalidInputValueHandle); 732 | if (inputError == vr::VRInputError_None) 733 | { 734 | sprintf_s(buf, sizeof(buf), "%s | GetDigitalActionData() Ok\n", actionDemoClickPath); 735 | printf_s(buf); 736 | 737 | if (digitalDataClick.bActive) { 738 | bool m_vDigitalValue0 = digitalDataClick.bState; 739 | sprintf_s(buf, sizeof(buf), "%s | State: %d\n", actionDemoClickPath, m_vDigitalValue0); 740 | printf_s(buf); 741 | 742 | // check from which device the action came 743 | vr::InputOriginInfo_t originInfo; 744 | if (vr::VRInputError_None == vr::VRInput()->GetOriginTrackedDeviceInfo(digitalDataClick.activeOrigin, &originInfo, sizeof(originInfo))) 745 | { 746 | if (originInfo.devicePath == m_inputHandLeftPath) { 747 | sprintf_s(buf, sizeof(buf), "Action comes from left hand\n"); 748 | printf_s(buf); 749 | } 750 | else if (originInfo.devicePath == m_inputHandRightPath) { 751 | sprintf_s(buf, sizeof(buf), "Action comes from right hand\n"); 752 | printf_s(buf); 753 | } 754 | } 755 | 756 | } 757 | else { 758 | sprintf_s(buf, sizeof(buf), "%s | action not avail to be bound\n", actionDemoClickPath); 759 | printf_s(buf); 760 | } 761 | } 762 | else { 763 | sprintf_s(buf, sizeof(buf), "%s | GetDigitalActionData() Not Ok. Error: %d\n", actionDemoClickPath, inputError); 764 | printf_s(buf); 765 | } 766 | 767 | 768 | // get pose data 769 | vr::InputPoseActionData_t poseData; 770 | inputError = vr::VRInput()->GetPoseActionDataForNextFrame(m_actionDemoHandLeft, vr::TrackingUniverseStanding, &poseData, sizeof(poseData), vr::k_ulInvalidInputValueHandle); 771 | if (inputError == vr::VRInputError_None) { 772 | sprintf_s(buf, sizeof(buf), "%s | GetPoseActionData() Ok\n", actionDemoHandLeftPath); 773 | printf_s(buf); 774 | 775 | if (poseData.bActive) { 776 | vr::VRInputValueHandle_t activeOrigin = poseData.activeOrigin; 777 | bool bPoseIsValid = poseData.pose.bPoseIsValid; 778 | bool bDeviceIsConnected = poseData.pose.bDeviceIsConnected; 779 | sprintf_s(buf, sizeof(buf), "Origin: %d Validity: %d DeviceIsConnected: %d\n", (int)activeOrigin, bPoseIsValid, bDeviceIsConnected); 780 | printf_s(buf); 781 | 782 | 783 | /* Code below is old ---> */ 784 | vr::HmdVector3_t position; 785 | vr::HmdQuaternion_t quaternion; 786 | 787 | // get the position and rotation 788 | position = GetPosition(poseData.pose.mDeviceToAbsoluteTracking); 789 | quaternion = GetRotation(poseData.pose.mDeviceToAbsoluteTracking); 790 | 791 | // print the tracking data 792 | //if (printHmdTrackingData) { 793 | sprintf_s(buf, sizeof(buf), "\n%s Pose\nx: %.2f y: %.2f z: %.2f\n", actionDemoHandLeftPath, position.v[0], position.v[1], position.v[2]); 794 | printf_s(buf); 795 | sprintf_s(buf, sizeof(buf), "qw: %.2f qx: %.2f qy: %.2f qz: %.2f\n", quaternion.w, quaternion.x, quaternion.y, quaternion.z); 796 | printf_s(buf); 797 | //} 798 | /* <--- End of old code */ 799 | 800 | 801 | } 802 | else { 803 | sprintf_s(buf, sizeof(buf), "%s | action not avail to be bound\n", actionDemoHandLeftPath); 804 | printf_s(buf); 805 | } 806 | } 807 | else { 808 | sprintf_s(buf, sizeof(buf), "%s | GetPoseActionData() Call Not Ok. Error: %d\n", actionDemoHandLeftPath, inputError); 809 | printf_s(buf); 810 | } 811 | } 812 | 813 | void OpenVRTrackingExample::PrintDevices() { 814 | 815 | char buf[1024]; 816 | sprintf_s(buf, sizeof(buf), "\nDevice list:\n---------------------------\n"); 817 | printf_s(buf); 818 | 819 | // Loop over all conntected devices and print some stuff about them 820 | for (vr::TrackedDeviceIndex_t unDevice = 0; unDevice < vr::k_unMaxTrackedDeviceCount; unDevice++) 821 | { 822 | // if no HMD is connected in slot 0 just skip the rest of the code 823 | // since a HMD must be present. 824 | if (!m_pHMD->IsTrackedDeviceConnected(unDevice)) 825 | continue; 826 | 827 | // Get what type of device it is and work with its data 828 | vr::ETrackedDeviceClass trackedDeviceClass = vr::VRSystem()->GetTrackedDeviceClass(unDevice); 829 | switch (trackedDeviceClass) { 830 | case vr::ETrackedDeviceClass::TrackedDeviceClass_Invalid: 831 | // do stuff for an invalid class 832 | 833 | sprintf_s(buf, sizeof(buf), "Device %d: Class: [Invalid]", unDevice); 834 | printf_s(buf); 835 | break; 836 | 837 | case vr::ETrackedDeviceClass::TrackedDeviceClass_HMD: 838 | // print stuff for the HMD here, see controller stuff in next case block 839 | 840 | char buf[1024]; 841 | sprintf_s(buf, sizeof(buf), "Device %d: Class: [HMD]", unDevice); 842 | printf_s(buf); 843 | break; 844 | 845 | case vr::ETrackedDeviceClass::TrackedDeviceClass_Controller: 846 | // do stuff for a controller here 847 | sprintf_s(buf, sizeof(buf), "Device %d: Class: [Controller]", unDevice); 848 | printf_s(buf); 849 | 850 | break; 851 | 852 | case vr::ETrackedDeviceClass::TrackedDeviceClass_GenericTracker: 853 | // do stuff for a generic tracker here 854 | 855 | sprintf_s(buf, sizeof(buf), "Device %d: Class: [GenericTracker]", unDevice); 856 | printf_s(buf); 857 | break; 858 | 859 | case vr::ETrackedDeviceClass::TrackedDeviceClass_TrackingReference: 860 | /// do stuff for a tracking reference here 861 | 862 | sprintf_s(buf, sizeof(buf), "Device %d: Class: [TrackingReference]", unDevice); 863 | printf_s(buf); 864 | break; 865 | 866 | case vr::ETrackedDeviceClass::TrackedDeviceClass_DisplayRedirect: 867 | /// do stuff for a display redirect here 868 | 869 | sprintf_s(buf, sizeof(buf), "Device %d: Class: [DisplayRedirect]", unDevice); 870 | printf_s(buf); 871 | break; 872 | 873 | } 874 | 875 | // print some of the meta data for the device 876 | 877 | // How does this work? deprecated due to new IVRInput? 878 | int32_t role; 879 | vr::ETrackedPropertyError pError; 880 | role = vr::VRSystem()->GetInt32TrackedDeviceProperty(unDevice, vr::ETrackedDeviceProperty::Prop_ControllerRoleHint_Int32, &pError); 881 | if (pError == vr::ETrackedPropertyError::TrackedProp_Success) { 882 | if (role == vr::ETrackedControllerRole::TrackedControllerRole_Invalid) { 883 | sprintf_s(buf, sizeof(buf), " | Invalid Role (?): %d", role); 884 | printf_s(buf); 885 | } 886 | else { 887 | sprintf_s(buf, sizeof(buf), " | Role: %d", role); 888 | printf_s(buf); 889 | } 890 | } 891 | 892 | char manufacturer[1024]; 893 | vr::VRSystem()->GetStringTrackedDeviceProperty(unDevice, vr::ETrackedDeviceProperty::Prop_ManufacturerName_String, manufacturer, sizeof(manufacturer)); 894 | 895 | char modelnumber[1024]; 896 | vr::VRSystem()->GetStringTrackedDeviceProperty(unDevice, vr::ETrackedDeviceProperty::Prop_ModelNumber_String, modelnumber, sizeof(modelnumber)); 897 | 898 | char serialnumber[1024]; 899 | vr::VRSystem()->GetStringTrackedDeviceProperty(unDevice, vr::ETrackedDeviceProperty::Prop_SerialNumber_String, serialnumber, sizeof(serialnumber)); 900 | 901 | bool canPowerOff = vr::VRSystem()->GetBoolTrackedDeviceProperty(unDevice, vr::ETrackedDeviceProperty::Prop_DeviceCanPowerOff_Bool); 902 | 903 | sprintf_s(buf, sizeof(buf), " | Manuf: %s | Model: %s | Serial: %s | Can power Off: %d\n", manufacturer, modelnumber, serialnumber, canPowerOff); 904 | printf_s(buf); 905 | } 906 | sprintf_s(buf, sizeof(buf), "---------------------------\nEnd of device list\n\n"); 907 | printf_s(buf); 908 | 909 | } 910 | -------------------------------------------------------------------------------- /OpenVR Tracking Example/OpenVRTrackingExample.h: -------------------------------------------------------------------------------- 1 | /* 2 | OpenVR-Tracking-Example Copyright 2016-2022 Omnifinity 3 | Example on how to access tracking data from OpenVR 4 | 5 | OpenVR Copyright (c) 2015, Valve Corporation 6 | 7 | All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without modification, 10 | are permitted provided that the following conditions are met : 11 | 12 | 1. Redistributions of source code must retain the above copyright notice, this 13 | list of conditions and the following disclaimer. 14 | 15 | 2. Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation and / or 17 | other materials provided with the distribution. 18 | 19 | 3. Neither the name of the copyright holder nor the names of its contributors 20 | may be used to endorse or promote products derived from this software without 21 | specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 27 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 30 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | #ifndef _OPENVRTRACKINGEXAMPLE_H_ 36 | #define _OPENVRTRACKINGEXAMPLE_H_ 37 | 38 | // OpenVR 39 | #include 40 | #include "samples\shared\Matrices.h" 41 | #include "samples\shared\pathtools.h" 42 | 43 | //#include "pathtools_excerpt.h" 44 | 45 | class OpenVRTrackingExample { 46 | private: 47 | 48 | // Basic stuff 49 | vr::IVRSystem *m_pHMD = NULL; 50 | vr::TrackedDevicePose_t m_rTrackedDevicePose[vr::k_unMaxTrackedDeviceCount]; 51 | Matrix4 m_rmat4DevicePose[vr::k_unMaxTrackedDeviceCount]; 52 | 53 | // For getting the steam application key 54 | char applicationKey[vr::k_unMaxApplicationKeyLength]; 55 | 56 | // Handles for the new IVRInput 57 | vr::VRActionSetHandle_t m_actionSetDemo = vr::k_ulInvalidActionSetHandle; 58 | const char *actionSetDemoPath = "/actions/demo"; 59 | 60 | vr::VRActionHandle_t m_actionAnalogInput = vr::k_ulInvalidActionHandle; 61 | const char *actionDemoAnalogInputPath = "/actions/demo/in/AnalogInput"; 62 | 63 | vr::VRActionHandle_t m_actionHideCubes = vr::k_ulInvalidActionHandle; 64 | const char *actionDemoHideCubesPath = "/actions/demo/in/HideCubes"; 65 | 66 | vr::VRActionHandle_t m_actionClick = vr::k_ulInvalidActionHandle; 67 | const char *actionDemoClickPath = "/actions/demo/in/ClickAction"; 68 | 69 | vr::VRActionHandle_t m_actionTouch = vr::k_ulInvalidActionHandle; 70 | const char *actionDemoTouchPath = "/actions/demo/in/TouchAction"; 71 | 72 | vr::VRActionHandle_t m_actionDemoHandLeft = vr::k_ulInvalidActionHandle; 73 | const char *actionDemoHandLeftPath = "/actions/demo/in/Hand_Left"; 74 | 75 | vr::VRActionHandle_t m_actionDemoHandRight = vr::k_ulInvalidActionHandle; 76 | const char *actionDemoHandRightPath = "/actions/demo/in/Hand_Right"; 77 | 78 | vr::VRInputValueHandle_t m_inputHandLeftPath = vr::k_ulInvalidInputValueHandle; 79 | const char *inputHandLeftPath = "/user/hand/left"; 80 | 81 | vr::VRInputValueHandle_t m_inputHandRightPath = vr::k_ulInvalidInputValueHandle; 82 | const char *inputHandRightPath = "/user/hand/right"; 83 | 84 | struct ControllerInfo_t 85 | { 86 | vr::VRInputValueHandle_t m_source = vr::k_ulInvalidInputValueHandle; 87 | vr::VRActionHandle_t m_actionPose = vr::k_ulInvalidActionHandle; 88 | vr::VRActionHandle_t m_actionHaptic = vr::k_ulInvalidActionHandle; 89 | Matrix4 m_rmat4Pose; 90 | //CGLRenderModel *m_pRenderModel = nullptr; 91 | std::string m_sRenderModelName; 92 | bool m_bShowController; 93 | }; 94 | 95 | enum EHand 96 | { 97 | Left = 0, 98 | Right = 1, 99 | }; 100 | ControllerInfo_t m_Hand[2]; 101 | 102 | vr::HmdVector3_t m_vecLeftController = {}; 103 | vr::HmdVector3_t m_vecRightController = {}; 104 | 105 | // Position and rotation of pose 106 | vr::HmdVector3_t GetPosition(vr::HmdMatrix34_t matrix); 107 | vr::HmdQuaternion_t GetRotation(vr::HmdMatrix34_t matrix); 108 | 109 | void StoreLeftControllerPosition(vr::HmdVector3_t vector); 110 | void StoreRightControllerPosition(vr::HmdVector3_t vector); 111 | 112 | // If false the program will parse tracking data continously and not wait for openvr events 113 | bool bWaitForEventsBeforeParsing = false; 114 | 115 | bool printHmdTrackingData = false; 116 | bool printRightControllerTrackingData = false; 117 | bool printLeftControllerTrackingData = false; 118 | bool printBasestationTrackingData = false; 119 | 120 | public: 121 | OpenVRTrackingExample(); 122 | ~OpenVRTrackingExample(); 123 | 124 | // Initialize the VR Compositor 125 | bool BInitCompositor(); 126 | 127 | // Main loop that listens for openvr events and calls process and parse routines, if false the service has quit 128 | bool RunProcedure(bool bWaitForEvents, int filterIndex); 129 | 130 | // Process a VR event and print some general info of what happens 131 | bool ProcessVREvent(const vr::VREvent_t & event, int filterIndex); 132 | 133 | // Parse a tracking frame and print its position / rotation / events. 134 | // Supply a filterIndex different than -1 to only show data for one specific device. 135 | void ParseTrackingFrame(int filterIndex); 136 | 137 | // calc diff between positions 138 | vr::HmdVector3_t GetControllerPositionDelta(); 139 | vr::HmdVector3_t GetLeftControllerPosition(); 140 | vr::HmdVector3_t GetRightControllerPosition(); 141 | 142 | // prints information of devices 143 | void PrintDevices(); 144 | }; 145 | 146 | #endif _OPENVRTRACKINGEXAMPLE_H_ 147 | -------------------------------------------------------------------------------- /OpenVR Tracking Example/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 4 | // Windows Header Files 5 | #include 6 | -------------------------------------------------------------------------------- /OpenVR Tracking Example/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | OpenVR-Tracking-Example Copyright 2016-2022 Omnifinity 3 | Example on how to access tracking data from OpenVR 4 | 5 | OpenVR Copyright (c) 2015, Valve Corporation 6 | 7 | All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without modification, 10 | are permitted provided that the following conditions are met : 11 | 12 | 1. Redistributions of source code must retain the above copyright notice, this 13 | list of conditions and the following disclaimer. 14 | 15 | 2. Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation and / or 17 | other materials provided with the distribution. 18 | 19 | 3. Neither the name of the copyright holder nor the names of its contributors 20 | may be used to endorse or promote products derived from this software without 21 | specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 27 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 30 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | #include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier 36 | #include "Windows.h" 37 | #include "tchar.h" 38 | #include 39 | #include 40 | #include // for std::setprecision 41 | #include 42 | 43 | #include "OpenVRTrackingExample.h" 44 | 45 | // windows keyboard input 46 | #include 47 | #include 48 | 49 | using std::vector; 50 | using std::string; 51 | 52 | #define SOFTWARE_NAME "openvr_tracking_example" 53 | #define SOFTWARE_VERSION "1.8" 54 | #define SOFTWARE_CURRENT_YEAR "2022" 55 | #define VER_180 "Using openvr 1.23.7" // Also: Built for MSVC2022. Updates to project settings. 56 | #define VER_170 "Built for MSVC2019. Renamed Executable. Renamed class." 57 | #define VER_160 "Using openvr 1.14.15" 58 | #define VER_150 "Using openvr 1.9.16" 59 | #define VER_140 "Internal use" 60 | #define VER_130 "Using openvr 1.3.22" 61 | #define VER_120 "Using openvr 1.2.10" 62 | #define VER_110 "Using openvr 1.1.3" 63 | #define VER_CURRENT_STRING VER_180 64 | 65 | void printSoftwareVersion() { 66 | char buf[1024]; 67 | sprintf_s(buf, sizeof(buf), "\n%s v%s by Omnifinity in %s\n%s\n\n", SOFTWARE_NAME, SOFTWARE_VERSION, SOFTWARE_CURRENT_YEAR, VER_CURRENT_STRING); 68 | printf_s(buf); 69 | } 70 | 71 | int _tmain(int argc, _TCHAR* argv[]) 72 | { 73 | bool parseTrackingData = true; 74 | int shouldListDevicesAndQuit = 0; 75 | int shouldPrintVersionAndQuit = 0; 76 | int showOnlyDevice = -1; 77 | int calcControllerDeltaPos = 0; 78 | int showEventsOnly = 0; 79 | 80 | char buf[1024]; 81 | 82 | // very basic command line parser, from: 83 | // http://stackoverflow.com/questions/17144037/change-a-command-line-argument-argv 84 | vector validArgs; 85 | validArgs.reserve(argc); //Avoids reallocation; it's one or two (if --item is given) too much, but safe and not pedentatic while handling rare cases where argc can be zero 86 | 87 | // parse all user input 88 | for (int i = 1; iPrintDevices(); 127 | 128 | if (parseTrackingData) { 129 | DWORD delayOnStart = 2000; 130 | sprintf_s(buf, sizeof(buf), "Press 'q' to quit. Starting capture of tracking data in %d ms...\n", delayOnStart); 131 | printf_s(buf); 132 | Sleep(delayOnStart); 133 | 134 | while (trackingHandler->RunProcedure(bAcquireTrackingDataByWaitingForVREvents, showOnlyDevice)) { 135 | 136 | // Windows quit routine - adapt as you need 137 | if (_kbhit()) { 138 | char ch = _getch(); 139 | if ('q' == ch) { 140 | 141 | char buf[1024]; 142 | sprintf_s(buf, sizeof(buf), "User pressed 'q' - exiting..."); 143 | printf_s(buf); 144 | 145 | break; 146 | } 147 | else if ('l' == ch) { 148 | trackingHandler->PrintDevices(); 149 | } 150 | } 151 | 152 | // calculate the difference 153 | if (calcControllerDeltaPos) { 154 | vr::HmdVector3_t vecDiff = trackingHandler->GetControllerPositionDelta(); 155 | vr::HmdVector3_t vecLeft = trackingHandler->GetLeftControllerPosition(); 156 | vr::HmdVector3_t vecRight = trackingHandler->GetRightControllerPosition(); 157 | sprintf_s(buf, sizeof(buf), "(lx, ly, lz) = (%.3f, %.3f, %.3f) | (rx, ry, rz) = (%.3f, %.3f, %.3f) | (dX, dY, dZ) = (%.3f, %.3f, %.3f)\n", vecLeft.v[0], vecLeft.v[1], vecLeft.v[2], vecRight.v[0], vecRight.v[1], vecRight.v[2], vecDiff.v[0], vecDiff.v[1], vecDiff.v[2]); 158 | //sprintf_s(buf, sizeof(buf), "(lx, ly, lz) = (%.4f, %.4f, %.4f) | (rx, ry, rz) = (%.4f, %.4f, %.4f) | (dX, dY, dZ) = (%.4f, %.4f, %.4f)\n", vecLeft.v[0], vecLeft.v[1], vecLeft.v[2], vecRight.v[0], vecRight.v[1], vecRight.v[2], vecDiff.v[0], vecDiff.v[1], vecDiff.v[2]); 159 | printf_s(buf); 160 | } 161 | 162 | // a delay to not overheat your computer... :) 163 | Sleep(2); 164 | } 165 | } 166 | 167 | delete trackingHandler; 168 | } 169 | return EXIT_SUCCESS; 170 | } 171 | 172 | -------------------------------------------------------------------------------- /OpenVR Tracking Example/pathtools_excerpt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | pathtools_excerpt.h - Excerpt of the full shared pathtools.c from valve: 3 | 4 | Copyright(c) 2015, Valve Corporation 5 | All rights reserved. 6 | 7 | Redistributionand use in sourceand binary forms, with or without modification, 8 | are permitted provided that the following conditions are met : 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditionsand the following disclaimer in the documentationand /or 15 | other materials provided with the distribution. 16 | 17 | 3. Neither the name of the copyright holder nor the names of its contributors 18 | may be used to endorse or promote products derived from this software without 19 | specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 25 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier 34 | 35 | #include 36 | #include "samples\shared\pathtools.h" 37 | 38 | bool Path_IsAbsolute(const std::string& sPath) 39 | { 40 | if (sPath.empty()) 41 | return false; 42 | 43 | #if defined( WIN32 ) 44 | if (sPath.size() < 3) // must be c:\x or \\x at least 45 | return false; 46 | 47 | if (sPath[1] == ':') // drive letter plus slash, but must test both slash cases 48 | { 49 | if (sPath[2] == '\\' || sPath[2] == '/') 50 | return true; 51 | } 52 | else if (sPath[0] == '\\' && sPath[1] == '\\') // UNC path 53 | return true; 54 | #else 55 | if (sPath[0] == '\\' || sPath[0] == '/') // any leading slash 56 | return true; 57 | #endif 58 | 59 | return false; 60 | } 61 | 62 | 63 | /** Removes redundant /.. elements in the path. Returns an empty path if the 64 | * specified path has a broken number of directories for its number of ..s */ 65 | std::string Path_Compact(const std::string& sRawPath, char slash) 66 | { 67 | if (slash == 0) 68 | slash = Path_GetSlash(); 69 | 70 | std::string sPath = Path_FixSlashes(sRawPath, slash); 71 | std::string sSlashString(1, slash); 72 | 73 | // strip out all /./ 74 | for (std::string::size_type i = 0; (i + 3) < sPath.length(); ) 75 | { 76 | if (sPath[i] == slash && sPath[i + 1] == '.' && sPath[i + 2] == slash) 77 | { 78 | sPath.replace(i, 3, sSlashString); 79 | } 80 | else 81 | { 82 | ++i; 83 | } 84 | } 85 | 86 | 87 | // get rid of trailing /. but leave the path separator 88 | if (sPath.length() > 2) 89 | { 90 | std::string::size_type len = sPath.length(); 91 | if (sPath[len - 1] == '.' && sPath[len - 2] == slash) 92 | { 93 | // sPath.pop_back(); 94 | sPath[len - 1] = 0; // for now, at least 95 | } 96 | } 97 | 98 | // get rid of leading ./ 99 | if (sPath.length() > 2) 100 | { 101 | if (sPath[0] == '.' && sPath[1] == slash) 102 | { 103 | sPath.replace(0, 2, ""); 104 | } 105 | } 106 | 107 | // each time we encounter .. back up until we've found the previous directory name 108 | // then get rid of both 109 | std::string::size_type i = 0; 110 | while (i < sPath.length()) 111 | { 112 | if (i > 0 && sPath.length() - i >= 2 113 | && sPath[i] == '.' 114 | && sPath[i + 1] == '.' 115 | && (i + 2 == sPath.length() || sPath[i + 2] == slash) 116 | && sPath[i - 1] == slash) 117 | { 118 | // check if we've hit the start of the string and have a bogus path 119 | if (i == 1) 120 | return ""; 121 | 122 | // find the separator before i-1 123 | std::string::size_type iDirStart = i - 2; 124 | while (iDirStart > 0 && sPath[iDirStart - 1] != slash) 125 | --iDirStart; 126 | 127 | // remove everything from iDirStart to i+2 128 | sPath.replace(iDirStart, (i - iDirStart) + 3, ""); 129 | 130 | // start over 131 | i = 0; 132 | } 133 | else 134 | { 135 | ++i; 136 | } 137 | } 138 | 139 | return sPath; 140 | } 141 | 142 | /** Fixes the directory separators for the current platform */ 143 | std::string Path_FixSlashes(const std::string& sPath, char slash) 144 | { 145 | if (slash == 0) 146 | slash = Path_GetSlash(); 147 | 148 | std::string sFixed = sPath; 149 | for (std::string::iterator i = sFixed.begin(); i != sFixed.end(); i++) 150 | { 151 | if (*i == '/' || *i == '\\') 152 | *i = slash; 153 | } 154 | 155 | return sFixed; 156 | } 157 | 158 | /** Jams two paths together with the right kind of slash */ 159 | std::string Path_Join(const std::string& first, const std::string& second, char slash) 160 | { 161 | if (slash == 0) 162 | slash = Path_GetSlash(); 163 | 164 | // only insert a slash if we don't already have one 165 | std::string::size_type nLen = first.length(); 166 | if (!nLen) 167 | return second; 168 | #if defined(_WIN32) 169 | if (first.back() == '\\' || first.back() == '/') 170 | nLen--; 171 | #else 172 | char last_char = first[first.length() - 1]; 173 | if (last_char == '\\' || last_char == '/') 174 | nLen--; 175 | #endif 176 | 177 | return first.substr(0, nLen) + std::string(1, slash) + second; 178 | } 179 | 180 | 181 | /** Makes an absolute path from a relative path and a base path */ 182 | std::string Path_MakeAbsolute(const std::string& sRelativePath, const std::string& sBasePath) 183 | { 184 | if (Path_IsAbsolute(sRelativePath)) 185 | return sRelativePath; 186 | else 187 | { 188 | if (!Path_IsAbsolute(sBasePath)) 189 | return ""; 190 | 191 | std::string sCompacted = Path_Compact(Path_Join(sBasePath, sRelativePath)); 192 | if (Path_IsAbsolute(sCompacted)) 193 | return sCompacted; 194 | else 195 | return ""; 196 | } 197 | } 198 | 199 | /** Returns the path (including filename) to the current executable */ 200 | std::string Path_GetExecutablePath() 201 | { 202 | wchar_t* pwchPath = new wchar_t[MAX_UNICODE_PATH]; 203 | char* pchPath = new char[MAX_UNICODE_PATH_IN_UTF8]; 204 | ::GetModuleFileNameW(NULL, pwchPath, MAX_UNICODE_PATH); 205 | WideCharToMultiByte(CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL); 206 | delete[] pwchPath; 207 | 208 | std::string sPath = pchPath; 209 | delete[] pchPath; 210 | return sPath; 211 | } 212 | 213 | /** Returns the specified path without its filename */ 214 | std::string Path_StripFilename(const std::string& sPath, char slash) 215 | { 216 | if (slash == 0) 217 | slash = Path_GetSlash(); 218 | 219 | std::string::size_type n = sPath.find_last_of(slash); 220 | if (n == std::string::npos) 221 | return sPath; 222 | else 223 | return std::string(sPath.begin(), sPath.begin() + n); 224 | } 225 | 226 | char Path_GetSlash() 227 | { 228 | #if defined(_WIN32) 229 | return '\\'; 230 | #else 231 | return '/'; 232 | #endif 233 | } -------------------------------------------------------------------------------- /OpenVR Tracking Example/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to the pre-compiled header 2 | 3 | #include "pch.h" 4 | 5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed. 6 | -------------------------------------------------------------------------------- /OpenVR Tracking Example/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: This is a precompiled header file. 2 | // Files listed below are compiled only once, improving build performance for future builds. 3 | // This also affects IntelliSense performance, including code completion and many code browsing features. 4 | // However, files listed here are ALL re-compiled if any one of them is updated between builds. 5 | // Do not add files here that you will be updating frequently as this negates the performance advantage. 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | // add headers that you want to pre-compile here 11 | #include "framework.h" 12 | 13 | #endif //PCH_H 14 | -------------------------------------------------------------------------------- /OpenVR Tracking Example/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /OpenVRTrackingExample.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30907.101 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenVRTrackingExample", "OpenVR Tracking Example\OpenVR Tracking Example.vcxproj", "{1C0BD20F-3476-41E0-AD62-8A54E2A51565}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {1C0BD20F-3476-41E0-AD62-8A54E2A51565}.Debug|x64.ActiveCfg = Debug|x64 15 | {1C0BD20F-3476-41E0-AD62-8A54E2A51565}.Debug|x64.Build.0 = Debug|x64 16 | {1C0BD20F-3476-41E0-AD62-8A54E2A51565}.Release|x64.ActiveCfg = Release|x64 17 | {1C0BD20F-3476-41E0-AD62-8A54E2A51565}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {9C3CFE9D-DC03-4E78-B942-824CE0131D71} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # What is this? 2 | A simple example showing how to fire up a background process for acquiring tracking data from openvr. 3 | 4 | Uses OpenVR 1.23.7. 5 | 6 | Compiled using Visual Studio 2022. Please adapt as suitable. 7 | 8 | ## How do I run it? 9 | There is an executable in the Binary folder. Unarchive that and run it through a console after you've started Steam VR. Background processes are not allowed to start up SteamVR by themselves. 10 | 11 | If you supply the parameter "--showonlydeviceid " you can choose to show data/events for a specific device. E.g. "--showonlydeviceid 0" would show only data for the HMD. 12 | 13 | There are two manifest files inside the Binary folder. 14 | 15 | ## How do I compile it? 16 | 1. Make sure that you point your includes and library bin folder to where you have openvr installed on your machine. 17 | 2. Make sure you've got the openvr_api.dll in the same folder as the built example 18 | 19 | ## How do I use it? 20 | 1. Edit the source code to point to where your manifest file is, search for SetActionManifestPath() inside Lighthousetracking.cpp. 21 | 2. Start up Steam VR 22 | 3. Compile and start the example - it launches as a background application 23 | 24 | 25 | ## Troubleshooting: 26 | 27 | *Unable to init VR runtime: Hmd Not Found (108)* 28 | 29 | Solution: Attach the HMD to the computer 30 | 31 | 32 | *Unable to init VR runtime: Not starting vrserver for background app (121)* 33 | 34 | Solution: Start Steam VR 35 | 36 | -------------------------------------------------------------------------------- /openvr-binding-files/openvr_tracking_example_actions.json: -------------------------------------------------------------------------------- 1 | { 2 | "default_bindings": [ 3 | { 4 | "controller_type": "vive", 5 | "binding_url": "openvr_tracking_example_bindings_vive.json" 6 | }, 7 | { 8 | "controller_type": "vive_controller", 9 | "binding_url": "openvr_tracking_example_bindings_vive_controller.json" 10 | }, 11 | { 12 | "controller_type": "knuckles", 13 | "binding_url": "openvr_tracking_example_bindings_knuckles.json" 14 | }, 15 | { 16 | "controller_type": "vive_pro", 17 | "binding_url": "openvr_tracking_example_bindings_vive_pro.json" 18 | } 19 | ], 20 | "actions": [ 21 | { 22 | "name": "/actions/demo/in/HideCubes", 23 | "type": "boolean" 24 | }, 25 | { 26 | "name": "/actions/demo/in/AnalogInput", 27 | "type": "vector2" 28 | }, 29 | { 30 | "name": "/actions/demo/in/TouchAction", 31 | "type": "boolean" 32 | }, 33 | { 34 | "name": "/actions/demo/in/ClickAction", 35 | "type": "boolean" 36 | }, 37 | { 38 | "name": "/actions/demo/in/Hand_Right", 39 | "type": "pose" 40 | }, 41 | { 42 | "name": "/actions/demo/in/Hand_Left", 43 | "type": "pose" 44 | } 45 | ], 46 | "localization" : [ 47 | { 48 | "language_tag": "en_US", 49 | "/actions/demo/in/AnalogInput" : "Analog Input", 50 | "/actions/demo/in/Hand_Right" : "Right Hand Pose", 51 | "/actions/demo/in/Hand_Left" : "Left Hand Pose" 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /openvr-binding-files/openvr_tracking_example_bindings_knuckles.json: -------------------------------------------------------------------------------- 1 | { 2 | "action_manifest_version": 1, 3 | "alias_info": {}, 4 | "app_key": "system.generated.openvr_tracking_example.exe", 5 | "bindings": { 6 | "/actions/demo": { 7 | "poses": [ 8 | { 9 | "output": "/actions/demo/in/hand_left", 10 | "path": "/user/hand/left/pose/raw" 11 | }, 12 | { 13 | "output": "/actions/demo/in/hand_right", 14 | "path": "/user/hand/right/pose/raw" 15 | } 16 | ], 17 | "sources": [ 18 | { 19 | "inputs": { 20 | "click": { 21 | "output": "/actions/demo/in/clickaction" 22 | }, 23 | "position": { 24 | "output": "/actions/demo/in/analoginput" 25 | }, 26 | "touch": { 27 | "output": "/actions/demo/in/touchaction" 28 | } 29 | }, 30 | "mode": "trackpad", 31 | "path": "/user/hand/left/input/trackpad" 32 | }, 33 | { 34 | "inputs": { 35 | "click": { 36 | "output": "/actions/demo/in/hidecubes" 37 | } 38 | }, 39 | "mode": "button", 40 | "path": "/user/hand/left/input/trigger" 41 | } 42 | ] 43 | } 44 | }, 45 | "category": "steamvr_input", 46 | "controller_type": "knuckles", 47 | "description": "Default Index Controller bindings for openvr_tracking_example.", 48 | "name": "My openvr_tracking_example Index Controller Bindings", 49 | "options": {}, 50 | "simulated_actions": [] 51 | } 52 | -------------------------------------------------------------------------------- /openvr-binding-files/openvr_tracking_example_bindings_vive.json: -------------------------------------------------------------------------------- 1 | { 2 | "action_manifest_version": 1, 3 | "alias_info": {}, 4 | "app_key": "system.generated.openvr_tracking_example.exe", 5 | "bindings": { 6 | "/actions/demo": { 7 | "poses": [ 8 | ], 9 | "sources": [ 10 | { 11 | "inputs": { 12 | "click": { 13 | "output": "/actions/omnitrack/in/headsetonhead" 14 | } 15 | }, 16 | "mode": "button", 17 | "path": "/user/head/proximity" 18 | } 19 | ] 20 | }, 21 | "/actions/legacy": { 22 | "haptics": [ 23 | ], 24 | "poses": [ 25 | ], 26 | "sources": [ 27 | { 28 | "inputs": { 29 | "click": { 30 | "output": "/actions/legacy/in/head_proximity" 31 | } 32 | }, 33 | "mode": "button", 34 | "path": "/user/head/proximity" 35 | } 36 | ] 37 | } 38 | }, 39 | "category": "steamvr_input", 40 | "controller_type": "vive", 41 | "description": "Default Vive configuration for openvr_tracking_example.", 42 | "name": "My openvr_tracking_example configuration for Vive.", 43 | "options": {}, 44 | "simulated_actions": [] 45 | } 46 | -------------------------------------------------------------------------------- /openvr-binding-files/openvr_tracking_example_bindings_vive_controller.json: -------------------------------------------------------------------------------- 1 | { 2 | "action_manifest_version": 1, 3 | "alias_info": {}, 4 | "app_key": "system.generated.openvr_tracking_example.exe", 5 | "bindings": { 6 | "/actions/demo": { 7 | "poses": [ 8 | { 9 | "output": "/actions/demo/in/hand_left", 10 | "path": "/user/hand/left/pose/raw" 11 | }, 12 | { 13 | "output": "/actions/demo/in/hand_right", 14 | "path": "/user/hand/right/pose/raw" 15 | } 16 | ], 17 | "sources": [ 18 | { 19 | "inputs": { 20 | "click": { 21 | "output": "/actions/demo/in/clickaction" 22 | }, 23 | "position": { 24 | "output": "/actions/demo/in/analoginput" 25 | }, 26 | "touch": { 27 | "output": "/actions/demo/in/touchaction" 28 | } 29 | }, 30 | "mode": "trackpad", 31 | "path": "/user/hand/left/input/trackpad" 32 | }, 33 | { 34 | "inputs": { 35 | "click": { 36 | "output": "/actions/demo/in/hidecubes" 37 | } 38 | }, 39 | "mode": "button", 40 | "path": "/user/hand/left/input/trigger" 41 | } 42 | ] 43 | } 44 | }, 45 | "category": "steamvr_input", 46 | "controller_type": "vive_controller", 47 | "description": "Default Vive Controller bindings for openvr_tracking_example.", 48 | "name": "My openvr_tracking_example configuration for Vive Controller", 49 | "options": {}, 50 | "simulated_actions": [] 51 | } 52 | -------------------------------------------------------------------------------- /openvr-binding-files/openvr_tracking_example_bindings_vive_pro.json: -------------------------------------------------------------------------------- 1 | { 2 | "action_manifest_version": 1, 3 | "alias_info": {}, 4 | "app_key": "system.generated.openvr_tracking_example.exe", 5 | "bindings": { 6 | "/actions/demo": { 7 | "poses": [ 8 | { 9 | "output": "/actions/demo/in/hand_left", 10 | "path": "/user/hand/left/pose/raw" 11 | }, 12 | { 13 | "output": "/actions/demo/in/hand_right", 14 | "path": "/user/hand/right/pose/raw" 15 | } 16 | ], 17 | "sources": [ 18 | { 19 | "inputs": { 20 | "click": { 21 | "output": "/actions/demo/in/clickaction" 22 | }, 23 | "position": { 24 | "output": "/actions/demo/in/analoginput" 25 | }, 26 | "touch": { 27 | "output": "/actions/demo/in/touchaction" 28 | } 29 | }, 30 | "mode": "trackpad", 31 | "path": "/user/hand/left/input/trackpad" 32 | }, 33 | { 34 | "inputs": { 35 | "click": { 36 | "output": "/actions/demo/in/hidecubes" 37 | } 38 | }, 39 | "mode": "button", 40 | "path": "/user/hand/left/input/trigger" 41 | } 42 | ] 43 | } 44 | }, 45 | "category": "steamvr_input", 46 | "controller_type": "vive_pro", 47 | "description": "Default Vive Pro configuration for openvr_tracking_example.", 48 | "name": "My openvr_tracking_example configuration for Vive Pro", 49 | "options": {}, 50 | "simulated_actions": [] 51 | } 52 | --------------------------------------------------------------------------------