using System; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; namespace UnityEngine.XR.ARKit { /// /// The space-mapping state and set of planes and anchors 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 { /// /// Disposes of the world map. This releases the native [ARWorldMap](https://developer.apple.com/documentation/arkit/arworldmap) resource. /// 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 => (nativeHandle != k_InvalidHandle) && Api.UnityARKit_isWorldMapValid(nativeHandle); /// /// Serialize the ARWorldMap to an array of bytes. This array can 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. /// The caller owns the returned /// [NativeArray](https://docs.unity3d.com/ScriptReference/Unity.Collections.NativeArray_1.html) /// and is responsible for disposing it. /// /// The /// [allocator](https://docs.unity3d.com/ScriptReference/Unity.Collections.Allocator.html) /// to use for the returned /// [NativeArray](https://docs.unity3d.com/ScriptReference/Unity.Collections.NativeArray_1.html) of bytes. /// An array of bytes representing the serialized ARWorldMap. /// The caller owns the memory and is responsible for disposing the `NativeArray`. /// Thrown if the world map is not . /// Thrown if the world map could not be serialized to a byte array. 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 . /// On success, holds the deserialized . /// `True` if was successfully deserialized, otherwise `false`. 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; } /// /// Generates a hash suitable for use with containers like `HashSet` and `Dictionary`. /// /// A hash code generated from this object's fields. public override int GetHashCode() => nativeHandle.GetHashCode(); /// /// Tests for equality. /// /// The `object` to compare against. /// `True` if is of type and /// also returns `true`; otherwise `false`. public override bool Equals(object obj) => obj is ARWorldMap other && Equals(other); /// /// Tests for equality. /// /// The other to compare against. /// `True` if every field in is equal to this , otherwise false. public bool Equals(ARWorldMap other) => nativeHandle == other.nativeHandle; /// /// Tests for equality. Same as . /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// `True` if is equal to , otherwise `false`. public static bool operator ==(ARWorldMap lhs, ARWorldMap rhs) => lhs.Equals(rhs); /// /// Tests for inequality. Same as `!`. /// /// The left-hand side of the comparison. /// The right-hand side of the comparison. /// `True` if is not equal to , otherwise `false`. public static bool operator !=(ARWorldMap lhs, ARWorldMap rhs) => !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 } }