using System; namespace UnityEngine.XR.ARSubsystems { /// /// Capabilities of a face subsystem implementation. /// [Flags] public enum FaceSubsystemCapabilities { /// /// The subsystem has no capabilities /// None = 0, /// /// The subsystem can produce a Pose for a face. /// Pose = 1 << 0, /// /// The subsystem can generate vertices and triangle indices for a mesh representing a face. /// MeshVerticesAndIndices = 1 << 1, /// /// The subsystem can supply texture coordinates for a face mesh. /// MeshUVs = 1 << 2, /// /// The subsystem can supply normals for a face mesh. /// MeshNormals = 1 << 3, /// /// The subsystem can supply eye tracking data for a face. /// EyeTracking = 1 << 4 } /// /// This struct is an initializer for the creation of a . /// /// /// Face Tracking data provider should create during InitializeOnLoad a descriptor using /// the params here to specify which of the XRFaceSubsystem features it supports. /// public struct FaceSubsystemParams : IEquatable { /// /// The string identifier for a specific implementation. /// public string id { get; set; } /// /// The concrete Type which will be instantiated if Create is called on this subsystem descriptor. /// public Type subsystemImplementationType { get; set; } /// /// Whether the subsystem supports getting a pose for the face. /// public bool supportsFacePose { get { return (m_Capabilities & FaceSubsystemCapabilities.Pose) != 0; } set { if (value) { m_Capabilities |= FaceSubsystemCapabilities.Pose; } else { m_Capabilities &= ~FaceSubsystemCapabilities.Pose; } } } /// /// Whether the subsystem supports getting vertices and triangle indices describing a face mesh. /// public bool supportsFaceMeshVerticesAndIndices { get { return (m_Capabilities & FaceSubsystemCapabilities.MeshVerticesAndIndices) != 0; } set { if (value) { m_Capabilities |= FaceSubsystemCapabilities.MeshVerticesAndIndices; } else { m_Capabilities &= ~FaceSubsystemCapabilities.MeshVerticesAndIndices; } } } /// /// Whether the subsystem supports texture coordinates for the face mesh. /// public bool supportsFaceMeshUVs { get { return (m_Capabilities & FaceSubsystemCapabilities.MeshUVs) != 0; } set { if (value) { m_Capabilities |= FaceSubsystemCapabilities.MeshUVs; } else { m_Capabilities &= ~FaceSubsystemCapabilities.MeshUVs; } } } /// /// Whether the subsystem supports normals for the face mesh. /// public bool supportsFaceMeshNormals { get { return (m_Capabilities & FaceSubsystemCapabilities.MeshNormals) != 0; } set { if (value) { m_Capabilities |= FaceSubsystemCapabilities.MeshNormals; } else { m_Capabilities &= ~FaceSubsystemCapabilities.MeshNormals; } } } /// /// Whether the subsystem supports eye tracking for each detected face. /// public bool supportsEyeTracking { get { return (m_Capabilities & FaceSubsystemCapabilities.EyeTracking) != 0; } set { if (value) { m_Capabilities |= FaceSubsystemCapabilities.EyeTracking; } else { m_Capabilities &= FaceSubsystemCapabilities.EyeTracking; } } } FaceSubsystemCapabilities m_Capabilities; //IEquatable boilerplate public bool Equals(FaceSubsystemParams other) { return (m_Capabilities == other.m_Capabilities) && (id == other.id) && (subsystemImplementationType == other.subsystemImplementationType); } public override bool Equals(object obj) { if (!(obj is FaceSubsystemParams)) { return false; } return Equals((FaceSubsystemParams)obj); } public override int GetHashCode() { unchecked { var hashCode = (id == null) ? 0 : id.GetHashCode(); hashCode = (hashCode * 486187739) + subsystemImplementationType.GetHashCode(); hashCode = (hashCode * 486187739) + ((int)m_Capabilities).GetHashCode(); return hashCode; } } public static bool operator==(FaceSubsystemParams lhs, FaceSubsystemParams rhs) { return lhs.Equals(rhs); } public static bool operator!=(FaceSubsystemParams lhs, FaceSubsystemParams rhs) { return !lhs.Equals(rhs); } } /// /// The descriptor of the that shows which face tracking features are available on that XRSubsystem. /// /// /// You use the Create factory method along with struct to construct and /// register one of these from each face tracking data provider. /// public class XRFaceSubsystemDescriptor : SubsystemDescriptor { XRFaceSubsystemDescriptor(FaceSubsystemParams descriptorParams) { id = descriptorParams.id; subsystemImplementationType = descriptorParams.subsystemImplementationType; supportsFacePose = descriptorParams.supportsFacePose; supportsFaceMeshVerticesAndIndices = descriptorParams.supportsFaceMeshVerticesAndIndices; supportsFaceMeshUVs = descriptorParams.supportsFaceMeshUVs; supportsFaceMeshNormals = descriptorParams.supportsFaceMeshNormals; supportsEyeTracking = descriptorParams.supportsEyeTracking; } /// /// Whether the subsystem can produce a Pose for each detected face. /// public bool supportsFacePose { get; } /// /// Whether the subsystem supports face meshes, and can produce vertices and triangle indices representing a face mesh. /// public bool supportsFaceMeshVerticesAndIndices { get; } /// /// Whether the subsystem supports texture coordinates for each face mesh. /// public bool supportsFaceMeshUVs { get; } /// /// Whether the subsystem supports normals for each face mesh. /// public bool supportsFaceMeshNormals { get; } /// /// Whether the subsystem supports eye tracking for each detected face. /// public bool supportsEyeTracking { get; } /// /// Creates a subsystem descriptor. Used to register an implementation of the . /// /// Parameters describing the . public static void Create(FaceSubsystemParams descriptorParams) { var descriptor = new XRFaceSubsystemDescriptor(descriptorParams); SubsystemRegistration.CreateDescriptor(descriptor); } } }