version 2.0.0
This commit is contained in:
129
com.htc.upm.vive.openxr/Runtime/Profiles/XR_EXT_hand_tracking.cs
Normal file
129
com.htc.upm.vive.openxr/Runtime/Profiles/XR_EXT_hand_tracking.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
// ===================== 2022 HTC Corporation. All Rights Reserved. ===================
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
//using VIVE.OpenXR.Utils;
|
||||
using VIVE.OpenXR.Hand;
|
||||
|
||||
namespace VIVE.OpenXR
|
||||
{
|
||||
public class XR_EXT_hand_tracking_defs
|
||||
{
|
||||
public virtual XrResult xrCreateHandTrackerEXT(ref XrHandTrackerCreateInfoEXT createInfo, out ulong handTracker)
|
||||
{
|
||||
handTracker = 0;
|
||||
return XrResult.XR_ERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
public virtual XrResult xrDestroyHandTrackerEXT(ulong handTracker)
|
||||
{
|
||||
return XrResult.XR_ERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
protected XrHandJointLocationsEXT m_JointLocations = new XrHandJointLocationsEXT(XrStructureType.XR_TYPE_HAND_JOINT_LOCATIONS_EXT, IntPtr.Zero, 0, 0, IntPtr.Zero);
|
||||
protected void InitializeHandJointLocations()
|
||||
{
|
||||
if (m_JointLocations.jointCount != 0) { return; }
|
||||
|
||||
m_JointLocations.type = XrStructureType.XR_TYPE_HAND_JOINT_LOCATIONS_EXT;
|
||||
m_JointLocations.next = IntPtr.Zero;
|
||||
m_JointLocations.isActive = 0;
|
||||
m_JointLocations.jointCount = (uint)XrHandJointEXT.XR_HAND_JOINT_MAX_ENUM_EXT;
|
||||
|
||||
XrHandJointLocationEXT joint_location_ext_type = default(XrHandJointLocationEXT);
|
||||
m_JointLocations.jointLocations = Marshal.AllocHGlobal(Marshal.SizeOf(joint_location_ext_type) * (int)m_JointLocations.jointCount);
|
||||
}
|
||||
public virtual XrResult xrLocateHandJointsEXT(ulong handTracker, XrHandJointsLocateInfoEXT locateInfo, out XrHandJointLocationsEXT locations)
|
||||
{
|
||||
locations = m_JointLocations;
|
||||
return XrResult.XR_ERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
protected Dictionary<bool, XrHandJointLocationEXT[]> s_JointLocation = new Dictionary<bool, XrHandJointLocationEXT[]>()
|
||||
{
|
||||
{ true, new XrHandJointLocationEXT[(int)XrHandJointEXT.XR_HAND_JOINT_MAX_ENUM_EXT] },
|
||||
{ false, new XrHandJointLocationEXT[(int)XrHandJointEXT.XR_HAND_JOINT_MAX_ENUM_EXT] }
|
||||
};
|
||||
protected List<XrHandJointLocationEXT> l_HandJointLocation = new List<XrHandJointLocationEXT>();
|
||||
/// <summary>
|
||||
/// A convenient function to retrieve the left/right hand joint <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XrHandJointLocationEXT">location data</see>.
|
||||
/// </summary>
|
||||
/// <param name="isLeft">True for left hand.</param>
|
||||
/// <param name="handJointLocation">Joint location data in <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XrHandJointLocationEXT">XrHandJointLocationEXT</see>.</param>
|
||||
/// <returns>True for valid data.</returns>
|
||||
public virtual bool GetJointLocations(bool isLeft, out XrHandJointLocationEXT[] handJointLocation)
|
||||
{
|
||||
handJointLocation = s_JointLocation[isLeft];
|
||||
|
||||
if (m_JointLocations.isActive == 1)
|
||||
{
|
||||
long offset = 0;
|
||||
XrHandJointLocationEXT joint_location_ext_type = default(XrHandJointLocationEXT);
|
||||
|
||||
if (IntPtr.Size == 4)
|
||||
offset = m_JointLocations.jointLocations.ToInt32();
|
||||
else
|
||||
offset = m_JointLocations.jointLocations.ToInt64();
|
||||
|
||||
for (int i = 0; i < m_JointLocations.jointCount; i++)
|
||||
{
|
||||
IntPtr joint_location_ext_ptr = new IntPtr(offset);
|
||||
s_JointLocation[isLeft][i] = (XrHandJointLocationEXT)Marshal.PtrToStructure(joint_location_ext_ptr, typeof(XrHandJointLocationEXT));
|
||||
offset += Marshal.SizeOf(joint_location_ext_type);
|
||||
}
|
||||
|
||||
handJointLocation = s_JointLocation[isLeft];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class XR_EXT_hand_tracking
|
||||
{
|
||||
static XR_EXT_hand_tracking_defs m_Instance = null;
|
||||
public static XR_EXT_hand_tracking_defs Interop
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Instance == null)
|
||||
{
|
||||
m_Instance = new XR_EXT_hand_tracking_impls();
|
||||
}
|
||||
return m_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refer to OpenXR <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#xrCreateHandTrackerEXT">xrCreateHandTrackerEXT</see>.
|
||||
/// </summary>
|
||||
/// <param name="createInfo"></param>
|
||||
/// <param name="handTracker"></param>
|
||||
/// <returns></returns>
|
||||
public static XrResult xrCreateHandTrackerEXT(ref XrHandTrackerCreateInfoEXT createInfo, out ulong handTracker)
|
||||
{
|
||||
return Interop.xrCreateHandTrackerEXT(ref createInfo, out handTracker);
|
||||
}
|
||||
/// <summary>
|
||||
/// Refer to OpenXR <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#xrDestroyHandTrackerEXT">xrDestroyHandTrackerEXT</see>.
|
||||
/// </summary>
|
||||
/// <param name="handTracker"></param>
|
||||
/// <returns></returns>
|
||||
public static XrResult xrDestroyHandTrackerEXT(ulong handTracker)
|
||||
{
|
||||
return Interop.xrDestroyHandTrackerEXT(handTracker);
|
||||
}
|
||||
/// <summary>
|
||||
/// Refer to OpenXR <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#xrLocateHandJointsEXT">xrLocateHandJointsEXT</see>.
|
||||
/// </summary>
|
||||
/// <param name="handTracker"></param>
|
||||
/// <param name="locateInfo"></param>
|
||||
/// <param name="locations"></param>
|
||||
/// <returns></returns>
|
||||
public static XrResult xrLocateHandJointsEXT(ulong handTracker, XrHandJointsLocateInfoEXT locateInfo, out XrHandJointLocationsEXT locations)
|
||||
{
|
||||
return Interop.xrLocateHandJointsEXT(handTracker, locateInfo, out locations);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e2bf12a4229e504096c59632e5d2a68
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,87 @@
|
||||
// ===================== 2022 HTC Corporation. All Rights Reserved. ===================
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
using UnityEngine.XR.OpenXR;
|
||||
using VIVE.OpenXR.Hand;
|
||||
|
||||
namespace VIVE.OpenXR
|
||||
{
|
||||
public class XR_EXT_hand_tracking_impls : XR_EXT_hand_tracking_defs
|
||||
{
|
||||
const string LOG_TAG = "VIVE.OpenXR.Android.XR_EXT_hand_tracking_impls";
|
||||
void DEBUG(string msg) { Debug.Log(LOG_TAG + " " + msg); }
|
||||
|
||||
public XR_EXT_hand_tracking_impls() { DEBUG("XR_EXT_hand_tracking_impls()"); }
|
||||
|
||||
private ViveHandTracking feature = null;
|
||||
private void ASSERT_FEATURE() {
|
||||
if (feature == null) { feature = OpenXRSettings.Instance.GetFeature<ViveHandTracking>(); }
|
||||
}
|
||||
|
||||
public override XrResult xrCreateHandTrackerEXT(ref XrHandTrackerCreateInfoEXT createInfo, out ulong handTracker)
|
||||
{
|
||||
DEBUG("xrCreateHandTrackerEXT");
|
||||
XrResult result = XrResult.XR_ERROR_VALIDATION_FAILURE;
|
||||
handTracker = 0;
|
||||
|
||||
ASSERT_FEATURE();
|
||||
if (feature)
|
||||
{
|
||||
XrHandTrackerCreateInfoEXT info = createInfo;
|
||||
result = (XrResult)feature.CreateHandTrackerEXT(ref info, out XrHandTrackerEXT tracker);
|
||||
if (result == XrResult.XR_SUCCESS) { handTracker = tracker; }
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
public override XrResult xrDestroyHandTrackerEXT(ulong handTracker)
|
||||
{
|
||||
DEBUG("xrDestroyHandTrackerEXT");
|
||||
|
||||
ASSERT_FEATURE();
|
||||
if (feature) { return (XrResult)feature.DestroyHandTrackerEXT(handTracker); }
|
||||
|
||||
return XrResult.XR_ERROR_VALIDATION_FAILURE;
|
||||
}
|
||||
public override XrResult xrLocateHandJointsEXT(ulong handTracker, XrHandJointsLocateInfoEXT locateInfo, out XrHandJointLocationsEXT locations)
|
||||
{
|
||||
XrResult result = XrResult.XR_ERROR_VALIDATION_FAILURE;
|
||||
|
||||
InitializeHandJointLocations();
|
||||
locations = m_JointLocations;
|
||||
|
||||
ASSERT_FEATURE();
|
||||
if (feature)
|
||||
{
|
||||
XrHandJointLocationsEXT joints = m_JointLocations;
|
||||
result = (XrResult)feature.LocateHandJointsEXT(handTracker, locateInfo, ref joints);
|
||||
if (result == XrResult.XR_SUCCESS) { locations = joints; }
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override bool GetJointLocations(bool isLeft, out XrHandJointLocationEXT[] handJointLocation)
|
||||
{
|
||||
ASSERT_FEATURE();
|
||||
if (feature)
|
||||
{
|
||||
if (feature.GetJointLocations(isLeft, out XrHandJointLocationEXT[] array))
|
||||
{
|
||||
if (l_HandJointLocation == null) { l_HandJointLocation = new List<XrHandJointLocationEXT>(); }
|
||||
l_HandJointLocation.Clear();
|
||||
for (int i = 0; i < array.Length; i++) { l_HandJointLocation.Add(array[i]); }
|
||||
|
||||
handJointLocation = l_HandJointLocation.ToArray();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
handJointLocation = s_JointLocation[isLeft];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7d6929ec60d5a2469d083059c5ba39a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,113 @@
|
||||
// ===================== 2022 HTC Corporation. All Rights Reserved. ===================
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using VIVE.OpenXR.FacialTracking;
|
||||
|
||||
namespace VIVE.OpenXR
|
||||
{
|
||||
public class XR_HTC_facial_tracking_defs
|
||||
{
|
||||
public virtual XrResult xrCreateFacialTrackerHTC(XrFacialTrackerCreateInfoHTC createInfo, out ulong facialTracker)
|
||||
{
|
||||
facialTracker = 0;
|
||||
return XrResult.XR_ERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
public virtual XrResult xrDestroyFacialTrackerHTC(ulong facialTracker)
|
||||
{
|
||||
return XrResult.XR_ERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
const int kMaxExpressionCount = 64;
|
||||
protected XrFacialExpressionsHTC m_FacialExpressions = new XrFacialExpressionsHTC(XrStructureType.XR_TYPE_FACIAL_EXPRESSIONS_HTC, IntPtr.Zero, 0, 0, 0, IntPtr.Zero);
|
||||
protected void InitializeFacialExpressions()
|
||||
{
|
||||
if (m_FacialExpressions.expressionCount != 0) { return; }
|
||||
|
||||
m_FacialExpressions.type = XrStructureType.XR_TYPE_FACIAL_EXPRESSIONS_HTC;
|
||||
m_FacialExpressions.next = IntPtr.Zero;
|
||||
m_FacialExpressions.isActive = 0;
|
||||
m_FacialExpressions.sampleTime = 0;
|
||||
m_FacialExpressions.expressionCount = kMaxExpressionCount;
|
||||
m_FacialExpressions.expressionWeightings = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(float)) * kMaxExpressionCount);
|
||||
}
|
||||
public virtual XrResult xrGetFacialExpressionsHTC(ulong facialTracker, out XrFacialExpressionsHTC facialExpressions)
|
||||
{
|
||||
facialExpressions = m_FacialExpressions;
|
||||
return XrResult.XR_ERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
|
||||
protected Dictionary<XrFacialTrackingTypeHTC, float[]> s_ExpressionWeightings = new Dictionary<XrFacialTrackingTypeHTC, float[]>()
|
||||
{
|
||||
{ XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC, new float[kMaxExpressionCount] },
|
||||
{ XrFacialTrackingTypeHTC.XR_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC, new float[kMaxExpressionCount] }
|
||||
};
|
||||
/// <summary>
|
||||
/// Retrieves an array of values of blend shapes for a facial expression on a given time.
|
||||
/// </summary>
|
||||
/// <param name="facialTrackingType">The <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XrFacialTrackingTypeHTC">XrFacialTrackingTypeHTC</see> describes which type of tracking the <see cref="XrFacialTrackerHTC">XrFacialTrackerHTC</see> is using.</param>
|
||||
/// <param name="expressionWeightings">A float array filled in by the runtime, specifying the weightings for each blend shape. The array size is <see cref="XrEyeExpressionHTC.XR_EYE_EXPRESSION_MAX_ENUM_HTC">XR_EYE_EXPRESSION_MAX_ENUM_HTC</see> for eye expression and <see cref="XrLipExpressionHTC.XR_LIP_EXPRESSION_MAX_ENUM_HTC">XR_LIP_EXPRESSION_MAX_ENUM_HTC</see> for lip expression.</param>
|
||||
/// <returns>True for success.</returns>
|
||||
public virtual bool GetExpressionWeightings(XrFacialTrackingTypeHTC facialTrackingType, out float[] expressionWeightings)
|
||||
{
|
||||
expressionWeightings = s_ExpressionWeightings[facialTrackingType];
|
||||
int expressionCount = s_ExpressionWeightings[facialTrackingType].Length;
|
||||
|
||||
if (m_FacialExpressions.isActive == 1 && expressionCount <= kMaxExpressionCount)
|
||||
{
|
||||
Marshal.Copy(m_FacialExpressions.expressionWeightings, s_ExpressionWeightings[facialTrackingType], 0, s_ExpressionWeightings[facialTrackingType].Length);
|
||||
expressionWeightings = s_ExpressionWeightings[facialTrackingType];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class XR_HTC_facial_tracking
|
||||
{
|
||||
static XR_HTC_facial_tracking_defs m_Instance = null;
|
||||
public static XR_HTC_facial_tracking_defs Interop
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Instance == null)
|
||||
{
|
||||
m_Instance = new XR_HTC_facial_tracking_impls();
|
||||
}
|
||||
return m_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refer to OpenXR <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#xrCreateFacialTrackerHTC">xrCreateFacialTrackerHTC</see>.
|
||||
/// </summary>
|
||||
/// <param name="createInfo"></param>
|
||||
/// <param name="facialTracker"></param>
|
||||
/// <returns></returns>
|
||||
public static XrResult xrCreateFacialTrackerHTC(XrFacialTrackerCreateInfoHTC createInfo, out ulong facialTracker)
|
||||
{
|
||||
return Interop.xrCreateFacialTrackerHTC(createInfo, out facialTracker);
|
||||
}
|
||||
/// <summary>
|
||||
/// Refer to OpenXR <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#xrDestroyFacialTrackerHTC">xrDestroyFacialTrackerHTC</see>.
|
||||
/// </summary>
|
||||
/// <param name="facialTracker"></param>
|
||||
/// <returns></returns>
|
||||
public static XrResult xrDestroyFacialTrackerHTC(ulong facialTracker)
|
||||
{
|
||||
return Interop.xrDestroyFacialTrackerHTC(facialTracker);
|
||||
}
|
||||
/// <summary>
|
||||
/// Refer to OpenXR <see href="https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#xrGetFacialExpressionsHTC">xrGetFacialExpressionsHTC</see>
|
||||
/// </summary>
|
||||
/// <param name="facialTracker"></param>
|
||||
/// <param name="facialExpressions"></param>
|
||||
/// <returns></returns>
|
||||
public static XrResult xrGetFacialExpressionsHTC(ulong facialTracker, out XrFacialExpressionsHTC facialExpressions)
|
||||
{
|
||||
return Interop.xrGetFacialExpressionsHTC(facialTracker, out facialExpressions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a291ffd0f5a17ca44b07fa43f29a8e48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
// ===================== 2022 HTC Corporation. All Rights Reserved. ===================
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.XR.OpenXR;
|
||||
|
||||
using VIVE.OpenXR.FacialTracking;
|
||||
|
||||
|
||||
namespace VIVE.OpenXR
|
||||
{
|
||||
public class XR_HTC_facial_tracking_impls : XR_HTC_facial_tracking_defs
|
||||
{
|
||||
const string LOG_TAG = "VIVE.OpenXR.Android.XR_HTC_facial_tracking_impls";
|
||||
void DEBUG(string msg) { Debug.Log(LOG_TAG + " " + msg); }
|
||||
|
||||
private ViveFacialTracking feature = null;
|
||||
private void ASSERT_FEATURE() {
|
||||
if (feature == null) { feature = OpenXRSettings.Instance.GetFeature<ViveFacialTracking>(); }
|
||||
}
|
||||
|
||||
public override XrResult xrCreateFacialTrackerHTC(XrFacialTrackerCreateInfoHTC createInfo, out ulong facialTracker)
|
||||
{
|
||||
DEBUG("xrCreateFacialTrackerHTC");
|
||||
XrResult result = XrResult.XR_ERROR_VALIDATION_FAILURE;
|
||||
facialTracker = 0;
|
||||
|
||||
ASSERT_FEATURE();
|
||||
if (feature)
|
||||
{
|
||||
result = (XrResult)feature.CreateFacialTracker(createInfo, out XrFacialTrackerHTC value);
|
||||
if (result == XrResult.XR_SUCCESS) { facialTracker = value; }
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
public override XrResult xrDestroyFacialTrackerHTC(ulong facialTracker)
|
||||
{
|
||||
DEBUG("xrDestroyFacialTrackerHTC");
|
||||
|
||||
ASSERT_FEATURE();
|
||||
if (feature) { return (XrResult)feature.DestroyFacialTracker(facialTracker); }
|
||||
|
||||
return XrResult.XR_ERROR_VALIDATION_FAILURE;
|
||||
}
|
||||
public override XrResult xrGetFacialExpressionsHTC(ulong facialTracker, out XrFacialExpressionsHTC facialExpressions)
|
||||
{
|
||||
InitializeFacialExpressions();
|
||||
facialExpressions = m_FacialExpressions;
|
||||
XrResult result = XrResult.XR_ERROR_VALIDATION_FAILURE;
|
||||
|
||||
ASSERT_FEATURE();
|
||||
if (feature)
|
||||
{
|
||||
result = (XrResult)feature.GetFacialExpressions(facialTracker, out XrFacialExpressionsHTC exps);
|
||||
if (result == XrResult.XR_SUCCESS) { facialExpressions = exps; }
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override bool GetExpressionWeightings(XrFacialTrackingTypeHTC facialTrackingType, out float[] expressionWeightings)
|
||||
{
|
||||
ASSERT_FEATURE();
|
||||
if (feature) { return feature.GetFacialExpressions((XrFacialTrackingTypeHTC)facialTrackingType, out expressionWeightings); }
|
||||
|
||||
expressionWeightings = s_ExpressionWeightings[facialTrackingType];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef22a055fe672f04990446ce0bd458d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user