using System; using Unity.Collections; using UnityEngine.Scripting; using UnityEngine.XR.ARSubsystems; #if UNITY_XR_ARKIT_LOADER_ENABLED using System.Runtime.InteropServices; #endif namespace UnityEngine.XR.ARKit { /// /// The room capture instructions, as defined by the specification of /// RoomCaptureSession.Instruction by Apple. /// [Flags] public enum XRBoundingBoxInstructions : uint { /// /// No instruction returning. /// None = 0, /// /// The instruction that indicates scanning proceeds normally. /// Normal = 1 << 0, /// /// The instruction that requests the user move closer to the wall when scanning. /// MoveCloseToWall = 1 << 1, /// /// The instruction that requests the user move further from the wall when scanning. /// MoveAwayFromWall = 1 << 2, /// /// The instruction that requests the user increase the amount of light in the room when scanning. /// TurnOnLight = 1 << 3, /// /// The instruction that requests the user move slower when scanning. /// SlowDown = 1 << 4, /// /// The instruction that indicates the room feature is not distinguishable to detect when scanning. /// LowTexture = 1 << 5, } /// /// The implementation of the XRBoundingBoxSubsystem. Do not create this directly. Use the SubsystemManager instead. /// [Preserve] public sealed class RoomPlanBoundingBoxSubsystem : XRBoundingBoxSubsystem { class ARKitProvider : Provider { public ARKitProvider() => NativeApi.UnityARKit_BoundingBox_Construct(); public override void Start() { } public override void Stop() { } public override void Destroy() => NativeApi.UnityARKit_BoundingBox_Destruct(); public override unsafe TrackableChanges GetChanges(XRBoundingBox defaultXRBoundingBox, Allocator allocator) { var context = NativeApi.UnityARKit_BoundingBox_GetChanges( out void* addedPtr, out int addedCount, out void* updatedPtr, out int updatedCount, out void* removedPtr, out int removedCount, out int elementSize); try { return new TrackableChanges( addedPtr, addedCount, updatedPtr, updatedCount, removedPtr, removedCount, defaultXRBoundingBox, elementSize, allocator); } finally { NativeApi.UnityARKit_BoundingBox_ReleaseChanges(context); } } } /// /// Set up room capture. /// /// `True` if room capture is successfully set up, otherwise false. /// /// /// public bool SetupRoomCapture() => NativeApi.UnityARKit_BoundingBox_SetupRoomCapture(); /// /// Start the room capture process. /// /// /// /// public void StartRoomCapture() => NativeApi.UnityARKit_BoundingBox_StartRoomCapture(); /// /// Stop the room capture process. /// /// /// /// public void StopRoomCapture() => NativeApi.UnityARKit_BoundingBox_StopRoomCapture(); /// /// Check the status of room capture process. /// /// `True` if the process is room capturing, otherwise false. /// /// /// public bool IsRoomCapturing() => NativeApi.UnityARKit_BoundingBox_IsRoomCapturing(); /// /// Receive the instruction during room capture. /// /// The instruction from room capture process. /// /// /// public void GetRoomCaptureInstruction(out XRBoundingBoxInstructions instruction) => NativeApi.UnityARKit_BoundingBox_GetRoomCaptureInstruction(out instruction); /// /// Register the roomplan boundingbox subsystem if iOS and not the editor. /// [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] static void Register() { if (!Api.AtLeast17_0()) return; const string subsystemId = "ARKit-RoomPlan-BoundingBox"; var boundingboxSubsystemCinfo = new XRBoundingBoxSubsystemDescriptor.Cinfo { id = subsystemId, providerType = typeof(RoomPlanBoundingBoxSubsystem.ARKitProvider), subsystemTypeOverride = typeof(RoomPlanBoundingBoxSubsystem), supportsClassification = true, }; XRBoundingBoxSubsystemDescriptor.Register(boundingboxSubsystemCinfo); } /// /// Container to wrap the native roomplan boundingbox APIs. /// static class NativeApi { #if UNITY_XR_ARKIT_LOADER_ENABLED [DllImport("__Internal")] public static extern void UnityARKit_BoundingBox_Construct(); [DllImport("__Internal")] public static extern void UnityARKit_BoundingBox_Destruct(); [DllImport("__Internal")] public static extern void UnityARKit_BoundingBox_StartRoomCapture(); [DllImport("__Internal")] public static extern void UnityARKit_BoundingBox_StopRoomCapture(); [DllImport("__Internal")] public static extern unsafe void UnityARKit_BoundingBox_GetRoomCaptureInstruction(out XRBoundingBoxInstructions instruction); [DllImport("__Internal")] public static extern bool UnityARKit_BoundingBox_SetupRoomCapture(); [DllImport("__Internal")] public static extern bool UnityARKit_BoundingBox_IsRoomCapturing(); [DllImport("__Internal")] public static extern unsafe void* UnityARKit_BoundingBox_GetChanges( out void* addedPtr, out int addedCount, out void* updatedPtr, out int updatedCount, out void* removedPtr, out int removedCount, out int elementSize); [DllImport("__Internal")] public static extern unsafe void UnityARKit_BoundingBox_ReleaseChanges(void* changes); #else public static void UnityARKit_BoundingBox_Construct() => throw new NotSupportedException(); public static void UnityARKit_BoundingBox_Destruct() => throw new NotSupportedException(); public static void UnityARKit_BoundingBox_StartRoomCapture() => throw new NotSupportedException(); public static void UnityARKit_BoundingBox_StopRoomCapture() => throw new NotSupportedException(); public static unsafe void UnityARKit_BoundingBox_GetRoomCaptureInstruction(out XRBoundingBoxInstructions instruction) => throw new NotSupportedException(); public static bool UnityARKit_BoundingBox_SetupRoomCapture() => throw new NotSupportedException(); public static bool UnityARKit_BoundingBox_IsRoomCapturing() => throw new NotSupportedException(); public static unsafe void* UnityARKit_BoundingBox_GetChanges( out void* addedPtr, out int addedCount, out void* updatedPtr, out int updatedCount, out void* removedPtr, out int removedCount, out int elementSize) => throw new NotSupportedException(); public static unsafe void UnityARKit_BoundingBox_ReleaseChanges(void* changes) => throw new NotSupportedException(); #endif } } }