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.

441 lines
19 KiB

4 years ago
  1. using AOT;
  2. using System;
  3. using System.Runtime.InteropServices;
  4. using UnityEngine.Scripting;
  5. using UnityEngine.XR.ARSubsystems;
  6. namespace UnityEngine.XR.ARKit
  7. {
  8. /// <summary>
  9. /// ARKit implementation of the <c>XRSessionSubsystem</c>. Do not create this directly. Use the <c>SubsystemManager</c> instead.
  10. /// </summary>
  11. [Preserve]
  12. public sealed class ARKitSessionSubsystem : XRSessionSubsystem
  13. {
  14. /// <summary>
  15. /// <c>true</c> if [Coaching Overlay](https://developer.apple.com/documentation/arkit/arcoachingoverlayview) is supported, otherwise <c>false</c>.
  16. /// </summary>
  17. public static bool coachingOverlaySupported
  18. {
  19. get
  20. {
  21. #if UNITY_IOS && !UNITY_EDITOR
  22. return NativeApi.UnityARKit_coachingOverlay_isSupported();
  23. #else
  24. return false;
  25. #endif
  26. }
  27. }
  28. /// <summary>
  29. /// Whether the [Coaching Overlay](https://developer.apple.com/documentation/arkit/arcoachingoverlayview)
  30. /// activates automatically or not. By default, it does not.
  31. /// </summary>
  32. public bool coachingActivatesAutomatically
  33. {
  34. get => NativeApi.UnityARKit_coachingOverlay_getActivatesAutomatically();
  35. set => NativeApi.UnityARKit_coachingOverlay_setActivatesAutomatically(value);
  36. }
  37. /// <summary>
  38. /// Defines the [Coaching Goal](https://developer.apple.com/documentation/arkit/arcoachingoverlayview/3192180-goal).
  39. /// This should be based on your app's tracking requirements and affects the UI that the coaching overlay presents.
  40. /// </summary>
  41. public ARCoachingGoal coachingGoal
  42. {
  43. get => NativeApi.UnityARKit_coachingOverlay_getGoal();
  44. set => NativeApi.UnityARKit_coachingOverlay_setGoal(value);
  45. }
  46. /// <summary>
  47. /// <c>true</c> if the [Coaching Overlay](https://developer.apple.com/documentation/arkit/arcoachingoverlayview) is active.
  48. /// </summary>
  49. public bool coachingActive => NativeApi.UnityARKit_coachingOverlay_isActive();
  50. /// <summary>
  51. /// Activates or deactivates the [Coaching Overlay](https://developer.apple.com/documentation/arkit/arcoachingoverlayview)
  52. /// </summary>
  53. /// <param name="active">Whether the coaching overlay should be active or not.</param>
  54. /// <param name="animate">The type of transition to use when showing or hiding the coaching overlay.</param>
  55. public void SetCoachingActive(bool active, ARCoachingOverlayTransition transition)
  56. {
  57. NativeApi.UnityARKit_coachingOverlay_setActive(active, transition == ARCoachingOverlayTransition.Animated);
  58. }
  59. /// <summary>
  60. /// <para>Asynchronously create an <see cref="ARWorldMap"/>. An <c>ARWorldMap</c>
  61. /// represents the state of the session and can be serialized to a byte
  62. /// array to persist the session data, or send it to another device for
  63. /// shared AR experiences.</para>
  64. /// <para>It is a wrapper for <a href="https://developer.apple.com/documentation/arkit/arworldmap">ARKit's ARWorldMap</a>.</para>
  65. /// </summary>
  66. /// <returns>An <see cref="ARWorldMapRequest"/> which can be used to determine the status
  67. /// of the request and get the <c>ARWorldMap</c> when complete.</returns>
  68. /// <seealso cref="ApplyWorldMap(ARWorldMap)"/>
  69. /// <seealso cref="worldMapSupported"/>
  70. public ARWorldMapRequest GetARWorldMapAsync()
  71. {
  72. var requestId = NativeApi.UnityARKit_createWorldMapRequest();
  73. return new ARWorldMapRequest(requestId);
  74. }
  75. /// <summary>
  76. /// <para>
  77. /// Asynchronously create an <see cref="ARWorldMap"/>. An <c>ARWorldMap</c>
  78. /// represents the state of the session and can be serialized to a byte
  79. /// array to persist the session data, or send it to another device for
  80. /// shared AR experiences.
  81. /// </para>
  82. /// <para>
  83. /// It is a wrapper for <a href="https://developer.apple.com/documentation/arkit/arworldmap">ARKit's ARWorldMap</a>.
  84. /// </para>
  85. /// <para>
  86. /// If the <see cref="ARWorldMapRequestStatus"/> is <see cref="ARWorldMapRequestStatus.Success"/>, then
  87. /// the resulting <see cref="ARWorldMap"/> must be disposed to avoid leaking native resources. Otherwise,
  88. /// the <see cref="ARWorldMap"/> is not valid, and need not be disposed.
  89. /// </para>
  90. /// </summary>
  91. /// <param name="onComplete">A method to invoke when the world map has either been created, or determined
  92. /// that it could not be created. Check the value of the <see cref="ARWorldMapRequestStatus"/> parameter
  93. /// to determine whether the world map was successfully created.</param>
  94. /// <seealso cref="ApplyWorldMap(ARWorldMap)"/>
  95. /// <seealso cref="worldMapSupported"/>
  96. public void GetARWorldMapAsync(
  97. Action<ARWorldMapRequestStatus, ARWorldMap> onComplete)
  98. {
  99. var handle = GCHandle.Alloc(onComplete);
  100. var context = GCHandle.ToIntPtr(handle);
  101. NativeApi.UnityARKit_createWorldMapRequestWithCallback(s_OnAsyncWorldMapCompleted, context);
  102. }
  103. /// <summary>
  104. /// Detect <see cref="ARWorldMap"/> support. <c>ARWorldMap</c> requires iOS 12 or greater.
  105. /// </summary>
  106. /// <returns><c>true</c> if <c>ARWorldMap</c>s are supported, otherwise <c>false</c>.</returns>
  107. /// <seealso cref="GetARWorldMapAsync()"/>
  108. public static bool worldMapSupported
  109. {
  110. get
  111. {
  112. #if UNITY_IOS && !UNITY_EDITOR
  113. return NativeApi.UnityARKit_worldMapSupported();
  114. #else
  115. return false;
  116. #endif
  117. }
  118. }
  119. /// <summary>
  120. /// Get the world mapping status. Used to determine the suitability of the current session for
  121. /// creating an <see cref="ARWorldMap"/>.
  122. /// </summary>
  123. /// <returns>The <see cref="ARWorldMappingStatus"/> of the session.</returns>
  124. public ARWorldMappingStatus worldMappingStatus => NativeApi.UnityARKit_session_getWorldMappingStatus();
  125. /// <summary>
  126. /// Apply an existing <see cref="ARWorldMap"/> to the session. This will attempt
  127. /// to relocalize the current session to the given <paramref name="worldMap"/>.
  128. /// If relocalization is successful, the stored planes and anchors from
  129. /// the <paramref name="worldMap"/> will be added to the current session.
  130. /// This is equivalent to setting the <a href="https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration/2968180-initialworldmap">initialWorldMap</a>
  131. /// property on the session's <a href="https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration">ARWorldTrackingConfiguration</a>.
  132. /// </summary>
  133. /// <param name="worldMap">An <see cref="ARWorldMap"/> with which to relocalize the session.</param>
  134. public void ApplyWorldMap(ARWorldMap worldMap)
  135. {
  136. if (worldMap.nativeHandle == ARWorldMap.k_InvalidHandle)
  137. throw new InvalidOperationException("ARWorldMap has been disposed.");
  138. NativeApi.UnityARKit_applyWorldMap(worldMap.nativeHandle);
  139. }
  140. /// <summary>
  141. /// Get or set whether collaboration is enabled. When collaboration is enabled, collaboration
  142. /// data is accumulated by the subsystem until you read it out with <see cref="DequeueCollaborationData"/>.
  143. /// </summary>
  144. /// <remarks>
  145. /// Note: If you change this value, the new value may not be reflected until the next frame.
  146. /// </remarks>
  147. /// <seealso cref="ARCollaborationData"/>
  148. /// <seealso cref="DequeueCollaborationData"/>
  149. /// <seealso cref="collaborationDataCount"/>
  150. public bool collaborationEnabled
  151. {
  152. get => NativeApi.UnityARKit_session_getCollaborationEnabled();
  153. set
  154. {
  155. if (supportsCollaboration)
  156. {
  157. NativeApi.UnityARKit_session_setCollaborationRequested(value);
  158. }
  159. else if (value)
  160. {
  161. throw new NotSupportedException("ARCollaborationData is not supported by this version of iOS.");
  162. }
  163. }
  164. }
  165. /// <summary>
  166. /// True if collaboration is supported. Collaboration is only supported on iOS versions 13.0 and later.
  167. /// </summary>
  168. /// <seealso cref="ARCollaborationData"/>
  169. public static bool supportsCollaboration => s_SupportsCollaboration;
  170. /// <summary>
  171. /// The number of <see cref="ARCollaborationData"/>s in the queue. Obtain <see cref="ARCollaborationData"/>
  172. /// with <see cref="DequeueCollaborationData"/>.
  173. /// </summary>
  174. /// <seealso cref="ARCollaborationData"/>
  175. /// <seealso cref="DequeueCollaborationData"/>
  176. public int collaborationDataCount => NativeApi.UnityARKit_session_getCollaborationDataQueueSize();
  177. /// <summary>
  178. /// Dequeues the oldest collaboration data in the queue. After calling this method, <see cref="collaborationDataCount"/>
  179. /// will be decremented by one.
  180. /// </summary>
  181. /// <exception cref="System.NotSupportedException">Thrown if <see cref="supportsCollaboration"/> is false.</exception>
  182. /// <exception cref="System.InvalidOperationException">Thrown if <see cref="collaborationDataCount"/> is zero.</exception>
  183. /// <seealso cref="ARCollaborationData"/>
  184. public ARCollaborationData DequeueCollaborationData()
  185. {
  186. if (!supportsCollaboration)
  187. throw new NotSupportedException("ARCollaborationData is not supported by this version of iOS.");
  188. if (collaborationDataCount == 0)
  189. throw new InvalidOperationException("There is no collaboration data to dequeue.");
  190. return new ARCollaborationData(NativeApi.UnityARKit_session_dequeueCollaborationData());
  191. }
  192. /// <summary>
  193. /// Applies <see cref="ARCollaborationData"/> to the session.
  194. /// </summary>
  195. /// <exception cref="System.NotSupportedException">Thrown if <see cref="supportsCollaboration"/> is false.</exception>
  196. /// <exception cref="System.InvalidOperationException">Thrown if <paramref name="collaborationData"/> is not valid.</exception>
  197. public void UpdateWithCollaborationData(ARCollaborationData collaborationData)
  198. {
  199. if (!supportsCollaboration)
  200. throw new NotSupportedException("ARCollaborationData is not supported by this version of iOS.");
  201. if (!collaborationData.valid)
  202. throw new InvalidOperationException("Invalid collaboration data.");
  203. NativeApi.UnityARKit_session_updateWithCollaborationData(collaborationData.m_NativePtr);
  204. }
  205. /// <summary>
  206. /// Creates the provider interface.
  207. /// </summary>
  208. /// <returns>The provider interface for ARKit</returns>
  209. protected override Provider CreateProvider() => new ARKitProvider();
  210. static ARKitSessionSubsystem()
  211. {
  212. s_OnAsyncWorldMapCompleted = OnAsyncConversionComplete;
  213. #if UNITY_IOS && !UNITY_EDITOR
  214. s_SupportsCollaboration = NativeApi.UnityARKit_session_getCollaborationSupported();
  215. #else
  216. s_SupportsCollaboration = false;
  217. #endif
  218. }
  219. static NativeApi.OnAsyncConversionCompleteDelegate s_OnAsyncWorldMapCompleted;
  220. static bool s_SupportsCollaboration;
  221. [MonoPInvokeCallback(typeof(NativeApi.OnAsyncConversionCompleteDelegate))]
  222. static unsafe void OnAsyncConversionComplete(ARWorldMapRequestStatus status, int worldMapId, IntPtr context)
  223. {
  224. var handle = GCHandle.FromIntPtr(context);
  225. var onComplete = (Action<ARWorldMapRequestStatus, ARWorldMap>)handle.Target;
  226. if (status.IsError())
  227. {
  228. onComplete(status, default(ARWorldMap));
  229. }
  230. else
  231. {
  232. var worldMap = new ARWorldMap(worldMapId);
  233. onComplete(status, worldMap);
  234. }
  235. handle.Free();
  236. }
  237. class ARKitProvider : Provider
  238. {
  239. public ARKitProvider() => NativeApi.UnityARKit_session_construct();
  240. public override void Resume() => NativeApi.UnityARKit_session_resume();
  241. public override void Pause() => NativeApi.UnityARKit_session_pause();
  242. public override void Update(XRSessionUpdateParams updateParams) => NativeApi.UnityARKit_session_update();
  243. public override void Destroy() => NativeApi.UnityARKit_session_destroy();
  244. public override void Reset() => NativeApi.UnityARKit_session_reset();
  245. public override Promise<SessionAvailability> GetAvailabilityAsync()
  246. {
  247. var result = NativeApi.UnityARKit_session_getAvailability();
  248. var retVal = SessionAvailability.None;
  249. if (result == NativeApi.Availability.Supported)
  250. retVal = SessionAvailability.Installed | SessionAvailability.Supported;
  251. return Promise<SessionAvailability>.CreateResolvedPromise(retVal);
  252. }
  253. public override Promise<SessionInstallationStatus> InstallAsync() =>
  254. throw new NotSupportedException("ARKit cannot be installed.");
  255. public override IntPtr nativePtr => NativeApi.UnityARKit_session_getNativePtr();
  256. public override TrackingState trackingState => NativeApi.UnityARKit_session_getTrackingState();
  257. public override NotTrackingReason notTrackingReason => NativeApi.UnityARKit_session_getNotTrackingReason();
  258. public override Guid sessionId => NativeApi.UnityARKit_session_getSessionId();
  259. public override bool matchFrameRate
  260. {
  261. get => NativeApi.UnityARKit_session_getMatchFrameRateEnabled();
  262. set => NativeApi.UnityARKit_session_setMatchFrameRateEnabled(value);
  263. }
  264. public override int frameRate => NativeApi.UnityARKit_Session_GetFrameRate();
  265. }
  266. [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
  267. static void RegisterDescriptor()
  268. {
  269. #if UNITY_IOS && !UNITY_EDITOR
  270. NativeApi.UnityARKit_ensureRootViewIsSetup();
  271. XRSessionSubsystemDescriptor.RegisterDescriptor(new XRSessionSubsystemDescriptor.Cinfo
  272. {
  273. id = "ARKit-Session",
  274. subsystemImplementationType = typeof(ARKitSessionSubsystem),
  275. supportsInstall = false,
  276. supportsMatchFrameRate = true
  277. });
  278. #endif
  279. }
  280. static class NativeApi
  281. {
  282. // Should match ARKitAvailability in ARKitXRSessionProvider.mm
  283. public enum Availability
  284. {
  285. None,
  286. Supported
  287. }
  288. public delegate void OnAsyncConversionCompleteDelegate(
  289. ARWorldMapRequestStatus status,
  290. int worldMapId,
  291. IntPtr context);
  292. [DllImport("__Internal")]
  293. public static extern int UnityARKit_createWorldMapRequest();
  294. [DllImport("__Internal")]
  295. public static extern void UnityARKit_createWorldMapRequestWithCallback(
  296. OnAsyncConversionCompleteDelegate callback,
  297. IntPtr context);
  298. [DllImport("__Internal")]
  299. public static extern bool UnityARKit_worldMapSupported();
  300. [DllImport("__Internal")]
  301. public static extern ARWorldMappingStatus UnityARKit_session_getWorldMappingStatus();
  302. [DllImport("__Internal")]
  303. public static extern void UnityARKit_applyWorldMap(int worldMapId);
  304. [DllImport("__Internal")]
  305. public static extern IntPtr UnityARKit_session_getNativePtr();
  306. [DllImport("__Internal")]
  307. public static extern Availability UnityARKit_session_getAvailability();
  308. [DllImport("__Internal")]
  309. public static extern void UnityARKit_session_update();
  310. [DllImport("__Internal")]
  311. public static extern void UnityARKit_session_construct();
  312. [DllImport("__Internal")]
  313. public static extern void UnityARKit_session_destroy();
  314. [DllImport("__Internal")]
  315. public static extern void UnityARKit_session_resume();
  316. [DllImport("__Internal")]
  317. public static extern void UnityARKit_session_pause();
  318. [DllImport("__Internal")]
  319. public static extern void UnityARKit_session_reset();
  320. [DllImport("__Internal")]
  321. public static extern TrackingState UnityARKit_session_getTrackingState();
  322. [DllImport("__Internal")]
  323. public static extern NotTrackingReason UnityARKit_session_getNotTrackingReason();
  324. [DllImport("__Internal")]
  325. public static extern bool UnityARKit_session_getCollaborationSupported();
  326. [DllImport("__Internal")]
  327. public static extern IntPtr UnityARKit_session_dequeueCollaborationData();
  328. [DllImport("__Internal")]
  329. public static extern int UnityARKit_session_getCollaborationDataQueueSize();
  330. [DllImport("__Internal")]
  331. public static extern void UnityARKit_session_updateWithCollaborationData(IntPtr data);
  332. [DllImport("__Internal")]
  333. public static extern bool UnityARKit_session_getCollaborationEnabled();
  334. [DllImport("__Internal")]
  335. public static extern void UnityARKit_session_setCollaborationRequested(bool requested);
  336. [DllImport("__Internal")]
  337. public static extern Guid UnityARKit_session_getSessionId();
  338. [DllImport("__Internal")]
  339. public static extern bool UnityARKit_session_getMatchFrameRateEnabled();
  340. [DllImport("__Internal")]
  341. public static extern void UnityARKit_session_setMatchFrameRateEnabled(bool enabled);
  342. [DllImport("__Internal")]
  343. public static extern int UnityARKit_Session_GetFrameRate();
  344. [DllImport("__Internal")]
  345. public static extern bool UnityARKit_coachingOverlay_getActivatesAutomatically();
  346. [DllImport("__Internal")]
  347. public static extern void UnityARKit_coachingOverlay_setActivatesAutomatically(bool activatesAutomatically);
  348. [DllImport("__Internal")]
  349. public static extern bool UnityARKit_coachingOverlay_isActive();
  350. [DllImport("__Internal")]
  351. public static extern void UnityARKit_coachingOverlay_setGoal(ARCoachingGoal goal);
  352. [DllImport("__Internal")]
  353. public static extern ARCoachingGoal UnityARKit_coachingOverlay_getGoal();
  354. [DllImport("__Internal")]
  355. public static extern void UnityARKit_coachingOverlay_setActive(bool active, bool animated);
  356. [DllImport("__Internal")]
  357. public static extern void UnityARKit_ensureRootViewIsSetup();
  358. [DllImport("__Internal")]
  359. public static extern bool UnityARKit_coachingOverlay_isSupported();
  360. }
  361. }
  362. }