public static async Task <AnchorManagerXR> TryCreate(IPlugin plugin, IHeadPoseTracker headTracker) { bool xrRunning = await CheckXRRunning(); if (!xrRunning) { return(null); } /// Try to find an XRAnchorManager (to be XRAnchorManager) here. /// If we fail that, /// give up. /// Else /// pass the manager into AnchorManagerXR for its use. XRAnchorSubsystem xrAnchorManager = FindAnchorManager(); if (xrAnchorManager == null) { return(null); } if (!xrAnchorManager.running) { xrAnchorManager.Start(); } var session = FindSessionSubsystem(); AnchorManagerXR anchorManager = new AnchorManagerXR(plugin, headTracker, xrAnchorManager, session); return(anchorManager); }
public static AnchorManagerXR TryCreate(IPlugin plugin, IHeadPoseTracker headTracker) { /// Try to find an XRAnchorManager (to be XRAnchorManager) here. /// If we fail that, /// give up. /// Else /// pass the manager into AnchorManagerXR for its use. XRAnchorSubsystem xrAnchorManager = FindAnchorManager(); if (xrAnchorManager == null) { return(null); } if (!xrAnchorManager.running) { xrAnchorManager.Start(); } var session = FindSessionSubsystem(); /// mafinc - Currently a problem in OpenXR obtaining the session subsystem. /// Everything can function without it, it is only used for detecting loss of tracking. //if (session == null) //{ // return null; //} AnchorManagerXR anchorManager = new AnchorManagerXR(plugin, headTracker, xrAnchorManager, session); return(anchorManager); }
/// <summary> /// Request an instance of <see cref="XRAnchorStore"/>. /// </summary> /// <param name="anchorSubsytem">Instance of a running <see cref="XRAnchorSubsystem"/></param> /// <returns>A [Task](https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1?view=netcore-3.1) that may return an instance of <see cref="XRAnchorStore"/> at some time in the future.</returns> public static Task <XRAnchorStore> TryGetAnchorStoreAsync(this XRAnchorSubsystem anchorSubsytem) { return(Task <XRAnchorStore> .Run(() => { IntPtr storePtr = NativeApi.UnityWindowsMR_refPoints_tryGetAnchorStore(); return new XRAnchorStore(storePtr); })); }
XRAnchorStore GetAnchorStore() { XRAnchorSubsystem rpsub = ActiveLoader.GetLoadedSubsystem <XRAnchorSubsystem>(); Assert.NotNull(rpsub); var store = rpsub.TryGetAnchorStoreAsync().Result; Assert.NotNull(store); return(store); }
/// <summary> /// Set up an anchor manager. /// </summary> /// <param name="plugin">The engine interface to update with the current anchor graph.</param> private AnchorManagerXR(IPlugin plugin, IHeadPoseTracker headTracker, XRAnchorSubsystem xrAnchorManager, XRSessionSubsystem session) : base(plugin, headTracker) { this.xrAnchorManager = xrAnchorManager; this.sessionSubsystem = session; Debug.Log($"XR: Created AnchorManager XR, xrMgr={(this.xrAnchorManager != null ? "good" : "null")}"); Debug.Log($"ActiveLoader name:[{XRGeneralSettings.Instance.Manager.activeLoader.name}] type:[{XRGeneralSettings.Instance.Manager.activeLoader.GetType().FullName}]"); #if WLT_XR_MANAGEMENT_PRESENT wmrPersistence = XRGeneralSettings.Instance.Manager.activeLoader.name.StartsWith("Windows MR"); openXRPersistence = XRGeneralSettings.Instance.Manager.activeLoader.name.StartsWith("Open XR"); #endif // WLT_XR_MANAGEMENT_PRESENT Debug.Log($"XRSDK Persistence: WMR={wmrPersistence} OpenXR={openXRPersistence}"); }
bool CheckThereAreNoAnchors() { XRAnchorSubsystem rpsub = ActiveLoader.GetLoadedSubsystem <XRAnchorSubsystem>(); Assert.NotNull(rpsub); TrackableChanges <XRAnchor>?currentRps = rpsub.GetChanges(Allocator.Temp); bool hasNoAnchors = (currentRps == null) ? false : currentRps?.added.Length == 0 && currentRps?.removed.Length == 0 && currentRps?.updated.Length == 0; return(hasNoAnchors); }
public void RunningStateTests() { XRAnchorSubsystem subsystem = CreateTestAnchorSubsystem(); // Initial state is not running Assert.That(subsystem.running == false); // After start subsystem is running subsystem.Start(); Assert.That(subsystem.running == true); // After start subsystem is running subsystem.Stop(); Assert.That(subsystem.running == false); }
bool CheckAnchorUpdateState(TrackableId id, UpdateState updateState) { XRAnchorSubsystem rpsub = ActiveLoader.GetLoadedSubsystem <XRAnchorSubsystem>(); Assert.NotNull(rpsub); TrackableChanges <XRAnchor>?currentRps = rpsub.GetChanges(Allocator.Temp); Assert.IsNotNull(currentRps); XRAnchor? rp = null; TrackableId idToCheck = defaultId; switch (updateState) { case UpdateState.Added: Assert.AreNotEqual(0, currentRps?.added.Length ?? 0); rp = currentRps?.added[0] ?? null; idToCheck = rp?.trackableId ?? defaultId; break; case UpdateState.Updated: Assert.AreNotEqual(0, currentRps?.updated.Length ?? 0); rp = currentRps?.updated[0] ?? null; idToCheck = rp?.trackableId ?? defaultId; break; case UpdateState.Removed: Assert.AreNotEqual(0, currentRps?.removed.Length ?? 0); idToCheck = currentRps?.removed[0] ?? defaultId; break; case UpdateState.None: default: return(false); } return(idToCheck == id); }
IEnumerator RemoveAndCheckAnchor(TrackableId id, Action <TrackableId> callback) { XRAnchorSubsystem rpsub = ActiveLoader.GetLoadedSubsystem <XRAnchorSubsystem>(); Assert.NotNull(rpsub); rpsub.TryRemoveAnchor(id); yield return(null); TrackableChanges <XRAnchor>?currentRps = rpsub.GetChanges(Allocator.Temp); Assert.IsNotNull(currentRps); Assert.AreNotEqual(0, currentRps?.removed.Length ?? 0); TrackableId?rpRemoved = currentRps?.removed[0] ?? null; if (callback != null) { callback.Invoke(rpRemoved ?? defaultId); } }
/// <summary> /// Find the correct AnchorManager for this session. /// </summary> /// <returns>Anchor manager for this session.</returns> /// <remarks> /// For HoloLens, we are looking for the _active_ anchor subsystem. There may be multiple /// anchor subsystems (e.g. OpenXR Plugin and WMR XR Plugin), but only one will be active. /// However, on Android, no anchor subsystem is active until we make it active by calling Start() on it. /// So if we still don't have an active subsystem, try calling start on any that are available and /// if that makes them active (running), then take that one. /// Note that this would be bad on HoloLens, as it would start up a subsystem that is installed but not currently selected. /// I believe that iOS works as HoloLens does, but I don't want to rely on undocumented behavior. The algorithm here /// should work on either. /// </remarks> private static XRAnchorSubsystem FindAnchorManager() { List <XRAnchorSubsystem> anchorSubsystems = new List <XRAnchorSubsystem>(); SubsystemManager.GetInstances(anchorSubsystems); Debug.Log($"Found {anchorSubsystems.Count} anchor subsystems."); XRAnchorSubsystem activeSubsystem = null; int numFound = 0; foreach (var sub in anchorSubsystems) { if (sub.running) { Debug.Log($"Found active anchor subsystem {sub.subsystemDescriptor.id}."); activeSubsystem = sub; ++numFound; } } if (activeSubsystem == null) { Debug.Log($"Found no anchor subsystem running, will try starting one."); foreach (var sub in anchorSubsystems) { sub.Start(); if (sub.running) { activeSubsystem = sub; ++numFound; Debug.Log($"Start changed an anchor subsystem to running."); } } } if (numFound != 1) { Debug.LogError($"Found {numFound} active anchor subsystems, expected exactly one."); } return(activeSubsystem); }
IEnumerator AddAndCheckAnchor(Action <TrackableId> callback) { XRAnchorSubsystem rpsub = ActiveLoader.GetLoadedSubsystem <XRAnchorSubsystem>(); Assert.NotNull(rpsub); XRAnchor rp; bool ret = rpsub.TryAddAnchor(defaultPose, out rp); Assert.IsTrue(ret); Assert.AreNotEqual(defaultId, rp.trackableId); yield return(null); TrackableChanges <XRAnchor>?currentRps = rpsub.GetChanges(Allocator.Temp); Assert.IsNotNull(currentRps); Assert.AreNotEqual(0, currentRps?.added.Length ?? 0); if (callback != null) { callback.Invoke(currentRps?.added[0].trackableId ?? defaultId); } }