using System;
using System.Runtime.InteropServices;
using System.Text;
using Unity.Collections;
namespace UnityEngine.XR.ARSubsystems
{
///
/// Represents the properties included in the camera frame.
///
[Flags]
public enum XROcclusionFrameProperties
{
///
/// No occlusion frame properties are included.
///
None = 0,
///
/// The timestamp of the frame is included.
///
Timestamp = 1 << 0,
///
/// The near and far planes are included.
///
NearFarPlanes = 1 << 1,
///
/// The poses for the frame are included.
///
Poses = 1 << 2,
///
/// The fields of view for the frame are included.
///
Fovs = 1 << 3,
}
///
/// Represents a frame captured by the device camera with included metadata.
///
[StructLayout(LayoutKind.Sequential)]
public struct XROcclusionFrame : IEquatable, IDisposable
{
///
/// The properties that are included in the frame.
///
/// The included properties.
public XROcclusionFrameProperties properties => m_Properties;
XROcclusionFrameProperties m_Properties;
///
/// The timestamp of the frame, in nanoseconds.
///
long m_TimestampNs;
XRNearFarPlanes m_NearFarPlanes;
///
/// Indices are correlated with .
///
NativeArray m_Poses;
///
/// Indices are correlated with .
///
NativeArray m_Fovs;
///
/// Constructor.
///
/// The properties that are included in the frame.
/// The timestamp of the frame, in nanoseconds.
/// The near and far planes.
/// The poses from which the frame was rendered.
/// The fields of view for the frame.
public XROcclusionFrame(
XROcclusionFrameProperties properties,
long timestamp,
XRNearFarPlanes nearFarPlanes,
NativeArray poses,
NativeArray fovs)
{
m_Properties = properties;
m_TimestampNs = timestamp;
m_NearFarPlanes = nearFarPlanes;
m_Poses = poses;
m_Fovs = fovs;
}
///
/// Get the timestamp of the frame, if possible.
///
/// The timestamp of the camera frame, in nanoseconds.
/// if the frame has a timestamp that was output to .
/// Otherwise, .
public bool TryGetTimestamp(out long timestampNs)
{
if ((m_Properties & XROcclusionFrameProperties.Timestamp) != 0)
{
timestampNs = m_TimestampNs;
return true;
}
timestampNs = default;
return false;
}
///
/// Get the near and far planes for the frame, if possible.
///
/// The near and far planes, if this method returns .
/// if the frame has near and far planes that were output to .
/// Otherwise, .
public bool TryGetNearFarPlanes(out XRNearFarPlanes nearFarPlanes)
{
if ((m_Properties & XROcclusionFrameProperties.NearFarPlanes) != 0)
{
nearFarPlanes = m_NearFarPlanes;
return true;
}
nearFarPlanes = default;
return false;
}
///
/// Get an array of poses from which the frame was rendered, if possible.
/// Poses are in Unity world space.
///
/// The output array of poses, if this method returns .
/// if the frame has poses that were output to .
/// Otherwise, .
public bool TryGetPoses(out NativeArray poses)
{
if ((m_Properties & XROcclusionFrameProperties.Poses) != 0)
{
poses = m_Poses;
return true;
}
poses = default;
return false;
}
///
/// Get an array of fields of view for the frame if possible.
///
/// The output array of fields of view, if this method returns .
/// if the frame has fields of view that were output to .
/// Otherwise, .
public bool TryGetFovs(out NativeArray fovs)
{
if ((m_Properties & XROcclusionFrameProperties.Fovs) != 0)
{
fovs = m_Fovs;
return true;
}
fovs = default;
return false;
}
///
/// Compares for equality.
///
/// The other to compare against.
/// if the represents the same object.
/// Otherwise, .
public bool Equals(XROcclusionFrame other)
{
return m_Properties == other.m_Properties &&
m_TimestampNs.Equals(other.m_TimestampNs) &&
m_NearFarPlanes.Equals(other.m_NearFarPlanes) &&
m_Poses.Equals(other.m_Poses) &&
m_Fovs.Equals(other.m_Fovs);
}
///
/// Compares for equality.
///
/// An object to compare against.
/// if is an and
/// is also . Otherwise, .
public override bool Equals(object obj)
{
return obj is XROcclusionFrame frame && Equals(frame);
}
///
/// Compares and for equality using .
///
/// The left-hand-side of the comparison.
/// The right-hand-side of the comparison.
/// if compares equal to .
/// Otherwise, .
public static bool operator ==(XROcclusionFrame lhs, XROcclusionFrame rhs)
{
return lhs.Equals(rhs);
}
///
/// Compares and for inequality using .
///
/// The left-hand-side of the comparison.
/// The right-hand-side of the comparison.
/// if compares equal to .
/// Otherwise, .
public static bool operator !=(XROcclusionFrame lhs, XROcclusionFrame rhs)
{
return !lhs.Equals(rhs);
}
///
/// Generates a hash code suitable for use in HashSet and Dictionary.
///
/// A hash of this .
public override int GetHashCode()
{
int hashCode = 486187739;
unchecked
{
hashCode = hashCode * 486187739 + m_TimestampNs.GetHashCode();
hashCode = hashCode * 486187739 + ((int)m_Properties).GetHashCode();
hashCode = hashCode * 486187739 + m_Poses.GetHashCode();
hashCode = hashCode * 486187739 + m_Fovs.GetHashCode();
}
return hashCode;
}
///
/// Generates a string representation of this instance suitable for debugging purposes.
///
/// The string.
public override string ToString()
{
var sb = new StringBuilder();
sb.AppendLine("{");
if ((m_Properties & XROcclusionFrameProperties.Timestamp) != 0)
sb.AppendLine($" TimestampNs: {m_TimestampNs}");
if ((m_Properties & XROcclusionFrameProperties.NearFarPlanes) != 0)
sb.AppendLine($" NearZ: {m_NearFarPlanes.nearZ}\n FarZ: {m_NearFarPlanes.farZ}");
if ((m_Properties & XROcclusionFrameProperties.Poses) != 0)
{
for (var i = 0; i < m_Poses.Length; i++)
{
sb.AppendLine($" Poses[{i}]: {m_Poses[i]}");
}
}
if ((m_Properties & XROcclusionFrameProperties.Fovs) != 0)
{
for (var i = 0; i < m_Fovs.Length; i++)
{
sb.AppendLine($" Fovs[{i}]: {m_Fovs[i]}");
}
}
sb.AppendLine("}");
return sb.ToString();
}
///
/// Dispose native resources associated with this frame, including the native array of display matrices.
///
public void Dispose()
{
if (m_Poses.IsCreated)
m_Poses.Dispose();
if (m_Fovs.IsCreated)
m_Fovs.Dispose();
}
}
}