SW 중심대학 OSS GIT 서버 박건태, 이승준, 고기완, 이준호 새로운 배포
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
9.1 KiB

4 years ago
  1. // Copyright (C) 2018 Daniel Fortes <daniel.fortes@gmail.com>
  2. // All rights reserved.
  3. //
  4. // See LICENSE.TXT for more info
  5. using System;
  6. using ARLocation.Session;
  7. using UnityEngine;
  8. using UnityEngine.Events;
  9. #if !ARGPS_USE_VUFORIA
  10. using UnityEngine.XR.ARFoundation;
  11. #endif
  12. namespace ARLocation
  13. {
  14. using Utils;
  15. /// <summary>
  16. /// This Component manages all positioned GameObjects, synchronizing their world position in the scene
  17. /// with their geographical coordinates. This is done by calculating their position relative to the device's position.
  18. ///
  19. /// Should be placed in a GameObject called "ARLocationRoot", whose parent is the "AR Session Origin".
  20. /// </summary>
  21. [RequireComponent(typeof(ARLocationOrientation))]
  22. [DisallowMultipleComponent]
  23. [AddComponentMenu("AR+GPS/AR Location Manager")]
  24. [HelpURL("https://http://docs.unity-ar-gps-location.com/guide/#arlocationmanager")]
  25. public class ARLocationManager : Singleton<ARLocationManager>
  26. {
  27. [Tooltip("The AR Camera that will be used for rendering the AR content. If this is not set, the camera tagger as 'MainCamera' will be used." +
  28. " Make sure either this is set, or a camera is tagged as 'MainCamera', or an error will be thrown.")]
  29. public Camera Camera;
  30. [Tooltip("If true, wait until the AR Tracking starts to start with location and orientation updates and object placement.")]
  31. public bool WaitForARTrackingToStart = true;
  32. [Tooltip("If true, every time the AR tracking is lost and regained, the AR+GPS system is restarted, repositioning all the objects.")]
  33. public bool RestartWhenARTrackingIsRestored;
  34. [Tooltip("If true, the manager will set 'Application.targetFrameRate' to 60." )]
  35. public bool SetTargetFrameRateTo60Mhz = true;
  36. [Header("Debug")]
  37. [Tooltip("When debug mode is enabled, this component will print relevant messages to the console. Filter by 'ARLocationManager' in the log output to see the messages.")]
  38. public bool DebugMode;
  39. [Header("AR Session Events")]
  40. public UnityEvent OnTrackingStarted = new UnityEvent();
  41. public UnityEvent OnTrackingLost = new UnityEvent();
  42. public UnityEvent OnTrackingRestored = new UnityEvent();
  43. /// <summary>
  44. /// The instance of the 'IARSessionManager'. Handles the interface with the underlying AR session (i.e., Vuforia or AR Foundation).
  45. /// </summary>
  46. public IARSessionManager SessionManager { get; private set; }
  47. /// <summary>
  48. /// The 'MainCamera' that is being used for rendering the AR content.
  49. /// </summary>
  50. public Camera MainCamera { get; private set; }
  51. /// <summary>
  52. /// Returns the Y world-coordinate of the detected plane which is nearest to the user/camera.
  53. /// </summary>
  54. public float CurrentGroundY => groundHeight ? groundHeight.CurrentGroundY : -ARLocation.Config.InitialGroundHeightGuess;
  55. private ARLocationOrientation arLocationOrientation;
  56. private ARLocationProvider arLocationProvider;
  57. private Action onARTrackingStartedAction;
  58. private GameObject groundHeightDummy;
  59. private GroundHeight groundHeight;
  60. public override void Awake()
  61. {
  62. base.Awake();
  63. if (SetTargetFrameRateTo60Mhz)
  64. {
  65. Logger.LogFromMethod("ARLocationManager", "Awake", "Setting 'Application.targetFrameRate' to 60", DebugMode);
  66. Application.targetFrameRate = 60;
  67. }
  68. MainCamera = Camera ? Camera : Camera.main;
  69. if (MainCamera == null)
  70. {
  71. throw new NullReferenceException("[AR+GPS][ARLocationManager#Start]: Missing Camera. " +
  72. "Either set the 'Camera' property to the AR Camera, or tag it as a 'MainCamera'.");
  73. }
  74. }
  75. private void Start()
  76. {
  77. arLocationOrientation = GetComponent<ARLocationOrientation>();
  78. arLocationProvider = ARLocationProvider.Instance;
  79. if (WaitForARTrackingToStart)
  80. {
  81. arLocationProvider.Mute();
  82. }
  83. #if !ARGPS_USE_VUFORIA
  84. var arSession = FindObjectOfType<ARSession>();
  85. if (!arSession)
  86. {
  87. throw new NullReferenceException("[AR+GPS][ARLocationManager#Start]: No ARSession found in the scene!");
  88. }
  89. SessionManager = new ARFoundationSessionManager(arSession);
  90. #else
  91. SessionManager = new VuforiaSessionManager();
  92. #endif
  93. SessionManager.DebugMode = DebugMode;
  94. SessionManager.OnARTrackingStarted(ARTrackingStartedCallback);
  95. SessionManager.OnARTrackingRestored(ARTrackingRestoredCallback);
  96. SessionManager.OnARTrackingLost(ARTrackingLostCallback);
  97. groundHeightDummy = new GameObject("ARLocationGroundHeight");
  98. groundHeightDummy.transform.SetParent(MainCamera.transform);
  99. groundHeightDummy.transform.localPosition = new Vector3();
  100. groundHeight = groundHeightDummy.AddComponent<GroundHeight>();
  101. }
  102. private void ARTrackingLostCallback()
  103. {
  104. Logger.LogFromMethod("ARLocationManager", "ARTrackingLostCallback", "'ARTrackingLost' event received.", DebugMode);
  105. OnTrackingLost?.Invoke();
  106. }
  107. private void ARTrackingRestoredCallback()
  108. {
  109. Logger.LogFromMethod("ARLocationManager", "ARTrackingRestoredCallback", "'ARTrackingRestore' event received.", DebugMode);
  110. if (RestartWhenARTrackingIsRestored)
  111. {
  112. Logger.LogFromMethod("ARLocationManager", "ARTrackingRestoredCallback", "'RestartWhenARTrackingIsRestored' is enabled; restarting.", DebugMode);
  113. Restart();
  114. }
  115. OnTrackingRestored?.Invoke();
  116. }
  117. private void ARTrackingStartedCallback()
  118. {
  119. Logger.LogFromMethod("ARLocationManager", "ARTrackingStartedCallback", "'OnARTrackingStarted' event received.", DebugMode);
  120. if (WaitForARTrackingToStart)
  121. {
  122. arLocationProvider.Unmute();
  123. }
  124. OnTrackingStarted?.Invoke();
  125. onARTrackingStartedAction?.Invoke();
  126. }
  127. /// <summary>
  128. /// This will reset the AR Session and the AR+GPS system, repositioning all objects.
  129. /// </summary>
  130. /// <param name="cb">Optional callback, called when the system has restarted.</param>
  131. public void ResetARSession(Action cb = null)
  132. {
  133. Logger.LogFromMethod("ARLocationManager", "ResetARSession", "Resetting the AR Session...", DebugMode);
  134. SessionManager?.Reset(() =>
  135. {
  136. Logger.LogFromMethod("ARLocationManager", "ResetARSession", "ARSession restarted. Resetting AR+GPS location...", DebugMode);
  137. Restart();
  138. cb?.Invoke();
  139. });
  140. }
  141. /// <summary>
  142. /// This will restart the AR+GPS system, repositioning all the objects.
  143. /// </summary>
  144. public void Restart()
  145. {
  146. Logger.LogFromMethod("ARLocationManager", "Restart", "Resetting AR+GPS location...", DebugMode);
  147. arLocationOrientation.Restart();
  148. arLocationProvider.Restart();
  149. Logger.LogFromMethod("ARLocationManager", "Restart", "Done.", DebugMode);
  150. }
  151. /// <summary>
  152. /// Returns a string describing the current AR session tracking status
  153. /// </summary>
  154. /// <returns></returns>
  155. public string GetARSessionInfoString()
  156. {
  157. return SessionManager != null ? SessionManager.GetSessionInfoString() : "None";
  158. }
  159. /// <summary>
  160. /// Returns a string describing the current AR Session provider, e.g., AR Foundation or Vuforia.
  161. /// </summary>
  162. /// <returns></returns>
  163. public string GetARSessionProviderString()
  164. {
  165. return SessionManager != null ? SessionManager.GetProviderString() : "None";
  166. }
  167. /// <summary>
  168. /// Add a event listener for when the AR Tracking starts.
  169. /// </summary>
  170. /// <param name="o"></param>
  171. public void OnARTrackingStarted(Action o)
  172. {
  173. if (SessionManager == null)
  174. {
  175. onARTrackingStartedAction += o;
  176. }
  177. else
  178. {
  179. SessionManager.OnARTrackingStarted(o);
  180. }
  181. }
  182. /// <summary>
  183. /// Add a event listener for when the AR Tracking regained after it was lost.
  184. /// </summary>
  185. /// <param name="callback"></param>
  186. public void OnARTrackingRestored(Action callback)
  187. {
  188. SessionManager?.OnARTrackingRestored(callback);
  189. }
  190. /// <summary>
  191. /// Add a event listener for when the AR Tracking is lost.
  192. /// </summary>
  193. /// <param name="callback"></param>
  194. public void OnARTrackingLost(Action callback)
  195. {
  196. SessionManager?.OnARTrackingLost(callback);
  197. }
  198. }
  199. }