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;
}
}