159 lines
4.9 KiB
C#

using UnityEditor;
using UnityEngine.XR.OpenXR.Features;
using System.Runtime.InteropServices;
using System;
using Unity.XR.OpenXR.Features.PICOSupport;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor.XR.OpenXR.Features;
[OpenXRFeature(UiName = "OpenXR Foveation",
BuildTargetGroups = new[] { BuildTargetGroup.Android },
OpenxrExtensionStrings = extensionList,
Company = "PICO",
Version = "1.0.0",
FeatureId = featureId)]
#endif
public class FoveationFeature : OpenXRFeatureBase
{
public const string extensionList = "XR_FB_foveation " +
"XR_FB_foveation_configuration " +
"XR_FB_foveation_vulkan " +
"XR_META_foveation_eye_tracked " +
"XR_META_vulkan_swapchain_create_info " +
"XR_FB_swapchain_update_state ";
public const string featureId = "com.pico.openxr.feature.foveation";
public enum FoveatedRenderingLevel
{
Off = 0,
Low = 1,
Medium = 2,
High = 3
}
public enum FoveatedRenderingMode
{
FixedFoveatedRendering = 0,
EyeTrackedFoveatedRendering = 1
}
private static string TAG = "FoveationFeature";
private static UInt32 _foveatedRenderingLevel = 0;
private static UInt32 _useDynamicFoveation = 0;
public static bool isExtensionEnable =false;
public override string GetExtensionString()
{
return extensionList;
}
public override void Initialize(IntPtr intPtr)
{
isExtensionEnable=_isExtensionEnable;
}
public override void SessionCreate()
{
if (!isExtensionEnable)
{
return ;
}
PICOProjectSetting projectConfig = PICOProjectSetting.GetProjectConfig();
if (projectConfig.foveationEnable)
{
setFoveationEyeTracked(projectConfig.foveatedRenderingMode ==
FoveatedRenderingMode.EyeTrackedFoveatedRendering);
foveatedRenderingLevel = projectConfig.foveatedRenderingLevel;
setSubsampledEnabled(projectConfig.isSubsampledEnabled);
}
}
public static FoveatedRenderingLevel foveatedRenderingLevel
{
get
{
if (!isExtensionEnable)
{
return FoveatedRenderingLevel.Off;
}
UInt32 level;
FBGetFoveationLevel(out level);
PLog.i($" foveatedRenderingLevel get if level= {level}");
return (FoveatedRenderingLevel)level;
}
set
{
if (!isExtensionEnable)
{
return;
}
PLog.i($" foveatedRenderingLevel set if value= {value}");
_foveatedRenderingLevel = (UInt32)value;
FBSetFoveationLevel(xrSession, _foveatedRenderingLevel, 0.0f, _useDynamicFoveation);
}
}
public static bool useDynamicFoveatedRendering
{
get
{
if (!isExtensionEnable)
{
return false;
}
UInt32 dynamic;
FBGetFoveationLevel(out dynamic);
return dynamic != 0;
}
set
{
if (!isExtensionEnable)
{
return ;
}
if (value)
_useDynamicFoveation = 1;
else
_useDynamicFoveation = 0;
FBSetFoveationLevel(xrSession, _foveatedRenderingLevel, 0.0f, _useDynamicFoveation);
}
}
public static bool supportsFoveationEyeTracked
{
get
{
if (!isExtensionEnable)
{
return false;
}
return isSupportsFoveationEyeTracked(xrInstance);
}
}
#region OpenXR Plugin DLL Imports
[DllImport("UnityOpenXR", EntryPoint = "FBSetFoveationLevel")]
private static extern void FBSetFoveationLevel(UInt64 session, UInt32 level, float verticalOffset, UInt32 dynamic);
[DllImport("UnityOpenXR", EntryPoint = "FBGetFoveationLevel")]
private static extern void FBGetFoveationLevel(out UInt32 level);
[DllImport("UnityOpenXR", EntryPoint = "FBGetFoveationDynamic")]
private static extern void FBGetFoveationDynamic(out UInt32 dynamic);
#endregion
const string extLib = "openxr_pico";
[DllImport(extLib, EntryPoint = "PICO_isSupportsFoveationEyeTracked", CallingConvention = CallingConvention.Cdecl)]
private static extern bool isSupportsFoveationEyeTracked(ulong xrInstance);
[DllImport(extLib, EntryPoint = "PICO_setFoveationEyeTracked", CallingConvention = CallingConvention.Cdecl)]
private static extern void setFoveationEyeTracked(bool value);
[DllImport(extLib, EntryPoint = "PICO_setSubsampledEnabled", CallingConvention = CallingConvention.Cdecl)]
private static extern void setSubsampledEnabled(bool value);
}