private void SpatialLocalizationSettingsGUI(string deviceTypeLabel, int selectedLocalizerIndex, ISpatialLocalizer[] localizers) { GUIStyle iconButtonStyle = GUI.skin.FindStyle("IconButton") ?? EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector).FindStyle("IconButton"); GUIContent content = new GUIContent(EditorGUIUtility.Load("icons/d__Popup.png") as Texture2D); ISpatialLocalizationSettings settings = localizers == null ? null : LoadLocalizerSettings(localizers[selectedLocalizerIndex]); IEditableSpatialLocalizationSettings settingsEditor = settings as IEditableSpatialLocalizationSettings; bool wasEnabled = GUI.enabled; GUI.enabled = settingsEditor != null; if (EditorGUILayout.DropdownButton(content, FocusType.Passive, iconButtonStyle, GUILayout.Width(settingsButtonWidth))) { Action <SpatialLocalizationSettingsEditor> editingCompleted = null; Guid localizerId = localizers[selectedLocalizerIndex].SpatialLocalizerId; editingCompleted = e => { e.EditingCompleted -= editingCompleted; SaveLocalizerSettings(localizerId, settings); }; var editor = settingsEditor.CreateEditor(); editor.EditingCompleted += editingCompleted; PopupWindow.Show(buttonRects[deviceTypeLabel], editor); } if (Event.current.type == EventType.Repaint) { buttonRects[deviceTypeLabel] = GUILayoutUtility.GetLastRect(); } GUI.enabled = wasEnabled; }
private void SaveLocalizerSettings(Guid spatialLocalizerId, ISpatialLocalizationSettings settings) { using (MemoryStream stream = new MemoryStream()) using (BinaryWriter writer = new BinaryWriter(stream)) { settings.Serialize(writer); PlayerPrefs.SetString(spatialLocalizerId.ToString(), Convert.ToBase64String(stream.ToArray())); PlayerPrefs.Save(); } }
bool ISpatialLocalizer.TryDeserializeSettings(BinaryReader reader, out ISpatialLocalizationSettings settings) { if (TryDeserializeSettings(reader, out TSpatialLocalizationSettings specificSettings)) { settings = specificSettings; return(true); } else { settings = default(ISpatialLocalizationSettings); return(false); } }
/// <summary> /// Runs a localization session on the specific <see cref="SpatialCoordinateSystemParticipant"/>'s connected peer, followed /// by creating a persisted WorldAnchor-based <see cref="ISpatialCoordinate"/> based on the located coordinate. /// </summary> /// <param name="participant">The participant to use to initiate the remote localization sessions.</param> /// <param name="spatialLocalizerId">The ID of the <see cref="ISpatialLocalizer"/> to use /// for discovering a spatial coordinate.</param> /// <param name="settings">The settings to pass to the remote localizer.</param> public async void RunRemoteLocalizationWithWorldAnchorPersistence(SpatialCoordinateSystemParticipant participant, Guid spatialLocalizerId, ISpatialLocalizationSettings settings) { // If the initial request to restore a coordinate from a WorldAnchor hasn't completed, wait for that to complete first. if (participantLocalizationTasks.TryGetValue(participant, out Task <bool> currentTask)) { await currentTask; } // Request localization using the specific localizer and settings, and wait for that localization to complete. participantLocalizationTasks[participant] = currentTask = SpatialCoordinateSystemManager.Instance.RunRemoteLocalizationAsync(participant.SocketEndpoint, spatialLocalizerId, settings); bool localizationSucceeded = await currentTask; if (localizationSucceeded) { // Once the specific localizer has found a shared coordinate, ask the WorldAnchorSpatialLocalizer // to create a WorldAnchor-based coordinate at the same location, and persist that coordinate across sessions. participantLocalizationTasks[participant] = currentTask = SpatialCoordinateSystemManager.Instance.RunRemoteLocalizationAsync(participant.SocketEndpoint, WorldAnchorSpatialLocalizer.Id, new WorldAnchorSpatialLocalizationSettings { Mode = WorldAnchorLocalizationMode.CreateAnchorAtWorldTransform, AnchorId = CompositorWorldAnchorId, AnchorPosition = participant.PeerSpatialCoordinateWorldPosition, AnchorRotation = participant.PeerSpatialCoordinateWorldRotation }); await currentTask; } else { Debug.LogError($"Remote localization failed on device {participant.SocketEndpoint.Address} for spatial localizer {spatialLocalizerId}"); } }
bool ISpatialLocalizer.TryCreateLocalizationSession(IPeerConnection peerConnection, ISpatialLocalizationSettings settings, out ISpatialLocalizationSession session) { if (settings is TSpatialLocalizationSettings specificSettings) { return(TryCreateLocalizationSession(peerConnection, specificSettings, out session)); } else { throw new ArgumentException(nameof(settings)); } }
public Task <bool> LocalizeAsync(SocketEndpoint socketEndpoint, Guid spatialLocalizerID, ISpatialLocalizationSettings settings) { DebugLog("LocalizeAsync"); if (currentLocalizationSession != null) { Debug.LogError($"Failed to start localization session because an existing localization session is in progress"); return(Task.FromResult(false)); } if (!participants.TryGetValue(socketEndpoint, out SpatialCoordinateSystemParticipant participant)) { Debug.LogError($"Could not find a SpatialCoordinateSystemParticipant for SocketEndpoint {socketEndpoint.Address}"); return(Task.FromResult(false)); } if (!localizers.TryGetValue(spatialLocalizerID, out ISpatialLocalizer localizer)) { Debug.LogError($"Could not find a ISpatialLocalizer for spatialLocalizerID {spatialLocalizerID}"); return(Task.FromResult(false)); } DebugLog("Returning a localization session."); return(RunLocalizationSessionAsync(localizer, settings, participant)); }
private async Task <bool> RunLocalizationSessionAsync(ISpatialLocalizer localizer, ISpatialLocalizationSettings settings, SpatialCoordinateSystemParticipant participant) { DebugLog($"Creating localization session: {participant.SocketEndpoint.Address}, {settings.ToString()}, {localizer.ToString()}"); if (!localizer.TryCreateLocalizationSession(participant, settings, out ISpatialLocalizationSession currentLocalizationSession)) { Debug.LogError($"Failed to create an ISpatialLocalizationSession from localizer {localizer.SpatialLocalizerId}"); return(false); } using (currentLocalizationSession) { DebugLog($"Setting localization session for participant: {participant.SocketEndpoint.Address}, {currentLocalizationSession.ToString()}"); participant.CurrentLocalizationSession = currentLocalizationSession; try { DebugLog($"Starting localization: {participant.SocketEndpoint.Address}, {currentLocalizationSession.ToString()}"); // Some SpatialLocalizers/SpatialCoordinateServices key off of token cancellation for their logic flow. // Therefore, we need to create a cancellation token even it is never actually cancelled by the SpatialCoordinateSystemManager. using (var localizeCTS = new CancellationTokenSource()) { var coordinate = await currentLocalizationSession.LocalizeAsync(localizeCTS.Token); participant.Coordinate = coordinate; } } finally { participant.CurrentLocalizationSession = null; } } currentLocalizationSession = null; return(participant.Coordinate != null); }
public Task <bool> RunRemoteLocalizationAsync(SocketEndpoint socketEndpoint, Guid spatialLocalizerID, ISpatialLocalizationSettings settings) { DebugLog($"Initiating remote localization: {socketEndpoint.Address}, {spatialLocalizerID.ToString()}"); TaskCompletionSource <bool> taskCompletionSource = new TaskCompletionSource <bool>(); remoteLocalizationSessions.Add(socketEndpoint, taskCompletionSource); using (MemoryStream stream = new MemoryStream()) using (BinaryWriter message = new BinaryWriter(stream)) { message.Write(LocalizeCommand); message.Write(spatialLocalizerID); settings.Serialize(message); socketEndpoint.Send(stream.ToArray()); } return(taskCompletionSource.Task); }
private async Task <bool> RunLocalizationSessionAsync(ISpatialLocalizer localizer, ISpatialLocalizationSettings settings, SpatialCoordinateSystemParticipant participant) { if (!TryCleanupExistingLocalizationSession(participant)) { DebugLog("Existing localization session with different participant prevented creating new localization session"); return(false); } if (!localizer.TryCreateLocalizationSession(participant, settings, out var localizationSession)) { Debug.LogError($"Failed to create an ISpatialLocalizationSession from localizer {localizer.SpatialLocalizerId}"); return(false); } Task <bool> resultTask; bool startSession = false; var localizationSessionDetails = new LocalizationSessionDetails(localizationSession, participant); lock (localizationLock) { if (currentLocalizationSession != null) { DebugLog($"Current localization session repopulated after cleanup, localization not performed."); localizationSessionDetails.Session.Dispose(); resultTask = Task.FromResult(false); } else { currentLocalizationSession = localizationSessionDetails; localizationSessionDetails.Participant.CurrentLocalizationSession = localizationSessionDetails.Session; resultTask = localizationSessionDetails.CompletionSource.Task; startSession = true; } } if (startSession) { await Dispatcher.ScheduleAsync(async() => { try { // Some SpatialLocalizers/SpatialCoordinateServices key off of token cancellation for their logic flow. // Therefore, we need to create a cancellation token even it is never actually cancelled by the SpatialCoordinateSystemManager. using (var localizeCTS = new CancellationTokenSource()) { var coordinate = await localizationSessionDetails.Session.LocalizeAsync(localizeCTS.Token); bool succeeded = (coordinate != null); localizationSessionDetails.Session.Dispose(); localizationSessionDetails.CompletionSource.TrySetResult(succeeded); if (localizationSessionDetails.Participant.CurrentLocalizationSession == localizationSessionDetails.Session) { localizationSessionDetails.Participant.Coordinate = coordinate; localizationSessionDetails.Participant.CurrentLocalizationSession = null; } else { Debug.LogWarning("Localization session completed but was no longer assigned to the associated participant"); } } } catch (OperationCanceledException) { DebugLog("Localization operation cancelled."); } catch (Exception e) { Debug.LogError($"Exception thrown localizing experience: {e.ToString()}"); } }, CancellationToken.None, true); } return(await resultTask); }
public Task <bool> LocalizeAsync(SocketEndpoint socketEndpoint, Guid spatialLocalizerID, ISpatialLocalizationSettings settings) { DebugLog("LocalizeAsync"); if (!participants.TryGetValue(socketEndpoint, out SpatialCoordinateSystemParticipant participant)) { Debug.LogError($"Could not find a SpatialCoordinateSystemParticipant for SocketEndpoint {socketEndpoint.Address}"); return(Task.FromResult(false)); } if (currentLocalizationSession != null) { if (participant == currentLocalizationSession.Peer && remoteLocalizationSessions.TryGetValue(socketEndpoint, out var taskCompletionSource) && taskCompletionSource.TrySetCanceled()) { DebugLog($"Current localization session for {socketEndpoint.Address} was canceled based on a new localization request."); remoteLocalizationSessions.Remove(socketEndpoint); } else { Debug.LogError($"Failed to start localization session because an existing localization session is in progress"); return(Task.FromResult(false)); } } if (!localizers.TryGetValue(spatialLocalizerID, out ISpatialLocalizer localizer)) { Debug.LogError($"Could not find a ISpatialLocalizer for spatialLocalizerID {spatialLocalizerID}"); return(Task.FromResult(false)); } DebugLog("Returning a localization session."); return(RunLocalizationSessionAsync(localizer, settings, participant)); }
public Task <bool> LocalizeAsync(INetworkConnection connection, Guid spatialLocalizerID, ISpatialLocalizationSettings settings) { DebugLog("LocalizeAsync"); if (!participants.TryGetValue(connection, out SpatialCoordinateSystemParticipant participant)) { Debug.LogError($"Could not find a SpatialCoordinateSystemParticipant for INetworkConnection {connection.ToString()}"); return(Task.FromResult(false)); } if (!localizers.TryGetValue(spatialLocalizerID, out ISpatialLocalizer localizer)) { Debug.LogError($"Could not find a ISpatialLocalizer for spatialLocalizerID {spatialLocalizerID}"); return(Task.FromResult(false)); } DebugLog("Returning a localization session."); return(RunLocalizationSessionAsync(localizer, settings, participant)); }
public Task <bool> RunRemoteLocalizationAsync(INetworkConnection connection, Guid spatialLocalizerID, ISpatialLocalizationSettings settings) { DebugLog($"Initiating remote localization: {connection.ToString()}, {spatialLocalizerID.ToString()}"); if (remoteLocalizationSessions.TryGetValue(connection, out var currentCompletionSource)) { DebugLog($"Canceling existing remote localization session: {connection.ToString()}"); currentCompletionSource.TrySetCanceled(); remoteLocalizationSessions.Remove(connection); } TaskCompletionSource <bool> taskCompletionSource = new TaskCompletionSource <bool>(); remoteLocalizationSessions.Add(connection, taskCompletionSource); using (MemoryStream stream = new MemoryStream()) using (BinaryWriter message = new BinaryWriter(stream)) { message.Write(LocalizeCommand); message.Write(spatialLocalizerID); settings.Serialize(message); byte[] data = stream.ToArray(); connection.Send(ref data); } return(taskCompletionSource.Task); }