// Copyright HTC Corporation All Rights Reserved. using System.Collections.Generic; using UnityEditor; using UnityEngine.XR.OpenXR; using UnityEngine.XR.OpenXR.Features; using System.Runtime.InteropServices; using System; using UnityEngine; #if UNITY_EDITOR using UnityEditor.XR.OpenXR.Features; #endif namespace VIVE.OpenXR { #if UNITY_EDITOR [OpenXRFeature(UiName = "VIVE XR Foveation", Desc = "Support the HTC foveation extension.", Company = "HTC", DocumentationLink = "..\\Documentation", OpenxrExtensionStrings = kOpenxrExtensionString, Version = "1.0.0", BuildTargetGroups = new[] { BuildTargetGroup.Android }, FeatureId = featureId )] #endif public class ViveFoveation : OpenXRFeature { const string LOG_TAG = "VIVE.OpenXR.ViveFoveation"; void DEBUG(string msg) { Debug.Log(LOG_TAG + " " + msg); } void WARNING(string msg) { Debug.LogWarning(LOG_TAG + " " + msg); } void ERROR(string msg) { Debug.LogError(LOG_TAG + " " + msg); } /// /// Flag bits for XrFoveationDynamicFlagsHTC /// public const UInt64 XR_FOVEATION_DYNAMIC_LEVEL_ENABLED_BIT_HTC = 0x00000001; public const UInt64 XR_FOVEATION_DYNAMIC_CLEAR_FOV_ENABLED_BIT_HTC = 0x00000002; public const UInt64 XR_FOVEATION_DYNAMIC_FOCAL_CENTER_OFFSET_ENABLED_BIT_HTC = 0x00000004; /// /// The feature id string. This is used to give the feature a well known id for reference. /// public const string featureId = "vive.openxr.feature.foveation"; /// /// OpenXR specification 12.90. XR_HTC_foveation. /// public const string kOpenxrExtensionString = "XR_HTC_foveation"; #region OpenXR Life Cycle /// /// Called when xrCreateInstance is done. /// /// The created instance. /// True for valid XrInstance protected override bool OnInstanceCreate(ulong xrInstance) { if (!OpenXRRuntime.IsExtensionEnabled(kOpenxrExtensionString)) { WARNING("OnInstanceCreate() " + kOpenxrExtensionString + " is NOT enabled."); return false; } DEBUG("OnInstanceCreate() " + xrInstance); return true; } #endregion protected override IntPtr HookGetInstanceProcAddr(IntPtr func) { Debug.Log("EXT: registering our own xrGetInstanceProcAddr"); if (SystemInfo.graphicsDeviceType == UnityEngine.Rendering.GraphicsDeviceType.Vulkan) { Debug.Log("Vulkan no hook foveation"); return func; } return intercept_xrGetInstanceProcAddr(func); } private const string ExtLib = "viveopenxr"; [DllImport(ExtLib, EntryPoint = "intercept_xrGetInstanceProcAddr")] private static extern IntPtr intercept_xrGetInstanceProcAddr(IntPtr func); [DllImport(ExtLib, EntryPoint = "applyFoveationHTC")] private static extern XrResult applyFoveationHTC(Foveation.XrFoveationModeHTC mode, UInt32 configCount, Foveation.XrFoveationConfigurationHTC[] configs, UInt64 flags); /// /// function to apply HTC Foveation /// public static XrResult ApplyFoveationHTC(Foveation.XrFoveationModeHTC mode, UInt32 configCount, Foveation.XrFoveationConfigurationHTC[] configs, UInt64 flags = 0) { //Debug.Log("Unity HTCFoveat:configCount " + configCount); //if (configCount >=2) { //Debug.Log("Unity HTCFoveat:configs[0].clearFovDegree " + configs[0].clearFovDegree); //Debug.Log("Unity HTCFoveat:configs[0].level " + configs[0].level); //Debug.Log("Unity HTCFoveat:configs[1].clearFovDegree " + configs[1].clearFovDegree); //Debug.Log("Unity HTCFoveat:configs[1].level " + configs[1].level); //} return applyFoveationHTC(mode, configCount, configs, flags); } } }