334 lines
16 KiB
C#
334 lines
16 KiB
C#
|
|
using System;
|
||
|
|
using UnityEngine.XR.ARSubsystems;
|
||
|
|
|
||
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
||
|
|
using System.Runtime.InteropServices;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
namespace UnityEngine.XR.ARCore
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// Represents an
|
||
|
|
/// [ARCore camera configuration](https://developers.google.com/ar/reference/c/group/ar-camera-config), which
|
||
|
|
/// describes the ARCore-related properties of a device camera.
|
||
|
|
/// </summary>
|
||
|
|
public struct ArCameraConfig : IDisposable, IEquatable<ArCameraConfig>
|
||
|
|
{
|
||
|
|
IntPtr m_Self;
|
||
|
|
|
||
|
|
ArCameraConfig(IntPtr value) => m_Self = value;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Creates a <see cref="ArCameraConfig"/> from an existing native pointer. The native pointer must point
|
||
|
|
/// to an existing <see cref="ArCameraConfig"/>.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="value">A pointer to an existing native <see cref="ArCameraConfig"/>.</param>
|
||
|
|
/// <returns>Returns an <see cref="ArCameraConfig"/> whose underlying native pointer is
|
||
|
|
/// <paramref name="value"/>.</returns>
|
||
|
|
public static ArCameraConfig FromIntPtr(IntPtr value) => new ArCameraConfig(value);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Represents a null <see cref="ArCameraConfig"/>, i.e., one whose underlying native pointer is `null`.
|
||
|
|
/// This property is deprecated. Use <see langword="default"/> instead.
|
||
|
|
/// </summary>
|
||
|
|
[Obsolete("Use default instead.")]
|
||
|
|
public static ArCameraConfig Null => default;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// (Read Only) Indicates whether this <see cref="ArCameraConfig"/> is `null`.
|
||
|
|
/// This property is deprecated. Use the equality operator (`==`) to compare with `null` instead.
|
||
|
|
/// </summary>
|
||
|
|
[Obsolete("Compare to null instead.")]
|
||
|
|
public bool IsNull => m_Self == IntPtr.Zero;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Gets the underlying native pointer for this <see cref="ArCameraConfig"/>.
|
||
|
|
/// </summary>
|
||
|
|
/// <returns>Returns the underlying native pointer for this <see cref="ArCameraConfig"/>.</returns>
|
||
|
|
public IntPtr AsIntPtr() => m_Self;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Creates a new camera config object. To prevent memory leaks, this object should be disposed with
|
||
|
|
/// <see cref="Dispose"/> when you no longer need it.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="session">The ARCore session.</param>
|
||
|
|
public ArCameraConfig(ArSession session) => Create(session, out this);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Destroys this <see cref="ArCameraConfig"/> and sets its underlying pointer to `null`.
|
||
|
|
/// </summary>
|
||
|
|
/// <remarks>
|
||
|
|
/// You should only dispose an <see cref="ArCameraConfig"/> if you explicitly created it, e.g., by calling
|
||
|
|
/// <see cref="ArCameraConfig(ArSession)"/>. If you convert an existing config from an <see cref="IntPtr"/>
|
||
|
|
/// (e.g., by calling <see cref="FromIntPtr"/>), then you should not dispose it.
|
||
|
|
/// </remarks>
|
||
|
|
public void Dispose()
|
||
|
|
{
|
||
|
|
if (m_Self != IntPtr.Zero)
|
||
|
|
{
|
||
|
|
Destroy(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
m_Self = default;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Obtains the camera id for this camera config.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="session">The ARCore session.</param>
|
||
|
|
/// <returns>Returns the camera id for this camera config.</returns>
|
||
|
|
public string GetCameraId(ArSession session)
|
||
|
|
{
|
||
|
|
GetCameraId(session, this, out var cameraId);
|
||
|
|
using (cameraId)
|
||
|
|
{
|
||
|
|
return cameraId.ToString();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Gets the depth sensor usage settings.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="session">The ARCore session.</param>
|
||
|
|
/// <returns>Returns the depth sensor usage settings.</returns>
|
||
|
|
public ArCameraConfigDepthSensorUsage GetDepthSensorUsage(ArSession session)
|
||
|
|
{
|
||
|
|
GetDepthSensorUsage(session, this, out var value);
|
||
|
|
return value;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Gets the facing direction of the camera selected by this config.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="session">The ARCore session.</param>
|
||
|
|
/// <returns>Returns the facing direction of the camera selected by this config.</returns>
|
||
|
|
public ArCameraConfigFacingDirection GetFacingDirection(ArSession session)
|
||
|
|
{
|
||
|
|
GetFacingDirection(session, this, out var value);
|
||
|
|
return value;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Gets the minimum and maximum camera capture rate in frames per second (fps) for the current camera config.
|
||
|
|
/// </summary>
|
||
|
|
/// <remarks>
|
||
|
|
/// Actual capture frame rate will vary within this range, depending on lighting conditions. Frame rates will
|
||
|
|
/// generally be lower under poor lighting conditions to accommodate longer exposure times.
|
||
|
|
/// </remarks>
|
||
|
|
/// <param name="session">The ARCore session.</param>
|
||
|
|
/// <returns>Returns the minimum and maximum camera capture rate in frames per second supported by this camera
|
||
|
|
/// config.</returns>
|
||
|
|
public (int minFps, int maxFps) GetFpsRange(ArSession session)
|
||
|
|
{
|
||
|
|
GetFpsRange(session, this, out var min, out var max);
|
||
|
|
return (min, max);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Gets the camera image dimensions for this camera config.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="session">The ARCore session.</param>
|
||
|
|
/// <returns>Returns the camera image dimensions for this camera config.</returns>
|
||
|
|
public (int width, int height) GetImageDimensions(ArSession session)
|
||
|
|
{
|
||
|
|
GetImageDimensions(session, this, out var width, out var height);
|
||
|
|
return (width, height);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Gets the camera texture dimensions for this camera config.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="session">The ARCore session.</param>
|
||
|
|
/// <returns>Returns the camera texture dimensions for this camera config.</returns>
|
||
|
|
public (int width, int height) GetTextureDimensions(ArSession session)
|
||
|
|
{
|
||
|
|
GetTextureDimensions(session, this, out var width, out var height);
|
||
|
|
return (width, height);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Casts an <see cref="ArCameraConfig"/> to its underlying native pointer.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="cameraConfig">The <see cref="ArCameraConfig"/> to cast.</param>
|
||
|
|
/// <returns>Returns the underlying native pointer for <paramref name="cameraConfig"/></returns>
|
||
|
|
public static explicit operator IntPtr(ArCameraConfig cameraConfig) => cameraConfig.AsIntPtr();
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Tests for equality.
|
||
|
|
/// </summary>
|
||
|
|
/// <remarks>
|
||
|
|
/// Two <see cref="ArCameraConfig"/>s are considered equal if their underlying pointers are equal.
|
||
|
|
/// </remarks>
|
||
|
|
/// <param name="other">The <see cref="ArCameraConfig"/> to compare against.</param>
|
||
|
|
/// <returns>Returns `true` if the underlying native pointers are the same. Returns `false` otherwise.</returns>
|
||
|
|
public bool Equals(ArCameraConfig other) => m_Self == other.m_Self;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Tests for equality.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="obj">An <see cref="object"/> to compare against.</param>
|
||
|
|
/// <returns>Returns `true` if <paramref name="obj"/> is an <see cref="ArCameraConfig"/> and it compares
|
||
|
|
/// equal to this one using <see cref="Equals(UnityEngine.XR.ARCore.ArCameraConfig)"/>.</returns>
|
||
|
|
public override bool Equals(object obj) => obj is ArCameraConfig other && Equals(other);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Generates a hash code suitable for use with a `HashSet` or `Dictionary`
|
||
|
|
/// </summary>
|
||
|
|
/// <returns>Returns a hash code for this <see cref="ArCameraConfig"/>.</returns>
|
||
|
|
public override int GetHashCode() => m_Self.GetHashCode();
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Tests for equality. Same as <see cref="Equals(UnityEngine.XR.ARCore.ArCameraConfig)"/>.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="lhs">The <see cref="ArCameraConfig"/> to compare with <paramref name="rhs"/>.</param>
|
||
|
|
/// <param name="rhs">The <see cref="ArCameraConfig"/> to compare with <paramref name="lhs"/>.</param>
|
||
|
|
/// <returns>Returns `true` if <paramref name="lhs"/> is equal to <paramref name="rhs"/> using
|
||
|
|
/// <see cref="Equals(UnityEngine.XR.ARCore.ArCameraConfig)"/>. Returns `false` otherwise.</returns>
|
||
|
|
public static bool operator ==(ArCameraConfig lhs, ArCameraConfig rhs) => lhs.Equals(rhs);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Tests for inequality. Same as the negation of <see cref="Equals(UnityEngine.XR.ARCore.ArCameraConfig)"/>.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="lhs">The <see cref="ArCameraConfig"/> to compare with <paramref name="rhs"/>.</param>
|
||
|
|
/// <param name="rhs">The <see cref="ArCameraConfig"/> to compare with <paramref name="lhs"/>.</param>
|
||
|
|
/// <returns>Returns `false` if <paramref name="lhs"/> is equal to <paramref name="rhs"/> using
|
||
|
|
/// <see cref="Equals(UnityEngine.XR.ARCore.ArCameraConfig)"/>. Returns `true` otherwise.</returns>
|
||
|
|
public static bool operator !=(ArCameraConfig lhs, ArCameraConfig rhs) => !lhs.Equals(rhs);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Tests for equality.
|
||
|
|
/// </summary>
|
||
|
|
/// <remarks>
|
||
|
|
/// This equality operator lets you to compare an <see cref="ArCameraConfig"/> with `null` to determine whether its
|
||
|
|
/// underlying pointer is null. This allows for a more natural comparison with the native ARCore object:
|
||
|
|
/// <example>
|
||
|
|
/// <code>
|
||
|
|
/// bool TestForNull(ArCameraConfig obj)
|
||
|
|
/// {
|
||
|
|
/// if (obj == null)
|
||
|
|
/// {
|
||
|
|
/// // obj.AsIntPtr() is IntPtr.Zero
|
||
|
|
/// }
|
||
|
|
/// }
|
||
|
|
/// </code>
|
||
|
|
/// </example>
|
||
|
|
/// </remarks>
|
||
|
|
/// <param name="lhs">The nullable <see cref="ArCameraConfig"/> to compare with <paramref name="rhs"/>.</param>
|
||
|
|
/// <param name="rhs">The nullable <see cref="ArCameraConfig"/> to compare with <paramref name="lhs"/>.</param>
|
||
|
|
/// <returns>Returns true if any of these conditions are met:
|
||
|
|
/// - <paramref name="lhs"/> and <paramref name="rhs"/> are both not null and their underlying pointers are equal.
|
||
|
|
/// - <paramref name="lhs"/> is null and <paramref name="rhs"/>'s underlying pointer is null.
|
||
|
|
/// - <paramref name="rhs"/> is null and <paramref name="lhs"/>'s underlying pointer is null.
|
||
|
|
/// - Both <paramref name="lhs"/> and <paramref name="rhs"/> are null.
|
||
|
|
///
|
||
|
|
/// Returns false otherwise.
|
||
|
|
/// </returns>
|
||
|
|
public static bool operator ==(ArCameraConfig? lhs, ArCameraConfig? rhs) => NativeObject.ArePointersEqual(lhs?.m_Self, rhs?.m_Self);
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Tests for inequality.
|
||
|
|
/// </summary>
|
||
|
|
/// <remarks>
|
||
|
|
/// This inequality operator lets you to compare an <see cref="ArCameraConfig"/> with `null` to determine whether its
|
||
|
|
/// underlying pointer is null. This allows for a more natural comparison with the native ARCore object:
|
||
|
|
/// <example>
|
||
|
|
/// <code>
|
||
|
|
/// bool TestForNull(ArCameraConfig obj)
|
||
|
|
/// {
|
||
|
|
/// if (obj != null)
|
||
|
|
/// {
|
||
|
|
/// // obj.AsIntPtr() is not IntPtr.Zero
|
||
|
|
/// }
|
||
|
|
/// }
|
||
|
|
/// </code>
|
||
|
|
/// </example>
|
||
|
|
/// </remarks>
|
||
|
|
/// <param name="lhs">The native object to compare with <paramref name="rhs"/>.</param>
|
||
|
|
/// <param name="rhs">The native object to compare with <paramref name="lhs"/>.</param>
|
||
|
|
/// <returns>Returns false if any of these conditions are met:
|
||
|
|
/// - <paramref name="lhs"/> and <paramref name="rhs"/> are both not null and their underlying pointers are equal.
|
||
|
|
/// - <paramref name="lhs"/> is null and <paramref name="rhs"/>'s underlying pointer is null.
|
||
|
|
/// - <paramref name="rhs"/> is null and <paramref name="lhs"/>'s underlying pointer is null.
|
||
|
|
/// - Both <paramref name="lhs"/> and <paramref name="rhs"/> are null.
|
||
|
|
///
|
||
|
|
/// Returns true otherwise.
|
||
|
|
/// </returns>
|
||
|
|
public static bool operator !=(ArCameraConfig? lhs, ArCameraConfig? rhs) => !(lhs == rhs);
|
||
|
|
|
||
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
||
|
|
[DllImport("arcore_sdk_c", EntryPoint = "ArCameraConfig_create")]
|
||
|
|
static extern void Create(ArSession session, out ArCameraConfig value);
|
||
|
|
|
||
|
|
[DllImport("arcore_sdk_c", EntryPoint = "ArCameraConfig_destroy")]
|
||
|
|
static extern void Destroy(ArCameraConfig self);
|
||
|
|
|
||
|
|
[DllImport("arcore_sdk_c", EntryPoint = "ArCameraConfig_getCameraId")]
|
||
|
|
static extern void GetCameraId(ArSession session, ArCameraConfig self, out ArString valueOut);
|
||
|
|
|
||
|
|
[DllImport("arcore_sdk_c", EntryPoint = "ArCameraConfig_getDepthSensorUsage")]
|
||
|
|
static extern void GetDepthSensorUsage(ArSession session, ArCameraConfig self, out ArCameraConfigDepthSensorUsage valueOut);
|
||
|
|
|
||
|
|
[DllImport("arcore_sdk_c", EntryPoint = "ArCameraConfig_getFacingDirection")]
|
||
|
|
static extern void GetFacingDirection(ArSession session, ArCameraConfig self, out ArCameraConfigFacingDirection valueOut);
|
||
|
|
|
||
|
|
[DllImport("arcore_sdk_c", EntryPoint = "ArCameraConfig_getFpsRange")]
|
||
|
|
static extern void GetFpsRange(ArSession session, ArCameraConfig self, out int minFps, out int maxFps);
|
||
|
|
|
||
|
|
[DllImport("arcore_sdk_c", EntryPoint = "ArCameraConfig_getImageDimensions")]
|
||
|
|
static extern void GetImageDimensions(ArSession session, ArCameraConfig self, out int width, out int height);
|
||
|
|
|
||
|
|
[DllImport("arcore_sdk_c", EntryPoint = "ArCameraConfig_getTextureDimensions")]
|
||
|
|
static extern void GetTextureDimensions(ArSession session, ArCameraConfig self, out int width, out int height);
|
||
|
|
#else
|
||
|
|
static void Create(ArSession session, out ArCameraConfig value) => value = default;
|
||
|
|
|
||
|
|
static void Destroy(ArCameraConfig self) { }
|
||
|
|
|
||
|
|
static void GetCameraId(ArSession session, ArCameraConfig self, out ArString valueOut) => valueOut = default;
|
||
|
|
|
||
|
|
static void GetDepthSensorUsage(ArSession session, ArCameraConfig self, out ArCameraConfigDepthSensorUsage valueOut) =>
|
||
|
|
valueOut = default;
|
||
|
|
|
||
|
|
static void GetFacingDirection(ArSession session, ArCameraConfig self, out ArCameraConfigFacingDirection valueOut) =>
|
||
|
|
valueOut = default;
|
||
|
|
|
||
|
|
static void GetFpsRange(ArSession session, ArCameraConfig self, out int minFps, out int maxFps)
|
||
|
|
{
|
||
|
|
minFps = default;
|
||
|
|
maxFps = default;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void GetImageDimensions(ArSession session, ArCameraConfig self, out int width, out int height)
|
||
|
|
{
|
||
|
|
width = default;
|
||
|
|
height = default;
|
||
|
|
}
|
||
|
|
|
||
|
|
static void GetTextureDimensions(ArSession session, ArCameraConfig self, out int width, out int height)
|
||
|
|
{
|
||
|
|
width = default;
|
||
|
|
height = default;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Extensions to the [XRCameraConfiguration](xref:UnityEngine.XR.ARSubsystems.XRCameraConfiguration) object.
|
||
|
|
/// </summary>
|
||
|
|
public static class XRCameraConfigurationExtensions
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// Gets <paramref name="cameraConfiguration"/> as an ARCore <see cref="ArCameraConfig"/>.
|
||
|
|
/// </summary>
|
||
|
|
/// <remarks>
|
||
|
|
/// > [!IMPORTANT]
|
||
|
|
/// > Do not <see cref="ArCameraConfig.Dispose"/> the returned <see cref="ArCameraConfig"/>.
|
||
|
|
/// </remarks>
|
||
|
|
/// <param name="cameraConfiguration">The
|
||
|
|
/// [XRCameraConfiguration](xref:UnityEngine.XR.ARSubsystems.XRCameraConfiguration) being extended.</param>
|
||
|
|
/// <returns>Returns the ARCore-specific representation of <paramref name="cameraConfiguration"/>.</returns>
|
||
|
|
public static ArCameraConfig AsArCameraConfig(this XRCameraConfiguration cameraConfiguration) =>
|
||
|
|
ArCameraConfig.FromIntPtr(cameraConfiguration.nativeConfigurationHandle);
|
||
|
|
}
|
||
|
|
}
|