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");
}
}
}