Example #1
0
    /// <summary>
    /// Creates an anchor at the Shared World Anchor's position and orientation
    /// </summary>
    /// <returns>The asynchronous Task that for this asynchronous function that will return the status of the anchor creation.</returns>
    public async Task <bool> CreateAnchorAsync()
    {
        // Set the LocalAnchor property of the CloudSpatialAnchor to the WorldAnchor component of our white sphere.
        WorldAnchor worldAnchor = SharedWorldAnchor.Instance.gameObject.AddComponent <WorldAnchor>();

        // In Editor, don't bother
        if (Application.isEditor)
        {
            // Simulate that we have found an anchor
            CloudSpatialAnchorId = FakeCloudSpatialAnchorId;
            return(true);
        }

        // Create the CloudSpatialAnchor.
        currentCloudAnchor            = new CloudSpatialAnchor();
        currentCloudAnchor.Expiration = DateTimeOffset.Now.AddDays(1);

        // Save the CloudSpatialAnchor to the cloud.
        currentCloudAnchor.LocalAnchor = worldAnchor.GetNativeSpatialAnchorPtr();

        // Wait for enough data about the environment.
        while (recommendedForCreate < 1.0F)
        {
            await Task.Delay(330);
        }

        bool success = false;

        try
        {
            await CloudSpatialAnchorSession.CreateAnchorAsync(currentCloudAnchor);

            success = currentCloudAnchor != null;

            if (success)
            {
                // Record the identifier to locate.
                CloudSpatialAnchorId = currentCloudAnchor.Identifier;

                Debug.Log("ASA Info: Saved anchor to Azure Spatial Anchors! Identifier: " + CloudSpatialAnchorId);
            }
            else
            {
                Debug.LogError("ASA Error: Failed to save, but no exception was thrown.");
            }

            return(success);
        }
        catch (Exception ex)
        {
            Debug.LogError("ASA Error: " + ex.Message);
        }

        return(false);
    }
Example #2
0
        public async Task <CloudSpatialAnchor> StoreAnchorInCloud(CloudSpatialAnchor cloudSpatialAnchor)
        {
            if (SessionStatusIndicators[(int)SessionStatusIndicatorType.ReadyForCreate] < 1)
            {
                return(null);
            }

            await cloudSpatialAnchorSession.CreateAnchorAsync(cloudSpatialAnchor);

            return(cloudSpatialAnchor);
        }
Example #3
0
    private void CreateAndSaveAnchor()
    {
        Log("Creating new anchor...");

        // Just in case clean up any visuals that have been placed.
        CleanupObjects();

        // Raycast to find a hitpoint where the anchor should be placed
        Ray gazeRay = new Ray(Camera.main.transform.position, Camera.main.transform.forward);

        Physics.Raycast(gazeRay, out RaycastHit hitPoint, float.MaxValue);

        // Instantiate the anchor visual Prefab
        _prefabInstance = Instantiate(Prefab, hitPoint.point, Quaternion.identity) as GameObject;
        var localAnchor = _prefabInstance.AddComponent <WorldAnchor>();

        Log("Created local anchor.");

        // Create CloudSpatialAnchor and link the local anchor
        _currentCloudAnchor = new CloudSpatialAnchor
        {
            LocalAnchor = localAnchor.GetNativeSpatialAnchorPtr()
        };

        _ = Task.Run(async() =>
        {
            // Wait for enough spatial data about the environment so the anchor can be relocalized later
            while (_recommendedSpatialDataForUpload < 1.0F)
            {
                Log($"Look around to capture enough anchor data: {_recommendedSpatialDataForUpload:P0}", Color.yellow);
                await Task.Delay(50);
            }

            try
            {
                Log($"Creating and uploading ASA anchor...", Color.yellow);
                await _cloudSpatialAnchorSession.CreateAnchorAsync(_currentCloudAnchor);

                if (_currentCloudAnchor != null)
                {
                    // Allow the user to tap again to clear the state and enter localization mode
                    _wasTapped            = false;
                    _currentCloudAnchorId = _currentCloudAnchor.Identifier;
                    Log($"Saved anchor to Azure Spatial Anchors: {_currentCloudAnchorId}\r\nTap to localize it.", Color.cyan);
                }
            }
            catch (Exception ex)
            {
                Log($"Failed to create ASA anchor: {ex.Message}", Color.red);
            }
        });
    }
Example #4
0
        public async Task <CloudSpatialAnchor> StoreAnchorInCloud(CloudSpatialAnchor cloudSpatialAnchor)
        {
            if (SessionStatusIndicators[(int)SessionStatusIndicatorType.ReadyForCreate] < 1)
            {
                return(null);
            }

            await cloudSpatialAnchorSession.CreateAnchorAsync(cloudSpatialAnchor);

            OnAnchorCreatedSuccessfully?.Invoke();
            Debug.Log("Anchor Created Succesfully!");

            return(cloudSpatialAnchor);
        }
Example #5
0
        private async Task <ISpatialCoordinate> TryCreateCoordinateImplAsync(Vector3 worldPosition, Quaternion worldRotation, CancellationToken cancellationToken)
        {
            await EnsureInitializedAsync().Unless(cancellationToken);

            RequestSessionStart();

            try
            {
                await recommendedForCreate.Task.Unless(cancellationToken);

                GameObject spawnedAnchorObject = SpawnGameObject(worldPosition, worldRotation);
                try
                {
                    spawnedAnchorObject.AddARAnchor();

                    // 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 = spawnedAnchorObject.GetNativeAnchorPointer(),
                        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 session.CreateAnchorAsync(cloudSpatialAnchor);

                    return(new SpatialAnchorsCoordinate(cloudSpatialAnchor, spawnedAnchorObject));
                }
                catch
                {
                    UnityEngine.Object.Destroy(spawnedAnchorObject);
                    throw;
                }
            }
            finally
            {
                ReleaseSessionStartRequest();
            }
        }
Example #6
0
        /// <summary>
        /// Creates the specified anchor when the session is ready to create it.
        /// This task is cancelable.
        /// </summary>
        /// <param name="anchor">
        /// The anchor to create.
        /// </param>
        /// <param name="cancellationToken">
        /// </param>
        /// <returns>
        /// A <see cref="Task"/> that represents the operation.
        /// </returns>
        /// <remarks>
        /// If there is no active <see cref="Session"/>, calling this method will
        /// result in an exception. If there is an active session, this method
        /// will wait until <see cref="IsReadyForCreate"/> returns <c>true</c>
        /// before continuing the operation. The <paramref name="cancellationToken"/>
        /// parameter can be used to cancel the operation.
        /// </remarks>
        public async Task CreateAnchorAsync(CloudSpatialAnchor anchor, CancellationToken cancellationToken)
        {
            // Validate
            if (anchor == null)
            {
                throw new ArgumentNullException(nameof(anchor));
            }
            EnsureSessionStarted();

            // Wait for enough data
            while (!IsReadyForCreate)
            {
                cancellationToken.ThrowIfCancellationRequested();
                await Task.Delay(50);
            }

            // Actually create
            await session.CreateAnchorAsync(anchor);
        }
        private async Task CreateAnchorAsync(Vector3 newPosition)
        {
            var dist = Vector3.Distance(localAnchorPosition, newPosition);

            if (newPosition != Vector3.zero && (localAnchorPosition == Vector3.zero || dist > minPositionChangeDistance))
            {
                // Lock game object. While anchor is saved.
                localAnchorGameObject.GetComponent <DragonAI>().StopPlayerPositionTracking();
                localAnchorGameObject.AddARAnchor();

                if (loadedAnchor != null)
                {
                    // Remove old anchor.
                    await cloudSession.DeleteAnchorAsync(loadedAnchor);
                }

                // Save to server.
                CloudSpatialAnchor cloudAnchor = new CloudSpatialAnchor();
                cloudAnchor.LocalAnchor             = localAnchorGameObject.GetNativeAnchorPointer();
                cloudAnchor.AppProperties[@"label"] = @"Dragon";
                await cloudSession.CreateAnchorAsync(cloudAnchor);

                await storageService.PostAnchorId(cloudAnchor.Identifier);

                Debug.Log(DEBUG_FILTER + $"Created a cloud anchor with ID={cloudAnchor.Identifier}");

                // Unlock game object.
                localAnchorGameObject.RemoveARAnchor();
                localAnchorGameObject.GetComponent <DragonAI>().ChangePosition(newPosition);
                Debug.Log(DEBUG_FILTER + "saved position" + newPosition + " to server");
                await Task.Delay(5000); // Wait 5 sec before tracking again.

                Debug.Log(DEBUG_FILTER + "continue tracking");
                localAnchorGameObject.GetComponent <DragonAI>().StartPlayerPositionTracking();
                localAnchorPosition = new Vector3(newPosition.x, newPosition.y, newPosition.z);
            }
        }
Example #8
0
    /// <summary>
    /// Creates an Azure Spatial Anchor at the position of the local World Anchor attached to the Litecoin symbol game object. Destroys the Litecoin symbol and instantiates the slate prefab.
    /// </summary>
    public void CreateAzureSpatialAnchor()
    {
#if UNITY_EDITOR
        if (!IsSlateActive)
        {
            GameObject litecoin = GameObject.FindGameObjectWithTag("Litecoin");
            GameObject slate    = Instantiate(SlatePrefab, litecoin.transform.position, litecoin.transform.rotation);
            Destroy(litecoin);

            IsSlateActive = true;

            Instructions.text = "Azure Spatial Anchor sessions can't be started when running in the Unity Editor. Build and deploy this sample to a HoloLens device to be able to create and find Azure Spatial Anchors.\n\nLook at the slate and it will detect your gaze and update itself.";
        }
        else
        {
            Instructions.text = "Azure Spatial Anchor sessions can't be started when running in the Unity Editor. Build and deploy this sample to a HoloLens device to be able to create and find Azure Spatial Anchors.\n\nDelete the current anchor before creating a new one.\n\nLook at the slate and it will detect your gaze and update itself.";
        }

        return;
#else
        if (!IsSlateActive)
        {
            GameObject litecoin = GameObject.FindGameObjectWithTag("Litecoin");
            litecoin.AddComponent <WorldAnchor>();

            // Create the CloudSpatialAnchor.
            currentCloudAnchor = new CloudSpatialAnchor();

            // Set the LocalAnchor property of the CloudSpatialAnchor to the WorldAnchor component of the Litecoin symbol.
            WorldAnchor worldAnchor = litecoin.GetComponent <WorldAnchor>();

            if (worldAnchor == null)
            {
                throw new Exception("Couldn't get the local anchor pointer.");
            }

            // Save the CloudSpatialAnchor to the cloud.
            currentCloudAnchor.LocalAnchor = worldAnchor.GetNativeSpatialAnchorPtr();

            Task.Run(async() =>
            {
                // Wait for enough data about the environment.
                while (recommendedForCreate < 1.0F)
                {
                    await Task.Delay(330);
                }

                bool success = false;

                try
                {
                    QueueOnUpdate(() =>
                    {
                        Instructions.text = "Saving the Azure Spatial Anchor...";
                    });

                    await cloudSpatialAnchorSession.CreateAnchorAsync(currentCloudAnchor);
                    success = currentCloudAnchor != null;

                    if (success)
                    {
                        // Record the identifier of the Azure Spatial Anchor.
                        cloudSpatialAnchorId = currentCloudAnchor.Identifier;

                        QueueOnUpdate(() =>
                        {
                            Instantiate(SlatePrefab, litecoin.transform.position, litecoin.transform.rotation);
                            Destroy(litecoin);

                            IsSlateActive = true;

                            // Save the Azure Spatial Anchor ID so it persists even after the app is closed.
                            PlayerPrefs.SetString("Anchor ID", cloudSpatialAnchorId);

                            Instructions.text = "The Azure Spatial Anchor has been created!\n\nLook at the slate and it will detect your gaze and update itself.";
                        });
                    }
                    else
                    {
                        QueueOnUpdate(() =>
                        {
                            Instructions.text = "An error occured while creating the Azure Spatial Anchor.\n\nPlease try again.";
                        });
                    }
                }
                catch (Exception ex)
                {
                    QueueOnUpdate(() =>
                    {
                        Instructions.text = $"An error occured while creating the Azure Spatial Anchor.\n\nPlease try again.\n\nException: {ex.Message}";
                    });
                }
            });
        }
        else
        {
            Instructions.text = "An Azure Spatial Anchor already exists. Delete the current anchor before creating a new one.\n\nLook at the slate and it will detect your gaze and update itself.";
        }
#endif
    }
Example #9
0
    /// <summary>
    /// Creates a sphere at the hit point, and then saves a CloudSpatialAnchor there.
    /// </summary>
    /// <param name="hitPoint">The hit point.</param>
    protected virtual void CreateAndSaveSphere(Vector3 hitPoint)
    {
        // Create a white sphere.
        sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        sphere.transform.position   = hitPoint;
        sphere.transform.localScale = new Vector3(0.25F, 0.25F, 0.25F);
        sphere.AddComponent <WorldAnchor>();
        sphereMaterial       = sphere.GetComponent <MeshRenderer>().material;
        sphereMaterial.color = Color.white;
        Debug.Log("ASA Info: Created a local anchor.");

        // Create the CloudSpatialAnchor.
        currentCloudAnchor = new CloudSpatialAnchor();

        // Set the LocalAnchor property of the CloudSpatialAnchor to the WorldAnchor component of our white sphere.
        WorldAnchor worldAnchor = sphere.GetComponent <WorldAnchor>();

        if (worldAnchor == null)
        {
            throw new Exception("ASA Error: Couldn't get the local anchor pointer.");
        }

        // Save the CloudSpatialAnchor to the cloud.
        currentCloudAnchor.LocalAnchor = worldAnchor.GetNativeSpatialAnchorPtr();
        Task.Run(async() =>
        {
            // Wait for enough data about the environment.
            while (recommendedForCreate < 1.0F)
            {
                await Task.Delay(330);
            }

            bool success = false;
            try
            {
                QueueOnUpdate(() =>
                {
                    // We are about to save the CloudSpatialAnchor to the Azure Spatial Anchors, turn it yellow.
                    sphereMaterial.color = Color.yellow;
                });

                await cloudSpatialAnchorSession.CreateAnchorAsync(currentCloudAnchor);
                success = currentCloudAnchor != null;

                if (success)
                {
                    // Allow the user to tap again to clear state and look for the anchor.
                    tapExecuted = false;

                    // Record the identifier to locate.
                    cloudSpatialAnchorId = currentCloudAnchor.Identifier;

                    QueueOnUpdate(() =>
                    {
                        // Turn the sphere blue.
                        sphereMaterial.color = Color.blue;
                    });

                    Debug.Log("ASA Info: Saved anchor to Azure Spatial Anchors! Identifier: " + cloudSpatialAnchorId);
                }
                else
                {
                    sphereMaterial.color = Color.red;
                    Debug.LogError("ASA Error: Failed to save, but no exception was thrown.");
                }
            }
            catch (Exception ex)
            {
                QueueOnUpdate(() =>
                {
                    sphereMaterial.color = Color.red;
                });
                Debug.LogError("ASA Error: " + ex.Message);
            }
        });
    }
 public Task <CloudSpatialAnchor> CreateAnchorAsync(CloudSpatialAnchor anchor)
 {
     return(spatialAnchorsSession.CreateAnchorAsync(anchor));
 }
    /// <summary>
    /// Creates a sphere at the hit point, and then saves a CloudSpatialAnchor there.
    /// </summary>
    /// <param name="hitPoint">The hit point.</param>
    public virtual void CreateAndSaveSphere()
    {
        GameObject refObj = GameObject.Find("RefernceSceneBuilder");

        refObj.AddComponent <WorldAnchor>();
        Material indicatorMat = indicator.GetComponent <MeshRenderer>().material;

        indicatorMat.color = Color.black;
        Debug.Log("ASA Info: Created a local anchor.");

        // Create the CloudSpatialAnchor.
        currentCloudAnchor = new CloudSpatialAnchor();

        // Set the LocalAnchor property of the CloudSpatialAnchor to the WorldAnchor component of our white sphere.

        WorldAnchor worldAnchor = refObj.GetComponent <WorldAnchor>();

        if (worldAnchor == null)
        {
            throw new Exception("ASA Error: Couldn't get the local anchor pointer.");
        }

        // Save the CloudSpatialAnchor to the cloud.
        currentCloudAnchor.LocalAnchor = worldAnchor.GetNativeSpatialAnchorPtr();
        Task.Run(async() =>
        {
            // Wait for enough data about the environment.
            while (recommendedForCreate < 1.0F)
            {
                await Task.Delay(330);
            }

            bool success = false;
            try
            {
                QueueOnUpdate(() =>
                {
                    // We are about to save the CloudSpatialAnchor to the Azure Spatial Anchors, turn it yellow.
                    indicatorMat.color = Color.yellow;
                });

                await cloudSpatialAnchorSession.CreateAnchorAsync(currentCloudAnchor);
                success = currentCloudAnchor != null;

                if (success)
                {
                    // Record the identifier to locate.
                    cloudSpatialAnchorId = currentCloudAnchor.Identifier;

                    QueueOnUpdate(() =>
                    {
                        // Turn the sphere blue.
                        indicatorMat.color = Color.green;
                    });

                    Debug.Log("ASA Info: Saved anchor to Azure Spatial Anchors! Identifier: " + cloudSpatialAnchorId);
                }
                else
                {
                    indicatorMat.color = Color.red;
                    Debug.LogError("ASA Error: Failed to save, but no exception was thrown.");
                }
            }
            catch (Exception ex)
            {
                QueueOnUpdate(() =>
                {
                    indicatorMat.color = Color.red;
                });
                Debug.LogError("ASA Error: " + ex.Message);
            }
        });
    }
Example #12
0
    public void SaveContentsPosition()
    {
        Debug.Log("Selected SaveContentsPosition.");
        m_noticeMSGLabel.text = string.Format("アンカー情報を保存しています。");

        /*
         * IdentifierとAnchorsをAzureSpatialAnchorsに登録
         */
        //CloudSpatialAnchorセッションを初期化するための処理を実行
        ASAInitializeSession();
        Debug.Log("ASA Info: 新しいアンカーを生成します。");
        currentCloudAnchor = null;
        // CloudSpatialAnchorを生成する
        currentCloudAnchor = new CloudSpatialAnchor();
        // CloudSpatialAnchorをクラウドに保存する
        m_labModel.AddComponent <WorldAnchor>();
        Debug.Log("ASA Info: ローカルアンカーを生成しました");
        WorldAnchor worldAnchor = m_labModel.GetComponent <WorldAnchor>();

        if (worldAnchor == null)
        {
            throw new Exception("ASA Error: ローカルアンカーのポインタを取得できませんでした。");
        }
        currentCloudAnchor.LocalAnchor = worldAnchor.GetNativeSpatialAnchorPtr();

        var context = SynchronizationContext.Current;

        Task.Run(async() =>
        {
            // アンカーを保存する周辺の環境情報を取得するまで待つ
            while (recommendedForCreate < 1.0F)
            {
                await Task.Delay(330);
            }
            bool success = false;
            try
            {
                await cloudSpatialAnchorSession.CreateAnchorAsync(currentCloudAnchor);
                success = currentCloudAnchor != null;

                if (success)
                {
                    // 検索するアンカーを記録
                    identifierEntity.Identifier = currentCloudAnchor.Identifier;
                    Debug.Log("ASA Info: Azure Spatial Anchorsへのアンカーを保存しました! Identifier: " + identifierEntity.Identifier);
                    ASAResetSession();
                }
                else
                {
                    Debug.LogError("ASA Error:保存に失敗しましたが、例外はスローされませんでした");
                }

                /*
                 * ObjectIDとIdentifierをFunctions経由でTableStorageに登録(既に同一ObjectIDのものが存在する場合は更新)
                 */
                identifierEntity.ObjectID = m_labModel.GetInstanceID().ToString();
                string jsonstr            = JsonUtility.ToJson(identifierEntity);
                context.Post(_ => {
                    StartCoroutine(AzureSpatialAnchorFunctionsRun.Instance.CallSaveFunctions(jsonstr));
                    DestroyImmediate(m_labModel.GetComponent <WorldAnchor>());
                }, null);
            }
            catch (Exception ex)
            {
                Debug.LogError("ASA Error: " + ex.Message);
            }
        });
    }