/// <inheritdoc/> protected override async Task <ISpatialCoordinate> TryCreateCoordinateAsync(Vector3 worldPosition, Quaternion worldRotation, CancellationToken cancellationToken) { GameObject spawnedAnchorObject = SpawnGameObject(worldPosition, worldRotation); try { // Use var here, type varies based on platform var nativeAnchor = spawnedAnchorObject.FindOrCreateNativeAnchor(); // Let a frame pass to ensure any AR anchor is properly attached (WorldAnchors used to have issues with this) await Task.Delay(100, cancellationToken); CloudSpatialAnchor cloudSpatialAnchor = new CloudSpatialAnchor() { LocalAnchor = nativeAnchor.GetPointer(), Expiration = DateTime.Now.AddDays(1) }; if (cloudSpatialAnchor.LocalAnchor == IntPtr.Zero) { Debug.LogError($"{nameof(SpatialAnchorsCoordinateService)} failed to get native anchor pointer when creating anchor."); return(null); } await spatialAnchorManager.CreateAnchorAsync(cloudSpatialAnchor, cancellationToken); return(new SpatialAnchorsCoordinate(cloudSpatialAnchor, nativeAnchor.gameObject)); } catch { UnityEngine.Object.Destroy(spawnedAnchorObject); throw; } }
private async Task OnObjectSpawned(GameObject spawnedObject) { var spawnedObjectMaterial = spawnedObject.GetComponentInChildren <MeshRenderer>().material; var cloudNativeAnchor = spawnedObject.GetComponent <CloudNativeAnchor>(); spawnedObjectMaterial.color = Color.white; if (cloudNativeAnchor.CloudAnchor == null) { cloudNativeAnchor.NativeToCloud(); } var cloudSpatialAnchor = cloudNativeAnchor.CloudAnchor; // TODO: add expirtaion, add properties while (!spatialAnchorManager.IsReadyForCreate) { await Task.Delay(300); // TODO: display RecommendedForCreateProgress feedback var createProgress = spatialAnchorManager.SessionStatus.RecommendedForCreateProgress; Debug.Log($"Create Progress: {createProgress}"); spawnedObjectMaterial.color = Color.Lerp(Color.white, Color.yellow, createProgress); } spawnedObjectMaterial.color = Color.blue; try { await spatialAnchorManager.CreateAnchorAsync(cloudSpatialAnchor); // TODO: save that anchor to sharing service if successful Debug.Log("Anchor saved: " + cloudSpatialAnchor.Identifier); spawnedObjectMaterial.color = Color.green; } catch (Exception ex) { // TODO: handle exception spawnedObjectMaterial.color = Color.red; } }
private async UniTask <string> CreateAnchorTask() { _instructionUIPresenter.UpdateMessage("画面をタップしてアンカーを設置してください"); var placementDisposable = _touchController.GetWorldTouchOnScreen() .Subscribe(screenPoint => { var pose = _touchController.GetARRaycastHitPose(screenPoint); if (_anchorObjectPresenter.IsPlacingAnchorExists) { _anchorObjectPresenter.MovePlacingAnchor(pose.position); } else { _anchorObjectPresenter.CreateNewAnchor(pose.position); } }).AddTo(_compositeDisposable); await _instructionUIPresenter.OnTriggerProceed().Where(_ => _anchorObjectPresenter.IsPlacingAnchorExists).First(); placementDisposable.Dispose(); if (!_spatialAnchorManager.IsReadyForCreate) { await Observable.EveryUpdate() .TakeWhile(_ => !_spatialAnchorManager.IsReadyForCreate | _spatialAnchorManager.SessionStatus.RecommendedForCreateProgress < 1) .ObserveOnMainThread() .Do(_ => { var progress = _spatialAnchorManager.SessionStatus.RecommendedForCreateProgress * 100; _instructionUIPresenter.UpdateMessage($"環境をスキャンして特徴点データを収集してください {progress:F1}% "); }); } var cloudAnchor = _anchorObjectPresenter.ConfirmNewAnchorAndGetCloudSpatialAnchor(); cloudAnchor.Expiration = DateTimeOffset.UtcNow + TimeSpan.FromMinutes(10); _instructionUIPresenter.UpdateMessage("アンカーを保存中..."); await _spatialAnchorManager.CreateAnchorAsync(cloudAnchor); _instructionUIPresenter.UpdateMessage($"アンカーの保存が完了しました! ID: {cloudAnchor.Identifier}"); await _instructionUIPresenter.OnTriggerProceed().First(); return(cloudAnchor.Identifier); }
/// <summary> /// Save a local ARAnchor as a cloud anchor. /// </summary> private async void SaveAnchorToCloudAsync(GameObject gameObject) { CloudNativeAnchor cloudNativeAnchor = gameObject.AddComponent <CloudNativeAnchor>(); await cloudNativeAnchor.NativeToCloud(); CloudSpatialAnchor cloudSpatialAnchor = cloudNativeAnchor.CloudAnchor; // In this sample app, the cloud anchors are deleted explicitly. // Here, we show how to set an anchor to expire automatically. cloudSpatialAnchor.Expiration = DateTimeOffset.Now.AddDays(7); while (!m_cloudSpatialAnchorManager.IsReadyForCreate) { await Task.Delay(1000); float createProgress = m_cloudSpatialAnchorManager.SessionStatus.RecommendedForCreateProgress; Debug.Log($"Move your device to capture more environment data: {createProgress:0%}"); } // Now that the cloud spatial anchor has been prepared, we can try the actual save here Debug.Log($"Saving cloud anchor..."); await m_cloudSpatialAnchorManager.CreateAnchorAsync(cloudSpatialAnchor); bool saveSucceeded = cloudSpatialAnchor != null; if (!saveSucceeded) { Debug.LogError("Failed to save, but no exception was thrown."); return; } m_cloudSpatialAnchorIDs.Add(cloudSpatialAnchor.Identifier); Debug.Log($"Saved cloud anchor: {cloudSpatialAnchor.Identifier}"); // Update the visuals of the gameobject gameObject.GetComponent <SampleSpatialAnchor>().Identifier = cloudSpatialAnchor.Identifier; gameObject.GetComponent <SampleSpatialAnchor>().Persisted = true; }
public async Task CreateCloudAnchor(CloudSpatialAnchor cloudAnchor, AnchorProperties anchorProperties) { anchorProperties.dateSecondsString = $"{(Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds}"; UpdateAnchorProperties(cloudAnchor, anchorProperties); if (cloudAnchor == null) { Log.debug("Cloud anchor is null"); return; } tutorialManager.gameObject.SetActive(true); anchorInfoText.GetComponentInParent <FadeText>().ShowText(); while (!spatialAnchorManager.IsReadyForCreate) { progressBar.SetActive(true); Log.debug($"Not enough environmental data : {spatialAnchorManager.SessionStatus.RecommendedForCreateProgress}"); anchorInfoText.text = $"Look around to gather more data"; progressBar.GetComponent <Slider>().value = spatialAnchorManager.SessionStatus.RecommendedForCreateProgress; await Task.Delay(333); } tutorialManager.gameObject.SetActive(false); try { Log.debug("Trying to create cloud anchor"); anchorInfoText.text = $"Creating anchor..."; progressBar.SetActive(false); await spatialAnchorManager.CreateAnchorAsync(cloudAnchor); anchorInfoText.GetComponentInParent <FadeText>().SetText("Anchor created!"); } catch (Exception ex) { Log.debug(ex.Message); anchorInfoText.GetComponentInParent <FadeText>().SetText("Oops there was problem created anchor!"); } }
protected async Task SaveCurrentObjectAnchorToCloudAsync() { CloudNativeAnchor cloudNativeAnchor = spawnedAnchorObject.GetComponent <CloudNativeAnchor>(); if (cloudNativeAnchor.CloudAnchor == null) { cloudNativeAnchor.NativeToCloud(); } CloudSpatialAnchor cloudSpatialAnchor = cloudNativeAnchor.CloudAnchor; cloudSpatialAnchor.Expiration = DateTimeOffset.Now.AddDays(2); while (!spatialAnchorManager.IsReadyForCreate) { await Task.Delay(200); float createProgress = spatialAnchorManager.SessionStatus.RecommendedForCreateProgress; appStateManager.currentOutputMessage = $"Move your device to capture more data points in the environment : {createProgress:0%}"; } appStateManager.currentOutputMessage = $"Saving anchor to cloud ..."; await spatialAnchorManager.CreateAnchorAsync(cloudSpatialAnchor); currentCloudSpatialAnchor = cloudSpatialAnchor; if (currentCloudSpatialAnchor != null) { OnSaveCloudAnchorSuccessful(); } else { appStateManager.currentOutputMessage = $"Failed saving anchor to cloud."; } }
public async void CreateAzureAnchor(GameObject theObject) { Debug.Log("\nAnchorModuleScript.CreateAzureAnchor()"); // Notify AnchorFeedbackScript OnCreateAnchorStarted?.Invoke(); // First we create a native XR anchor at the location of the object in question theObject.CreateNativeAnchor(); // Notify AnchorFeedbackScript OnCreateLocalAnchor?.Invoke(); // Then we create a new local cloud anchor CloudSpatialAnchor localCloudAnchor = new CloudSpatialAnchor(); // Now we set the local cloud anchor's position to the native XR anchor's position localCloudAnchor.LocalAnchor = theObject.FindNativeAnchor().GetPointer(); // Check to see if we got the local XR anchor pointer if (localCloudAnchor.LocalAnchor == IntPtr.Zero) { Debug.Log("Didn't get the local anchor..."); return; } else { Debug.Log("Local anchor created"); } // In this sample app we delete the cloud anchor explicitly, but here we show how to set an anchor to expire automatically localCloudAnchor.Expiration = DateTimeOffset.Now.AddDays(7); // Save anchor to cloud while (!cloudManager.IsReadyForCreate) { await Task.Delay(330); float createProgress = cloudManager.SessionStatus.RecommendedForCreateProgress; QueueOnUpdate(new Action(() => Debug.Log($"Move your device to capture more environment data: {createProgress:0%}"))); } bool success; try { Debug.Log("Creating Azure anchor... please wait..."); // Actually save await cloudManager.CreateAnchorAsync(localCloudAnchor); // Store currentCloudAnchor = localCloudAnchor; localCloudAnchor = null; // Success? success = currentCloudAnchor != null; if (success) { Debug.Log($"Azure anchor with ID '{currentCloudAnchor.Identifier}' created successfully"); // Notify AnchorFeedbackScript OnCreateAnchorSucceeded?.Invoke(); // Update the current Azure anchor ID Debug.Log($"Current Azure anchor ID updated to '{currentCloudAnchor.Identifier}'"); currentAzureAnchorID = currentCloudAnchor.Identifier; } else { Debug.Log($"Failed to save cloud anchor with ID '{currentAzureAnchorID}' to Azure"); // Notify AnchorFeedbackScript OnCreateAnchorFailed?.Invoke(); } } catch (Exception ex) { Debug.Log(ex.ToString()); } }
private async void CreateAzureAnchor(AnchorPosition anchorPos) { // change the color of the currentAnchor to inprogress anchorPos.AnchorInProgress(); if (cloudManager.Session == null) { // Creates a new session if one does not exist Debug.Log("\ncloudManager.CreateSessionAsync()"); await cloudManager.CreateSessionAsync(); } // Starts the session if not already started Debug.Log("\ncloudManager.StartSessionAsync()"); await cloudManager.StartSessionAsync(); // Notify AnchorFeedbackScript OnCreateAnchorStarted?.Invoke(); // Create local cloud anchor var localCloudAnchor = new CloudSpatialAnchor(); // Create native XR anchor at the location of the object anchorPos.gameObject.CreateNativeAnchor(); Debug.Log("anchorPosition.gameObject.CreateNativeAnchor()"); // create a cloud anchor at the position of the local anchor localCloudAnchor.LocalAnchor = anchorPos.gameObject.FindNativeAnchor().GetPointer(); Debug.Log("anchorPosition.gameObject.FindNativeAnchor().GetPointer()"); // Check to see if we got the local XR anchor pointer if (localCloudAnchor.LocalAnchor == IntPtr.Zero) { Debug.Log("Didn't get the local anchor..."); return; } else { Debug.Log("Local anchor created"); } // Set expiration (when anchor will be deleted from Azure) localCloudAnchor.Expiration = DateTimeOffset.Now.AddDays(90); // upload cloud anchor to the cloud while (!cloudManager.IsReadyForCreate) { // check with the create progress await Task.Delay(330); var createProgress = cloudManager.SessionStatus.RecommendedForCreateProgress; UnityDispatcher.InvokeOnAppThread(() => Debug.Log($"Move your device to capture more environment data: {createProgress:0%}")); } Debug.Log("cloudManager is ready."); try { // Actually save Debug.Log("await cloudManager.CreateAnchorAsync(localCloudAnchor)"); await cloudManager.CreateAnchorAsync(localCloudAnchor); Debug.Log("Anchor created!"); // Store currentCloudAnchor = localCloudAnchor; localCloudAnchor = null; // Success? var success = currentCloudAnchor != null; if (success) { // update the spaital anchor id of the currentSpatialAnchor Debug.Log($"Azure anchor with ID '{currentCloudAnchor.Identifier}' created successfully"); anchorPos.SpatialAnchorObject.SpatialAnchorId = currentCloudAnchor.Identifier; // Update the current Azure anchor ID Debug.Log($"Current Azure anchor ID updated to '{currentCloudAnchor.Identifier}'"); OnCreateAnchorSucceeded?.Invoke(); } else { Debug.Log($"Failed to save cloud anchor with ID '{currentCloudAnchor.Identifier}' to Azure"); // Notify AnchorFeedbackScript OnCreateAnchorFailed?.Invoke(); } } catch (Exception ex) { Debug.Log(ex.ToString()); } // StopAzureSession(); }
private async void CreateAsaAnchor(Transform indicatorTransform) { Debug.Log("\nAnchorManager.CreateAsaAnchor()"); anchorCreationController.StartProgressIndicatorSession(); if (cloudManager.Session == null) { // Creates a new session if one does not exist Debug.Log("await cloudManager.CreateSessionAsync()"); await cloudManager.CreateSessionAsync(); } // Starts the session if not already started Debug.Log("await cloudManager.StartSessionAsync()"); await cloudManager.StartSessionAsync(); var anchorPositionIndicator = Instantiate(anchorPositionPrefab, indicatorTransform.position, indicatorTransform.rotation); // Create native XR anchor at the location of the object anchorPositionIndicator.gameObject.CreateNativeAnchor(); Debug.Log("anchorPosition.gameObject.CreateNativeAnchor()"); // Create local cloud anchor var localCloudAnchor = new CloudSpatialAnchor(); // Set the local cloud anchor's position to the native XR anchor's position localCloudAnchor.LocalAnchor = anchorPositionIndicator.gameObject.FindNativeAnchor().GetPointer(); Debug.Log("anchorPosition.gameObject.FindNativeAnchor().GetPointer()"); // Check to see if we got the local XR anchor pointer if (localCloudAnchor.LocalAnchor == IntPtr.Zero) { Debug.Log("Didn't get the local anchor..."); return; } else { Debug.Log("Local anchor created"); } // Set expiration (when anchor will be deleted from Azure) localCloudAnchor.Expiration = DateTimeOffset.Now.AddDays(7); // Save anchor to cloud while (!cloudManager.IsReadyForCreate) { await Task.Delay(330); var createProgress = cloudManager.SessionStatus.RecommendedForCreateProgress; UnityDispatcher.InvokeOnAppThread(() => Debug.Log($"Move your device to capture more environment data: {createProgress:0%}")); } Debug.Log("cloudManager is ready."); try { // Actually save Debug.Log("await cloudManager.CreateAnchorAsync(localCloudAnchor)"); await cloudManager.CreateAnchorAsync(localCloudAnchor); Debug.Log("Anchor created!"); // Store currentCloudAnchor = localCloudAnchor; // Success? var success = currentCloudAnchor != null; if (success) { Debug.Log($"Azure anchor with ID '{currentCloudAnchor.Identifier}' created successfully"); // Update the current Azure anchor ID Debug.Log($"Current Azure anchor ID updated to '{currentCloudAnchor.Identifier}'"); currentTrackedObject.SpatialAnchorId = currentCloudAnchor.Identifier; activeAnchors.Add(currentTrackedObject.SpatialAnchorId, anchorPositionIndicator); // Notify subscribers Debug.Log("OnCreateAnchorSucceeded?.Invoke(this, currentCloudAnchor.Identifier)"); AppDispatcher.Instance().Enqueue(() => { anchorPositionIndicator.Init(currentTrackedObject); currentTrackedObject = null; OnCreateAnchorSucceeded?.Invoke(this, currentCloudAnchor.Identifier); }); } else { Debug.Log($"Failed to save cloud anchor with ID '{currentCloudAnchor.Identifier}' to Azure"); // Notify subscribers AppDispatcher.Instance().Enqueue(() => { currentTrackedObject = null; Destroy(anchorPositionIndicator.gameObject); OnCreateAnchorFailed?.Invoke(this, EventArgs.Empty); }); } } catch (Exception ex) { Debug.Log(ex.ToString()); } StopAzureSession(); }
protected virtual async Task SaveCurrentObjectAnchorToCloudAsync() { Debug.LogFormat("Saving anchor"); // Get the cloud-native anchor behavior CloudNativeAnchor cna = spawnedObject.GetComponent <CloudNativeAnchor>(); // If the cloud portion of the anchor hasn't been created yet, create it if (cna.CloudAnchor == null) { Debug.LogFormat("Cloud anchor null"); cna.NativeToCloud(); } // Get the cloud portion of the anchor CloudSpatialAnchor cloudAnchor = cna.CloudAnchor; // In this sample app we delete the cloud anchor explicitly, but here we show how to set an anchor to expire automatically cloudAnchor.Expiration = DateTimeOffset.Now.AddYears(200); Debug.Log("Waiting to be ready to create"); Debug.Log(CloudManager.SessionStatus.RecommendedForCreateProgress); try { while (!CloudManager.IsReadyForCreate) { await Task.Delay(330); float createProgress = CloudManager.SessionStatus.RecommendedForCreateProgress; //feedbackBox.text = $"Move your device to capture more environment data: {createProgress:0%}"; } } catch (Exception exc) { Debug.Log(exc); } Debug.LogFormat("Ready to create"); bool success = false; //feedbackBox.text = "Saving..."; try { // Actually save await CloudManager.CreateAnchorAsync(cloudAnchor); Debug.LogFormat("Created anchor"); // Store currentCloudAnchor = cloudAnchor; // Success? success = currentCloudAnchor != null; Debug.LogFormat("Success: {0}", success); if (success) { // Await override, which may perform additional tasks // such as storing the key in the AnchorExchanger // await OnSaveCloudAnchorSuccessfulAsync(); } else { // OnSaveCloudAnchorFailed(new Exception("Failed to save, but no exception was thrown.")); Debug.LogError("Failed to save, but no exception was thrown."); } } catch (System.Exception ex) { Debug.LogError(ex); } }
/// <summary> /// Azure Spatial Anchorsサービスにアンカーを追加します。 /// </summary> /// <param name="theObject">Spatial Anchorの情報として登録する現実空間に設置したオブジェクト</param> /// <param name="appProperties">Spatial Anchorに含める情報</param> /// <returns>登録時のAnchorId</returns> public async Task <string> CreateAzureAnchor(GameObject theObject, IDictionary <string, string> appProperties) { try { Debug.Log("\nAnchorModuleScript.CreateAzureAnchor()"); OutputLog("Creating Azure anchor"); // Azure Spatial Anchorsサービスの登録に必要なNative Anchorの設定を行います。 theObject.CreateNativeAnchor(); OutputLog("Creating local anchor"); // Azure Spatial Anchorsサービスに登録するSpatial Anchorの情報を準備します。 var localCloudAnchor = new CloudSpatialAnchor(); // Spatial Anchorにふくめる情報を格納します。 foreach (var key in appProperties.Keys) { localCloudAnchor.AppProperties.Add(key, appProperties[key]); } // Native Anchorのポインタを渡します。 localCloudAnchor.LocalAnchor = theObject.FindNativeAnchor().GetPointer(); // Native Anchorが正常に生成されているかを確認します。生成に失敗している時は終了します。 if (localCloudAnchor.LocalAnchor == IntPtr.Zero) { OutputLog("Didn't get the local anchor...", LogType.Error); return(null); } Debug.Log("Local anchor created"); // Spatial Anchorの寿命を設定します。この日数分Azure Spatial Anchorsサービス上にAnchorが残ります。 localCloudAnchor.Expiration = DateTimeOffset.Now.AddDays(expiration); OutputLog("Move your device to capture more environment data: 0%"); // Spatial Anchorの登録に必要な空間の特徴点が必要十分になっているかを確認します。 // RecommendedForCreateProgressが100%で必要な情報が収集できています(HoloLensの場合ほぼ一瞬でおわります) do { await Task.Delay(330); var createProgress = cloudManager.SessionStatus.RecommendedForCreateProgress; QueueOnUpdate(() => OutputLog($"Move your device to capture more environment data: {createProgress:0%}", isOverWrite: true)); } while (!cloudManager.IsReadyForCreate); try { OutputLog("Creating Azure anchor... please wait..."); // Azure Spatial Anchorsに登録を試みます。 await cloudManager.CreateAnchorAsync(localCloudAnchor); // 正常に登録できた場合は登録結果(AnchorId)が格納されたオブジェクトが返却されます。 var success = localCloudAnchor != null; if (success) { OutputLog($"Azure anchor with ID '{localCloudAnchor.Identifier}' created successfully"); locatedAnchors.Add(localCloudAnchor.Identifier, localCloudAnchor); return(localCloudAnchor.Identifier); } OutputLog("Failed to save cloud anchor to Azure", LogType.Error); } catch (Exception ex) { Debug.Log(ex.ToString()); } return(null); } catch (Exception e) { Debug.Log(e); throw; } }