using System; using Unity.Collections; using UnityEngine.SubsystemsImplementation; namespace UnityEngine.XR.ARSubsystems { /// /// Defines an interface for interacting with human body functionality. /// public class XRHumanBodySubsystem : TrackingSubsystem { #if DEVELOPMENT_BUILD || UNITY_EDITOR ValidationUtility m_ValidationUtility = new(); #endif /// /// Whether 2D human body pose estimation is requested. /// /// /// true if 2D human body pose estimation is requested. Otherwise, false. /// public bool pose2DRequested { get => provider.pose2DRequested; set => provider.pose2DRequested = value; } /// /// Whether 2D human body pose estimation is enabled. /// /// /// true if 2D human body pose estimation is enabled. Otherwise, false. /// public bool pose2DEnabled => provider.pose2DEnabled; /// /// Whether 3D human body pose estimation is requested. /// /// /// true if 3D human body pose estimation is requested. Otherwise, false. /// public bool pose3DRequested { get => provider.pose3DRequested; set => provider.pose3DRequested = value; } /// /// Whether 3D human body pose estimation is enabled. /// /// /// true if 3D human body pose estimation is enabled. Otherwise, false. /// public bool pose3DEnabled => provider.pose3DEnabled; /// /// Whether 3D human body scale estimation is requested. /// /// /// true if 3D human body scale estimation is requested. Otherwise, false. /// public bool pose3DScaleEstimationRequested { get => provider.pose3DScaleEstimationRequested; set => provider.pose3DScaleEstimationRequested = value; } /// /// Whether 3D human body scale estimation is enabled. /// /// /// true if 3D human body scale estimation is enabled. Otherwise, false. /// public bool pose3DScaleEstimationEnabled => provider.pose3DScaleEstimationEnabled; /// /// Construct the subsystem by creating the functionality provider. /// public XRHumanBodySubsystem() { } /// /// Query the provider for the trackable changes. /// /// The memory allocator to use for allocating the arrays. /// /// The trackable human body changes. /// public override TrackableChanges GetChanges(Allocator allocator) { var changes = provider.GetChanges(XRHumanBody.defaultValue, allocator); #if DEVELOPMENT_BUILD || UNITY_EDITOR m_ValidationUtility.ValidateAndDisposeIfThrown(changes); #endif return changes; } /// /// Query the provider for the skeleton joints for the requested trackable identifier. /// /// The human body trackable identifier for which to query. /// The memory allocator to use for the returned arrays. /// The array of skeleton joints to update and returns. public void GetSkeleton(TrackableId trackableId, Allocator allocator, ref NativeArray skeleton) => provider.GetSkeleton(trackableId, allocator, ref skeleton); /// /// Gets the human body pose 2D joints for the current frame. /// /// The allocator to use for the returned array memory. /// /// The array of body pose 2D joints. /// /// /// The returned array can be empty if the system is not enabled for human body pose 2D or if the system /// does not detect a human in the camera image. /// /// Thrown if the implementation does not support human body /// pose 2D. public NativeArray GetHumanBodyPose2DJoints(Allocator allocator) => provider.GetHumanBodyPose2DJoints( default, Screen.width, Screen.height, Screen.orientation, allocator); /// /// Register the descriptor for the human body subsystem implementation. /// /// The human body subsystem implementation construction information. /// /// /// true if the descriptor was registered. Otherwise, false. /// [Obsolete("XRHumanBodySubsystem.Register(XRHumanBodySubsystemCinfo) has been deprecated in AR Foundation version 6.0. Use XRHumanBodySubsystemDescriptor.Register(XRHumanBodySubsystemDescriptor.Cinfo) instead.")] public static bool Register(XRHumanBodySubsystemCinfo humanBodySubsystemCinfo) { var humanBodySubsystemInfo = new XRHumanBodySubsystemDescriptor.Cinfo() { id = humanBodySubsystemCinfo.id, providerType = humanBodySubsystemCinfo.providerType, subsystemTypeOverride = humanBodySubsystemCinfo.subsystemTypeOverride, supportsHumanBody2D = humanBodySubsystemCinfo.supportsHumanBody2D, supportsHumanBody3D = humanBodySubsystemCinfo.supportsHumanBody3D, supportsHumanBody3DScaleEstimation = humanBodySubsystemCinfo.supportsHumanBody3DScaleEstimation }; XRHumanBodySubsystemDescriptor.Register(humanBodySubsystemInfo); return true; } /// /// The provider which will service the . /// public abstract class Provider : SubsystemProvider { /// /// Property to be implemented by the provider to set whether human body pose 2D estimation is requested. /// /// /// true if human body pose 2D estimation has been requested. Otherwise, false. /// /// Thrown when setting the human body pose 2D estimation to /// true if the implementation does not support human body pose 2D estimation. public virtual bool pose2DRequested { get => false; set { if (value) { throw new NotSupportedException("Setting human body pose 2D estimation to enabled is not " + "supported by this implementation"); } } } /// /// Property to be implemented by the provider to get whether human body pose 2D estimation is enabled. /// public virtual bool pose2DEnabled => false; /// /// Property to be implemented by the provider to set whether human body pose 3D estimation is requested. /// /// /// true if the human body pose 3D estimation has been requested. Otherwise, false. /// /// Thrown when setting the human body pose 3D estimation to /// true if the implementation does not support human body pose 3D estimation. public virtual bool pose3DRequested { get => false; set { if (value) { throw new NotSupportedException("Setting human body pose 3D estimation to enabled is not " + "supported by this implementation"); } } } /// /// Method to be implemented by the provider to get whether human body pose 3D estimation is enabled. /// public virtual bool pose3DEnabled => false; /// /// Property to be implemented by the provider to get or set whether 3D human body scale estimation is requested. /// /// /// true if the 3D human body scale estimation is set to the given value. Otherwise, false. /// /// Thrown when setting the 3D human body scale estimation to /// true if the implementation does not support 3D human body scale estimation. public virtual bool pose3DScaleEstimationRequested { get => false; set { if (value) { throw new NotSupportedException("Setting 3D human body scale estimation to enabled is not " + "supported by this implementation"); } } } /// /// Property to be implemented by the provider to get whether 3D human body scale estimation is enabled. /// public virtual bool pose3DScaleEstimationEnabled => false; /// /// Method to be implemented by the provider to query for the set of human body changes. /// /// The default human body. /// The memory allocator to use for the returned trackable changes. /// /// The set of human body changes. /// /// Thrown for platforms that don't support human body pose /// estimation. public abstract TrackableChanges GetChanges(XRHumanBody defaultHumanBody, Allocator allocator); /// /// Method to be implemented by the provider to get the skeleton joints for the requested trackable identifier. /// /// The human body trackable identifier for which to query. /// The memory allocator to use for the returned arrays. /// The array of skeleton joints to update and return. /// Thrown for platforms that don't support human body pose 3D. /// public virtual void GetSkeleton(TrackableId trackableId, Allocator allocator, ref NativeArray skeleton) => throw new NotSupportedException("Skeletons are not supported by this implementation."); /// /// Method to be implemented by the provider to get the human body pose 2D joints for the current frame. /// /// The default value for the body pose 2D joint. /// The width of the screen, in pixels. /// The height of the screen, in pixels. /// The orientation of the device so that the joint positions can be /// adjusted as required. /// The allocator to use for the returned array memory. /// /// The array of body pose 2D joints. /// /// /// The returned array can be empty if the system is not enabled for human body pose 2D or if the system /// does not detect a human in the camera image. /// /// Thrown if the implementation does not support human body /// pose 2D. public virtual NativeArray GetHumanBodyPose2DJoints(XRHumanBodyPose2DJoint defaultHumanBodyPose2DJoint, int screenWidth, int screenHeight, ScreenOrientation screenOrientation, Allocator allocator) => throw new NotSupportedException("Human body pose 2D is not supported by this implementation"); } } }