Ejemplo n.º 1
0
    /// <summary>
    /// This method is called when the AnchorLocatedEvent is fired. <see cref="CloudManager_AnchorLocated(object, AnchorLocatedEventArgs)"/>
    /// </summary>
    /// <param name="newAnchorFromAzure"></param>
    private void OnCloudAnchorLocated(CloudSpatialAnchor newAnchorFromAzure)
    {
        Pose anchorPose = newAnchorFromAzure.GetPose();

        logger.Log($"Anchor from Cloud Pose: {anchorPose}");
        createOrUpdatePrefabInstance(anchorPose);
        resetUI();
    }
Ejemplo n.º 2
0
    private void CloudManager_AnchorLocated(object sender, AnchorLocatedEventArgs args)
    {
        QueueOnUpdate(new Action(() => Debug.Log($"Anchor recognized as a possible Azure anchor")));

        if (args.Status == LocateAnchorStatus.Located || args.Status == LocateAnchorStatus.AlreadyTracked)
        {
            currentCloudAnchor = args.Anchor;

            QueueOnUpdate(() =>
            {
                Debug.Log($"Azure anchor located successfully");

                // Notify AnchorFeedbackScript
                OnASAAnchorLocated?.Invoke();

#if UNITY_ANDROID || UNITY_IOS
                Pose anchorPose = Pose.identity;
                anchorPose      = currentCloudAnchor.GetPose();
#endif

#if WINDOWS_UWP || UNITY_WSA
                // HoloLens: The position will be set based on the unityARUserAnchor that was located.

                // Create a local anchor at the location of the object in question
                gameObject.CreateNativeAnchor();

                // Notify AnchorFeedbackScript
                OnCreateLocalAnchor?.Invoke();

                // On HoloLens, if we do not have a cloudAnchor already, we will have already positioned the
                // object based on the passed in worldPos/worldRot and attached a new world anchor,
                // so we are ready to commit the anchor to the cloud if requested.
                // If we do have a cloudAnchor, we will use it's pointer to setup the world anchor,
                // which will position the object automatically.
                if (currentCloudAnchor != null)
                {
                    Debug.Log("Local anchor position successfully set to Azure anchor position");

                    gameObject.GetComponent <UnityEngine.XR.WSA.WorldAnchor>().SetNativeSpatialAnchorPtr(currentCloudAnchor.LocalAnchor);
                }
#else
                Debug.Log($"Setting object to anchor pose with position '{anchorPose.position}' and rotation '{anchorPose.rotation}'");
                transform.position = anchorPose.position;
                transform.rotation = anchorPose.rotation;

                // Create a native anchor at the location of the object in question
                gameObject.CreateNativeAnchor();

                // Notify AnchorFeedbackScript
                OnCreateLocalAnchor?.Invoke();
#endif
            });
        }
        else
        {
            QueueOnUpdate(new Action(() => Debug.Log($"Attempt to locate Anchor with ID '{args.Identifier}' failed, locate anchor status was not 'Located' but '{args.Status}'")));
        }
    }
Ejemplo n.º 3
0
    protected virtual async Task SaveCurrentObjectAnchorToCloudAsync()
    {
        CloudNativeAnchor nativeAnchor = this.GetComponent <CloudNativeAnchor>();

        nativeAnchor.SetPose(this.transform.position, this.transform.rotation);

        // If the cloud portion of the anchor hasn't been created yet, create it
        if (nativeAnchor.CloudAnchor == null)
        {
            nativeAnchor.NativeToCloud();
        }

        CloudSpatialAnchor cloudAnchor = nativeAnchor.CloudAnchor;

        cloudAnchor.Expiration = DateTimeOffset.Now.AddDays(7);

        while (!GetComponent <SpatialAnchorManager>().IsReadyForCreate)
        {
            await Task.Delay(330);

            float createProgress = GetComponent <SpatialAnchorManager>().SessionStatus.RecommendedForCreateProgress;
            feedback.text = $"Move your device to capture more environment data: {createProgress:0%}";
        }

        Pose anchorPose = cloudAnchor.GetPose();

        feedback.text = "Anchor Position: " + anchorPose.position + " Rotation: " + anchorPose.rotation;


        try
        {
            // Actually save
            await GetComponent <SpatialAnchorManager>().CreateAnchorAsync(cloudAnchor);

            feedback.text = "Saved: " + cloudAnchor.Identifier;
            // Store
            currentCloudAnchor = cloudAnchor;

            //    // Success?
            //    success = currentCloudAnchor != null;

            //    if (success && !isErrorActive)
            //    {
            //        // 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."));
            //    }
        }
        catch (Exception ex)
        {
            feedback.text = ex.ToString();
            //    OnSaveCloudAnchorFailed(ex);
        }
    }
        /// <summary>
        /// Applies the specified cloud anchor to the GameObject by
        /// creating or updating the native anchor.
        /// to match.
        /// </summary>
        /// <param name="gameObject">
        /// The <see cref="GameObject"/> where the cloud anchor should be
        /// applied.
        /// </param>
        /// <param name="cloudAnchor">
        /// The cloud anchor to apply.
        /// </param>
        /// <returns>
        /// The <see cref="NativeAnchor"/> created or updated during the
        /// operation.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">
        /// Thrown if <paramref name="gameObject"/> or <paramref name="cloudAnchor"/>
        /// are <see langword = "null" />.
        /// </exception>
        /// <exception cref="PlatformNotSupportedException">
        /// Thrown if the current platform is not supported by the SDK.
        /// </exception>
        static public NativeAnchor ApplyCloudAnchor(this GameObject gameObject, CloudSpatialAnchor cloudAnchor)
        {
            // Validate
            if (gameObject == null)
            {
                throw new ArgumentNullException(nameof(gameObject));
            }
            if (cloudAnchor == null)
            {
                throw new ArgumentNullException(nameof(cloudAnchor));
            }

            // Placeholder
            NativeAnchor nativeAnchor = null;

            #if WINDOWS_UWP || UNITY_WSA
            // On UWP we can just update the pointer on any existing WorldAnchor.
            // Doing so will also automatically update the objects pose.

            // Find or create the world anchor
            nativeAnchor = gameObject.FindOrCreateNativeAnchor();

            // Update the World Anchor to use the cloud-based native anchor
            nativeAnchor.SetNativeSpatialAnchorPtr(cloudAnchor.LocalAnchor);
            #elif UNITY_IOS || UNITY_ANDROID
            // On iOS and Android we need to remove any existing native anchor,
            // move the object to the new pose, and then re-apply the native anchor.

            // Delete any existing native anchor
            gameObject.DeleteNativeAnchor();

            // Get the pose from the cloud anchor
            Pose pose = cloudAnchor.GetPose();

            // Move the GameObject to match the new pose
            gameObject.transform.position = pose.position;
            gameObject.transform.rotation = pose.rotation;

            // Add the native anchor back on
            nativeAnchor = gameObject.CreateNativeAnchor();
            #else
            throw new PlatformNotSupportedException("Unable to apply the cloud anchor. The platform is not supported.");
#endif
#if UNITY_EDITOR
#pragma warning disable CS0162 // Conditional compile statements prevent reaching this code in the unity editor
#endif
            // Return the created or updated anchor
            return(nativeAnchor);

#if UNITY_EDITOR
#pragma warning restore CS0162
#endif
        }
Ejemplo n.º 5
0
        private void HandleAnchorLocated(object sender, AnchorLocatedEventArgs args)
        {
            Debug.Log($"Anchor recognized as a possible Azure anchor");

            if (args.Status == LocateAnchorStatus.Located || args.Status == LocateAnchorStatus.AlreadyTracked)
            {
                currentCloudAnchor = args.Anchor;

                AppDispatcher.Instance().Enqueue(() =>
                {
                    Debug.Log($"Azure anchor located successfully");
                    var indicator = Instantiate(anchorPositionPrefab);

#if WINDOWS_UWP || UNITY_WSA
                    indicator.gameObject.CreateNativeAnchor();

                    if (currentCloudAnchor == null)
                    {
                        return;
                    }
                    Debug.Log("Local anchor position successfully set to Azure anchor position");

                    indicator.GetComponent <UnityEngine.XR.WSA.WorldAnchor>().SetNativeSpatialAnchorPtr(currentCloudAnchor.LocalAnchor);
#elif UNITY_ANDROID || UNITY_IOS
                    Pose anchorPose = Pose.identity;
                    anchorPose      = currentCloudAnchor.GetPose();

                    Debug.Log($"Setting object to anchor pose with position '{anchorPose.position}' and rotation '{anchorPose.rotation}'");
                    indicator.transform.position = anchorPose.position;
                    indicator.transform.rotation = anchorPose.rotation;

                    // Create a native anchor at the location of the object in question
                    indicator.gameObject.CreateNativeAnchor();
#endif

                    indicator.Init(currentTrackedObject);
                    anchorArrowGuide.SetTargetObject(indicator.transform);
                    activeAnchors.Add(currentTrackedObject.SpatialAnchorId, indicator);

                    // Notify subscribers
                    OnFindAnchorSucceeded?.Invoke(this, EventArgs.Empty);
                    currentWatcher?.Stop();
                    currentTrackedObject = null;
                });
            }
            else
            {
                Debug.Log($"Attempt to locate Anchor with ID '{args.Identifier}' failed, locate anchor status was not 'Located' but '{args.Status}'");
            }

            StopAzureSession();
        }
Ejemplo n.º 6
0
    private void CloudManagerAnchorLocated(object sender, AnchorLocatedEventArgs args)
    {
        if (args.Status == LocateAnchorStatus.Located && appStateManager.currentCloudAnchorState == CloudAnchorStateEnum.ReadyToLookForCloudAnchor)
        {
            if (spawnedAnchorObject == null)
            {
                currentCloudSpatialAnchor = args.Anchor;
                Pose anchorPose = currentCloudSpatialAnchor.GetPose();
                spawnedAnchorObject = SpawnNewAnchoredObject(anchorPose.position, anchorPose.rotation);
            }

            appStateManager.currentCloudAnchorState = CloudAnchorStateEnum.NothingHappening;
            appStateManager.currentUIState          = UIStateEnum.SceneryButtonsOnly_NothingHappening;
            appStateManager.currentOutputMessage    = $"Found cloud anchor OK.  Press 'Place' to add new scenery, or press 'Restore' to get previously saved scenery..";
        }
    }
Ejemplo n.º 7
0
    private void CloudAnchor_Located(object sender, AnchorLocatedEventArgs args)
    {
        feedback.text      = "Anchor " + anchorNumber + " located";
        currentCloudAnchor = args.Anchor;
        Pose anchorPose = currentCloudAnchor.GetPose();

        feedback.text = "Anchor position: " + anchorPose.position;
        this.transform.SetPositionAndRotation(anchorPose.position, anchorPose.rotation);
        this.GetComponentInChildren <Renderer>().enabled        = true;
        this.GetComponentInChildren <Renderer>().material.color = Color.green;
        this.GetComponentInChildren <TextMeshPro>().text        = anchorNumber;



        GetComponent <SpatialAnchorManager>().StopSession();
        feedback.text = "Stopped Session";
    }
        protected void OnCloudAnchorLocated(AnchorLocatedEventArgs args)
        {
            if (args.Status == LocateAnchorStatus.Located)
            {
                currentCloudAnchor = args.Anchor;

                UnityDispatcher.InvokeOnAppThread(() =>
                {
                    Pose anchorPose = Pose.identity;

#if UNITY_ANDROID || UNITY_IOS
                    anchorPose = currentCloudAnchor.GetPose();
#endif
                    // HoloLens: The position will be set based on the unityARUserAnchor that was located.
                    SpawnOrMoveCurrentAnchoredObject(anchorPose.position, anchorPose.rotation);
                });
            }
        }
        /// <summary>
        /// For each anchor located by the spatial anchor manager, instantiate and setup a corresponding GameObject.
        /// </summary>
        private void SpatialAnchorManagerAnchorLocated(object sender, AnchorLocatedEventArgs args)
        {
            Debug.Log($"Anchor recognized as a possible anchor {args.Identifier} {args.Status}");

            if (args.Status == LocateAnchorStatus.Located)
            {
                UnityDispatcher.InvokeOnAppThread(() =>
                {
                    CloudSpatialAnchor cloudSpatialAnchor = args.Anchor;
                    Pose anchorPose = cloudSpatialAnchor.GetPose();

                    GameObject anchorGameObject = Instantiate(m_sampleSpatialAnchorPrefab, anchorPose.position, anchorPose.rotation);
                    anchorGameObject.AddComponent <CloudNativeAnchor>().CloudToNative(cloudSpatialAnchor);
                    anchorGameObject.GetComponent <SampleSpatialAnchor>().Identifier = cloudSpatialAnchor.Identifier;
                    anchorGameObject.GetComponent <SampleSpatialAnchor>().Persisted  = true;

                    m_foundOrCreatedAnchorObjects.Add(anchorGameObject);
                });
            }
        }
Ejemplo n.º 10
0
    /// <summary>
    /// The watcher created in <see cref="FindSpatialAnchor(string)"/> invokes this event for every anchor requested
    /// This event fires if an anchor is located or also if it cannot be located.
    /// </summary>
    /// <param name="args"></param>
    private void ReportAnchorLocationResultReceived(Microsoft.Azure.SpatialAnchors.AnchorLocatedEventArgs args)
    {
        if (args.Watcher != null)
        {
            args.Watcher.Stop();
        }
        switch (args.Status)
        {
        case LocateAnchorStatus.AlreadyTracked:
            Log($"The requested anchor {args.Identifier} was already tracked.", true);
            SendUpdateOnMainThread(AsaStatusEventType.FindAnchor_AlreadyTracked, status);
            break;

        case LocateAnchorStatus.Located:
            CloudSpatialAnchor foundAnchor = args.Anchor;

            Log($"The requested anchor {args.Identifier} was found!", true);

            if (foundAnchor == null)
            {
                Log($"Found the requested anchor but the returned anchor is null!", true);
                return;
            }

            SendUpdateOnMainThread(AsaStatusEventType.FindAnchor_Finished, status);

            ExecuteOnMainThread(() =>
            {
                Log("Processing the found anchor's position", true);
                // Notify AnchorFeedbackScript
                Pose anchorPose = Pose.identity;

#if UNITY_ANDROID || UNITY_IOS
                anchorPose = foundAnchor.GetPose();
#endif

#if WINDOWS_UWP || UNITY_WSA
                // HoloLens: The position will be set based on the unityARUserAnchor that was located.

                // Create a local anchor at the location of the object in question
                gameObject.CreateNativeAnchor();

                // On HoloLens, if we do not have a cloudAnchor already, we will have already positioned the
                // object based on the passed in worldPos/worldRot and attached a new world anchor,
                // so we are ready to commit the anchor to the cloud if requested.
                // If we do have a cloudAnchor, we will use it's pointer to setup the world anchor,
                // which will position the object automatically.
                if (foundAnchor != null)
                {
                    Log("Local anchor position successfully set to Azure anchor position", true);

                    var worldAnchor = gameObject.GetComponent <UnityEngine.XR.WSA.WorldAnchor>();
                    if (worldAnchor != null)
                    {
                        worldAnchor.SetNativeSpatialAnchorPtr(foundAnchor.LocalAnchor);
                    }
                    else
                    {
                        Log("WorldAnchorComponent was null", true);
                    }
                }
#else
                Log($"Setting object to anchor pose with position '{anchorPose.position}' and rotation '{anchorPose.rotation}'", true);
                transform.position = anchorPose.position;
                transform.rotation = anchorPose.rotation;

                // Create a native anchor at the location of the object in question
                //gameObject.CreateNativeAnchor();
#endif
            });

            break;

        case LocateAnchorStatus.NotLocatedAnchorDoesNotExist:
            // The anchor was deleted or never existed in the first place
            // Drop it, or show UI to ask user to anchor the content anew
            Log($"The requested anchor {args.Identifier} does not exist.", true);
            SendUpdateOnMainThread(AsaStatusEventType.FindAnchor_DoesNotExist, status);
            break;

        case LocateAnchorStatus.NotLocated:
            // The anchor hasn't been found given the location data
            // The user might in the wrong location, or maybe more data will help
            // Show UI to tell user to keep looking around
            Log($"The requested anchor {args.Identifier} could not be located.", true);
            SendUpdateOnMainThread(AsaStatusEventType.FindAnchor_CouldNotLocate, status);
            break;
        }
    }
Ejemplo n.º 11
0
    private void CloudAnchorManager_AnchorLocated(object sender, AnchorLocatedEventArgs args)
    {
        if (args.Status == LocateAnchorStatus.Located)
        {
            Debug.Log("Found anchor: " + args.Identifier);
            if (args.Identifier != null)
            {
                foundAnchors.Add(args.Anchor);
            }
            debugText.text = "Anchor Located: " + args.Identifier;
            //shift current to previous and get new current
            if (currentCloudAnchor == null || args.Anchor.Identifier != currentCloudAnchor.Identifier)
            {
                previousCloudAnchor = currentCloudAnchor;
                currentCloudAnchor  = args.Anchor;
            }


            //get a list of all gameobjects with tag AnchorContainer.  This will get a list of all anchor prefabs
            var anchorContainers = GameObject.FindGameObjectsWithTag("AnchorContainer");
            debugText.text += "\nNum Anchors: " + anchorContainers.Length;
            GameObject anchorContainer = null;


            for (int i = 0; i < anchorContainers.Length; i++)
            {
                //if anchorcontainer is at location of the current anchor, this is the one we just found
                if (anchorContainers[i].gameObject.transform.position == currentCloudAnchor.GetPose().position)
                {
                    anchorContainer = anchorContainers[i];
                    anchorContainer.gameObject.GetComponent <AnchorContainer>().anchorID = args.Anchor.Identifier;
                    debugText.text += "\nAnchor Added: " + anchorContainer.gameObject.GetComponent <AnchorContainer>().anchorID;
                }

                //if we found the previous container, we need to reset this one so it isn't highlighted
                if (previousCloudAnchor != null)
                {
                    if (anchorContainers[i].gameObject.transform.position == previousCloudAnchor.GetPose().position)
                    {
                        changeAnchorMaterials(anchorContainers[i], baseMaterial);
                    }
                }
            }

            if (anchorContainer != null)
            {
                //make all the children in the anchorcontainer visible and highlight the cyclinder
                for (int i = 0; i < anchorContainer.transform.childCount; i++)
                {
                    GameObject child = anchorContainer.transform.GetChild(i).gameObject;
                    if (!child.name.Equals("Cylinder"))
                    {
                        child.SetActive(true);
                    }
                    //if (anchorContainer.transform.GetChild(i).gameObject.name.Equals("Cylinder"))
                    //{
                    //    anchorContainer.transform.GetChild(i).gameObject.GetComponent<Renderer>().material = highlightMaterial;
                    //}
                }

                changeAnchorMaterials(anchorContainer, highlightMaterial);

                //set the curved text to the identifier
                TMP_Text containerText = anchorContainer.GetComponentInChildren <TMP_Text>();
                containerText.text = "" + currentCloudAnchor.Identifier;

                //set the curved text to the label if it exists
                //TODO: change this so that it algorithmically determines the amount of
                //      repeats and the amount of spacing so it looks good with
                //      any word
                if (currentCloudAnchor.AppProperties.ContainsKey("label") && currentCloudAnchor.AppProperties["label"] != null)
                {
                    string label             = currentCloudAnchor.AppProperties["label"];
                    int    anchorLabelLength = 0;
                    containerText.text = "";
                    while (anchorLabelLength <= 26)
                    {
                        containerText.text += label + "    ";
                        anchorLabelLength  += label.Length + 4;
                    }
                }
                else
                {
                    Debug.Log("Anchor found with ID: " + currentCloudAnchor.Identifier);
                }
                topText.text = "Anchors located!  Localization complete!";
            }
            else
            {
                debugText.text += "No Anchor Detected";
            }
        }
    }