NativeInterface_SlamAndRender.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. using UnityEngine;
  2. using System;
  3. using Rokid.UXR.Utility;
  4. using System.Runtime.InteropServices;
  5. namespace Rokid.UXR.Native
  6. {
  7. public enum HeadTrackingStatus
  8. {
  9. Unknow = 0,
  10. UnInit = 1,
  11. Detecting = 2,//RESERVED
  12. Tracking = 3,
  13. Track_Limited = 4,//RESERVED
  14. Tracking_Bad = 5,//RESERVED
  15. Tracking_Paused = 6,
  16. Tracking_Stopped = 7,
  17. Tracking_Error = 99
  18. }
  19. public partial class NativeInterface
  20. {
  21. public partial class NativeAPI
  22. {
  23. private static float[] frustum_left = new float[6];
  24. private static float[] frustum_right = new float[6];
  25. private static float[] position = new float[3];
  26. private static float[] rotation = new float[4];
  27. /// <summary>
  28. /// Get head tracking status
  29. /// </summary>
  30. /// <returns></returns>
  31. public static HeadTrackingStatus GetHeadTrackingStatus()
  32. {
  33. if (Utils.IsAndroidPlatfrom())
  34. return (HeadTrackingStatus)Api.getHeadTrackerState();
  35. return HeadTrackingStatus.Tracking;
  36. }
  37. /// <summary>
  38. /// Update screen parameters
  39. /// </summary>
  40. [Obsolete]
  41. public static void UpdateScreenParams()
  42. {
  43. if (Utils.IsAndroidPlatfrom())
  44. Api.UpdateScreenParams();
  45. }
  46. /// <summary>
  47. /// Reset center
  48. /// </summary>
  49. public static void Recenter()
  50. {
  51. if (Utils.IsAndroidPlatfrom())
  52. Api.Recenter();
  53. }
  54. /// <summary>
  55. /// Get debug informatio
  56. /// </summary>
  57. public static string GetDebugInfo()
  58. {
  59. if (Utils.IsAndroidPlatfrom())
  60. {
  61. return Api.getDebugInfoU();
  62. }
  63. return null;
  64. }
  65. /// <summary>
  66. /// Get left and right eye projection parameters
  67. /// </summary>
  68. /// <param name="frustum_left">float[4] {hFov,vFov,near,far}</param>
  69. /// <param name="frustum_right">float[4] {hFov,vFov,near,far}</param>
  70. /// <returns></returns>
  71. public static void GetUnityFrustum(ref float[] frustum_left, ref float[] frustum_right)
  72. {
  73. if (!Utils.IsAndroidPlatfrom())
  74. return;
  75. if (frustum_left.Length != 4 || frustum_right.Length != 4)
  76. {
  77. RKLog.Error("====NativeAnd====:+ GetUnityFrustum 参数数组长度不正确");
  78. return;
  79. }
  80. if (GetFrustum())
  81. {
  82. frustum_left[0] = GetHFov(false);
  83. frustum_left[1] = GetVFov(false);
  84. frustum_left[2] = NativeAPI.frustum_left[4];
  85. frustum_left[3] = NativeAPI.frustum_left[5];
  86. frustum_right[0] = GetHFov(true);
  87. frustum_right[1] = GetVFov(true);
  88. frustum_right[2] = NativeAPI.frustum_right[4];
  89. frustum_right[3] = NativeAPI.frustum_right[5];
  90. }
  91. }
  92. /// <summary>
  93. /// Get left and right eye fov parameters
  94. /// </summary>
  95. /// <returns></returns>
  96. public static void GetUnityEyeFrustumHalf(bool isRight, ref float[] fov)
  97. {
  98. if (!Utils.IsAndroidPlatfrom())
  99. return;
  100. if (GetFrustum())
  101. {
  102. RKLog.KeyInfo($"====GetUnityEyeFrustumHalf====: left fov {Newtonsoft.Json.JsonConvert.SerializeObject(frustum_left)},right fov {Newtonsoft.Json.JsonConvert.SerializeObject(frustum_right)} ");
  103. float[] frustum = isRight ? frustum_right : frustum_left;
  104. float left = frustum[0];
  105. float right = frustum[1];
  106. float bottom = frustum[2];
  107. float top = frustum[3];
  108. float near = frustum[4];
  109. float RAD2DEG = 180.0f / 3.14159265358979323846f;
  110. fov[0] = RAD2DEG * (float)Math.Atan(Math.Abs(left) / near);
  111. fov[1] = RAD2DEG * (float)Math.Atan(Math.Abs(right) / near);
  112. fov[2] = RAD2DEG * (float)Math.Atan(Math.Abs(top) / near);
  113. fov[3] = RAD2DEG * (float)Math.Atan(Math.Abs(bottom) / near);
  114. }
  115. }
  116. /// <summary>
  117. /// Get left and right eye projection parameters
  118. /// </summary>
  119. /// <param name="frustum_lest">float[6] {left,right,bottom,top,near,far}</param>
  120. /// <param name="frustum_right">{left,right,bottom,top,near,far}</param>
  121. /// <returns></returns>
  122. private static bool GetFrustum()
  123. {
  124. return Api.getFrustum(frustum_left, frustum_right);
  125. }
  126. /// <summary>
  127. /// Get vertical field of view
  128. /// </summary>
  129. /// <param name="frustum"></param>
  130. /// <returns></returns>
  131. public static float GetVFov(bool isRight)
  132. {
  133. float[] frustum = isRight ? frustum_right : frustum_left;
  134. float near = frustum[4];
  135. float top = frustum[3];
  136. float bottom = frustum[2];
  137. float RAD2DEG = 180.0f / 3.14159265358979323846f;
  138. float fov = RAD2DEG * (2.0f * (float)Math.Atan((top - bottom) / (2.0f * near)));
  139. return fov;
  140. }
  141. /// <summary>
  142. /// Get horizontal field of view
  143. /// </summary>
  144. /// <param name="frustum"></param>
  145. /// <returns></returns>
  146. public static float GetHFov(bool isRight)
  147. {
  148. float[] frustum = isRight ? frustum_right : frustum_left;
  149. float near = frustum[4];
  150. float left = frustum[0];
  151. float right = frustum[1];
  152. float RAD2DEG = 180.0f / 3.14159265358979323846f;
  153. float fov = RAD2DEG * (2.0f * (float)Math.Atan((right - left) / (2.0f * near)));
  154. return fov;
  155. }
  156. /// <summary>
  157. /// Get camera pose
  158. /// </summary>
  159. /// <returns></returns>
  160. [Obsolete("Use GetHeadPose instead")]
  161. public static Pose GetCameraPose(out long timeStamp)
  162. {
  163. return GetHeadPose(out timeStamp);
  164. }
  165. /// <summary>
  166. /// Get current time head pose
  167. /// </summary>
  168. /// <returns></returns>
  169. public static Pose GetHeadPose(out long timeStamp)
  170. {
  171. if (Utils.IsAndroidPlatfrom())
  172. {
  173. timeStamp = getHeadPoseRHS(position, rotation);
  174. Pose pose = new Pose(new Vector3(position[0], position[1], -position[2]),
  175. new Quaternion(-rotation[0], -rotation[1], rotation[2], rotation[3]));
  176. return pose;
  177. }
  178. timeStamp = 0;
  179. return Pose.identity;
  180. }
  181. /// <summary>
  182. /// Input a timestamp to retrieve the head pose at that specific timestamp only for ges.
  183. /// </summary>
  184. /// <param name="timestamp"></param> (t-1000ms ~ t-10ms)
  185. /// <returns></returns>
  186. public static Pose GetHistoryHeadPose(long timestamp)
  187. {
  188. Pose pose = Pose.identity;
  189. if (Utils.IsAndroidPlatfrom())
  190. {
  191. getHistoryHeadPoseRHS(timestamp, position, rotation);
  192. pose.position = new Vector3(position[0], position[1], -position[2]);
  193. pose.rotation = new Quaternion(-rotation[0], -rotation[1], rotation[2], rotation[3]);
  194. }
  195. return pose;
  196. }
  197. /// <summary>
  198. /// It is current physics camera pose
  199. /// </summary>
  200. /// <returns></returns>
  201. public static Pose GetCameraPhysicsPose(out long timeStamp)
  202. {
  203. Pose pose = Pose.identity;
  204. if (Utils.IsAndroidPlatfrom())
  205. {
  206. timeStamp = getHeadPosePysRHS(position, rotation);
  207. pose.position = new Vector3(position[0], position[1], -position[2]);
  208. pose.rotation = new Quaternion(-rotation[0], -rotation[1], rotation[2], rotation[3]);
  209. return pose;
  210. }
  211. timeStamp = 0;
  212. return pose;
  213. }
  214. /// <summary>
  215. /// It is history physics camera pose
  216. /// </summary>
  217. /// <param name="timestamp"></param>
  218. /// <returns></returns>
  219. public static Pose GetHistoryCameraPhysicsPose(long timestamp)
  220. {
  221. Pose pose = Pose.identity;
  222. if (Utils.IsAndroidPlatfrom())
  223. {
  224. getHistoryHeadPosePysRHS(timestamp, position, rotation);
  225. pose.position = new Vector3(position[0], position[1], -position[2]);
  226. pose.rotation = new Quaternion(-rotation[0], -rotation[1], rotation[2], rotation[3]);
  227. }
  228. return pose;
  229. }
  230. /// <summary>
  231. /// Get Head Origin Pose
  232. /// </summary>
  233. /// <returns></returns>
  234. public static Pose GetHeadPoseOrigin()
  235. {
  236. Pose pose = Pose.identity;
  237. if (Utils.IsAndroidPlatfrom())
  238. {
  239. getHeadPoseOriginRHS(0, position, rotation);
  240. pose.position = new Vector3(position[0], position[1], -position[2]);
  241. pose.rotation = new Quaternion(-rotation[0], -rotation[1], rotation[2], rotation[3]);
  242. }
  243. return pose;
  244. }
  245. /// <summary>
  246. /// Get Head Origin Pose
  247. /// </summary>
  248. /// <returns></returns>
  249. public static Pose GetHeadPoseOffset()
  250. {
  251. Pose pose = Pose.identity;
  252. if (Utils.IsAndroidPlatfrom())
  253. {
  254. getHeadPoseOffsetRHS(position, rotation);
  255. pose.position = new Vector3(position[0], position[1], -position[2]);
  256. pose.rotation = new Quaternion(-rotation[0], -rotation[1], rotation[2], rotation[3]);
  257. }
  258. return pose;
  259. }
  260. /// <summary>
  261. /// SetTrackingType
  262. /// </summary>
  263. /// <param name="type"></param>
  264. public static void SetTrackingType(int type)
  265. {
  266. if (Utils.IsAndroidPlatfrom())
  267. {
  268. RKLog.Info($"====NativeAPI====: SetHeadTrackingType :{type}");
  269. Api.setTrackingType(type);
  270. }
  271. }
  272. /// <summary>
  273. /// Get ost info
  274. /// </summary>
  275. /// <returns></returns>
  276. public static string GetOSTInfo()
  277. {
  278. IntPtr calPtr = Api.getGlassCalFile();
  279. if (calPtr != null)
  280. {
  281. string cal = Marshal.PtrToStringAuto(calPtr);
  282. return cal;
  283. }
  284. else
  285. {
  286. return null;
  287. }
  288. }
  289. [DllImport(ApiConstants.UXR_GFX_PLUGIN)]
  290. private static extern long getHeadPoseRHS(float[] position, float[] orientation);
  291. [DllImport(ApiConstants.UXR_GFX_PLUGIN)]
  292. private static extern void getHistoryHeadPoseRHS(long timestamp, float[] position, float[] orientation);
  293. [DllImport(ApiConstants.UXR_GFX_PLUGIN)]
  294. private static extern long getHeadPosePysRHS(float[] position, float[] orientation);
  295. [DllImport(ApiConstants.UXR_GFX_PLUGIN)]
  296. private static extern void getHeadPoseOriginRHS(long timestamp, float[] position, float[] orientation);
  297. [DllImport(ApiConstants.UXR_GFX_PLUGIN)]
  298. private static extern void getHeadPoseOffsetRHS(float[] position, float[] orientation);
  299. }
  300. }
  301. }