Commit c273ed9f authored by Jérémy Lacoche's avatar Jérémy Lacoche
Browse files

Add possibility to use AssetBundle from a given url for mesh tracking

parent e02fee32
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -36,11 +36,14 @@ ARKit can track meshes that are defined in the .arobject format. Such an object

Unity serializes .arobject into ARKitReferenceObjectEntry in the editor. ARKitReferenceObjectEntry cannot then be imported at runtime from a .arobjject file. Dynamic loading is not supported yet.

To support adding .arobject without recompiling the full application, we use a dedicated AssetBundle (named "arfmeshes"). To do so:
To support adding .arobject without recompiling the full application, we use a dedicated AssetBundle.
* Place you .arobject in the Assets Folder. For instance under Assets/ARObjects
* Associate the ARKitReferenceObjectEntry with the arfmeshes AssetBundle in the editor
* Build the AssetBundles. For that you can use the following menu: ARF--> Build AssetBundles iOS
* Pace the "arfmeshes" file in the Unity persistent data path of the application on the user device.

Then you have two options:
* Placing the AssetBundle "arfmeshes" file (with this exact file name) in the Unity persistent data path of the application on the user device.
* The variable keyvalueTags of the Trackable can also contain a parameter with the "url" key providing a link to download the AssetBundle to the Unity persistent data path on the user device. Only one AssetBundle can be loaded.

The name of the Trackable in the World Storage must correspond to the name of the ARKitReferenceObjectEntry.

+45 −17
Original line number Diff line number Diff line
@@ -19,6 +19,10 @@ public class WorldAnalysisARFoundationModuleMesh : WorldAnalysisARFoundationModu
    /// </summary>
    private List<string> m_trackedMeshesInLibrary;
    /// <summary>
    /// Has downloaded asset bundle from an url
    /// </summary>
    private bool m_hasDownloadedBundle; 
    /// <summary>
    /// List of tracked meshses with tracking infos
    /// </summary>
    private Dictionary<string,TrackableInfo> m_trackedMeshes = new Dictionary<string,TrackableInfo>();
@@ -45,17 +49,7 @@ public class WorldAnalysisARFoundationModuleMesh : WorldAnalysisARFoundationModu
        m_trackedObjectManager.trackedObjectsChanged += OnTrackedMeshesChanged;
        m_trackedObjectManager.enabled = true ; // when instantiated without library : it is disabled
        m_entries = null;
      
        #if UNITY_EDITOR
            string bundlePath = Application.streamingAssetsPath + "/arfmeshes" ;
        #else
            string bundlePath = Application.persistentDataPath  + "/arfmeshes" ;
        #endif
        if (System.IO.File.Exists(bundlePath))
        {
            AssetBundle bu = AssetBundle.LoadFromFile(bundlePath);
            m_entries = bu.LoadAllAssets<XRReferenceObjectEntry>() ;
        }
        m_hasDownloadedBundle = false; 
    }

    /// <summary>
@@ -87,7 +81,20 @@ public class WorldAnalysisARFoundationModuleMesh : WorldAnalysisARFoundationModu
        {
            return false;
        }
        bool resul = AddMeshToLibrary(trackable.Name) ;// (float)trackable.TrackableSize[0]);

        // Check if an AssetBundle url is provided
        string url = "";
        if (trackable.KeyvalueTags.ContainsKey("url"))
        {
            foreach (string s in trackable.KeyvalueTags["url"])
            {
                // first one
                url = s;
                break;
            }
        }

        bool resul = AddMeshToLibrary(trackable.Name , url) ;// (float)trackable.TrackableSize[0]);
        if (resul)
        {
            m_uuidToName[trackable.UUID] = trackable.Name;
@@ -96,7 +103,7 @@ public class WorldAnalysisARFoundationModuleMesh : WorldAnalysisARFoundationModu
    }

    /// <summary>
    ///  Initialize capability object with image tracking
    ///  Initialize capability object with Mesh tracking
    /// </summary>
    public ETSI.ARF.OpenAPI.WorldAnalysis.Capability  GetSupportedCapability()
    {
@@ -153,7 +160,7 @@ public class WorldAnalysisARFoundationModuleMesh : WorldAnalysisARFoundationModu
    /// </summary>
    /// <param name="fileName">file name</param>
    /// <returns></returns>
    protected bool AddMeshToLibrary(string fileName)
    protected bool AddMeshToLibrary(string fileName, string url)
    {
        // check if mesh is in the library
        if (m_trackedMeshesInLibrary.Contains(fileName))
@@ -164,9 +171,30 @@ public class WorldAnalysisARFoundationModuleMesh : WorldAnalysisARFoundationModu

        if (m_entries == null)
        {
            Debug.LogWarning("Try to Track Mesh but ARF Bundle with meshes is null");

#if UNITY_EDITOR
            string bundlePath = Application.streamingAssetsPath + "/arfmeshes";
#else
            string bundlePath = Application.persistentDataPath  + "/arfmeshes" ;
#endif

            if (url.Length > 0 && !m_hasDownloadedBundle)
            {
                KeyValuePair<string, string> download = System.Threading.Tasks.Task.Run(() => WorldAnalysisARFoundationHelper.DownloadFileHTTP(url)).Result; // synchronous : not perfect at all prevent to add another mesh while bundle is downloading
                bundlePath = download.Key;
                m_hasDownloadedBundle = true;
            }

            if (System.IO.File.Exists(bundlePath))
            {
                AssetBundle bu = AssetBundle.LoadFromFile(bundlePath);
                m_entries = bu.LoadAllAssets<XRReferenceObjectEntry>();
            }
            else
            {
                return false;
            }
        }
    
        XRReferenceObjectEntry toAdd = null ;
        foreach(XRReferenceObjectEntry entry in m_entries)