XRTracking.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. using UnityEngine;
  2. using Ximmerse.XR.Utils;
  3. using Ximmerse.XR.Internal;
  4. using System.Collections;
  5. using System.Linq;
  6. namespace Ximmerse.XR.Tag
  7. {
  8. /// <summary>
  9. /// Implement tracing capabilities and handle appropriate events.
  10. /// </summary>
  11. public class XRTracking : MonoBehaviour
  12. {
  13. #region Property
  14. TrackingManager trackingManager;
  15. GameObject tracking_clone;
  16. private long predTimestampNano = 0;
  17. private Vector3 poslost;
  18. GameObject followGo;
  19. Quaternion rotlost;
  20. TagTracking tagTracking;
  21. private TrackingEvent trackingEvent;
  22. private bool first = false;
  23. private bool exit = false;
  24. private bool onfirstTrackingEnter = false;
  25. private bool onTrackingEnter = false;
  26. private bool onTrackingStay = false;
  27. private bool onTrackingExit = false;
  28. private bool trackingstate;
  29. int index = 0;
  30. long timestamp = 0;
  31. int state = 0;
  32. float posX = 0;
  33. float posY = 0;
  34. float posZ = 0;
  35. float rotX = 0;
  36. float rotY = 0;
  37. float rotZ = 0;
  38. float rotW = 0;
  39. float confidence = 0;
  40. float marker_distance = 0;
  41. #endregion
  42. #region Unity
  43. private void Start()
  44. {
  45. CloneTagTracking();
  46. trackingEvent = gameObject.GetComponent<TrackingEvent>();
  47. }
  48. private void Update()
  49. {
  50. tagTracking = GetComponent<TagTracking>();
  51. TagTracking();
  52. if (trackingEvent != null)
  53. {
  54. if (OnFirstTrackingEnter())
  55. {
  56. trackingEvent.onFirstTrackingEvent?.Invoke();
  57. }
  58. if (OnTrackingEnter())
  59. {
  60. trackingEvent.onTrackingEnter?.Invoke();
  61. }
  62. if (OnTrackingStay())
  63. {
  64. trackingEvent.onTrackingStay?.Invoke();
  65. }
  66. if (OnTrackingExit())
  67. {
  68. trackingEvent.onTrackingExit?.Invoke();
  69. }
  70. }
  71. }
  72. #endregion
  73. #region Method
  74. /// <summary>
  75. /// Correct the coordinate information.
  76. /// </summary>
  77. private void CloneTagTracking()
  78. {
  79. trackingManager = TrackingManager.Instance;
  80. if (trackingManager == null)
  81. {
  82. trackingManager = new GameObject("TagTracking Manager").AddComponent<TrackingManager>();
  83. }
  84. tracking_clone = new GameObject(gameObject.name);
  85. tracking_clone.transform.parent = trackingManager.transform;
  86. }
  87. /// <summary>
  88. /// Tag Tracking function
  89. /// </summary>
  90. private void TagTracking()
  91. {
  92. #if !UNITY_EDITOR
  93. NativePluginApi.Unity_getTagTracking2(tagTracking.TrackId,
  94. ref index, ref timestamp, ref state, ref posX, ref posY, ref posZ,
  95. ref rotX, ref rotY, ref rotZ, ref rotW,
  96. ref confidence, ref marker_distance);
  97. #endif
  98. if (TagProfileLoading.Instance!=null)
  99. {
  100. trackingstate = IsTracking();
  101. if (trackingstate)
  102. {
  103. poslost = Vector3.zero;
  104. rotlost = new Quaternion(0, 0, 0, 1);
  105. tracking_clone.transform.localPosition = new Vector3(posX, posY, posZ);
  106. tracking_clone.transform.localRotation = new Quaternion(rotX, rotY, rotZ, rotW);
  107. gameObject.transform.position = tracking_clone.transform.position;
  108. gameObject.transform.rotation = tracking_clone.transform.rotation;
  109. if (tagTracking.DebugView)
  110. {
  111. DrawDebugView(tagTracking.Size);
  112. }
  113. }
  114. else
  115. {
  116. if (tagTracking.TrackingIsLost == LostState.FollowHead)
  117. {
  118. if (poslost == Vector3.zero && rotlost == new Quaternion(0, 0, 0, 1))
  119. {
  120. poslost = gameObject.transform.position;
  121. rotlost = gameObject.transform.rotation;
  122. if (followGo == null)
  123. {
  124. followGo = new GameObject();
  125. }
  126. followGo.transform.position = poslost;
  127. followGo.transform.rotation = rotlost;
  128. if (trackingManager.xROrigin != null)
  129. {
  130. followGo.transform.parent = trackingManager.xROrigin.Camera.transform;
  131. }
  132. else
  133. {
  134. followGo.transform.parent = FindObjectOfType<Camera>().transform;
  135. throw new System.Exception("XR Origin is not found");
  136. }
  137. }
  138. gameObject.transform.position = followGo.transform.position;
  139. gameObject.transform.rotation = followGo.transform.rotation;
  140. }
  141. }
  142. }
  143. }
  144. /// <summary>
  145. /// Plot the axes
  146. /// </summary>
  147. /// <param name="size"></param>
  148. private void DrawDebugView(float size)
  149. {
  150. RxDraw.DrawWirePlane(transform.position, transform.rotation, size, size, Color.green);
  151. if (trackingManager.xROrigin != null)
  152. {
  153. var textRotation = Quaternion.LookRotation(transform.position - trackingManager.xROrigin.Camera.transform.position);
  154. textRotation = textRotation.PitchNYaw();
  155. string debugTxt = tagTracking.TrackId.ToString();
  156. RxDraw.Text3D(transform.position, textRotation, 0.02f, debugTxt, Color.green);
  157. }
  158. else
  159. {
  160. var textRotation = Quaternion.LookRotation(transform.position - FindObjectOfType<Camera>().transform.position);
  161. textRotation = textRotation.PitchNYaw();
  162. string debugTxt = tagTracking.TrackId.ToString();
  163. RxDraw.Text3D(transform.position, textRotation, 0.02f, debugTxt, Color.green);
  164. }
  165. RxDraw.DrawTranslateGizmos(transform.position, transform.rotation, size * 0.85f);
  166. }
  167. /// <summary>
  168. /// Get the Tag tracking status
  169. /// </summary>
  170. /// <returns></returns>
  171. protected bool IsTracking()
  172. {
  173. if (TagProfileLoading.Instance.TrackingTagList.Contains(tagTracking.TrackId))
  174. {
  175. return true;
  176. }
  177. else return false;
  178. }
  179. /// <summary>
  180. /// First identification
  181. /// </summary>
  182. /// <returns></returns>
  183. private bool OnFirstTrackingEnter()
  184. {
  185. if (trackingstate && first == false)
  186. {
  187. first = true;
  188. onfirstTrackingEnter = true;
  189. }
  190. else if (trackingstate && first == true)
  191. {
  192. onfirstTrackingEnter = false;
  193. }
  194. return onfirstTrackingEnter;
  195. }
  196. /// <summary>
  197. /// Identify
  198. /// </summary>
  199. /// <returns></returns>
  200. private bool OnTrackingEnter()
  201. {
  202. if (trackingstate && onTrackingEnter == false && onTrackingStay == false)
  203. {
  204. onTrackingEnter = true;
  205. onTrackingStay = true;
  206. }
  207. else
  208. {
  209. onTrackingEnter = false;
  210. }
  211. return onTrackingEnter;
  212. }
  213. /// <summary>
  214. /// Identifying
  215. /// </summary>
  216. /// <returns></returns>
  217. private bool OnTrackingStay()
  218. {
  219. if (trackingstate)
  220. {
  221. onTrackingStay = true;
  222. exit = true;
  223. }
  224. else
  225. {
  226. onTrackingStay = false;
  227. }
  228. return onTrackingStay;
  229. }
  230. /// <summary>
  231. /// lose
  232. /// </summary>
  233. /// <returns></returns>
  234. private bool OnTrackingExit()
  235. {
  236. if (trackingstate == false && exit)
  237. {
  238. exit = false;
  239. onTrackingExit = true;
  240. }
  241. else
  242. {
  243. onTrackingExit = false;
  244. }
  245. return onTrackingExit;
  246. }
  247. #endregion
  248. }
  249. }