using System; using Unity.Collections; using UnityEngine.XR.ARSubsystems; using UnityEngine.XR.Management; #if UNITY_EDITOR using System.IO; using System.Linq; using UnityEditor; #endif namespace UnityEngine.XR.ARKit { /// /// Represents an ARKit-specific reference object for participation in an /// XRReferenceObjectLibrary. /// /// /// The actual data used at runtime is packaged into the Xcode project /// in an asset catalog called ARReferenceObjects.xcassets. It should /// exist on disk in your project as an .arobject file. /// See Scanning and Detecting 3D Objects /// for instructions on how to generate these files. /// /// /// public sealed class ARKitReferenceObjectEntry : XRReferenceObjectEntry, ISerializationCallbackReceiver { /// /// (Read Only) The reference origin of the scanned object (in session space). /// public Pose referenceOrigin => m_ReferenceOrigin; internal ARReferenceObject GetARKitReferenceObject(XRReferenceObject referenceObject) { m_ARKitReferenceObject.SetName(referenceObject); return m_ARKitReferenceObject; } /// /// Creates a new from a serialized /// [ARReferenceObject](https://developer.apple.com/documentation/arkit/arreferenceobject?language=objc). /// /// The bytes of a serialized /// [ARReferenceObject](https://developer.apple.com/documentation/arkit/arreferenceobject?language=objc). /// Returns a new if is successfully /// deserialized into an ARReferenceObject. Returns `null` otherwise. public static ARKitReferenceObjectEntry Create(NativeSlice data) { var referenceObject = new ARReferenceObject(data); if (referenceObject == null) return null; var entry = CreateInstance(); entry.m_ARKitReferenceObject = referenceObject; return entry; } /// /// Invoked when a new [XRReferenceObject](xref:UnityEngine.XR.ARSubsystems.XRReferenceObject) is added to an /// [XRReferenceObjectLibrary](xref:UnityEngine.XR.ARSubsystems.XRReferenceObjectLibrary). /// /// The library to which the reference object is being added. /// The reference object being added to the . protected override void OnAddToLibrary(XRReferenceObjectLibrary library, XRReferenceObject xrReferenceObject) { base.OnAddToLibrary(library, xrReferenceObject); if (m_ARKitReferenceObject == null) return; var instance = XRGeneralSettings.Instance; if (instance == null) return; var manager = instance.Manager; if (manager == null) return; var loader = manager.activeLoader; if (loader == null) return; if (loader.GetLoadedSubsystem() is ARKitObjectTrackingSubsystem subsystem) { subsystem.AddReferenceObject(library, GetARKitReferenceObject(xrReferenceObject)); } } void OnDestroy() => m_ARKitReferenceObject.Dispose(); /// /// Invoked just before serialization. /// void ISerializationCallbackReceiver.OnBeforeSerialize() { } /// /// Invoked just after deserialization. /// void ISerializationCallbackReceiver.OnAfterDeserialize() => m_ARKitReferenceObject = new ARReferenceObject(m_ReferenceObjectBytes); #if UNITY_EDITOR static bool s_ObjectBytesShouldBeSet; // Called by ARKitReferenceObjectLibraryBuildProcessor internal static void SetObjectBytesEnabled(bool value) { // Set the desired result s_ObjectBytesShouldBeSet = value; // Iterate over all reference object libraries, reimporting if necessary var entries = AssetDatabase.FindAssets($"t:{nameof(XRReferenceObjectLibrary)}") .Select(AssetDatabase.GUIDToAssetPath) .Select(AssetDatabase.LoadAssetAtPath) .SelectMany(library => library) .Select(referenceObject => referenceObject.FindEntry()) .Where(entry => entry != null); foreach (var entry in entries) { entry.ReimportIfNecessary(); } } // Called by ARObjectImporter internal void SetSourceAsset(string path) => m_ReferenceObjectBytes = s_ObjectBytesShouldBeSet ? File.ReadAllBytes(path) : new byte[0]; void ReimportIfNecessary() { if (s_ObjectBytesShouldBeSet && m_ReferenceObjectBytes?.Length == 0 || !s_ObjectBytesShouldBeSet && m_ReferenceObjectBytes?.Length > 0) { AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(this)); } } #endif #pragma warning disable CS0649 [SerializeField] internal Pose m_ReferenceOrigin; [SerializeField] internal byte[] m_ReferenceObjectBytes; #pragma warning restore CS0649 ARReferenceObject m_ARKitReferenceObject; } }