using System; using System.Runtime.InteropServices; namespace UnityEngine.XR.ARKit { /// /// Represents a disposable locked configurable primary camera associated with the current /// session configuration. Use this object to configure advanced camera hardware properties. /// [StructLayout(LayoutKind.Sequential)] public struct ARKitLockedCamera : IEquatable, IDisposable { IntPtr m_Self; ARKitExposureMode m_ExposureMode; ARKitWhiteBalanceMode m_WhiteBalanceMode; ARKitFocusMode m_FocusMode; /// /// Get the native pointer of [AVCaptureDevice] /// (https://developer.apple.com/documentation/avfoundation/avcapturedevice?language=objc). /// /// Returns the native pointer of [AVCaptureDevice] /// (https://developer.apple.com/documentation/avfoundation/avcapturedevice?language=objc). public IntPtr AsIntPtr() => m_Self; /// /// Get the supported exposure modes for the camera. /// public ARKitExposureMode supportedExposureModes => NativeApi.UnityARKit_Camera_GetSupportedExposureModes(m_Self); /// /// Get the supported white balance modes for the camera. /// public ARKitWhiteBalanceMode supportedWhiteBalanceModes => NativeApi.UnityARKit_Camera_GetSupportedWhiteBalanceModes(m_Self); /// /// Get the supported focus modes for the camera. /// public ARKitFocusMode supportedFocusModes => NativeApi.UnityARKit_Camera_GetSupportedFocusModes(m_Self); /// /// Get the current exposure mode for the camera. /// /// public ARKitExposureMode currentExposureMode => NativeApi.UnityARKit_Camera_GetExposureMode(m_Self); /// /// Get the current white balance mode for the camera device. /// /// public ARKitWhiteBalanceMode currentWhiteBalanceMode => NativeApi.UnityARKit_Camera_GetWhiteBalanceMode(m_Self); /// /// Get the current focus mode for the camera. /// /// public ARKitFocusMode currentFocusMode => NativeApi.UnityARKit_Camera_GetFocusMode(m_Self); /// /// Get or set the requested exposure mode for the camera. /// /// public ARKitExposureMode requestedExposureMode { get => m_ExposureMode; set { m_ExposureMode = value; NativeApi.UnityARKit_Camera_SetExposureMode(m_Self, value); } } /// /// Get or set the requested white balance mode for the camera device. /// /// public ARKitWhiteBalanceMode requestedWhiteBalanceMode { get => m_WhiteBalanceMode; set { m_WhiteBalanceMode = value; NativeApi.UnityARKit_Camera_SetWhiteBalanceMode(m_Self, value); } } /// /// Get or set the requested focus mode for the camera. /// /// public ARKitFocusMode requestedFocusMode { get => m_FocusMode; set { m_FocusMode = value; NativeApi.UnityARKit_Camera_SetFocusMode(m_Self, value); } } /// /// Get the supported exposure range of the camera. /// public ARKitExposureRange exposureRange { get { NativeApi.UnityARKit_Camera_GetExposureRange(m_Self, out var range); return range; } } /// /// Get the supported white balance gain values. /// public ARKitWhiteBalanceRange whiteBalanceRange { get { NativeApi.UnityARKit_Camera_GetWhiteBalanceRange(m_Self, out var range); return range; } } /// /// Get the supported focus range of the camera. /// public ARKitFocusRange focusRange { get { NativeApi.UnityARKit_Camera_GetFocusRange(m_Self, out var range); return range; } } /// /// Get or set the current exposure of the camera. /// public ARKitExposure exposure { get { NativeApi.UnityARKit_Camera_GetExposure(m_Self, out var duration, out var iso); return new ARKitExposure(duration, iso); } set => NativeApi.UnityARKit_Camera_TrySetExposure(m_Self, value.duration, value.iso); } /// /// Get or set the current white balance of the camera. /// public ARKitWhiteBalanceGains whiteBalance { get { NativeApi.UnityARKit_Camera_GetWhiteBalance(m_Self, out var blue, out var green, out var red); return new ARKitWhiteBalanceGains(blue, green, red); } set => NativeApi.UnityARKit_Camera_TrySetWhiteBalance(m_Self, value.blue, value.green, value.red); } /// /// Get or set the current focus of the camera. /// public ARKitFocus focus { get { NativeApi.UnityARKit_Camera_GetFocus(m_Self, out var lensPosition); return new ARKitFocus(lensPosition); } set => NativeApi.UnityARKit_Camera_TrySetFocus(m_Self, value.lensPosition); } ARKitLockedCamera(IntPtr value) { m_Self = value; m_ExposureMode = ARKitExposureMode.Auto; m_WhiteBalanceMode = ARKitWhiteBalanceMode.Auto; m_FocusMode = ARKitFocusMode.Auto; } /// /// Creates an from an existing native pointer. The native pointer must point to /// a valid [AVCaptureDevice](https://developer.apple.com/documentation/avfoundation/avcapturedevice?language=objc). /// /// A pointer to [AVCaptureDevice] /// (https://developer.apple.com/documentation/avfoundation/avcapturedevice?language=objc). /// Returns an whose underlying [AVCaptureDevice] /// (https://developer.apple.com/documentation/avfoundation/avcapturedevice?language=objc) pointer is /// . internal static ARKitLockedCamera FromIntPtr(IntPtr value) => new(value); /// /// Releases the lock on the native camera device. For more information, see ARKit's /// [AVCaptureDevice.unlockForConfiguration](https://developer.apple.com/documentation/avfoundation/avcapturedevice/1387917-unlockforconfiguration?language=objc). /// public void Dispose() { if (m_Self == IntPtr.Zero) return; NativeApi.UnityARKit_Camera_ReleaseCameraLock(m_Self); m_Self = IntPtr.Zero; } /// /// Tests for equality. /// /// /// Two s are considered equal if their underlying pointers are equal. /// /// The to compare against. /// Returns if the underlying native pointers are the same. Returns otherwise. public bool Equals(ARKitLockedCamera other) => m_Self == other.m_Self; /// /// Tests for equality. /// /// An to compare against. /// Returns if is an and it compares /// equal to this one using . public override bool Equals(object obj) { return obj is ARKitLockedCamera other && Equals(other); } /// /// Generates a hash code suitable for use with a `HashSet` or `Dictionary` /// /// Returns a hash code for this . public override int GetHashCode() => m_Self.GetHashCode(); /// /// Tests for equality. Equivalent to . /// /// The instance to compare with . /// The instance to compare with . /// if is equal to using /// . Otherwise, returns . public static bool operator ==(ARKitLockedCamera lhs, ARKitLockedCamera rhs) => lhs.Equals(rhs); /// /// Tests for inequality. Equivalent to the negation of . /// /// The to compare with . /// The to compare with . /// if is equal to using /// . Otherwise, returns . public static bool operator !=(ARKitLockedCamera lhs, ARKitLockedCamera rhs) => !lhs.Equals(rhs); /// /// Tests for equality. /// /// /// This equality operator lets you compare an instance with to determine whether its /// native pointer is `null`. /// /// /// /// bool TestForNull(ARKitLockedCamera obj) /// { /// if (obj == null) /// { /// // obj.AsIntPtr() is IntPtr.Zero /// } /// } /// /// /// The nullable `ARKitLockedCamera` to compare with . /// The nullable `ARKitLockedCamera` to compare with . /// if any of these conditions are met: /// - and are both not `null` and their native pointers are equal. /// - is `null` and 's native pointer is `null`. /// - is `null` and 's native pointer is `null`. /// - Both and are `null`. /// /// Otherwise, returns . /// public static bool operator ==(ARKitLockedCamera? lhs, ARKitLockedCamera? rhs) { var lhsPtr = lhs?.m_Self; var rhsPtr = rhs?.m_Self; // Both non null; compare pointers if (lhsPtr.HasValue && rhsPtr.HasValue) return lhsPtr.Value == rhsPtr.Value; // rhsPtr is null if (lhsPtr.HasValue) return lhsPtr.Value == IntPtr.Zero; // lhsPtr is null if (rhsPtr.HasValue) return rhsPtr.Value == IntPtr.Zero; // both null return true; } /// /// Tests for inequality. /// /// /// This inequality operator lets you compare an instance with to determine whether its /// native pointer is `null`. /// /// /// /// bool TestForNull(ARKitLockedCamera obj) /// { /// if (obj != null) /// { /// // obj.AsIntPtr() is not IntPtr.Zero /// } /// } /// /// /// The nullable `ARKitLockedCamera` to compare with . /// The nullable `ARKitLockedCamera` to compare with . /// if any of these conditions are met: /// - and are both not `null` and their native pointers are equal. /// - is `null` and 's native pointer is `null`. /// - is `null` and 's native pointer is `null`. /// - Both and are `null`. /// /// Otherwise, returns . /// public static bool operator !=(ARKitLockedCamera? lhs, ARKitLockedCamera? rhs) => !(lhs == rhs); /// /// Casts an instance to its underlying native pointer. /// /// The instance to cast. /// The native pointer. public static explicit operator IntPtr(ARKitLockedCamera lockedCamera) => lockedCamera.AsIntPtr(); static class NativeApi { #if UNITY_XR_ARKIT_LOADER_ENABLED [DllImport("__Internal")] public static extern void UnityARKit_Camera_ReleaseCameraLock(IntPtr cameraDevice); [DllImport("__Internal")] public static extern void UnityARKit_Camera_SetExposureMode(IntPtr cameraDevice, ARKitExposureMode exposureMode); [DllImport("__Internal")] public static extern ARKitExposureMode UnityARKit_Camera_GetExposureMode(IntPtr cameraDevice); [DllImport("__Internal")] public static extern ARKitExposureMode UnityARKit_Camera_GetSupportedExposureModes(IntPtr cameraDevice); [DllImport("__Internal")] public static extern void UnityARKit_Camera_SetWhiteBalanceMode(IntPtr cameraDevice, ARKitWhiteBalanceMode whiteBalanceMode); [DllImport("__Internal")] public static extern ARKitWhiteBalanceMode UnityARKit_Camera_GetWhiteBalanceMode(IntPtr cameraDevice); [DllImport("__Internal")] public static extern ARKitWhiteBalanceMode UnityARKit_Camera_GetSupportedWhiteBalanceModes(IntPtr cameraDevice); [DllImport("__Internal")] public static extern void UnityARKit_Camera_SetFocusMode(IntPtr cameraDevice, ARKitFocusMode exposureMode); [DllImport("__Internal")] public static extern ARKitFocusMode UnityARKit_Camera_GetFocusMode(IntPtr cameraDevice); [DllImport("__Internal")] public static extern ARKitFocusMode UnityARKit_Camera_GetSupportedFocusModes(IntPtr cameraDevice); [DllImport("__Internal")] public static extern void UnityARKit_Camera_GetExposureRange(IntPtr cameraDevice, out ARKitExposureRange exposureRange); [DllImport("__Internal")] public static extern void UnityARKit_Camera_GetWhiteBalanceRange(IntPtr cameraDevice, out ARKitWhiteBalanceRange whiteBalanceRange); [DllImport("__Internal")] public static extern void UnityARKit_Camera_GetFocusRange(IntPtr cameraDevice, out ARKitFocusRange focusRange); [DllImport("__Internal")] public static extern bool UnityARKit_Camera_TrySetExposure(IntPtr cameraDevice, double duration, float iso); [DllImport("__Internal")] public static extern void UnityARKit_Camera_GetExposure(IntPtr cameraDevice, out double duration, out float iso); [DllImport("__Internal")] public static extern bool UnityARKit_Camera_TrySetWhiteBalance(IntPtr cameraDevice, float blue, float green, float red); [DllImport("__Internal")] public static extern void UnityARKit_Camera_GetWhiteBalance(IntPtr cameraDevice, out float blue, out float green, out float red); [DllImport("__Internal")] public static extern bool UnityARKit_Camera_TrySetFocus(IntPtr cameraDevice, float lensPosition); [DllImport("__Internal")] public static extern void UnityARKit_Camera_GetFocus(IntPtr cameraDevice, out float lensPosition); #else public static void UnityARKit_Camera_ReleaseCameraLock(IntPtr cameraDevice) => throw new System.NotImplementedException(Constants.k_LoaderDisabledExceptionMsg); public static void UnityARKit_Camera_SetExposureMode(IntPtr cameraDevice, ARKitExposureMode exposureMode) => throw new System.NotImplementedException(Constants.k_LoaderDisabledExceptionMsg); public static ARKitExposureMode UnityARKit_Camera_GetExposureMode(IntPtr cameraDevice) => ARKitExposureMode.None; public static ARKitExposureMode UnityARKit_Camera_GetSupportedExposureModes(IntPtr cameraDevice) => ARKitExposureMode.None; public static void UnityARKit_Camera_SetWhiteBalanceMode(IntPtr cameraDevice, ARKitWhiteBalanceMode whiteBalanceMode) => throw new System.NotImplementedException(Constants.k_LoaderDisabledExceptionMsg); public static ARKitWhiteBalanceMode UnityARKit_Camera_GetWhiteBalanceMode(IntPtr cameraDevice) => ARKitWhiteBalanceMode.None; public static ARKitWhiteBalanceMode UnityARKit_Camera_GetSupportedWhiteBalanceModes(IntPtr cameraDevice) => ARKitWhiteBalanceMode.None; public static void UnityARKit_Camera_SetFocusMode(IntPtr cameraDevice, ARKitFocusMode exposureMode) => throw new System.NotImplementedException(Constants.k_LoaderDisabledExceptionMsg); public static ARKitFocusMode UnityARKit_Camera_GetFocusMode(IntPtr cameraDevice) => ARKitFocusMode.None; public static ARKitFocusMode UnityARKit_Camera_GetSupportedFocusModes(IntPtr cameraDevice) => ARKitFocusMode.None; public static void UnityARKit_Camera_GetExposureRange(IntPtr cameraDevice, out ARKitExposureRange exposureRange) => throw new System.NotImplementedException(Constants.k_LoaderDisabledExceptionMsg); public static void UnityARKit_Camera_GetWhiteBalanceRange(IntPtr cameraDevice, out ARKitWhiteBalanceRange whiteBalanceRange) => throw new System.NotImplementedException(Constants.k_LoaderDisabledExceptionMsg); public static void UnityARKit_Camera_GetFocusRange(IntPtr cameraDevice, out ARKitFocusRange focusRange) => throw new System.NotImplementedException(Constants.k_LoaderDisabledExceptionMsg); public static bool UnityARKit_Camera_TrySetExposure(IntPtr cameraDevice, double duration, float iso) => false; public static void UnityARKit_Camera_GetExposure(IntPtr cameraDevice, out double duration, out float iso) => throw new System.NotImplementedException(Constants.k_LoaderDisabledExceptionMsg); public static bool UnityARKit_Camera_TrySetWhiteBalance(IntPtr cameraDevice, float blue, float green, float red) => false; public static void UnityARKit_Camera_GetWhiteBalance(IntPtr cameraDevice, out float blue, out float green, out float red) => throw new System.NotImplementedException(Constants.k_LoaderDisabledExceptionMsg); public static bool UnityARKit_Camera_TrySetFocus(IntPtr cameraDevice, float lensPosition) => false; public static void UnityARKit_Camera_GetFocus(IntPtr cameraDevice, out float lensPosition) => throw new System.NotImplementedException(Constants.k_LoaderDisabledExceptionMsg); #endif } } }