上传YomovSDK
This commit is contained in:
@@ -0,0 +1,291 @@
|
||||
// Copyright HTC Corporation All Rights Reserved.
|
||||
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using UnityEngine.XR.OpenXR.Features;
|
||||
using UnityEngine;
|
||||
using System.Text;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.XR.OpenXR.Features;
|
||||
#endif
|
||||
|
||||
namespace VIVE.OpenXR
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[OpenXRFeature(UiName = "VIVE XR Path Enumeration (Beta)",
|
||||
BuildTargetGroups = new[] { BuildTargetGroup.Android, BuildTargetGroup.Standalone },
|
||||
Company = "HTC",
|
||||
Desc = "The extension provides more flexibility for the user paths and input/output source paths related to an interaction profile. Developers can use this extension to obtain the path that the user has decided on.",
|
||||
DocumentationLink = "..\\Documentation",
|
||||
Version = "1.0.6",
|
||||
OpenxrExtensionStrings = kOpenxrExtensionString,
|
||||
FeatureId = featureId)]
|
||||
#endif
|
||||
public class VivePathEnumeration : OpenXRFeature
|
||||
{
|
||||
const string LOG_TAG = "VIVE.OpenXR.VivePathEnumeration ";
|
||||
StringBuilder m_sb = null;
|
||||
StringBuilder sb {
|
||||
get {
|
||||
if (m_sb == null) { m_sb = new StringBuilder(); }
|
||||
return m_sb;
|
||||
}
|
||||
}
|
||||
void DEBUG(StringBuilder msg) { Debug.Log(msg); }
|
||||
void WARNING(StringBuilder msg) { Debug.LogWarning(msg); }
|
||||
void ERROR(StringBuilder msg) { Debug.LogError(msg); }
|
||||
/// <summary>
|
||||
/// OpenXR specification <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_HTC_path_enumeration">12.1. XR_HTC_path_enumeration</see>.
|
||||
/// </summary>
|
||||
public const string kOpenxrExtensionString = "XR_HTC_path_enumeration";
|
||||
|
||||
/// <summary>
|
||||
/// The feature id string. This is used to give the feature a well known id for reference.
|
||||
/// </summary>
|
||||
public const string featureId = "vive.wave.openxr.feature.pathenumeration";
|
||||
|
||||
#region OpenXR Life Cycle
|
||||
#pragma warning disable
|
||||
private bool m_XrInstanceCreated = false;
|
||||
#pragma warning enable
|
||||
private XrInstance m_XrInstance = 0;
|
||||
/// <summary>
|
||||
/// Called when <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#xrCreateInstance">xrCreateInstance</see> is done.
|
||||
/// </summary>
|
||||
/// <param name="xrInstance">The created instance.</param>
|
||||
/// <returns>True for valid <see cref="XrInstance">XrInstance</see></returns>
|
||||
protected override bool OnInstanceCreate(ulong xrInstance)
|
||||
{
|
||||
if (!OpenXRRuntime.IsExtensionEnabled(kOpenxrExtensionString))
|
||||
{
|
||||
sb.Clear().Append(LOG_TAG).Append("OnInstanceCreate() ").Append(kOpenxrExtensionString).Append(" is NOT enabled."); WARNING(sb);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_XrInstanceCreated = true;
|
||||
m_XrInstance = xrInstance;
|
||||
sb.Clear().Append(LOG_TAG).Append("OnInstanceCreate() ").Append(m_XrInstance); DEBUG(sb);
|
||||
GetXrFunctionDelegates(m_XrInstance);
|
||||
return base.OnInstanceCreate(xrInstance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#xrDestroyInstance">xrDestroyInstance</see> is done.
|
||||
/// </summary>
|
||||
/// <param name="xrInstance">The instance to destroy.</param>
|
||||
protected override void OnInstanceDestroy(ulong xrInstance)
|
||||
{
|
||||
if (m_XrInstance == xrInstance)
|
||||
{
|
||||
m_XrInstanceCreated = false;
|
||||
m_XrInstance = 0;
|
||||
}
|
||||
sb.Clear().Append(LOG_TAG).Append("OnInstanceDestroy() ").Append(xrInstance); DEBUG(sb);
|
||||
}
|
||||
|
||||
private XrSystemId m_XrSystemId = 0;
|
||||
/// <summary>
|
||||
/// Called when the <see cref="XrSystemId">XrSystemId</see> retrieved by <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#xrGetSystem">xrGetSystem</see> is changed.
|
||||
/// </summary>
|
||||
/// <param name="xrSystem">The system id.</param>
|
||||
protected override void OnSystemChange(ulong xrSystem)
|
||||
{
|
||||
m_XrSystemId = xrSystem;
|
||||
sb.Clear().Append(LOG_TAG).Append("OnSystemChange() ").Append(m_XrSystemId); DEBUG(sb);
|
||||
}
|
||||
|
||||
private bool m_XrSessionCreated = false;
|
||||
private XrSession m_XrSession = 0;
|
||||
/// <summary>
|
||||
/// Called when <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#xrCreateSession">xrCreateSession</see> is done.
|
||||
/// </summary>
|
||||
/// <param name="xrSession">The created session ID.</param>
|
||||
protected override void OnSessionCreate(ulong xrSession)
|
||||
{
|
||||
m_XrSession = xrSession;
|
||||
m_XrSessionCreated = true;
|
||||
sb.Clear().Append(LOG_TAG).Append("OnSessionCreate() ").Append(m_XrSession); DEBUG(sb);
|
||||
}
|
||||
/// <summary>
|
||||
/// Called when <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#xrDestroySession">xrDestroySession</see> is done.
|
||||
/// </summary>
|
||||
/// <param name="xrSession">The session ID to destroy.</param>
|
||||
protected override void OnSessionDestroy(ulong xrSession)
|
||||
{
|
||||
sb.Clear().Append(LOG_TAG).Append("OnSessionDestroy() ").Append(xrSession); DEBUG(sb);
|
||||
m_XrSession = 0;
|
||||
m_XrSessionCreated = false;
|
||||
}
|
||||
#endregion
|
||||
#region OpenXR function delegates
|
||||
/// xrGetInstanceProcAddr
|
||||
OpenXRHelper.xrGetInstanceProcAddrDelegate XrGetInstanceProcAddr;
|
||||
VivePathEnumerationHelper.xrEnumeratePathsForInteractionProfileHTCDelegate xrEnumeratePathsForInteractionProfileHTC;
|
||||
private bool GetXrFunctionDelegates(XrInstance xrInstance)
|
||||
{
|
||||
// xrGetInstanceProcAddr
|
||||
if (xrGetInstanceProcAddr != null && xrGetInstanceProcAddr != IntPtr.Zero)
|
||||
{
|
||||
sb.Clear().Append(LOG_TAG).Append("Get function pointer of xrGetInstanceProcAddr."); DEBUG(sb);
|
||||
XrGetInstanceProcAddr = Marshal.GetDelegateForFunctionPointer(
|
||||
xrGetInstanceProcAddr,
|
||||
typeof(OpenXRHelper.xrGetInstanceProcAddrDelegate)) as OpenXRHelper.xrGetInstanceProcAddrDelegate;
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Clear().Append(LOG_TAG).Append("No function pointer of xrGetInstanceProcAddr"); ERROR(sb);
|
||||
return false;
|
||||
}
|
||||
|
||||
IntPtr funcPtr = IntPtr.Zero;
|
||||
/// xrEnumeratePathsForInteractionProfileHTC
|
||||
if (XrGetInstanceProcAddr(xrInstance, "xrEnumeratePathsForInteractionProfileHTC", out funcPtr) == XrResult.XR_SUCCESS)
|
||||
{
|
||||
if (funcPtr != IntPtr.Zero)
|
||||
{
|
||||
sb.Clear().Append(LOG_TAG).Append("Get function pointer of xrEnumeratePathsForInteractionProfileHTC."); DEBUG(sb);
|
||||
xrEnumeratePathsForInteractionProfileHTC = Marshal.GetDelegateForFunctionPointer(
|
||||
funcPtr,
|
||||
typeof(VivePathEnumerationHelper.xrEnumeratePathsForInteractionProfileHTCDelegate)) as VivePathEnumerationHelper.xrEnumeratePathsForInteractionProfileHTCDelegate;
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Clear().Append(LOG_TAG).Append("No function pointer of xrEnumeratePathsForInteractionProfileHTC.");
|
||||
ERROR(sb);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Clear().Append(LOG_TAG).Append("No function pointer of xrEnumeratePathsForInteractionProfileHTC");
|
||||
ERROR(sb);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private List<T> CreateList<T>(UInt32 count, T initialValue)
|
||||
{
|
||||
List<T> list = new List<T>();
|
||||
for (int i = 0; i < count; i++)
|
||||
list.Add(initialValue);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public XrResult EnumeratePathsForInteractionProfileHTC(
|
||||
ref XrPathsForInteractionProfileEnumerateInfoHTC createInfo,
|
||||
UInt32 pathCapacityInput,
|
||||
ref UInt32 pathCountOutput,
|
||||
[In, Out] XrPath[] paths)
|
||||
{
|
||||
if (!m_XrInstanceCreated)
|
||||
{
|
||||
sb.Clear().Append(LOG_TAG).Append("EnumeratePathsForInteractionProfileHTC() XR_ERROR_INSTANCE_LOST."); ERROR(sb);
|
||||
paths = null;
|
||||
return XrResult.XR_ERROR_INSTANCE_LOST;
|
||||
}
|
||||
return xrEnumeratePathsForInteractionProfileHTC(m_XrInstance,
|
||||
ref createInfo, pathCapacityInput,ref pathCountOutput, paths);
|
||||
}
|
||||
|
||||
public bool GetUserPaths(string interactionProfileString, out XrPath[] userPaths)
|
||||
{
|
||||
userPaths = null;
|
||||
XrPathsForInteractionProfileEnumerateInfoHTC enumerateInfo;
|
||||
if (!m_XrInstanceCreated) { return false; }
|
||||
|
||||
string func = "GetUserPaths() ";
|
||||
|
||||
if (xrEnumeratePathsForInteractionProfileHTC == null)
|
||||
{
|
||||
sb.Clear().Append(LOG_TAG).Append(func).Append("No function pointer of xrEnumeratePathsForInteractionProfileHTC"); WARNING(sb);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 1. Get user path count of sepecified profile.
|
||||
UInt32 trackerCount = 0;
|
||||
enumerateInfo.type = XrStructureType.XR_TYPE_UNKNOWN;
|
||||
enumerateInfo.next = IntPtr.Zero;
|
||||
enumerateInfo.interactionProfile = StringToPath(interactionProfileString);
|
||||
enumerateInfo.userPath = OpenXRHelper.XR_NULL_PATH;
|
||||
|
||||
XrResult result = xrEnumeratePathsForInteractionProfileHTC(m_XrInstance, ref enumerateInfo, 0, ref trackerCount, null);
|
||||
sb.Clear().Append(LOG_TAG).Append(func).Append("xrEnumeratePathsForInteractionProfileHTC result: ").Append(result)
|
||||
.Append(", profile: ").Append(interactionProfileString)
|
||||
.Append(", trackerCount: ").Append(trackerCount);
|
||||
DEBUG(sb);
|
||||
if (result != XrResult.XR_SUCCESS || trackerCount <= 0) { return false; }
|
||||
|
||||
// 2. Get user paths of sepecified profile.
|
||||
List<XrPath> trackerList = CreateList<XrPath>(trackerCount, OpenXRHelper.XR_NULL_PATH);
|
||||
XrPath[] trackers = trackerList.ToArray();
|
||||
result = xrEnumeratePathsForInteractionProfileHTC(
|
||||
m_XrInstance,
|
||||
ref enumerateInfo,
|
||||
pathCapacityInput: (UInt32)(trackers.Length & 0x7FFFFFFF),
|
||||
pathCountOutput: ref trackerCount,
|
||||
paths: trackers);
|
||||
if (result != XrResult.XR_SUCCESS)
|
||||
{
|
||||
sb.Clear().Append(LOG_TAG).Append(func).Append("Retrieves trackers failed."); ERROR(sb);
|
||||
return false;
|
||||
}
|
||||
|
||||
userPaths = trackers;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool GetInputPathsWithUserPath(string interactionProfileString, XrPath userPath, out XrPath[] inputPaths)
|
||||
{
|
||||
string func = "GetInputPathsWithUserPath() ";
|
||||
if (!m_XrInstanceCreated) { inputPaths = null; return false; }
|
||||
UInt32 trackerCount = 0;
|
||||
XrPathsForInteractionProfileEnumerateInfoHTC enumerateInfo;
|
||||
enumerateInfo.type = (XrStructureType)1000319000;//Todo : update openxr spec and prevent hard-code.
|
||||
enumerateInfo.next = IntPtr.Zero;
|
||||
enumerateInfo.interactionProfile = StringToPath(interactionProfileString);
|
||||
enumerateInfo.userPath = userPath;
|
||||
UInt32 Count = 0;
|
||||
xrEnumeratePathsForInteractionProfileHTC(
|
||||
m_XrInstance,
|
||||
ref enumerateInfo,
|
||||
0,
|
||||
pathCountOutput: ref Count,
|
||||
paths: null);
|
||||
if (Count > 0)
|
||||
{
|
||||
List<XrPath> pathlist = CreateList<XrPath>(Count, OpenXRHelper.XR_NULL_PATH);
|
||||
inputPaths = pathlist.ToArray();
|
||||
XrResult result = xrEnumeratePathsForInteractionProfileHTC(
|
||||
m_XrInstance,
|
||||
ref enumerateInfo,
|
||||
pathCapacityInput: (UInt32)(inputPaths.Length & 0x7FFFFFFF),
|
||||
pathCountOutput: ref Count,
|
||||
paths: inputPaths);
|
||||
UnityEngine.Debug.Log("Get inputpath str : "+PathToString(inputPaths[0]));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
inputPaths = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public string xrPathToString(ulong path)
|
||||
{
|
||||
return PathToString(path);
|
||||
}
|
||||
|
||||
public ulong xrStringToPath(string str)
|
||||
{
|
||||
return StringToPath(str);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80a759a91a5fd35479312cdd18e70a32
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright HTC Corporation All Rights Reserved.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VIVE.OpenXR
|
||||
{
|
||||
/// <summary>
|
||||
/// When developers would like to retrieve the supported user paths from the interactionProfile, userPath should be <see cref="OpenXRHelper.XR_NULL_PATH">XR_NULL_PATH</see>. If the interaction profile for any of the suggested bindings does not exist in the allowlist defined in Interaction Profile Paths, the runtime must return <see cref="XrResult.XR_ERROR_PATH_UNSUPPORTED">XR_ERROR_PATH_UNSUPPORTED</see>.
|
||||
///
|
||||
/// If developers would like to retrieve the input/output paths related to the interactionProfile, userPath should be a valid user path.If userPath is not one of the device input subpaths described in section /user paths, the runtime must return <see cref="XrResult.XR_ERROR_PATH_UNSUPPORTED">XR_ERROR_PATH_UNSUPPORTED</see>.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct XrPathsForInteractionProfileEnumerateInfoHTC
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="XrStructureType">XrStructureType</see> of this structure.
|
||||
/// </summary>
|
||||
public XrStructureType type;
|
||||
/// <summary>
|
||||
/// NULL or a pointer to the next structure in a structure chain.
|
||||
/// </summary>
|
||||
public IntPtr next;
|
||||
/// <summary>
|
||||
/// The <see cref="XrPath">XrPath</see> of an interaction profile.
|
||||
/// </summary>
|
||||
public XrPath interactionProfile;
|
||||
/// <summary>
|
||||
/// The top level user path the application would like to retrieve the interaction profile for. Set <see cref="OpenXRHelper.XR_NULL_PATH">XR_NULL_PATH</see> is used to enumerate all user paths from the input interactionProfile. Set as a valid user path is used to enumerate all input/output source paths.
|
||||
/// </summary>
|
||||
public XrPath userPath;
|
||||
}
|
||||
|
||||
public static class VivePathEnumerationHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Provided by XR_HTC_path_enumerate.
|
||||
/// Developers should call this API with the value of pathCapacityInput equals to 0 to retrieve the size of paths from pathCountOutput. Then developers allocate the array of <see cref="XrPath">XrPath</see> data and assign the pathCapacityInput and call the API in the second time.
|
||||
///
|
||||
/// If the input pathCapacityInput is not sufficient to contain all output indices, the runtime must return <see cref="XrResult.XR_ERROR_SIZE_INSUFFICIENT">XR_ERROR_SIZE_INSUFFICIENT</see> on calls to <see cref="xrEnumeratePathsForInteractionProfileHTC">xrEnumeratePathsForInteractionProfileHTC</see> and not change the content in paths.
|
||||
/// </summary>
|
||||
/// <param name="instance">An <see cref="XrInstance">XrInstance</see> previously created.</param>
|
||||
/// <param name="enumerateInfo">A <see cref="XrPathsForInteractionProfileEnumerateInfoHTC">XrPathsForInteractionProfileEnumerateInfoHTC</see> providing the query information.</param>
|
||||
/// <param name="pathCapacityInput">The capacity of the paths array, or 0 to indicate a request to retrieve the required capacity.</param>
|
||||
/// <param name="pathCountOutput">A pointer to the count of paths written, or a pointer to the required capacity in the case that pathCapacityInput is insufficient.</param>
|
||||
/// <param name="paths">A pointer to an array of <see cref="XrPath">XrPath</see>, but can be NULL if pathCapacityInput is 0.</param>
|
||||
/// <returns>XR_SUCCESS for success.</returns>
|
||||
public delegate XrResult xrEnumeratePathsForInteractionProfileHTCDelegate(
|
||||
XrInstance instance,
|
||||
ref XrPathsForInteractionProfileEnumerateInfoHTC enumerateInfo,
|
||||
UInt32 pathCapacityInput,
|
||||
ref UInt32 pathCountOutput,
|
||||
[In, Out] XrPath[] paths);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d4f3e0bc01e6c34a9b9a1faf40aa93f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user