using System;
using System.Runtime.InteropServices;
namespace UnityEngine.XR.ARSubsystems
{
///
/// Contains information about camera configuration.
///
///
/// Different devices support different camera configurations. This includes
/// image resolution and might include framerate on some platforms.
///
/// The camera image configuration affects the resolution of the image
/// returned by .
///
[StructLayout(LayoutKind.Sequential)]
public struct XRCameraConfiguration : IEquatable
{
Vector2Int m_Resolution;
int m_Framerate;
IntPtr m_NativeConfigurationHandle;
Supported m_DepthSensorSupported;
///
/// The width of the camera resolution.
///
/// The width, in pixels, of the camera resolution.
public int width => m_Resolution.x;
///
/// The height of the camera resolution.
///
/// The height, in pixels, of the camera resolution.
public int height => m_Resolution.y;
///
/// The camera resolution.
///
/// The camera resolution in pixels.
public Vector2Int resolution => m_Resolution;
///
/// The framerate, if this camera configuration specifies one.
///
/// The framerate, if this camera configuration specifies one. Otherwise, null.
///
/// On some platforms, different resolutions might affect the available framerate.
///
public int? framerate => m_Framerate > 0 ? m_Framerate : new int?();
///
/// Whether the configuration supports a depth sensor.
///
/// A value indicating whether a depth sensor is supported, not supported, or if support is unknown.
public Supported depthSensorSupported => m_DepthSensorSupported;
///
/// The platform-dependent handle that contains information required to acquire
/// the native camera configuration.
///
public IntPtr nativeConfigurationHandle => m_NativeConfigurationHandle;
///
/// Constructs a camera configuration.
///
/// The platform-specific native handle that you can use to get the native configuration.
/// The resolution of the camera image.
/// The camera framerate.
/// Whether the configuration supports a depth sensor.
/// Thrown if has a value less than or equal to zero.
public XRCameraConfiguration(IntPtr handle, Vector2Int resolution, int? framerate, Supported depthSensorSupported)
{
if (framerate <= 0)
throw new ArgumentOutOfRangeException(nameof(framerate), framerate, $"{framerate} is not a valid framerate; it must be greater than zero.");
m_NativeConfigurationHandle = handle;
m_Resolution = resolution;
m_Framerate = framerate ?? 0;
m_DepthSensorSupported = depthSensorSupported;
}
///
/// Constructs a camera configuration with a framerate.
///
/// The platform-specific native handle that you can use to get the native configuration.
/// The resolution of the camera image.
/// The camera framerate. Throws ArgumentOutOfRangeException
/// if is less than or equal to zero.
///
/// is set to .
///
public XRCameraConfiguration(IntPtr handle, Vector2Int resolution, int framerate)
{
if (framerate <= 0)
throw new ArgumentOutOfRangeException(nameof(framerate), framerate, $"{framerate} is not a valid framerate; it must be greater than zero.");
m_NativeConfigurationHandle = handle;
m_Resolution = resolution;
m_Framerate = framerate;
m_DepthSensorSupported = Supported.Unknown;
}
///
/// Constructs a camera configuration without a framerate.
///
/// The platform-specific native handle that can be used to get the native configuration.
/// The resolution of the camera image.
///
/// will have no value, and is set to
/// .
///
public XRCameraConfiguration(IntPtr handle, Vector2Int resolution)
{
m_NativeConfigurationHandle = handle;
m_Resolution = resolution;
m_Framerate = 0;
m_DepthSensorSupported = Supported.Unknown;
}
///
/// Converts the configuration to a string, suitable for debug logging.
///
/// A string representation of the configuration.
public override string ToString()
{
var supportsDepthText = depthSensorSupported switch
{
Supported.Unsupported => " no depth sensor",
Supported.Supported => " depth sensor",
_ => "",
};
return $"handle <{m_NativeConfigurationHandle}> {width}x{height}{(framerate.HasValue ? $" at {framerate.Value} Hz" : "")}{supportsDepthText}";
}
///
/// 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() =>
HashCodeUtil.Combine(m_NativeConfigurationHandle.GetHashCode(), m_Resolution.GetHashCode(),
framerate.GetHashCode(), ((int)m_DepthSensorSupported).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 XRCameraConfiguration) && Equals((XRCameraConfiguration)obj));
///
/// Tests for equality.
///
/// The other to compare against.
/// `True` if every field in is equal to this , otherwise false.
public bool Equals(XRCameraConfiguration other) =>
m_Resolution == other.m_Resolution &&
framerate == other.framerate &&
m_NativeConfigurationHandle == other.m_NativeConfigurationHandle &&
m_DepthSensorSupported == other.m_DepthSensorSupported;
///
/// 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 ==(XRCameraConfiguration lhs, XRCameraConfiguration 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 !=(XRCameraConfiguration lhs, XRCameraConfiguration rhs) => !lhs.Equals(rhs);
}
}