giacomo homunculus
giacomo homunculus

Reputation: 31

ARCore Extended ImageTracking / Anchoring API in Unity

The ARCore AugmentedImage example application that comes with the Unity SDK package places a picture frame around the sample images included in the sample AugmentedImageDatabase. It will place a picture frame around multiple images in the scene if they are found, and only destroy the picture frames once tracking is lost entirely.

Suppose you wanted to only display a picture frame around the image most recently recognized - and remove the frame from the previous image? Checking the TrackingState of a given image doesn't help since the tracking is extended by default without any way to turn off, and the anchor API doesn't offer any information that would help either.

I have it working by destroying the old session (and creating a new one) once the list that holds the Trackable images exceeds 1, but that leads to the app temporarily freezing up for a second before resuming.

Are there suggestions on a better way to do this?

Upvotes: 3

Views: 2080

Answers (3)

GuruJeya
GuruJeya

Reputation: 141

Use the following code to achieve the same scenario as of TrackingState.Tracking and TrackingState.Stopped. Its just here I've used AugmentedImageTrackingMethod.FullTracking and AugmentedImageTrackingMethod.LastKnownPose. Works fine, and tested with different images in Unity Engine.

foreach(AugmentedImage image in images)
    {
        var viz = GetVisualizer(image);

        //Marker is being tracked
        if(image.TrackingState == TrackingState.Tracking && viz == null && image.TrackingMethod == AugmentedImageTrackingMethod.FullTracking)
        {
            AddVisualizer(image);
        }
        //marker is not tracked in camera output
        else if(image.TrackingMethod == AugmentedImageTrackingMethod.LastKnownPose && viz != null)
        {
            RemoveVisualizer(image, viz);
        }
    }

Answer reference is from here.

Upvotes: 1

DRYRA
DRYRA

Reputation: 11

5 Months later and this problem is still there, really weird from Google that they did not fix this and are ignoring such issues on Github.

I found a workaround that exploits AugmentedImageTrackingMethod, it is not very optimal, but the only thing that I found that works: in the Update method in AugmentedImageController.cs

 foreach (var image in m_TempAugmentedImages)
    {

        AugmentedImageVisualizerZreality visualizer = null;
        m_Visualizers.TryGetValue(image.DatabaseIndex, out visualizer);

        if (image.TrackingState == TrackingState.Tracking && visualizer == null)
        {
            // Create an anchor to ensure that ARCore keeps tracking this augmented image.
           // This only fires Tracking and then goes directly to paused, for ever..
            Anchor anchor = image.CreateAnchor(image.CenterPose);
            visualizer = Instantiate(
                AugmentedImageVisualizerPrefab, anchor.transform);
            visualizer.Image = image;
            m_Visualizers.Add(image.DatabaseIndex, visualizer);
        }
        else if (image.TrackingState == TrackingState.Stopped && visualizer != null)
        {
            m_Visualizers.Remove(image.DatabaseIndex);
            GameObject.Destroy(visualizer.gameObject);
        } else if (image.TrackingState == TrackingState.Paused)
        {
            trackingHint.text = "Tracking paused";
        }

        // We take care of hiding and showing here
        switch (image.TrackingMethod)
        {
            case AugmentedImageTrackingMethod.FullTracking:
                visualizer.gameObject.SetActive(true);
                trackingHint.text = "Tracking in progress..";
                break;
            case AugmentedImageTrackingMethod.LastKnownPose:
                visualizer.gameObject.SetActive(false);
                trackingHint.text = "LastKnownPose";
                break;
            case AugmentedImageTrackingMethod.NotTracking:
                trackingHint.text = "NotTracking";
                visualizer.gameObject.SetActive(false);
                break;
        }
    }

Not a very clean workaround, but it does the trick if you choose ARCore over vuforia..

Upvotes: 0

Ali Kanat
Ali Kanat

Reputation: 1889

Okay this is not an exact solution considering the reply to this github issue from Google developers but it solves the issue. As i said in my comments TrackableQueryFilter.Updated gives you images that are updated(not just in terms of status but position etc.) in the current frame. Therefore, when i log the m_TempAugmentedImages.Count for 318 frames while my image is in the view of my phone and being tracked, my image is updated 18 times.

Since there is no way of knowing when image is updated and it is not happening frequently, i thought of checking if image is not updated for 3 seconds i can destroy the image. In order to do so, i added public float TimePassed to my AugmentedImageVisualizer script. Then in my AugmentedImageController script i added these lines to check TimePassed of every image that is in the Session like this:

        foreach (var visualizer in m_Visualizers.Values)
        {
            // if image is Updated TimePassed is assigned to zero for that image
            if (m_TempAugmentedImages.Count != 0 && visualizer.Image == m_TempAugmentedImages[0])
            {

                    visualizer.TimePassed = 0;

            }
            else
            {
                visualizer.TimePassed += Time.deltaTime;
            }

            if (visualizer.TimePassed > 3.0f)
            {
                Debug.Log("Destroy is called");
                m_Visualizers.Remove(visualizer.Image.DatabaseIndex);
                GameObject.Destroy(visualizer.gameObject);
            }              
        }

I built it and this way you can go back to images which are tracked before and if you are not happy about 3 seconds you can lower it as well. Good luck

Upvotes: 2

Related Questions