// ===================== 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 s_JointLocation = new Dictionary() { { true, new XrHandJointLocationEXT[(int)XrHandJointEXT.XR_HAND_JOINT_MAX_ENUM_EXT] }, { false, new XrHandJointLocationEXT[(int)XrHandJointEXT.XR_HAND_JOINT_MAX_ENUM_EXT] } }; protected List l_HandJointLocation = new List(); /// /// A convenient function to retrieve the left/right hand joint location data. /// /// True for left hand. /// Joint location data in XrHandJointLocationEXT. /// True for valid data. 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; } } /// /// Refer to OpenXR xrCreateHandTrackerEXT. /// /// /// /// public static XrResult xrCreateHandTrackerEXT(ref XrHandTrackerCreateInfoEXT createInfo, out ulong handTracker) { return Interop.xrCreateHandTrackerEXT(ref createInfo, out handTracker); } /// /// Refer to OpenXR xrDestroyHandTrackerEXT. /// /// /// public static XrResult xrDestroyHandTrackerEXT(ulong handTracker) { return Interop.xrDestroyHandTrackerEXT(handTracker); } /// /// Refer to OpenXR xrLocateHandJointsEXT. /// /// /// /// /// public static XrResult xrLocateHandJointsEXT(ulong handTracker, XrHandJointsLocateInfoEXT locateInfo, out XrHandJointLocationsEXT locations) { return Interop.xrLocateHandJointsEXT(handTracker, locateInfo, out locations); } } }