Skip to content

Commit

Permalink
OpenVR SDK 1.0.8:
Browse files Browse the repository at this point in the history
General:
- Added VRCompositorError_InvalidBounds - This is returned when the application passes texture bounds to Submit that are outside the range of 0.0 to 1.0 or are otherwise invalid.          
- Added sample programs: hellovr_vulkan and hellovr_dx12.

IVRVirtualDisplay:
- The IVRVirtualDisplay interface is provided to allow OpenVR driver authors access to the final composited backbuffer intended for the headset’s display. The primary expected use case is for wireless transport, though this could also be used for saving output to disk or streaming. From the perspective of the runtime, the VR compositor is interfacing with a virtual rather than an actual display. See https://github.com/ValveSoftware/virtual_display

IVRSystem:
- GetOutputDevice interface added for applications to know which primary graphics adapter to use.  This returns a LUID on Win32, vk::PhysicalDevice for Vulkan and id<MTLDevice> on OSX.

IVRDriverManager:
- Public API to query installed device drivers. 

Drivers: 
- Drivers can now set Prop_DriverDirectModeSendsVsyncEvents_Bool to true to indicate they will call VsyncEvent on their own.  This enables avoiding the hardcoded 2.8ms vsync offset for IVRDriverDirectModeComponent implementations.
- Allow drivers to specify which graphics adapter to use by settings Prop_GraphicsAdapterLuid_Uint64.  This is a LUID on Win32.

MacOS/OSX:
 - includes a private framework compatible with Xcode 8 and higher. Embedding frameworks as binaries in your macOS app bundle can be error prone - see detailed instructions in issue #543 ValveSoftware/openvr#543 (comment)

Cmake Build System (optional):
 - cmake script changes to better support Cygwin
 - supports building universal 32/64 binaries on OSX
 - supports building as a private OSX framework

[git-p4: depot-paths = "//vr/steamvr/sdk_release/": change = 4009583]
  • Loading branch information
jeremyselan committed Jun 13, 2017
1 parent b653929 commit dc860fe
Show file tree
Hide file tree
Showing 64 changed files with 53,549 additions and 50 deletions.
Binary file modified bin/linux32/libopenvr_api.so
Binary file not shown.
Binary file modified bin/linux32/libopenvr_api.so.dbg
Binary file not shown.
Binary file modified bin/linux64/libopenvr_api.so
Binary file not shown.
Binary file modified bin/linux64/libopenvr_api.so.dbg
Binary file not shown.
Binary file modified bin/osx32/libopenvr_api.dylib
Binary file not shown.
Binary file not shown.
Binary file modified bin/win32/openvr_api.dll
Binary file not shown.
Binary file modified bin/win32/openvr_api.pdb
Binary file not shown.
Binary file modified bin/win64/openvr_api.dll
Binary file not shown.
Binary file modified bin/win64/openvr_api.pdb
Binary file not shown.
87 changes: 74 additions & 13 deletions headers/openvr.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ enum ETrackingResult
TrackingResult_Running_OutOfRange = 201,
};

typedef uint32_t DriverId_t;
static const uint32_t k_nDriverNone = 0xFFFFFFFF;

static const uint32_t k_unMaxDriverDebugResponseSize = 32768;

/** Used to pass device IDs to API calls */
Expand Down Expand Up @@ -309,6 +312,9 @@ enum ETrackedDeviceProperty
Prop_DisplayMCImageNumChannels_Int32 = 2040,
Prop_DisplayMCImageData_Binary = 2041,
Prop_SecondsFromPhotonsToVblank_Float = 2042,
Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043,
Prop_DisplayDebugMode_Bool = 2044,
Prop_GraphicsAdapterLuid_Uint64 = 2045,

// Properties that are unique to TrackedDeviceClass_Controller
Prop_AttachedDeviceId_String = 3000,
Expand All @@ -330,15 +336,15 @@ enum ETrackedDeviceProperty
Prop_ModeLabel_String = 4006,

// Properties that are used for user interface like icons names
Prop_IconPathName_String = 5000, // usually a directory named "icons"
Prop_NamedIconPathDeviceOff_String = 5001, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceSearching_String = 5002, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceReady_String = 5004, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceReadyAlert_String = 5005, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceNotReady_String = 5006, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceStandby_String = 5007, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceAlertLow_String = 5008, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties.
Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others
Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others

// Properties that are used by helpers, but are opaque to applications
Prop_DisplayHiddenArea_Binary_Start = 5100,
Expand Down Expand Up @@ -539,6 +545,7 @@ enum EVREventType
VREvent_ModelSkinSettingsHaveChanged = 853,
VREvent_EnvironmentSettingsHaveChanged = 854,
VREvent_PowerSettingsHaveChanged = 855,
VREvent_EnableHomeAppSettingsHaveChanged = 856,

VREvent_StatusUpdate = 900,

Expand Down Expand Up @@ -1044,6 +1051,8 @@ enum EVRInitError
VRInitError_Init_WatchdogDisabledInSettings = 132,
VRInitError_Init_VRDashboardNotFound = 133,
VRInitError_Init_VRDashboardStartupFailed = 134,
VRInitError_Init_VRHomeNotFound = 135,
VRInitError_Init_VRHomeStartupFailed = 136,

VRInitError_Driver_Failed = 200,
VRInitError_Driver_Unknown = 201,
Expand Down Expand Up @@ -1074,6 +1083,7 @@ enum EVRInitError
VRInitError_Compositor_FirmwareRequiresUpdate = 402,
VRInitError_Compositor_OverlayInitFailed = 403,
VRInitError_Compositor_ScreenshotsInitFailed = 404,
VRInitError_Compositor_UnableToCreateDevice = 405,

VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000,

Expand Down Expand Up @@ -1265,6 +1275,22 @@ class IVRSystem
* and swap chain in DX10 and DX11. If an error occurs the index will be set to -1.
*/
virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex ) = 0;

/**
* Returns platform- and texture-type specific adapter identification so that applications and the
* compositor are creating textures and swap chains on the same GPU. If an error occurs the device
* will be set to 0.
* [D3D10/11/12 Only (D3D9 Not Supported)]
* Returns the adapter LUID that identifies the GPU attached to the HMD. The user should
* enumerate all adapters using IDXGIFactory::EnumAdapters and IDXGIAdapter::GetDesc to find
* the adapter with the matching LUID, or use IDXGIFactory4::EnumAdapterByLuid.
* The discovered IDXGIAdapter should be used to create the device and swap chain.
* [Vulkan Only]
* Returns the vk::PhysicalDevice that should be used by the application.
* [macOS Only]
* Returns an id<MTLDevice> that should be used by the application.
*/
virtual void GetOutputDevice( uint64_t *pnDevice, ETextureType textureType ) = 0;

// ------------------------------------
// Display Mode methods
Expand Down Expand Up @@ -1482,7 +1508,7 @@ class IVRSystem

};

static const char * const IVRSystem_Version = "IVRSystem_015";
static const char * const IVRSystem_Version = "IVRSystem_016";

}

Expand Down Expand Up @@ -1770,7 +1796,7 @@ namespace vr
static const char * const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees";
static const char * const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement";
static const char * const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses";
static const char * const k_pch_SteamVR_RenderTargetMultiplier_Float = "renderTargetMultiplier";
static const char * const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale";
static const char * const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection";
static const char * const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection";
static const char * const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection";
Expand All @@ -1783,10 +1809,10 @@ namespace vr
static const char * const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch";
static const char * const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard";
static const char * const k_pch_SteamVR_EnableHomeApp = "enableHomeApp";
static const char * const k_pch_SteamVR_SetInitialDefaultHomeApp = "setInitialDefaultHomeApp";
static const char * const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec";
static const char * const k_pch_SteamVR_RetailDemo_Bool = "retailDemo";
static const char * const k_pch_SteamVR_IpdOffset_Float = "ipdOffset";
static const char * const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering";

//-----------------------------------------------------------------------------
// lighthouse keys
Expand Down Expand Up @@ -1844,6 +1870,7 @@ namespace vr
static const char * const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore";
static const char * const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit";
static const char * const k_pch_Perf_TestData_Float = "perfTestData";
static const char * const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling";

//-----------------------------------------------------------------------------
// collision bounds keys
Expand Down Expand Up @@ -2087,6 +2114,7 @@ enum EVRCompositorError
VRCompositorError_SharedTexturesNotSupported = 106,
VRCompositorError_IndexOutOfRange = 107,
VRCompositorError_AlreadySubmitted = 108,
VRCompositorError_InvalidBounds = 109,
};

const uint32_t VRCompositor_ReprojectionReason_Cpu = 0x01;
Expand Down Expand Up @@ -3350,7 +3378,26 @@ class IVRResources
static const char * const IVRResources_Version = "IVRResources_001";


}// End
}
// ivrdrivermanager.h
namespace vr
{

class IVRDriverManager
{
public:
virtual uint32_t GetDriverCount() const = 0;

/** Returns the length of the number of bytes necessary to hold this string including the trailing null. */
virtual uint32_t GetDriverName( vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0;
};

static const char * const IVRDriverManager_Version = "IVRDriverManager_001";

} // namespace vr


// End

#endif // _OPENVR_API

Expand Down Expand Up @@ -3571,6 +3618,17 @@ namespace vr
return m_pVRTrackedCamera;
}

IVRDriverManager *VRDriverManager()
{
CheckClear();
if ( !m_pVRDriverManager )
{
EVRInitError eError;
m_pVRDriverManager = ( IVRDriverManager * )VR_GetGenericInterface( IVRDriverManager_Version, &eError );
}
return m_pVRDriverManager;
}

private:
IVRSystem *m_pVRSystem;
IVRChaperone *m_pVRChaperone;
Expand All @@ -3584,6 +3642,7 @@ namespace vr
IVRApplications *m_pVRApplications;
IVRTrackedCamera *m_pVRTrackedCamera;
IVRScreenshots *m_pVRScreenshots;
IVRDriverManager *m_pVRDriverManager;
};

inline COpenVRContext &OpenVRInternal_ModuleContext()
Expand All @@ -3604,6 +3663,7 @@ namespace vr
inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleContext().VRResources(); }
inline IVRExtendedDisplay *VR_CALLTYPE VRExtendedDisplay() { return OpenVRInternal_ModuleContext().VRExtendedDisplay(); }
inline IVRTrackedCamera *VR_CALLTYPE VRTrackedCamera() { return OpenVRInternal_ModuleContext().VRTrackedCamera(); }
inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleContext().VRDriverManager(); }

inline void COpenVRContext::Clear()
{
Expand All @@ -3619,6 +3679,7 @@ namespace vr
m_pVRTrackedCamera = nullptr;
m_pVRResources = nullptr;
m_pVRScreenshots = nullptr;
m_pVRDriverManager = nullptr;
}

VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal( EVRInitError *peError, EVRApplicationType eApplicationType );
Expand Down
63 changes: 60 additions & 3 deletions headers/openvr_api.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ public struct IVRSystem
[MarshalAs(UnmanagedType.FunctionPtr)]
internal _GetDXGIOutputInfo GetDXGIOutputInfo;

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate void _GetOutputDevice(ref ulong pnDevice, ETextureType textureType);
[MarshalAs(UnmanagedType.FunctionPtr)]
internal _GetOutputDevice GetOutputDevice;

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate bool _IsDisplayOnDesktop();
[MarshalAs(UnmanagedType.FunctionPtr)]
Expand Down Expand Up @@ -1477,6 +1482,21 @@ public struct IVRResources

}

[StructLayout(LayoutKind.Sequential)]
public struct IVRDriverManager
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate uint _GetDriverCount();
[MarshalAs(UnmanagedType.FunctionPtr)]
internal _GetDriverCount GetDriverCount;

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
internal delegate uint _GetDriverName(uint nDriver, System.Text.StringBuilder pchValue, uint unBufferSize);
[MarshalAs(UnmanagedType.FunctionPtr)]
internal _GetDriverName GetDriverName;

}


public class CVRSystem
{
Expand Down Expand Up @@ -1531,6 +1551,11 @@ public void GetDXGIOutputInfo(ref int pnAdapterIndex)
pnAdapterIndex = 0;
FnTable.GetDXGIOutputInfo(ref pnAdapterIndex);
}
public void GetOutputDevice(ref ulong pnDevice,ETextureType textureType)
{
pnDevice = 0;
FnTable.GetOutputDevice(ref pnDevice,textureType);
}
public bool IsDisplayOnDesktop()
{
bool result = FnTable.IsDisplayOnDesktop();
Expand Down Expand Up @@ -3145,6 +3170,26 @@ public uint GetResourceFullPath(string pchResourceName,string pchResourceTypeDir
}


public class CVRDriverManager
{
IVRDriverManager FnTable;
internal CVRDriverManager(IntPtr pInterface)
{
FnTable = (IVRDriverManager)Marshal.PtrToStructure(pInterface, typeof(IVRDriverManager));
}
public uint GetDriverCount()
{
uint result = FnTable.GetDriverCount();
return result;
}
public uint GetDriverName(uint nDriver,System.Text.StringBuilder pchValue,uint unBufferSize)
{
uint result = FnTable.GetDriverName(nDriver,pchValue,unBufferSize);
return result;
}
}


public class OpenVRInterop
{
[DllImportAttribute("openvr_api", EntryPoint = "VR_InitInternal", CallingConvention = CallingConvention.Cdecl)]
Expand Down Expand Up @@ -3296,6 +3341,9 @@ public enum ETrackedDeviceProperty
Prop_DisplayMCImageNumChannels_Int32 = 2040,
Prop_DisplayMCImageData_Binary = 2041,
Prop_SecondsFromPhotonsToVblank_Float = 2042,
Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043,
Prop_DisplayDebugMode_Bool = 2044,
Prop_GraphicsAdapterLuid_Uint64 = 2045,
Prop_AttachedDeviceId_String = 3000,
Prop_SupportedButtons_Uint64 = 3001,
Prop_Axis0Type_Int32 = 3002,
Expand Down Expand Up @@ -3449,6 +3497,7 @@ public enum EVREventType
VREvent_ModelSkinSettingsHaveChanged = 853,
VREvent_EnvironmentSettingsHaveChanged = 854,
VREvent_PowerSettingsHaveChanged = 855,
VREvent_EnableHomeAppSettingsHaveChanged = 856,
VREvent_StatusUpdate = 900,
VREvent_MCImageUpdated = 1000,
VREvent_FirmwareUpdateStarted = 1100,
Expand Down Expand Up @@ -3632,6 +3681,8 @@ public enum EVRInitError
Init_WatchdogDisabledInSettings = 132,
Init_VRDashboardNotFound = 133,
Init_VRDashboardStartupFailed = 134,
Init_VRHomeNotFound = 135,
Init_VRHomeStartupFailed = 136,
Driver_Failed = 200,
Driver_Unknown = 201,
Driver_HmdUnknown = 202,
Expand All @@ -3658,6 +3709,7 @@ public enum EVRInitError
Compositor_FirmwareRequiresUpdate = 402,
Compositor_OverlayInitFailed = 403,
Compositor_ScreenshotsInitFailed = 404,
Compositor_UnableToCreateDevice = 405,
VendorSpecific_UnableToConnectToOculusRuntime = 1000,
VendorSpecific_HmdFound_CantOpenDevice = 1101,
VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102,
Expand Down Expand Up @@ -3798,6 +3850,7 @@ public enum EVRCompositorError
SharedTexturesNotSupported = 106,
IndexOutOfRange = 107,
AlreadySubmitted = 108,
InvalidBounds = 109,
}
public enum VROverlayInputMethod
{
Expand Down Expand Up @@ -4479,6 +4532,7 @@ public void Unpack(ref RenderModel_t unpacked)
public IntPtr m_pVRApplications; // class vr::IVRApplications *
public IntPtr m_pVRTrackedCamera; // class vr::IVRTrackedCamera *
public IntPtr m_pVRScreenshots; // class vr::IVRScreenshots *
public IntPtr m_pVRDriverManager; // class vr::IVRDriverManager *
}

public class OpenVR
Expand Down Expand Up @@ -4524,6 +4578,7 @@ public static uint GetInitToken()
return OpenVRInterop.GetInitToken();
}

public const uint k_nDriverNone = 4294967295;
public const uint k_unMaxDriverDebugResponseSize = 32768;
public const uint k_unTrackedDeviceIndex_Hmd = 0;
public const uint k_unMaxTrackedDeviceCount = 16;
Expand All @@ -4547,7 +4602,7 @@ public static uint GetInitToken()
public const uint k_unControllerStateAxisCount = 5;
public const ulong k_ulOverlayHandleInvalid = 0;
public const uint k_unScreenshotHandleInvalid = 0;
public const string IVRSystem_Version = "IVRSystem_015";
public const string IVRSystem_Version = "IVRSystem_016";
public const string IVRExtendedDisplay_Version = "IVRExtendedDisplay_001";
public const string IVRTrackedCamera_Version = "IVRTrackedCamera_003";
public const uint k_unMaxApplicationKeyLength = 128;
Expand Down Expand Up @@ -4598,7 +4653,7 @@ public static uint GetInitToken()
public const string k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees";
public const string k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement";
public const string k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses";
public const string k_pch_SteamVR_RenderTargetMultiplier_Float = "renderTargetMultiplier";
public const string k_pch_SteamVR_SupersampleScale_Float = "supersampleScale";
public const string k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection";
public const string k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection";
public const string k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection";
Expand All @@ -4611,10 +4666,10 @@ public static uint GetInitToken()
public const string k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch";
public const string k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard";
public const string k_pch_SteamVR_EnableHomeApp = "enableHomeApp";
public const string k_pch_SteamVR_SetInitialDefaultHomeApp = "setInitialDefaultHomeApp";
public const string k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec";
public const string k_pch_SteamVR_RetailDemo_Bool = "retailDemo";
public const string k_pch_SteamVR_IpdOffset_Float = "ipdOffset";
public const string k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering";
public const string k_pch_Lighthouse_Section = "driver_lighthouse";
public const string k_pch_Lighthouse_DisableIMU_Bool = "disableimu";
public const string k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation";
Expand Down Expand Up @@ -4654,6 +4709,7 @@ public static uint GetInitToken()
public const string k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore";
public const string k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit";
public const string k_pch_Perf_TestData_Float = "perfTestData";
public const string k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling";
public const string k_pch_CollisionBounds_Section = "collisionBounds";
public const string k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle";
public const string k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn";
Expand Down Expand Up @@ -4694,6 +4750,7 @@ public static uint GetInitToken()
public const string k_pch_Driver_Enable_Bool = "enable";
public const string IVRScreenshots_Version = "IVRScreenshots_001";
public const string IVRResources_Version = "IVRResources_001";
public const string IVRDriverManager_Version = "IVRDriverManager_001";

static uint VRToken { get; set; }

Expand Down
Loading

0 comments on commit dc860fe

Please sign in to comment.