using System; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; namespace UnityEngine.XR.ARKit { /// /// The space-mapping state and set of planes and reference points from /// an AR session. This is a wrapper for /// ARKit's ARWorldMap /// Note: The ARWorldMap must be explicitly disposed to avoid leaking native resources. /// public struct ARWorldMap : IDisposable, IEquatable { /// /// Dispose of the world map. This will invalidate any NativeArrays /// previously returned by . /// public void Dispose() { Api.UnityARKit_disposeWorldMap(nativeHandle); nativeHandle = k_InvalidHandle; #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.Release(m_SafetyHandle); #endif } /// /// Use this to determine whether this ARWorldMap is valid, or /// if it has been disposed. /// public bool valid { get { return (nativeHandle != k_InvalidHandle) && Api.UnityARKit_isWorldMapValid(nativeHandle); } } /// /// Serialize the ARWorldMap to an array of bytes. This array may be saved to disk /// and loaded at another time to persist the session, or sent over a network /// to another ARKit-enabled app to share the session. /// It is an error to call this method after the ARWorldMap has been disposed. /// /// An array of bytes representing the serialized ARWorldMap. public unsafe NativeArray Serialize(Allocator allocator) { if (!valid) throw new InvalidOperationException("ARWorldMap has been disposed."); IntPtr nsdata; int length; if (!Api.UnityARKit_trySerializeWorldMap(nativeHandle, out nsdata, out length)) throw new InvalidOperationException("Internal error."); var serializedWorldMap = new NativeArray( length, allocator, NativeArrayOptions.UninitializedMemory); Api.UnityARKit_copyAndReleaseNsData( new IntPtr(serializedWorldMap.GetUnsafePtr()), nsdata, length); return serializedWorldMap; } /// /// Create a new ARWorldMap from a NativeArray of bytes produced /// from . Use this to create an ARWorldMap from /// a serialized array of bytes, either loaded from disk or sent from another device. /// /// An array of bytes representing a serialized ARWorldMap, /// produced by . public static unsafe bool TryDeserialize(NativeArray serializedWorldMap, out ARWorldMap worldMap) { var nativeHandle = Api.UnityARKit_deserializeWorldMap( new IntPtr(serializedWorldMap.GetUnsafePtr()), serializedWorldMap.Length); if (nativeHandle == k_InvalidHandle) { worldMap = default(ARWorldMap); return false; } worldMap = new ARWorldMap(nativeHandle); return true; } public override int GetHashCode() { return nativeHandle.GetHashCode(); } public override bool Equals(object obj) { if (!(obj is ARWorldMap)) return false; return Equals((ARWorldMap)obj); } public bool Equals(ARWorldMap other) { return (nativeHandle == other.nativeHandle); } public static bool operator ==(ARWorldMap lhs, ARWorldMap rhs) { return lhs.Equals(rhs); } public static bool operator !=(ARWorldMap lhs, ARWorldMap rhs) { return !lhs.Equals(rhs); } internal ARWorldMap(int nativeHandle) { this.nativeHandle = nativeHandle; #if ENABLE_UNITY_COLLECTIONS_CHECKS m_SafetyHandle = AtomicSafetyHandle.Create(); #endif } internal const int k_InvalidHandle = 0; internal int nativeHandle { get; private set; } #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle m_SafetyHandle; #endif } }