├── .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 |
--------------------------------------------------------------------------------