NativeHeadTracking.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /****************************************************************************
  2. * Copyright 2019 Nreal Techonology Limited. All rights reserved.
  3. *
  4. * This file is part of NRSDK.
  5. *
  6. * https://www.nreal.ai/
  7. *
  8. *****************************************************************************/
  9. namespace NRKernal
  10. {
  11. using System;
  12. using System.Runtime.InteropServices;
  13. using UnityEngine;
  14. /// <summary> 6-dof Head Tracking's Native API . </summary>
  15. public class NativeHeadTracking
  16. {
  17. /// <summary> The native interface. </summary>
  18. private NativeInterface m_NativeInterface;
  19. /// <summary> Gets the handle of the tracking. </summary>
  20. /// <value> The tracking handle. </value>
  21. public UInt64 TrackingHandle
  22. {
  23. get
  24. {
  25. return m_NativeInterface.TrackingHandle;
  26. }
  27. }
  28. /// <summary> Handle of the head tracking. </summary>
  29. private UInt64 m_HeadTrackingHandle = 0;
  30. /// <summary> Gets the handle of the head tracking. </summary>
  31. /// <value> The head tracking handle. </value>
  32. public UInt64 HeadTrackingHandle
  33. {
  34. get
  35. {
  36. return m_HeadTrackingHandle;
  37. }
  38. }
  39. /// <summary> Constructor. </summary>
  40. /// <param name="nativeInterface"> The native interface.</param>
  41. public NativeHeadTracking(NativeInterface nativeInterface)
  42. {
  43. m_NativeInterface = nativeInterface;
  44. }
  45. /// <summary> Creates a new bool. </summary>
  46. /// <returns> True if it succeeds, false if it fails. </returns>
  47. public bool Start()
  48. {
  49. if (m_NativeInterface.TrackingHandle == 0)
  50. {
  51. return false;
  52. }
  53. var result = NativeApi.NRHeadTrackingCreate(m_NativeInterface.TrackingHandle, ref m_HeadTrackingHandle);
  54. NativeErrorListener.Check(result, this, "Create");
  55. return result == NativeResult.Success;
  56. }
  57. /// <summary> Gets head pose. </summary>
  58. /// <param name="pose"> [in,out] The pose.</param>
  59. /// <param name="timestamp"> (Optional) The timestamp.</param>
  60. /// <param name="predict"> (Optional) The predict.</param>
  61. /// <returns> True if it succeeds, false if it fails. </returns>
  62. public bool GetHeadPose(ref Pose pose, UInt64 timestamp)
  63. {
  64. if (m_HeadTrackingHandle == 0)
  65. {
  66. pose = Pose.identity;
  67. return false;
  68. }
  69. UInt64 headPoseHandle = 0;
  70. var acquireTrackingPoseResult = NativeApi.NRHeadTrackingAcquireTrackingPose(m_NativeInterface.TrackingHandle, m_HeadTrackingHandle, timestamp, ref headPoseHandle);
  71. if (acquireTrackingPoseResult != NativeResult.Success)
  72. {
  73. return false;
  74. }
  75. NativeMat4f headpos_native = new NativeMat4f(Matrix4x4.identity);
  76. var getPoseResult = NativeApi.NRTrackingPoseGetPose(m_NativeInterface.TrackingHandle, headPoseHandle, ref headpos_native);
  77. if (getPoseResult != NativeResult.Success)
  78. {
  79. return false;
  80. }
  81. ConversionUtility.ApiPoseToUnityPose(headpos_native, out pose);
  82. NativeApi.NRTrackingPoseDestroy(m_NativeInterface.TrackingHandle, headPoseHandle);
  83. return (acquireTrackingPoseResult == NativeResult.Success) && (getPoseResult == NativeResult.Success);
  84. }
  85. public bool GetHeadPoseRecommend(ref Pose pose)
  86. {
  87. if (m_HeadTrackingHandle == 0)
  88. {
  89. pose = Pose.identity;
  90. return false;
  91. }
  92. ulong recommend_time = 0;
  93. ulong predict_time = 0;
  94. var result = NativeApi.NRTrackingGetHMDTimeNanos(m_NativeInterface.TrackingHandle, ref recommend_time);
  95. if (result != NativeResult.Success)
  96. {
  97. return false;
  98. }
  99. result = NativeApi.NRHeadTrackingGetRecommendPredictTime(m_NativeInterface.TrackingHandle, m_HeadTrackingHandle, ref predict_time);
  100. if (result != NativeResult.Success)
  101. {
  102. return false;
  103. }
  104. recommend_time += predict_time;
  105. return GetHeadPose(ref pose, recommend_time);
  106. }
  107. public ulong GetHMDTimeNanos()
  108. {
  109. ulong timestamp = 0;
  110. NativeApi.NRTrackingGetHMDTimeNanos(m_NativeInterface.TrackingHandle, ref timestamp);
  111. return timestamp;
  112. }
  113. public bool GetFramePresentHeadPose(ref Pose pose, ref LostTrackingReason lostReason, ref UInt64 timestamp)
  114. {
  115. if (m_HeadTrackingHandle == 0 || m_NativeInterface.TrackingHandle == 0)
  116. {
  117. NRDebugger.Error("[NativeTrack] GetFramePresentHeadPose: trackingHandle is zero");
  118. pose = Pose.identity;
  119. timestamp = 0;
  120. return false;
  121. }
  122. UInt64 headPoseHandle = 0;
  123. m_NativeInterface.NativeRenderring.GetFramePresentTime(ref timestamp);
  124. var acquireTrackingPoseResult = NativeApi.NRHeadTrackingAcquireTrackingPose(m_NativeInterface.TrackingHandle, m_HeadTrackingHandle, timestamp, ref headPoseHandle);
  125. if (acquireTrackingPoseResult != NativeResult.Success)
  126. {
  127. // NRDebugger.Warning("[NativeTrack] GetFramePresentHeadPose: acquireTrackingPoseResult={0}", acquireTrackingPoseResult);
  128. lostReason = LostTrackingReason.PRE_INITIALIZING;
  129. return true;
  130. }
  131. var trackReasonRst = NativeApi.NRTrackingPoseGetTrackingReason(m_NativeInterface.TrackingHandle, headPoseHandle, ref lostReason);
  132. NativeErrorListener.Check(trackReasonRst, this, "GetFramePresentHeadPose-LostReason");
  133. // NRDebugger.Info("[NativeTrack] GetFramePresentHeadPose: getPoseResult={0}, lost_tracking_reason={1}, result={2}", getPoseResult, lost_tracking_reason, result);
  134. NativeMat4f headpos_native = new NativeMat4f(Matrix4x4.identity);
  135. var getPoseResult = NativeApi.NRTrackingPoseGetPose(m_NativeInterface.TrackingHandle, headPoseHandle, ref headpos_native);
  136. NativeErrorListener.Check(getPoseResult, this, "GetFramePresentHeadPose");
  137. ConversionUtility.ApiPoseToUnityPose(headpos_native, out pose);
  138. if (float.IsNaN(pose.position.x) || float.IsNaN(pose.position.y) || float.IsNaN(pose.position.z) ||
  139. float.IsNaN(pose.rotation.x) || float.IsNaN(pose.rotation.y) || float.IsNaN(pose.rotation.z) || float.IsNaN(pose.rotation.w))
  140. {
  141. NRDebugger.Error("[NativeTrack] GetFramePresentHeadPose invalid: lostReason={0}, unityPose=\n{1}\nnativePose=\n{2}", lostReason, pose.ToString("F6"), headpos_native.ToString());
  142. }
  143. NativeApi.NRTrackingPoseDestroy(m_NativeInterface.TrackingHandle, headPoseHandle);
  144. return true;
  145. }
  146. public bool GetFramePresentTimeByCount(int count, ref UInt64 timestamp)
  147. {
  148. return m_NativeInterface.NativeRenderring.GetFramePresentTimeByCount(ref timestamp, count);
  149. }
  150. /// <summary> Destroys this object. </summary>
  151. public void Destroy()
  152. {
  153. if (m_HeadTrackingHandle == 0)
  154. {
  155. return;
  156. }
  157. var result = NativeApi.NRHeadTrackingDestroy(m_NativeInterface.TrackingHandle, m_HeadTrackingHandle);
  158. m_HeadTrackingHandle = 0;
  159. NativeErrorListener.Check(result, this, "Destroy");
  160. }
  161. private partial struct NativeApi
  162. {
  163. /// <summary> Nr head tracking create. </summary>
  164. /// <param name="tracking_handle"> Handle of the tracking.</param>
  165. /// <param name="outHeadTrackingHandle"> [in,out] Handle of the out head tracking.</param>
  166. /// <returns> A NativeResult. </returns>
  167. [DllImport(NativeConstants.NRNativeLibrary)]
  168. public static extern NativeResult NRHeadTrackingCreate(UInt64 tracking_handle,
  169. ref UInt64 outHeadTrackingHandle);
  170. /// <summary> Nr tracking get hmd time nanos. </summary>
  171. /// <param name="tracking_handle"> Handle of the tracking.</param>
  172. /// <param name="out_hmd_time_nanos"> [in,out] The out hmd time nanos.</param>
  173. /// <returns> A NativeResult. </returns>
  174. [DllImport(NativeConstants.NRNativeLibrary)]
  175. public static extern NativeResult NRTrackingGetHMDTimeNanos(UInt64 tracking_handle,
  176. ref UInt64 out_hmd_time_nanos);
  177. /// <summary> Nr head tracking get recommend predict time. </summary>
  178. /// <param name="tracking_handle"> Handle of the tracking.</param>
  179. /// <param name="head_tracking_handle"> Handle of the head tracking.</param>
  180. /// <param name="out_predict_time_nanos"> [in,out] The out predict time nanos.</param>
  181. /// <returns> A NativeResult. </returns>
  182. [DllImport(NativeConstants.NRNativeLibrary)]
  183. public static extern NativeResult NRHeadTrackingGetRecommendPredictTime(
  184. UInt64 tracking_handle, UInt64 head_tracking_handle, ref UInt64 out_predict_time_nanos);
  185. /// <summary> Nr head tracking acquire tracking pose. </summary>
  186. /// <param name="sessionHandle"> Handle of the session.</param>
  187. /// <param name="head_tracking_handle"> Handle of the head tracking.</param>
  188. /// <param name="hmd_time_nanos"> The hmd time nanos.</param>
  189. /// <param name="out_tracking_pose_handle"> [in,out] Handle of the out tracking pose.</param>
  190. /// <returns> A NativeResult. </returns>
  191. [DllImport(NativeConstants.NRNativeLibrary)]
  192. public static extern NativeResult NRHeadTrackingAcquireTrackingPose(UInt64 sessionHandle,
  193. UInt64 head_tracking_handle, UInt64 hmd_time_nanos, ref UInt64 out_tracking_pose_handle);
  194. /// <summary> Nr tracking pose get pose. </summary>
  195. /// <param name="tracking_handle"> Handle of the tracking.</param>
  196. /// <param name="tracking_pose_handle"> Handle of the tracking pose.</param>
  197. /// <param name="out_pose"> [in,out] The out pose.</param>
  198. /// <returns> A NativeResult. </returns>
  199. [DllImport(NativeConstants.NRNativeLibrary)]
  200. public static extern NativeResult NRTrackingPoseGetPose(UInt64 tracking_handle,
  201. UInt64 tracking_pose_handle, ref NativeMat4f out_pose);
  202. /// <summary> Nr tracking pose get tracking reason. </summary>
  203. /// <param name="tracking_handle"> Handle of the tracking.</param>
  204. /// <param name="tracking_pose_handle"> Handle of the tracking pose.</param>
  205. /// <param name="out_tracking_reason"> [in,out] The out tracking reason.</param>
  206. /// <returns> A NativeResult. </returns>
  207. [DllImport(NativeConstants.NRNativeLibrary)]
  208. public static extern NativeResult NRTrackingPoseGetTrackingReason(UInt64 tracking_handle,
  209. UInt64 tracking_pose_handle, ref LostTrackingReason out_tracking_reason);
  210. /// <summary> Nr tracking pose destroy. </summary>
  211. /// <param name="tracking_handle"> Handle of the tracking.</param>
  212. /// <param name="tracking_pose_handle"> Handle of the tracking pose.</param>
  213. /// <returns> A NativeResult. </returns>
  214. [DllImport(NativeConstants.NRNativeLibrary)]
  215. public static extern NativeResult NRTrackingPoseDestroy(UInt64 tracking_handle, UInt64 tracking_pose_handle);
  216. /// <summary> Nr head tracking destroy. </summary>
  217. /// <param name="tracking_handle"> Handle of the tracking.</param>
  218. /// <param name="head_tracking_handle"> Handle of the head tracking.</param>
  219. /// <returns> A NativeResult. </returns>
  220. [DllImport(NativeConstants.NRNativeLibrary)]
  221. public static extern NativeResult NRHeadTrackingDestroy(UInt64 tracking_handle, UInt64 head_tracking_handle);
  222. };
  223. }
  224. }