NativeSwapManager.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #define GrayCamera
  2. using UnityEngine;
  3. using System.Runtime.InteropServices;
  4. using System;
  5. using EZXR.Glass.SixDof;
  6. using EZXR.Glass.Core;
  7. namespace EZXR.Glass.Inputs
  8. {
  9. /// <summary>
  10. /// 确保此脚本执行顺序在ARHandSDK中为首位,因为整个ARHandSDK的数据刷新在此脚本的Update中
  11. /// </summary>
  12. [ScriptExecutionOrder(-53)]
  13. /// <summary>
  14. /// 与底层算法交互
  15. /// </summary>
  16. public class NativeSwapManager : MonoBehaviour
  17. {
  18. #region 单例
  19. private static NativeSwapManager instance;
  20. public static NativeSwapManager Instance
  21. {
  22. get
  23. {
  24. return instance;
  25. }
  26. }
  27. #endregion
  28. #region 与算法交互的struct定义
  29. [StructLayout(LayoutKind.Sequential)]
  30. public struct Point2
  31. {
  32. public float x;
  33. public float y;
  34. public override string ToString()
  35. {
  36. return "(" + x + "," + y + ")";
  37. }
  38. }
  39. [StructLayout(LayoutKind.Sequential)]
  40. public struct Point3
  41. {
  42. public float x;
  43. public float y;
  44. public float z;
  45. public Point3(float x, float y, float z)
  46. {
  47. this.x = x;
  48. this.y = y;
  49. this.z = z;
  50. }
  51. public Point3(Vector3 point)
  52. {
  53. x = point.x;
  54. y = point.y;
  55. z = point.z;
  56. }
  57. public override string ToString()
  58. {
  59. return "(" + x + "," + y + "," + z + ")";
  60. }
  61. }
  62. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  63. public struct HandTrackingData
  64. {
  65. public int version;
  66. /// <summary>
  67. /// 检测范围内是否存在手
  68. /// </summary>
  69. [MarshalAs(UnmanagedType.I1)]
  70. public bool isTracked;
  71. public float confidence;
  72. /// <summary>
  73. /// 用来确定这个数据是左手的还是右手的
  74. /// </summary>
  75. public HandType handType;
  76. /// <summary>
  77. /// 手势类型
  78. /// </summary>
  79. public GestureType gestureType;
  80. /// <summary>
  81. /// 手部节点的数量
  82. /// </summary>
  83. public uint handJointsCount;
  84. /// <summary>
  85. /// 0是拇指根节点,3是大拇指指尖点,4是食指根节点,16是小拇指根节点向手腕延伸点(不到手腕),21是掌心点,22是手腕靠近大拇指,23是手腕靠近小拇指,24是手腕中心点
  86. /// </summary>
  87. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
  88. public HandJointData[] handJointData;
  89. /// <summary>
  90. /// 模型手拉伸的比例参数
  91. /// </summary>
  92. public float model_scale;
  93. /// <summary>
  94. /// 数组id从0到4分别代表大拇指到小拇指
  95. /// 值:0代表伸直,1代表完全弯曲
  96. /// </summary>
  97. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
  98. public float[] fingler_curl;
  99. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
  100. public int[] reserved;
  101. }
  102. [StructLayout(LayoutKind.Sequential)]
  103. public struct HandJointData
  104. {
  105. public int version;
  106. public HandJointType handJointType;
  107. public Mat4f handJointPose;
  108. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
  109. public int[] reserved;
  110. }
  111. [StructLayout(LayoutKind.Sequential)]
  112. public struct Mat4f
  113. {
  114. public Vector4f col0;
  115. public Vector4f col1;
  116. public Vector4f col2;
  117. public Vector4f col3;
  118. }
  119. public struct Vector4f
  120. {
  121. public float x, y, z, w;
  122. }
  123. #endregion
  124. private partial struct NativeAPI
  125. {
  126. #if EZXRCS
  127. [DllImport(NativeConsts.NativeLibrary)]
  128. public static extern void getHandPoseData([Out, In] IntPtr handposedata, int size);
  129. [DllImport(NativeConsts.NativeLibrary)]
  130. public static extern void getHandPoseDataWithHeadPose([Out, In] IntPtr handposedata, int handposedataSize, float[] headpose, int headposeSize, double headposetimestamp);
  131. #else
  132. [DllImport(NativeConsts.NativeLibrary)]
  133. public static extern void getHandPoseData([Out, In] IntPtr handposedata);
  134. [DllImport(NativeConsts.NativeLibrary)]
  135. public static extern void getHandPoseDataWithHeadPose([Out, In] IntPtr handposedata, float[] headpose, double headposetimestamp);
  136. #endif
  137. }
  138. /// <summary>
  139. ///
  140. /// </summary>
  141. /// <param name="mode">0是GPU,1是DSP</param>
  142. /// <returns></returns>
  143. [DllImport(NativeConsts.NativeLibrary)]
  144. public static extern bool setHandRunMode(int mode);
  145. public static void filterPoint(ref Point3 point, int id)
  146. {
  147. //if (!Application.isEditor)
  148. //{
  149. // filter_point(ref point, id);
  150. //}
  151. }
  152. #region 变量定义
  153. /// <summary>
  154. /// HandTrackingData更新的话会通知到外部
  155. /// </summary>
  156. public static event Action<HandTrackingData[]> OnHandTrackingDataUpdated;
  157. /// <summary>
  158. /// 用于从算法c++获得检测结果,这个指针是在非托管区域开辟的内存的指针(内存大小是2个HandTrackingData长度)
  159. /// </summary>
  160. public static IntPtr ptr_HandTrackingData;
  161. public static IntPtr ptr_HandTrackingData0;
  162. /// <summary>
  163. /// 手部追踪数据
  164. /// </summary>
  165. HandTrackingData[] handTrackingData = new HandTrackingData[2];
  166. int handTrackingDataLength;
  167. #endregion
  168. private void Awake()
  169. {
  170. instance = this;
  171. }
  172. void Start()
  173. {
  174. //为了接收算法的结果,在非托管内存区域开辟长度为2个HandTrackingData的内存
  175. handTrackingDataLength = Marshal.SizeOf(typeof(HandTrackingData));
  176. ptr_HandTrackingData = Marshal.AllocHGlobal(handTrackingDataLength * 2);
  177. ptr_HandTrackingData0 = new IntPtr(ptr_HandTrackingData.ToInt64() + handTrackingDataLength);
  178. //用于将Marshal开辟的非托管区域的所有值清零以避免内存区域原数据造成的影响
  179. HandTrackingData handTrackingDataTemp = new HandTrackingData();
  180. Marshal.StructureToPtr(handTrackingDataTemp, ptr_HandTrackingData, false);
  181. Marshal.StructureToPtr(handTrackingDataTemp, ptr_HandTrackingData0, false);
  182. handTrackingData[0] = new HandTrackingData();
  183. handTrackingData[1] = new HandTrackingData();
  184. }
  185. void Update()
  186. {
  187. if (!Application.isEditor && (ARFrame.SessionStatus == EZVIOState.EZVIOCameraState_Tracking || ARFrame.SessionStatus == EZVIOState.EZVIOCameraState_Track_Limited))
  188. {
  189. Vector3 position = Vector3.zero;
  190. Quaternion rotation = Quaternion.identity;
  191. //Debug.Log("开始get_nreal_result_predict");
  192. //getHandPoseData(ptr_HandTrackingData);
  193. position = HMDPoseTracker.Instance.Head.position;
  194. rotation = HMDPoseTracker.Instance.Head.rotation;
  195. float[] headPosearr = new float[]{
  196. position.x,position.y,position.z,
  197. rotation.x,rotation.y,rotation.z,rotation.w };
  198. #if EZXRCS
  199. NativeAPI.getHandPoseDataWithHeadPose(ptr_HandTrackingData, handTrackingDataLength * 2, headPosearr, headPosearr.Length, ARFrame.HeadPoseTimestamp);
  200. #else
  201. NativeAPI.getHandPoseDataWithHeadPose(ptr_HandTrackingData, headPosearr, ARFrame.HeadPoseTimestamp);
  202. #endif
  203. //Debug.Log("得到数据get_nreal_result_predict");
  204. //Debug.Log("开始解析handTrackingData");
  205. handTrackingData[0] = Marshal.PtrToStructure<HandTrackingData>(ptr_HandTrackingData);
  206. handTrackingData[1] = Marshal.PtrToStructure<HandTrackingData>(ptr_HandTrackingData0);
  207. //Debug.Log("解析handTrackingData完毕");
  208. //#region 用于测试
  209. //NativeSwapManager.Mat4f mat4 = handTrackingData[0].handJointData[21].handJointPose;
  210. //Matrix4x4 m = new Matrix4x4();
  211. //m.SetColumn(0, new Vector4(mat4.col0.x, mat4.col0.y, mat4.col0.z, mat4.col0.w));
  212. //m.SetColumn(1, new Vector4(mat4.col1.x, mat4.col1.y, mat4.col1.z, mat4.col1.w));
  213. //m.SetColumn(2, new Vector4(mat4.col2.x, mat4.col2.y, mat4.col2.z, mat4.col2.w));
  214. //m.SetColumn(3, new Vector4(mat4.col3.x, mat4.col3.y, mat4.col3.z, mat4.col3.w));
  215. //if (!m.ValidTRS())
  216. //{
  217. // return;
  218. //}
  219. //Vector3 pos = m.GetColumn(3);
  220. //Debug.Log("Launcher - Test => headPosition:" + position.ToString("0.00") + ", headRotation:" + rotation.ToString("0.00000") + ", HeadPoseTimestamp:" + ARFrame.HeadPoseTimestamp + ", handPosition:" + pos.ToString("0.00"));
  221. //#endregion
  222. if (OnHandTrackingDataUpdated != null)
  223. {
  224. OnHandTrackingDataUpdated(handTrackingData);
  225. }
  226. }
  227. }
  228. }
  229. }