using System; using UnityEngine; using UnityEngine.XR.ARSubsystems; namespace UnityEditor.XR.ARSubsystems { /// /// Extension methods for the . /// /// /// At runtime, s are immutable. These /// Editor-only extension methods let you build and manipulate image libraries /// in Editor scripts. /// public static class XRReferenceImageLibraryExtensions { /// /// Associate binary data with a string key. /// /// /// Providers use this to associate provider-specific data with the library. During Player Build (in an /// [IPreprocessBuildWithReport.OnPreprocessBuild](xref:UnityEditor.Build.IPreprocessBuildWithReport.OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport)) /// callback), the data store is first cleared. Each enabled provider then has an opportunity to add one or more /// entries for itself. /// /// Providers can use this to store a serialized version of the image library specific to that provider. /// Retrieve data with . /// /// The being extended. /// The key which can be used to later retrieve . /// The data to associate with . /// Thrown if is `null`. public static void SetDataForKey(this XRReferenceImageLibrary library, string key, byte[] data) { if (key == null) throw new ArgumentNullException(nameof(key)); library.InternalSetDataForKey(key, data); } /// /// Clears the binary data store. /// /// /// Provider-specific binary data can be associated with each /// (see ). This is /// used to store arbitrarily large blocks of binary data required at runtime -- usually some form of processed /// image data. This data is regenerated during Player Build, and may be safely discarded otherwise. Use this /// method to clear the data store to avoid large files in your project. /// /// The being extended. public static void ClearDataStore(this XRReferenceImageLibrary library) => library.InternalClearDataStore(); /// /// Creates an empty XRReferenceImage and adds it to the library. The new /// reference image is inserted at the end of the list of reference images. /// /// The being extended. /// Thrown if is null. public static void Add(this XRReferenceImageLibrary library) { if (library == null) throw new ArgumentNullException(nameof(library)); library.m_Images.Add(new XRReferenceImage { m_SerializedGuid = SerializableGuidUtil.Create(Guid.NewGuid()) }); } /// /// Set the texture on the reference image. /// /// The being extended. /// The reference image index to modify. /// The texture to set. /// Whether to store a strong reference to the texture. If true, /// the texture will be available in the Player. Otherwise, XRReferenceImage.texture will be set to null. /// Thrown if is null. /// Thrown if is not between 0 and .count - 1. public static void SetTexture(this XRReferenceImageLibrary library, int index, Texture2D texture, bool keepTexture) { ValidateAndThrow(library, index); var referenceImage = library.m_Images[index]; referenceImage.m_SerializedTextureGuid = SerializableGuidUtil.Create(GetGuidForTexture(texture)); referenceImage.m_Texture = keepTexture ? texture : null; library.m_Images[index] = referenceImage; } /// /// Sets the XRReferenceImage.specifySize value on the XRReferenceImage at . /// This value is read-only in the Player; it can only be modified in the Editor. /// /// The XRReferenceImageLibrary being extended. /// The index of the reference image within the library to modify. /// Whether XRReferenceImage.size is specified. /// Thrown if is null. /// Thrown if is not between 0 and .count - 1. public static void SetSpecifySize(this XRReferenceImageLibrary library, int index, bool specifySize) { ValidateAndThrow(library, index); var image = library.m_Images[index]; image.m_SpecifySize = specifySize; library.m_Images[index] = image; } /// /// Sets the XRReferenceImage.size value on the XRReferenceImage at . /// This value is read-only in the Player; it can only be modified in the Editor. /// /// The XRReferenceImageLibrary being extended. /// The index of the reference image within the library to modify. /// The size that the reference image is being set to. /// Thrown if is null. /// Thrown if is not between 0 and .count - 1. public static void SetSize(this XRReferenceImageLibrary library, int index, Vector2 size) { ValidateAndThrow(library, index); var image = library.m_Images[index]; image.m_Size = size; library.m_Images[index] = image; } /// /// Sets the XRReferenceImage.name value on the XRReferenceImage at . /// This value is read-only in the Player; it can only be modified in the Editor. /// /// The XRReferenceImageLibrary being extended. /// The index of the reference image within the library to modify. /// The name being applied to the reference image. /// Thrown if is null. /// Thrown if is not between 0 and .count - 1. public static void SetName(this XRReferenceImageLibrary library, int index, string name) { ValidateAndThrow(library, index); var image = library.m_Images[index]; image.m_Name = name; library.m_Images[index] = image; } /// /// Removes the at . /// /// The being extended. /// The index in the list of images to remove. /// Thrown if is null. /// Thrown if is not between 0 and .count - 1. public static void RemoveAt(this XRReferenceImageLibrary library, int index) { ValidateAndThrow(library, index); library.m_Images.RemoveAt(index); } static Guid GetGuidForTexture(Texture2D texture) { if (texture == null) return Guid.Empty; string guid; long localId; if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(texture, out guid, out localId)) return new Guid(guid); return Guid.Empty; } static void ValidateAndThrow(XRReferenceImageLibrary library, int index) { if (library == null) throw new ArgumentNullException(nameof(library)); if (library.count == 0) throw new IndexOutOfRangeException("The reference image library is empty; cannot index into it."); if (index < 0 || index >= library.count) throw new IndexOutOfRangeException($"{index} is out of range. 'index' must be between 0 and {library.count - 1}"); } } }