1 module openvr.helper; 2 3 import openvr.api; 4 5 /** Returns true if the tracked controller role is allowed to be a hand */ 6 pragma(inline, true) bool IsRoleAllowedAsHand(ETrackedControllerRole eRole) 7 { 8 switch (eRole) with (ETrackedControllerRole) 9 { 10 case Invalid: 11 case LeftHand: 12 case RightHand: 13 return true; 14 default: 15 return false; 16 } 17 } 18 19 pragma(inline, true) ulong ButtonMaskFromId(EVRButtonId id) 20 { 21 return 1UL << id; 22 } 23 24 /** Compositor frame timing reprojection flags. */ 25 26 /// This flag indicates the async reprojection mode is active, 27 /// but does not indicate if reprojection actually happened or not. 28 /// Use the ReprojectionReason flags above to check if reprojection 29 /// was actually applied (i.e. scene texture was reused). 30 /// NumFramePresents > 1 also indicates the scene texture was reused, 31 /// and also the number of times that it was presented in total. 32 enum uint VRCompositor_ReprojectionReason_Cpu = 0x01; 33 enum uint VRCompositor_ReprojectionReason_Gpu = 0x02; 34 enum uint VRCompositor_ReprojectionAsync = 0x04; 35 36 /// This flag indicates whether or not motion smoothing was triggered for this frame 37 enum uint VRCompositor_ReprojectionMotion = 0x08; 38 39 /// The runtime may predict more than one frame (up to four) ahead if 40 /// it detects the application is taking too long to render. These two 41 /// bits will contain the count of additional frames (normally zero). 42 /// Use the VR_COMPOSITOR_ADDITIONAL_PREDICTED_FRAMES macro to read from 43 /// the latest frame timing entry. 44 enum uint VRCompositor_PredictionMask = 0x30; 45 46 /// Number of frames the compositor is throttling the application. 47 /// Use the VR_COMPOSITOR_NUMBER_OF_THROTTLED_FRAMES macro to read from 48 /// the latest frame timing entry. 49 enum uint VRCompositor_ThrottleMask = 0xC0; 50 51 enum VR_COMPOSITOR_ADDITIONAL_PREDICTED_FRAMES(alias timing) = (((timing) 52 .m_nReprojectionFlags & vr.VRCompositor_PredictionMask) >> 4); 53 enum VR_COMPOSITOR_NUMBER_OF_THROTTLED_FRAMES(alias timing) = (((timing) 54 .m_nReprojectionFlags & vr.VRCompositor_ThrottleMask) >> 6); 55 56 /** These flags will be set on DriverDirectMode_FrameTiming::m_nReprojectionFlags when IVRDriverDirectModeComponent::GetFrameTiming is called for drivers to optionally respond to. */ 57 enum uint VRCompositor_ReprojectionMotion_Enabled = 0x100; /// Motion Smoothing is enabled in the UI for the currently running application 58 enum uint VRCompositor_ReprojectionMotion_ForcedOn = 0x200; /// Motion Smoothing is forced on in the UI for the currently running application 59 enum uint VRCompositor_ReprojectionMotion_AppThrottled = 0x400; /// Application is requesting throttling via ForceInterleavedReprojectionOn 60 61 /** Returns the current IVRHeadsetView pointer or NULL the interface could not be found. */ 62 extern (C) IVRHeadsetView VRHeadsetView(); 63 64 /** Returns true if there is an HMD attached. This check is as lightweight as possible and 65 * can be called outside of VR_Init/VR_Shutdown. It should be used when an application wants 66 * to know if initializing VR is a possibility but isn't ready to take that step yet. 67 */ 68 extern (C) bool VR_IsHmdPresent(); 69 70 /** Returns true if the OpenVR runtime is installed. */ 71 extern (C) bool VR_IsRuntimeInstalled(); 72 73 /** Returns where the OpenVR runtime is installed. */ 74 extern (C) bool VR_GetRuntimePath(char* pchPathBuffer, uint unBufferSize, 75 uint* punRequiredBufferSize); 76 77 /** Returns the name of the enum value for an EVRInitError. This function may be called outside of VR_Init()/VR_Shutdown(). */ 78 extern (C) const(char)* VR_GetVRInitErrorAsSymbol(EVRInitError error); 79 80 /** Returns an English string for an EVRInitError. Applications should call VR_GetVRInitErrorAsSymbol instead and 81 * use that as a key to look up their own localized error message. This function may be called outside of VR_Init()/VR_Shutdown(). */ 82 extern (C) const(char)* VR_GetVRInitErrorAsEnglishDescription(EVRInitError error); 83 84 /** Returns the interface of the specified version. This method must be called after VR_Init. The 85 * pointer returned is valid until VR_Shutdown is called. 86 */ 87 extern (C) void* VR_GetGenericInterface(const(char)* pchInterfaceVersion, EVRInitError* peError); 88 89 /** Returns whether the interface of the specified version exists. 90 */ 91 extern (C) bool VR_IsInterfaceVersionValid(const(char)* pchInterfaceVersion); 92 93 /** Returns a token that represents whether the VR interface handles need to be reloaded */ 94 extern (C) uint VR_GetInitToken(); 95 96 extern (C) uint VR_InitInternal2(EVRInitError* peError, 97 EVRApplicationType eApplicationType, const(char)* pStartupInfo); 98 extern (C) void VR_ShutdownInternal(); 99 100 extern (C++, vr) 101 { 102 103 /** Finds the active installation of the VR API and initializes it. The provided path must be absolute 104 * or relative to the current working directory. These are the local install versions of the equivalent 105 * functions in steamvr.h and will work without a local Steam install. 106 * 107 * This path is to the "root" of the VR API install. That's the directory with 108 * the "drivers" directory and a platform (i.e. "win32") directory in it, not the directory with the DLL itself. 109 * 110 * pStartupInfo is reserved for future use. 111 */ 112 pragma(inline, true) IVRSystem VR_Init(EVRInitError* peError, 113 EVRApplicationType eApplicationType, const(char)* pStartupInfo = null); 114 115 /** unloads vrclient.dll. Any interface pointers from the interface are 116 * invalid after this point */ 117 pragma(inline, true) void VR_Shutdown(); 118 119 pragma(inline, true) ref uint VRToken() 120 { 121 static uint token; 122 return token; 123 } 124 125 class COpenVRContext 126 { 127 public: 128 this() 129 { 130 Clear(); 131 } 132 133 pragma(inline, true) void Clear() 134 { 135 m_pVRSystem = null; 136 m_pVRChaperone = null; 137 m_pVRChaperoneSetup = null; 138 m_pVRCompositor = null; 139 m_pVROverlay = null; 140 m_pVROverlayView = null; 141 m_pVRHeadsetView = null; 142 m_pVRRenderModels = null; 143 m_pVRExtendedDisplay = null; 144 m_pVRSettings = null; 145 m_pVRApplications = null; 146 m_pVRTrackedCamera = null; 147 m_pVRResources = null; 148 m_pVRScreenshots = null; 149 m_pVRDriverManager = null; 150 m_pVRInput = null; 151 m_pVRIOBuffer = null; 152 m_pVRSpatialAnchors = null; 153 m_pVRNotifications = null; 154 m_pVRDebug = null; 155 } 156 157 pragma(inline, true) void CheckClear() 158 { 159 if (VRToken() != VR_GetInitToken()) 160 { 161 Clear(); 162 VRToken() = VR_GetInitToken(); 163 } 164 } 165 166 IVRSystem VRSystem() 167 { 168 CheckClear(); 169 if (m_pVRSystem is null) 170 { 171 EVRInitError eError; 172 m_pVRSystem = cast(IVRSystem) VR_GetGenericInterface(IVRSystem_Version, 173 &eError); 174 } 175 return m_pVRSystem; 176 } 177 178 IVRChaperone VRChaperone() 179 { 180 CheckClear(); 181 if (m_pVRChaperone is null) 182 { 183 EVRInitError eError; 184 m_pVRChaperone = cast(IVRChaperone) VR_GetGenericInterface( 185 IVRChaperone_Version, &eError); 186 } 187 return m_pVRChaperone; 188 } 189 190 IVRChaperoneSetup VRChaperoneSetup() 191 { 192 CheckClear(); 193 if (m_pVRChaperoneSetup is null) 194 { 195 EVRInitError eError; 196 m_pVRChaperoneSetup = cast(IVRChaperoneSetup) VR_GetGenericInterface( 197 IVRChaperoneSetup_Version, &eError); 198 } 199 return m_pVRChaperoneSetup; 200 } 201 202 IVRCompositor VRCompositor() 203 { 204 CheckClear(); 205 if (m_pVRCompositor is null) 206 { 207 EVRInitError eError; 208 m_pVRCompositor = cast(IVRCompositor) VR_GetGenericInterface( 209 IVRCompositor_Version, &eError); 210 } 211 return m_pVRCompositor; 212 } 213 214 IVROverlay VROverlay() 215 { 216 CheckClear(); 217 if (m_pVROverlay is null) 218 { 219 EVRInitError eError; 220 m_pVROverlay = cast(IVROverlay) VR_GetGenericInterface( 221 IVROverlay_Version, &eError); 222 } 223 return m_pVROverlay; 224 } 225 226 IVROverlayView VROverlayView() 227 { 228 CheckClear(); 229 if (m_pVROverlayView is null) 230 { 231 EVRInitError eError; 232 m_pVROverlayView = cast(IVROverlayView) VR_GetGenericInterface( 233 IVROverlayView_Version, &eError); 234 } 235 return m_pVROverlayView; 236 } 237 238 IVRHeadsetView VRHeadsetView() 239 { 240 CheckClear(); 241 if (m_pVRHeadsetView is null) 242 { 243 EVRInitError eError; 244 m_pVRHeadsetView = cast(IVRHeadsetView) VR_GetGenericInterface( 245 IVRHeadsetView_Version, &eError); 246 } 247 return m_pVRHeadsetView; 248 } 249 250 IVRResources VRResources() 251 { 252 CheckClear(); 253 if (m_pVRResources is null) 254 { 255 EVRInitError eError; 256 m_pVRResources = cast(IVRResources) VR_GetGenericInterface( 257 IVRResources_Version, &eError); 258 } 259 return m_pVRResources; 260 } 261 262 IVRScreenshots VRScreenshots() 263 { 264 CheckClear(); 265 if (m_pVRScreenshots is null) 266 { 267 EVRInitError eError; 268 m_pVRScreenshots = cast(IVRScreenshots) VR_GetGenericInterface( 269 IVRScreenshots_Version, &eError); 270 } 271 return m_pVRScreenshots; 272 } 273 274 IVRRenderModels VRRenderModels() 275 { 276 CheckClear(); 277 if (m_pVRRenderModels is null) 278 { 279 EVRInitError eError; 280 m_pVRRenderModels = cast(IVRRenderModels) VR_GetGenericInterface( 281 IVRRenderModels_Version, &eError); 282 } 283 return m_pVRRenderModels; 284 } 285 286 IVRExtendedDisplay VRExtendedDisplay() 287 { 288 CheckClear(); 289 if (m_pVRExtendedDisplay is null) 290 { 291 EVRInitError eError; 292 m_pVRExtendedDisplay = cast(IVRExtendedDisplay) VR_GetGenericInterface( 293 IVRExtendedDisplay_Version, &eError); 294 } 295 return m_pVRExtendedDisplay; 296 } 297 298 IVRSettings VRSettings() 299 { 300 CheckClear(); 301 if (m_pVRSettings is null) 302 { 303 EVRInitError eError; 304 m_pVRSettings = cast(IVRSettings) VR_GetGenericInterface( 305 IVRSettings_Version, &eError); 306 } 307 return m_pVRSettings; 308 } 309 310 IVRApplications VRApplications() 311 { 312 CheckClear(); 313 if (m_pVRApplications is null) 314 { 315 EVRInitError eError; 316 m_pVRApplications = cast(IVRApplications) VR_GetGenericInterface( 317 IVRApplications_Version, &eError); 318 } 319 return m_pVRApplications; 320 } 321 322 IVRTrackedCamera VRTrackedCamera() 323 { 324 CheckClear(); 325 if (m_pVRTrackedCamera is null) 326 { 327 EVRInitError eError; 328 m_pVRTrackedCamera = cast(IVRTrackedCamera) VR_GetGenericInterface( 329 IVRTrackedCamera_Version, &eError); 330 } 331 return m_pVRTrackedCamera; 332 } 333 334 IVRDriverManager VRDriverManager() 335 { 336 CheckClear(); 337 if (!m_pVRDriverManager) 338 { 339 EVRInitError eError; 340 m_pVRDriverManager = cast(IVRDriverManager) VR_GetGenericInterface( 341 IVRDriverManager_Version, &eError); 342 } 343 return m_pVRDriverManager; 344 } 345 346 IVRInput VRInput() 347 { 348 CheckClear(); 349 if (!m_pVRInput) 350 { 351 EVRInitError eError; 352 m_pVRInput = cast(IVRInput) VR_GetGenericInterface(IVRInput_Version, 353 &eError); 354 } 355 return m_pVRInput; 356 } 357 358 IVRIOBuffer VRIOBuffer() 359 { 360 if (!m_pVRIOBuffer) 361 { 362 EVRInitError eError; 363 m_pVRIOBuffer = cast(IVRIOBuffer) VR_GetGenericInterface( 364 IVRIOBuffer_Version, &eError); 365 } 366 return m_pVRIOBuffer; 367 } 368 369 IVRSpatialAnchors VRSpatialAnchors() 370 { 371 CheckClear(); 372 if (!m_pVRSpatialAnchors) 373 { 374 EVRInitError eError; 375 m_pVRSpatialAnchors = cast(IVRSpatialAnchors) VR_GetGenericInterface( 376 IVRSpatialAnchors_Version, &eError); 377 } 378 return m_pVRSpatialAnchors; 379 } 380 381 IVRDebug VRDebug() 382 { 383 CheckClear(); 384 if (!m_pVRDebug) 385 { 386 EVRInitError eError; 387 m_pVRDebug = cast(IVRDebug) VR_GetGenericInterface(IVRDebug_Version, 388 &eError); 389 } 390 return m_pVRDebug; 391 } 392 393 IVRNotifications VRNotifications() 394 { 395 CheckClear(); 396 if (!m_pVRNotifications) 397 { 398 EVRInitError eError; 399 m_pVRNotifications = cast(IVRNotifications) VR_GetGenericInterface( 400 IVRNotifications_Version, &eError); 401 } 402 return m_pVRNotifications; 403 } 404 405 private: 406 IVRSystem m_pVRSystem; 407 IVRChaperone m_pVRChaperone; 408 IVRChaperoneSetup m_pVRChaperoneSetup; 409 IVRCompositor m_pVRCompositor; 410 IVRHeadsetView m_pVRHeadsetView; 411 IVROverlay m_pVROverlay; 412 IVROverlayView m_pVROverlayView; 413 IVRResources m_pVRResources; 414 IVRRenderModels m_pVRRenderModels; 415 IVRExtendedDisplay m_pVRExtendedDisplay; 416 IVRSettings m_pVRSettings; 417 IVRApplications m_pVRApplications; 418 IVRTrackedCamera m_pVRTrackedCamera; 419 IVRScreenshots m_pVRScreenshots; 420 IVRDriverManager m_pVRDriverManager; 421 IVRInput m_pVRInput; 422 IVRIOBuffer m_pVRIOBuffer; 423 IVRSpatialAnchors m_pVRSpatialAnchors; 424 IVRDebug m_pVRDebug; 425 IVRNotifications m_pVRNotifications; 426 } 427 428 pragma(inline, true) ref COpenVRContext OpenVRInternal_ModuleContext() 429 { 430 static COpenVRContext ctx = null; 431 if (ctx is null) 432 ctx = new COpenVRContext(); 433 return ctx; 434 } 435 436 pragma(inline, true) IVRSystem VRSystem() 437 { 438 return OpenVRInternal_ModuleContext().VRSystem(); 439 } 440 441 pragma(inline, true) IVRChaperone VRChaperone() 442 { 443 return OpenVRInternal_ModuleContext().VRChaperone(); 444 } 445 446 pragma(inline, true) IVRChaperoneSetup VRChaperoneSetup() 447 { 448 return OpenVRInternal_ModuleContext().VRChaperoneSetup(); 449 } 450 451 pragma(inline, true) IVRCompositor VRCompositor() 452 { 453 return OpenVRInternal_ModuleContext().VRCompositor(); 454 } 455 456 pragma(inline, true) IVROverlay VROverlay() 457 { 458 return OpenVRInternal_ModuleContext().VROverlay(); 459 } 460 461 pragma(inline, true) IVROverlayView VROverlayView() 462 { 463 return OpenVRInternal_ModuleContext().VROverlayView(); 464 } 465 466 pragma(inline, true) IVRHeadsetView VRHeadsetView() 467 { 468 return OpenVRInternal_ModuleContext().VRHeadsetView(); 469 } 470 471 pragma(inline, true) IVRScreenshots VRScreenshots() 472 { 473 return OpenVRInternal_ModuleContext().VRScreenshots(); 474 } 475 476 pragma(inline, true) IVRRenderModels VRRenderModels() 477 { 478 return OpenVRInternal_ModuleContext().VRRenderModels(); 479 } 480 481 pragma(inline, true) IVRApplications VRApplications() 482 { 483 return OpenVRInternal_ModuleContext().VRApplications(); 484 } 485 486 pragma(inline, true) IVRSettings VRSettings() 487 { 488 return OpenVRInternal_ModuleContext().VRSettings(); 489 } 490 491 pragma(inline, true) IVRResources VRResources() 492 { 493 return OpenVRInternal_ModuleContext().VRResources(); 494 } 495 496 pragma(inline, true) IVRExtendedDisplay VRExtendedDisplay() 497 { 498 return OpenVRInternal_ModuleContext().VRExtendedDisplay(); 499 } 500 501 pragma(inline, true) IVRTrackedCamera VRTrackedCamera() 502 { 503 return OpenVRInternal_ModuleContext().VRTrackedCamera(); 504 } 505 506 pragma(inline, true) IVRDriverManager VRDriverManager() 507 { 508 return OpenVRInternal_ModuleContext().VRDriverManager(); 509 } 510 511 pragma(inline, true) IVRInput VRInput() 512 { 513 return OpenVRInternal_ModuleContext().VRInput(); 514 } 515 516 pragma(inline, true) IVRIOBuffer VRIOBuffer() 517 { 518 return OpenVRInternal_ModuleContext().VRIOBuffer(); 519 } 520 521 pragma(inline, true) IVRSpatialAnchors VRSpatialAnchors() 522 { 523 return OpenVRInternal_ModuleContext().VRSpatialAnchors(); 524 } 525 526 pragma(inline, true) IVRNotifications VRNotifications() 527 { 528 return OpenVRInternal_ModuleContext().VRNotifications(); 529 } 530 531 pragma(inline, true) IVRDebug VRDebug() 532 { 533 return OpenVRInternal_ModuleContext().VRDebug(); 534 } 535 536 /** Finds the active installation of vrclient.dll and initializes it */ 537 pragma(inline, true) IVRSystem VR_Init(EVRInitError* peError, 538 EVRApplicationType eApplicationType, const(char)* pStartupInfo) 539 { 540 IVRSystem pVRSystem = null; 541 542 EVRInitError eError; 543 VRToken() = VR_InitInternal2(&eError, eApplicationType, pStartupInfo); 544 COpenVRContext* ctx = &OpenVRInternal_ModuleContext(); 545 ctx.Clear(); 546 547 if (eError == EVRInitError.None) 548 { 549 if (VR_IsInterfaceVersionValid(IVRSystem_Version)) 550 { 551 pVRSystem = VRSystem(); 552 } 553 else 554 { 555 VR_ShutdownInternal(); 556 eError = EVRInitError.Init_InterfaceNotFound; 557 } 558 } 559 560 if (peError) 561 *peError = eError; 562 return pVRSystem; 563 } 564 565 /** unloads vrclient.dll. Any interface pointers from the interface are 566 * invalid after this point */ 567 pragma(inline, true) void VR_Shutdown() 568 { 569 VR_ShutdownInternal(); 570 } 571 572 }