NRSessionManager.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  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 UnityEngine;
  13. using System.Collections;
  14. using System.Collections.Generic;
  15. using NRKernal.Record;
  16. #if USING_XR_SDK
  17. using UnityEngine.XR;
  18. using System.Runtime.InteropServices;
  19. #endif
  20. /// <summary>
  21. /// Manages AR system state and handles the session lifecycle. this class, application can create
  22. /// a session, configure it, start/pause or stop it. </summary>
  23. public class NRSessionManager : SingleTon<NRSessionManager>
  24. {
  25. /// <summary> The lost tracking reason. </summary>
  26. private LostTrackingReason m_LostTrackingReason = LostTrackingReason.INITIALIZING;
  27. /// <summary> Current lost tracking reason. </summary>
  28. /// <value> The lost tracking reason. </value>
  29. public LostTrackingReason LostTrackingReason
  30. {
  31. get
  32. {
  33. return m_LostTrackingReason;
  34. }
  35. }
  36. /// <summary> State of the session. </summary>
  37. private SessionState m_SessionState = SessionState.UnInitialized;
  38. /// <summary> Gets or sets the state of the session. </summary>
  39. /// <value> The session state. </value>
  40. public SessionState SessionState
  41. {
  42. get
  43. {
  44. return m_SessionState;
  45. }
  46. private set
  47. {
  48. m_SessionState = value;
  49. }
  50. }
  51. /// <summary> Gets or sets the nr session behaviour. </summary>
  52. /// <value> The nr session behaviour. </value>
  53. public NRSessionBehaviour NRSessionBehaviour { get; private set; }
  54. /// <summary> Gets or sets the nrhmd pose tracker. </summary>
  55. /// <value> The nrhmd pose tracker. </value>
  56. public NRHMDPoseTracker NRHMDPoseTracker { get; private set; }
  57. /// <summary> Gets or sets the native a pi. </summary>
  58. /// <value> The native a pi. </value>
  59. public NativeInterface NativeAPI { get; set; }
  60. /// <summary> Gets or sets the nr renderer. </summary>
  61. /// <value> The nr renderer. </value>
  62. public NRRenderer NRRenderer { get; set; }
  63. /// <summary> Gets or sets the virtual displayer. </summary>
  64. /// <value> The virtual displayer. </value>
  65. public NRVirtualDisplayer VirtualDisplayer { get; set; }
  66. public NRTrackingModeChangedListener TrackingLostListener { get; set; }
  67. /// <summary> Gets or sets the trackable factory. </summary>
  68. /// <value> The trackable factory. </value>
  69. public NRTrackableManager TrackableFactory { get; set; }
  70. /// <summary> Gets the center camera anchor. </summary>
  71. /// <value> The center camera anchor. </value>
  72. public Transform CenterCameraAnchor
  73. {
  74. get
  75. {
  76. if (NRHMDPoseTracker != null && NRHMDPoseTracker.centerAnchor != null)
  77. {
  78. return NRHMDPoseTracker.centerAnchor;
  79. }
  80. else
  81. {
  82. return Camera.main.transform;
  83. }
  84. }
  85. }
  86. /// <summary> Gets the left camera anchor. </summary>
  87. /// <value> The left camera anchor. </value>
  88. public Transform LeftCameraAnchor
  89. {
  90. get
  91. {
  92. return NRHMDPoseTracker?.leftCamera.transform;
  93. }
  94. }
  95. /// <summary> Gets the right camera anchor. </summary>
  96. /// <value> The right camera anchor. </value>
  97. public Transform RightCameraAnchor
  98. {
  99. get
  100. {
  101. return NRHMDPoseTracker?.rightCamera.transform;
  102. }
  103. }
  104. #region Events
  105. public delegate void SessionError(NRKernalError exception);
  106. /// <summary> Event queue for all listeners interested in OnHMDPoseReady events. </summary>
  107. public static HMDPoseTrackerEvent OnHMDPoseReady;
  108. /// <summary> Event queue for all listeners interested in OnHMDLostTracking events. </summary>
  109. public static HMDPoseTrackerEvent OnHMDLostTracking;
  110. /// <summary> Event queue for all listeners interested in OnChangeTrackingMode events. </summary>
  111. public static HMDPoseTrackerModeChangeEvent OnChangeTrackingMode;
  112. /// <summary> Event queue for all listeners interested in OnGlassesStateChanged events. </summary>
  113. public static GlassesEvent OnGlassesStateChanged;
  114. /// <summary> Event queue for all listeners interested in OnGlassesDisconnect events. </summary>
  115. public static GlassesDisconnectEvent OnGlassesDisconnect;
  116. /// <summary> Event queue for all listeners interested in kernal error,
  117. /// such as NRRGBCameraDeviceNotFindError, NRPermissionDenyError, NRUnSupportedHandtrackingCalculationError. </summary>
  118. public static event SessionError OnKernalError;
  119. #endregion
  120. private NRTrackingSubsystem m_TrackingSystem;
  121. public NRTrackingSubsystem TrackingSubSystem
  122. {
  123. get
  124. {
  125. if (m_TrackingSystem == null)
  126. {
  127. string tracking_match = NRTrackingSubsystemDescriptor.Name;
  128. List<NRTrackingSubsystemDescriptor> trackings = new List<NRTrackingSubsystemDescriptor>();
  129. NRSubsystemManager.GetSubsystemDescriptors(trackings);
  130. foreach (var tracking in trackings)
  131. {
  132. if (tracking.id.Equals(tracking_match))
  133. {
  134. m_TrackingSystem = tracking.Create();
  135. }
  136. }
  137. }
  138. return m_TrackingSystem;
  139. }
  140. }
  141. #if USING_XR_SDK
  142. private const string display_match = "NRSDK Display";
  143. private const string input_match = "NRSDK Head Tracking";
  144. private XRDisplaySubsystem m_XRDisplaySubsystem;
  145. public XRDisplaySubsystem XRDisplaySubsystem{
  146. get{
  147. if (m_XRDisplaySubsystem == null)
  148. {
  149. List<XRDisplaySubsystemDescriptor> displays = new List<XRDisplaySubsystemDescriptor>();
  150. SubsystemManager.GetSubsystemDescriptors(displays);
  151. foreach (var d in displays)
  152. {
  153. if (d.id.Contains(display_match))
  154. {
  155. m_XRDisplaySubsystem = d.Create();
  156. }
  157. }
  158. }
  159. return m_XRDisplaySubsystem;
  160. }
  161. }
  162. private XRInputSubsystem m_XRInputSubsystem;
  163. public XRInputSubsystem XRInputSubsystem
  164. {
  165. get{
  166. if (m_XRInputSubsystem == null)
  167. {
  168. List<XRInputSubsystemDescriptor> inputs = new List<XRInputSubsystemDescriptor>();
  169. SubsystemManager.GetSubsystemDescriptors(inputs);
  170. foreach (var i in inputs)
  171. {
  172. if (i.id.Contains(input_match))
  173. {
  174. m_XRInputSubsystem = i.Create();
  175. }
  176. }
  177. }
  178. return m_XRInputSubsystem;
  179. }
  180. }
  181. #endif
  182. /// <summary> Gets a value indicating whether this object is initialized. </summary>
  183. /// <value> True if this object is initialized, false if not. </value>
  184. public bool IsInitialized
  185. {
  186. get
  187. {
  188. return (SessionState != SessionState.UnInitialized
  189. && SessionState != SessionState.Destroyed);
  190. }
  191. }
  192. /// <summary> Creates a session. </summary>
  193. /// <param name="session"> The session behaviour.</param>
  194. public void CreateSession(NRSessionBehaviour session)
  195. {
  196. if (SessionState != SessionState.UnInitialized && SessionState != SessionState.Destroyed)
  197. {
  198. return;
  199. }
  200. SetAppSettings();
  201. if (NRSessionBehaviour != null)
  202. {
  203. NRDebugger.Error("[NRSessionManager] Multiple SessionBehaviour components cannot exist in the scene. " +
  204. "Destroying the newest.");
  205. GameObject.DestroyImmediate(session.gameObject);
  206. return;
  207. }
  208. NRSessionBehaviour = session;
  209. NRHMDPoseTracker = session.GetComponent<NRHMDPoseTracker>();
  210. if (NRHMDPoseTracker == null)
  211. {
  212. NRDebugger.Error("[NRSessionManager] Can not find the NRHMDPoseTracker in the NRSessionBehaviour object.");
  213. OprateInitException(new NRMissingKeyComponentError("Missing the key component of 'NRHMDPoseTracker'."));
  214. return;
  215. }
  216. try
  217. {
  218. NRDevice.Instance.Init();
  219. }
  220. catch (Exception ex)
  221. {
  222. NRDebugger.Error("[NRSessionManager] NRDevice Init failed: {0}", ex.Message);
  223. return;
  224. }
  225. var config = NRSessionBehaviour.SessionConfig;
  226. if (config != null)
  227. {
  228. var deviceType = NRDevice.Subsystem.GetDeviceType();
  229. NRDebugger.Info("[NRSessionManager] targetDeviceType : curDevice={0}, targetDevices={1}", deviceType, config.GetTargetDeviceTypesDesc());
  230. if (!config.IsTargetDevice(deviceType))
  231. {
  232. OprateInitException(new NRUnSupportDeviceError(string.Format("Unsuppport running on {0}!", deviceType)));
  233. return;
  234. }
  235. }
  236. NativeAPI = new NativeInterface();
  237. TrackableFactory = new NRTrackableManager();
  238. AsyncTaskExecuter.Instance.RunAction(() =>
  239. {
  240. NRHMDPoseTracker.AutoAdaptTrackingType();
  241. NRDebugger.Info("[NRSessionManager] Create tracking : {0}", NRHMDPoseTracker.TrackingMode);
  242. this.AutoAdaptSessionConfig();
  243. switch (NRHMDPoseTracker.TrackingMode)
  244. {
  245. case NRHMDPoseTracker.TrackingType.Tracking6Dof:
  246. TrackingSubSystem.InitTrackingMode(TrackingMode.MODE_6DOF);
  247. break;
  248. case NRHMDPoseTracker.TrackingType.Tracking3Dof:
  249. NRSessionBehaviour.SessionConfig.PlaneFindingMode = TrackablePlaneFindingMode.DISABLE;
  250. NRSessionBehaviour.SessionConfig.ImageTrackingMode = TrackableImageFindingMode.DISABLE;
  251. TrackingSubSystem.InitTrackingMode(TrackingMode.MODE_3DOF);
  252. break;
  253. case NRHMDPoseTracker.TrackingType.Tracking0Dof:
  254. NRSessionBehaviour.SessionConfig.PlaneFindingMode = TrackablePlaneFindingMode.DISABLE;
  255. NRSessionBehaviour.SessionConfig.ImageTrackingMode = TrackableImageFindingMode.DISABLE;
  256. TrackingSubSystem.InitTrackingMode(TrackingMode.MODE_0DOF);
  257. break;
  258. case NRHMDPoseTracker.TrackingType.Tracking0DofStable:
  259. NRSessionBehaviour.SessionConfig.PlaneFindingMode = TrackablePlaneFindingMode.DISABLE;
  260. NRSessionBehaviour.SessionConfig.ImageTrackingMode = TrackableImageFindingMode.DISABLE;
  261. TrackingSubSystem.InitTrackingMode(TrackingMode.MODE_0DOF_STAB);
  262. break;
  263. default:
  264. break;
  265. }
  266. });
  267. TrackingLostListener = new NRTrackingModeChangedListener();
  268. #if USING_XR_SDK && !UNITY_EDITOR
  269. TrackingLostListener.OnTrackStateChanged += (bool onSwitchingMode, RenderTexture rt) =>
  270. {
  271. SetSwitchModeFrameInfo(new SwitchModeFrameInfo() { flag = onSwitchingMode, renderTexture = rt.GetNativeTexturePtr() });
  272. };
  273. #endif
  274. NRKernalUpdater.OnPreUpdate -= OnPreUpdate;
  275. NRKernalUpdater.OnPreUpdate += OnPreUpdate;
  276. #if !UNITY_EDITOR && !USING_XR_SDK
  277. if (NRSessionBehaviour.gameObject.GetComponent<NRRenderer>() == null)
  278. NRRenderer = NRSessionBehaviour.gameObject.AddComponent<NRRenderer>();
  279. #endif
  280. NRDebugger.Info("[NRSessionManager] CreateSession : AddComponent NRRenderer");
  281. SessionState = SessionState.Initialized;
  282. LoadNotification();
  283. }
  284. public NRNotificationListener NotificationListener { get; private set; }
  285. /// <summary> Loads the notification. </summary>
  286. private void LoadNotification()
  287. {
  288. NotificationListener = GameObject.FindObjectOfType<NRNotificationListener>();
  289. if (NotificationListener == null)
  290. {
  291. NotificationListener = GameObject.Instantiate(Resources.Load<NRNotificationListener>("NRNotificationListener"));
  292. }
  293. }
  294. /// <summary> True if is session error, false if not. </summary>
  295. private bool m_IsSessionError = false;
  296. /// <summary> Oprate initialize exception. </summary>
  297. /// <param name="e"> An Exception to process.</param>
  298. internal void OprateInitException(Exception e)
  299. {
  300. NRDebugger.Error("[NRSessionManager] Kernal error:" + e.Message);
  301. if (m_IsSessionError || !(e is NRKernalError))
  302. {
  303. return;
  304. }
  305. var kernal_error = e as NRKernalError;
  306. if (kernal_error.level == Level.High)
  307. {
  308. m_IsSessionError = true;
  309. ShowErrorTips(kernal_error);
  310. }
  311. else if (kernal_error.level == Level.Normal)
  312. {
  313. OnKernalError?.Invoke((NRKernalError)e);
  314. }
  315. }
  316. /// <summary>
  317. /// Get error tip been shown for users.
  318. /// </summary>
  319. /// <param name="error"> The error exception.</param>
  320. /// <returns> Error tip. </returns>
  321. private string GetErrorTip(Exception error)
  322. {
  323. string tip = GetErrorTipDesc(error);
  324. if (error is NRNativeError)
  325. {
  326. NativeResult result = (error as NRNativeError).result;
  327. tip = string.Format("Error Code-{0}, {1}", (int)result, tip);
  328. }
  329. return tip;
  330. }
  331. private string GetErrorTipDesc(Exception error)
  332. {
  333. if (error is NRGlassesConnectError)
  334. {
  335. return NativeConstants.GlassesDisconnectErrorTip;
  336. }
  337. else if (error is NRGlassesNotAvailbleError)
  338. {
  339. return NativeConstants.GlassesNotAvailbleErrorTip;
  340. }
  341. else if (error is NRSdkVersionMismatchError)
  342. {
  343. return NativeConstants.SdkVersionMismatchErrorTip;
  344. }
  345. else if (error is NRSdcardPermissionDenyError)
  346. {
  347. return NativeConstants.SdcardPermissionDenyErrorTip;
  348. }
  349. else if (error is NRUnSupportDeviceError)
  350. {
  351. return NativeConstants.UnSupportDeviceErrorTip;
  352. }
  353. else if (error is NRDPDeviceNotFindError)
  354. {
  355. return NativeConstants.DPDeviceNotFindErrorTip;
  356. }
  357. else if (error is NRGetDisplayFailureError)
  358. {
  359. return NativeConstants.GetDisplayFailureErrorTip;
  360. }
  361. else if (error is NRDisplayModeMismatchError)
  362. {
  363. return NativeConstants.DisplayModeMismatchErrorTip;
  364. }
  365. else
  366. {
  367. return NativeConstants.UnknowErrorTip;
  368. }
  369. }
  370. /// <summary> Shows the error tips. </summary>
  371. /// <param name="msg"> The message.</param>
  372. private void ShowErrorTips(NRKernalError error)
  373. {
  374. string msg = GetErrorTip(error);
  375. var sessionbehaviour = GameObject.FindObjectOfType<NRSessionBehaviour>();
  376. NRGlassesInitErrorTip errortips;
  377. if (sessionbehaviour != null && sessionbehaviour.SessionConfig.GlassesErrorTipPrefab != null)
  378. {
  379. errortips = GameObject.Instantiate<NRGlassesInitErrorTip>(sessionbehaviour.SessionConfig.GlassesErrorTipPrefab);
  380. }
  381. else
  382. {
  383. errortips = GameObject.Instantiate<NRGlassesInitErrorTip>(Resources.Load<NRGlassesInitErrorTip>("NRErrorTips"));
  384. }
  385. // Clear objects of scene.
  386. if (sessionbehaviour != null)
  387. {
  388. GameObject.Destroy(sessionbehaviour.gameObject);
  389. }
  390. var input = GameObject.FindObjectOfType<NRInput>();
  391. if (input != null)
  392. {
  393. GameObject.Destroy(input.gameObject);
  394. }
  395. var virtualdisplay = GameObject.FindObjectOfType<NRVirtualDisplayer>();
  396. if (virtualdisplay != null)
  397. {
  398. GameObject.Destroy(virtualdisplay.gameObject);
  399. }
  400. GameObject.DontDestroyOnLoad(errortips);
  401. errortips.Init(msg, () =>
  402. {
  403. NRDevice.QuitApp();
  404. });
  405. }
  406. /// <summary> Executes the 'pre update' action. </summary>
  407. private void OnPreUpdate()
  408. {
  409. if (SessionState != SessionState.Running || m_IsSessionError)
  410. {
  411. Debug.LogError(SessionState.ToString());
  412. return;
  413. }
  414. if (NRHMDPoseTracker.IsTrackModeChanging || NRHMDPoseTracker.TrackingMode == NRHMDPoseTracker.TrackingType.Tracking0Dof)
  415. return;
  416. #if USING_XR_SDK && !UNITY_EDITOR
  417. m_LostTrackingReason = GetLostTrackingReason();
  418. #else
  419. NRFrame.OnPreUpdate(ref m_LostTrackingReason);
  420. #endif
  421. }
  422. /// <summary> Sets a configuration. </summary>
  423. /// <param name="config"> The configuration.</param>
  424. public void SetConfiguration(NRSessionConfig config)
  425. {
  426. if (SessionState == SessionState.UnInitialized
  427. || SessionState == SessionState.Destroyed
  428. || SessionState == SessionState.Paused
  429. || m_IsSessionError)
  430. {
  431. NRDebugger.Error("[NRSessionManager] Can not set configuration in this state:" + SessionState.ToString());
  432. return;
  433. }
  434. #if !UNITY_EDITOR
  435. if (config == null)
  436. {
  437. return;
  438. }
  439. AsyncTaskExecuter.Instance.RunAction(() =>
  440. {
  441. NRDebugger.Info("[NRSessionManager] Update config");
  442. NativeAPI.Configration.UpdateConfig(config);
  443. });
  444. #endif
  445. }
  446. /// <summary> Recenters this object. </summary>
  447. public void Recenter()
  448. {
  449. if (SessionState != SessionState.Running || m_IsSessionError)
  450. {
  451. return;
  452. }
  453. AsyncTaskExecuter.Instance.RunAction(() =>
  454. {
  455. TrackingSubSystem.Recenter();
  456. });
  457. }
  458. /// <summary> Sets application settings. </summary>
  459. private void SetAppSettings()
  460. {
  461. Application.targetFrameRate = 240;
  462. QualitySettings.maxQueuedFrames = -1;
  463. QualitySettings.vSyncCount = 0;
  464. Screen.fullScreen = true;
  465. Screen.sleepTimeout = SleepTimeout.NeverSleep;
  466. }
  467. /// <summary> Starts a session. </summary>
  468. public void StartSession()
  469. {
  470. if (SessionState == SessionState.Running
  471. || SessionState == SessionState.Destroyed
  472. || m_IsSessionError)
  473. {
  474. return;
  475. }
  476. AfterInitialized(() =>
  477. {
  478. NRDebugger.Info("[NRSessionManager] Start session after initialized");
  479. #if !UNITY_EDITOR && !USING_XR_SDK
  480. if (NRRenderer == null)
  481. NRRenderer = NRSessionBehaviour.gameObject.AddComponent<NRRenderer>();
  482. NRRenderer.Initialize(NRHMDPoseTracker.leftCamera, NRHMDPoseTracker.rightCamera);
  483. #endif
  484. #if USING_XR_SDK && !UNITY_EDITOR
  485. XRDisplaySubsystem?.Start();
  486. XRInputSubsystem?.Start();
  487. #endif
  488. TrackableFactory.Start();
  489. AsyncTaskExecuter.Instance.RunAction(() =>
  490. {
  491. NRDebugger.Info("[NRSessionManager] Start tracking");
  492. TrackingSubSystem.Start();
  493. SessionState = SessionState.Running;
  494. });
  495. SetConfiguration(NRSessionBehaviour.SessionConfig);
  496. });
  497. }
  498. /// <summary>Do it after session manager initialized. </summary>
  499. /// <param name="callback"> The after initialized callback.</param>
  500. private void AfterInitialized(Action callback)
  501. {
  502. NRKernalUpdater.Instance.StartCoroutine(WaitForInitialized(callback));
  503. }
  504. /// <summary> Wait for initialized. </summary>
  505. /// <param name="affterInitialized"> The affter initialized.</param>
  506. /// <returns> An IEnumerator. </returns>
  507. private IEnumerator WaitForInitialized(Action affterInitialized)
  508. {
  509. while (SessionState == SessionState.UnInitialized || m_IsSessionError)
  510. {
  511. NRDebugger.Debug("[NRSessionManager] Wait for initialized...");
  512. yield return new WaitForEndOfFrame();
  513. }
  514. affterInitialized?.Invoke();
  515. }
  516. /// <summary> Disables the session. </summary>
  517. public void DisableSession()
  518. {
  519. if (SessionState != SessionState.Running || m_IsSessionError)
  520. {
  521. return;
  522. }
  523. // Do not put it in other thread...
  524. TrackableFactory.Pause();
  525. NRRenderer?.Pause();
  526. TrackingSubSystem.Pause();
  527. NRDevice.Instance.Pause();
  528. #if USING_XR_SDK && !UNITY_EDITOR
  529. XRDisplaySubsystem?.Stop();
  530. XRInputSubsystem?.Stop();
  531. #endif
  532. SessionState = SessionState.Paused;
  533. }
  534. /// <summary> Resume session. </summary>
  535. public void ResumeSession()
  536. {
  537. if (SessionState != SessionState.Paused || m_IsSessionError)
  538. {
  539. return;
  540. }
  541. // Do not put it in other thread...
  542. TrackableFactory.Resume();
  543. TrackingSubSystem.Resume();
  544. NRRenderer?.Resume();
  545. NRDevice.Instance.Resume();
  546. #if USING_XR_SDK && !UNITY_EDITOR
  547. XRDisplaySubsystem?.Start();
  548. XRInputSubsystem?.Start();
  549. #endif
  550. SessionState = SessionState.Running;
  551. }
  552. /// <summary> Destroys the session. </summary>
  553. public void DestroySession()
  554. {
  555. if (SessionState == SessionState.Destroyed || SessionState == SessionState.UnInitialized)
  556. {
  557. return;
  558. }
  559. // Do not put it in other thread...
  560. SessionState = SessionState.Destroyed;
  561. TrackableFactory.Stop();
  562. NRRenderer?.Destroy();
  563. TrackingSubSystem.Stop();
  564. NRDevice.Instance.Destroy();
  565. NRInput.Destroy();
  566. VirtualDisplayer.Stop();
  567. #if USING_XR_SDK && !UNITY_EDITOR
  568. ShutDownNativeSystems();
  569. #endif
  570. }
  571. public void SetFPSMode(FrameRateMode mode)
  572. {
  573. #if USING_XR_SDK && !UNITY_EDITOR
  574. SetFrameRateMode(mode);
  575. #endif
  576. }
  577. /// <summary> Auto adaption for sessionConfig(PlaneFindingMode&ImageTrackingMode) based on supported feature on current device. </summary>
  578. private void AutoAdaptSessionConfig()
  579. {
  580. if (NRDevice.Subsystem.GetDeviceType() == NRDeviceType.NrealAir)
  581. {
  582. if (NRSessionBehaviour.SessionConfig.PlaneFindingMode != TrackablePlaneFindingMode.DISABLE)
  583. {
  584. NRDebugger.Warning("[NRSessionManager] AutoAdaptConfig PlaneFindingMode : {0} => {1}", NRSessionBehaviour.SessionConfig.PlaneFindingMode, TrackablePlaneFindingMode.DISABLE);
  585. NRSessionBehaviour.SessionConfig.PlaneFindingMode = TrackablePlaneFindingMode.DISABLE;
  586. }
  587. if (NRSessionBehaviour.SessionConfig.ImageTrackingMode != TrackableImageFindingMode.DISABLE)
  588. {
  589. NRDebugger.Warning("[NRSessionManager] AutoAdaptConfig ImageTrackingMode : {0} => {1}", NRSessionBehaviour.SessionConfig.ImageTrackingMode, TrackableImageFindingMode.DISABLE);
  590. NRSessionBehaviour.SessionConfig.ImageTrackingMode = TrackableImageFindingMode.DISABLE;
  591. }
  592. }
  593. }
  594. #if USING_XR_SDK && !UNITY_EDITOR
  595. [DllImport("NrealXRPlugin", CharSet = CharSet.Auto)]
  596. static extern void ShutDownNativeSystems();
  597. [DllImport("NrealXRPlugin", CharSet = CharSet.Auto)]
  598. static extern void SetFrameRateMode(FrameRateMode mode);
  599. [DllImport("NrealXRPlugin", CharSet = CharSet.Auto)]
  600. static extern void SetSwitchModeFrameInfo(SwitchModeFrameInfo mode);
  601. [DllImport("NrealXRPlugin", CharSet = CharSet.Auto)]
  602. static extern LostTrackingReason GetLostTrackingReason();
  603. #endif
  604. }
  605. }