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

Module image : possibility to load local image from streamingassets, add...

Module image : possibility to load local image from streamingassets, add vision OS support with Polyspatial 1.X
parent b0e25fae
Loading
Loading
Loading
Loading
+128 −10
Original line number Diff line number Diff line
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using System.IO;
@@ -123,7 +124,11 @@ public class WorldAnalysisARFoundationModuleImage : WorldAnalysisARFoundationMod
            Quaternion rotation = trackedImage.transform.rotation;

            TrackableInfo info = new TrackableInfo();
            #if UNITY_VISIONOS
            info.name = GetImageNameWithoutUUID(trackedImage.referenceImage.name);
            #else
            info.name = trackedImage.referenceImage.name;
            #endif
            if (trackedImage.trackingState == TrackingState.Tracking)
            {
                info.state = ETSI.ARF.OpenAPI.WorldAnalysis.PoseEstimationState.OK;
@@ -147,6 +152,47 @@ public class WorldAnalysisARFoundationModuleImage : WorldAnalysisARFoundationMod
        }
    }


#if UNITY_VISIONOS

    /// Loaded one time
   private XRReferenceImageLibrary m_libaryVision ;

    protected bool AddImageToLibrary(string fileName, string url, float imageWidthInMeters)
    {
        // VISION OS/Polyspatial 1.X does not suppoort dynamically adding images, url is ignored as well as imageWidthInMeters that cannot be modified
        // Include change in 2.X : https://discussions.unity.com/t/adding-tracking-ar-maker-images-at-runtime-support-for-vision-pro/345127
        if (m_trackedImageInLibrary.Contains(fileName))
        {
            Debug.Log("Image allready added to library");
            return true;
        }

        // Load Image Library from resources folder
        if (m_trackedImageManager.referenceLibrary == null)
        {
            m_libaryVision = (XRReferenceImageLibrary) Resources.Load("VisionOSImageLibrary");
            m_trackedImageManager.referenceLibrary = m_libaryVision;
        }

        if (m_libaryVision != null)
        {
            if (!m_trackedImageManager.enabled) m_trackedImageManager.enabled = true; // Necessary?
            foreach(XRReferenceImage image in m_libaryVision)
            {
                if (image.name == fileName)
                {
                    m_trackedImageInLibrary.Add(fileName);
                    return true ;
                }
            }
        }
        return false ;        
    }


#else 

    /// <summary>
    /// Add a new image to the arfoundation library
    /// </summary>
@@ -171,7 +217,7 @@ public class WorldAnalysisARFoundationModuleImage : WorldAnalysisARFoundationMod
        bool found = CheckImageExist(ref imagePath); // try to find in jpg or png
        if (!found && url.Length == 0)
        {
            Debug.LogWarning("Try to Track Image " + fileName + "  but file not found");
            Debug.LogWarning("Try to track image " + fileName + "  but file was not found");
            return false; 
        }

@@ -191,6 +237,7 @@ public class WorldAnalysisARFoundationModuleImage : WorldAnalysisARFoundationMod
        }
        return true;
    }
#endif

    /// <summary>
    /// Add a new image from local memory to the arfoundation library
@@ -200,11 +247,52 @@ public class WorldAnalysisARFoundationModuleImage : WorldAnalysisARFoundationMod
    /// <param name="imageWidthInMeters">image width in meters</param>
    private void LoadTextureFromMemory(string imagePath, string fileName, float imageWidthInMeters)
    {
        var rawData = File.ReadAllBytes(imagePath);
        try
        {
            byte[] rawData;
            if (imagePath.Contains("://"))
            {
                // Hack to make sync request
                UnityWebRequest request = UnityWebRequest.Get(imagePath);
                request.SendWebRequest();
                while (!request.isDone)
                {
                    if (request.result != UnityWebRequest.Result.InProgress)
                    {
                        break;
                    }
                }

                if (request.result != UnityWebRequest.Result.Success)
                {
                    rawData = null;
                }
                else
                {
                    rawData = request.downloadHandler.data;
                }
            }
            else
            {
                rawData = File.ReadAllBytes(imagePath);
            }

            if (rawData != null)
            {
                Texture2D tex = new Texture2D(2, 2);
                tex.LoadImage(rawData);
                AddTextureToLibrary(tex, fileName, imageWidthInMeters);
            }
            else
            {
                Debug.LogError($"Fail to read data from file {imagePath}");
            }
        }
        catch(Exception ex)
        {
            Debug.LogError($"Fail to read data from file {imagePath} ({ex})");
        }
    }

    /// <summary>
    /// Add a new image from a given url to the arfoundation library
@@ -213,12 +301,24 @@ public class WorldAnalysisARFoundationModuleImage : WorldAnalysisARFoundationMod
    /// <param name="fileName">file name</param>
    /// <param name="imageWidthInMeters">image width in meters</param>
    private async void LoadTextureFromURL(string url, string fileName, float imageWidthInMeters)
    {
        Uri uri = new Uri(url);

        if (uri.Scheme == "file" && uri.LocalPath.StartsWith("/%streamingassets%/"))
        {
            // Load image from streaming assets
            string imagePath = Path.Combine(Application.streamingAssetsPath, uri.LocalPath.Replace("/%streamingassets%/", ""));
            Debug.Log($"Try to load image from {imagePath}");
            LoadTextureFromMemory(imagePath, fileName, imageWidthInMeters);
        } 
        else 
        {
            Debug.Log("Download image from url "+ url);
            m_allDownloadedImages.Add(url);
            KeyValuePair<string , string> downloaded = await WorldAnalysisARFoundationHelper.DownloadFileHTTP(url);
            LoadTextureFromMemory(downloaded.Key, fileName, imageWidthInMeters);
        }
    }

    /// <summary>
    /// Add a texture2D to the list of tracked image of the ARFoundation image library
@@ -242,6 +342,7 @@ public class WorldAnalysisARFoundationModuleImage : WorldAnalysisARFoundationMod
            library = m_trackedImageManager.referenceLibrary;
        }


        if (library is MutableRuntimeReferenceImageLibrary mutableLibrary)
        {
            if (!m_trackedImageInLibrary.Contains(imageName))
@@ -282,4 +383,21 @@ public class WorldAnalysisARFoundationModuleImage : WorldAnalysisARFoundationMod
        }
        return false; 
    }

#if UNITY_VISIONOS
    /// <summary>
    ///  With images libraries not created at runtime Tracked images reference names include an UUID after a "_", this function removes it
    /// </summary>
    /// <param input="input"></param>
    /// <returns></returns>
    private string GetImageNameWithoutUUID(string input)
    {
        int lastIndex=  input.LastIndexOf('_');
        if (lastIndex !=-1)
        {
            return input.Substring(0, lastIndex);
        }
        return input ;
    }
 #endif
}
 No newline at end of file