Image Target App Development For Magic Leap 2 Using Vuforia Engine

Hi folks,
I have followed this link to develop the simple image target app using vuforia engine.
Image Target Vuforia
I haven't added any customize script. I am able to run the image target in ML2 but the child object attached to the image target appear well below the image target.
Scene and hierarchy settings

The child object of the image target viewed from magic leap 2 is like below

I am using
Unity Editor version: 2022.3.40f1
ML2 OS version:1.9.0
Unity SDK version:v2.4.0
Host OS: (Windows/MacOS):Windows10
Do anybody know what is the cause of this issue and how to resolve it. Any sample project link will be highly appreciated.

Hi @acharya ,
When you're creating the image target in Vuforia, it's important to specify the target's dimensions according to its real-world size. For instance, if the target is 20 cm wide and 10 cm high, set the ImageTarget's width to 0.2 and height to 0.1. Even slight inaccuracies in these dimensions can lead to errors when positioning the augmentations.
Initially, I thought only the scale mattered (e.g., setting width to 20 and height to 10), but that's not the case. It seems the depth camera also influences augmentation positioning.
Hope this helps!

1 Like

Hi @gregkoutsikos,
Thanks for the reply. I used to match only the image target's width. I'm using A4 paper as a real object for image tracking. Should I use the paper's thickness (0.0005~0.001 m) as the height of the image target or the length of the other edge of the paper (let's say 0.1 m), as you mentioned?

Hi @gregkoutsikos,
Can you explain a little bit more about the depth camera and how it influences the image target as well?

The width of the A4 paper is 29.7 and the height is 21, so you should use these numbers.. The paper's thickness does not matter, as you track an image. From my testing, i think that the depth camera calculates the distance from the object when tracking it, and takes it into consideration when calculating the size of the imagetarget and the placement of the augmentations. On the contrary, using slightly wrong measurements for the image target using vuforia on phones without depth camera doesn't pose such a big problem as the tracking still works well..

1 Like

Hi @gregkoutsikos
I tried with the webcam in game model and found that it is working well. Still, I am not able to get the desired result using magic leap 2 (the attached child model appear well below the image target). Is there any other settings required within the unity for magic leap 2 which I am missing? Do you have a sample project used to create image target application for magic leap 2 using vuforia engine and unity ?

I don't have one, but you could use Vuforia's samples from the asset store.. Also there is this guide on how to use Vuforia with Magic Leap 2... But from what you are saying, i still believe that there is a problem with the imagetarget dimensions, because that would not pose a problem to the webcam as it doesn't have a depth camera, but would affect the magic leap tracking that uses one.

1 Like

@acharya Are you using OpenXR or the MLSDK XR workflow?

Hi @kbabilinski
I am slecting OpenXR workflow while setting the project using Magic Leap Setup tool.

I'm not sure if Vuforia supports the OpenXR workflow out of the box. If I remember correctly they are using the MLCamera and calling MLCVCamera.GetFramePose under the hood which returns the pose of the camera in unbounded space Reference Space when using OpenXR.

To make sure your application tracks in the same reference space as the Camera Pose. You can use the following script to set the tracking origin to unbounded on start.

This feature requires the OpenXR Magic Leap 2 Reference Space Feature to be enabled in your project's OpenXR Settings (Window > XR Plugin Manager > OpenXR Settings ).

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.XR;
using UnityEngine.XR.Management;
using UnityEngine.XR.OpenXR;
using UnityEngine.XR.OpenXR.Features.MagicLeapSupport;

public class ReferenceSpaceToggle : MonoBehaviour
{
    private bool inputSubsystemValid;
    private XRInputSubsystem inputSubsystem;

    // Start is called before the first frame update
    IEnumerator Start()
    {
       var referenceSpaceFeature = OpenXRSettings.Instance.GetFeature<MagicLeapReferenceSpacesFeature>();
       if (!referenceSpaceFeature.enabled)
       {
           Debug.LogError("Unbounded Tracking Space cannot be set if the OpenXR Magic Leap Reference Spaces Feature is not enabled. Stopping Script.");
           yield break;
       }

       yield return new WaitUntil(() => XRGeneralSettings.Instance != null &&
                                         XRGeneralSettings.Instance.Manager != null &&
                                         XRGeneralSettings.Instance.Manager.activeLoader != null &&
                                         XRGeneralSettings.Instance.Manager.activeLoader.GetLoadedSubsystem<XRInputSubsystem>() != null);
       
       inputSubsystem = XRGeneralSettings.Instance.Manager.activeLoader.GetLoadedSubsystem<XRInputSubsystem>();
       TrackingOriginModeFlags supportedModes = inputSubsystem.GetSupportedTrackingOriginModes();
       
       string supportedSpaces = string.Join("\n",
            ((TrackingOriginModeFlags[])Enum.GetValues(typeof(TrackingOriginModeFlags))).Where((flag) =>
                supportedModes.HasFlag(flag) && flag != TrackingOriginModeFlags.Unknown));
       Debug.Log($"Supported Spaces:{supportedSpaces}");
       
       string currentSpace = inputSubsystem.GetTrackingOriginMode().ToString();
       Debug.Log($"Current Space:{currentSpace}");
       
       inputSubsystemValid = true;

       SetSpace(TrackingOriginModeFlags.Unbounded);
    }

    public void SetSpace(TrackingOriginModeFlags flag)
    {
        if (inputSubsystemValid)
        {
            if (inputSubsystem.TrySetTrackingOriginMode(flag))
            {
                string currentSpace = inputSubsystem.GetTrackingOriginMode().ToString();
                Debug.Log($"Current Space:{currentSpace}");
                inputSubsystem.TryRecenter();
                return;
            }
        }
        Debug.LogError("SetSpace failed to set Tracking Mode Origin to " + flag.ToString());
    }
}

Below is the structure of my hierarchy.

I copied the script you suggested as above.
I don't know how to use the above script to set the tracking origin to unbounded on start. Can you explain more in details, where to bound this script?

You might be able to attach it to the Main Camera. You may also need to add an XR Origin component and parent the Main Camera underneath it.

I tried both ways. First without adding the XR Origin and after adding the XR origin and adding the ReferenceSpaceToggle Script in main camera. Still the model doesn't appear in the correct location as in scene.
The project hierarchy and Main camera inspector panel is like this

As an alternative, you may want to consider configuring your project with the MLSDK instead of OpenXR, This should resolve your issues.Just make sure to remove the script that I posted above so it doesn't conflict with your app

You may also want to reach out through the official Vuforia Support channels such as stack overflow since they would be more familiar with the implementation: