ARHumanBodyManager.cs
9.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
using System;
using System.Collections.Generic;
using Unity.Collections;
using UnityEngine.XR.ARSubsystems;
using UnityEngine.Serialization;
namespace UnityEngine.XR.ARFoundation
{
/// <summary>
/// The manager for the human body subsystem.
/// </summary>
[DisallowMultipleComponent]
[DefaultExecutionOrder(ARUpdateOrder.k_HumanBodyManager)]
[HelpURL(HelpUrls.ApiWithNamespace + nameof(ARHumanBodyManager) + ".html")]
public sealed class ARHumanBodyManager :
#if UNITY_2020_2_OR_NEWER
ARTrackableManager<XRHumanBodySubsystem, XRHumanBodySubsystemDescriptor, XRHumanBodySubsystem.Provider, XRHumanBody, ARHumanBody>
#else
ARTrackableManager<XRHumanBodySubsystem, XRHumanBodySubsystemDescriptor, XRHumanBody, ARHumanBody>
#endif
{
/// <summary>
/// Whether 2D body pose tracking is enabled. This method is obsolete.
/// Use <see cref="pose2DRequested"/>
/// or <see cref="pose2DEnabled"/> instead.
/// </summary>
[Obsolete("Use pose2DEnabled or pose2DRequested instead. 2020-01-14")]
public bool humanBodyPose2DEstimationEnabled
{
get => m_Pose2D;
set => pose2DRequested = value;
}
[SerializeField, FormerlySerializedAs("m_HumanBodyPose2DEstimationEnabled")]
[Tooltip("Whether to estimate the 2D pose for any human bodies detected.")]
bool m_Pose2D = true;
/// <summary>
/// Whether 2D human pose estimation is enabled. While
/// <see cref="pose2DRequested"/> tells you whether 2D pose
/// estimation has been requested, this property tells you
/// whether 2D pose estimation is currently active in the subsystem.
/// </summary>
public bool pose2DEnabled => subsystem?.pose2DEnabled ?? false;
/// <summary>
/// Whether 2D human pose estimation is requested.
/// </summary>
/// <value>
/// <c>true</c> if 2D human pose estimation is requested. Otherwise, <c>false</c>.
/// </value>
public bool pose2DRequested
{
get => subsystem?.pose2DRequested ?? m_Pose2D;
set
{
m_Pose2D = value;
if (enabled && subsystem != null)
{
subsystem.pose2DRequested = value;
}
}
}
/// <summary>
/// Whether 3D body pose tracking is enabled. This method is obsolete.
/// Use <see cref="pose3DEnabled"/> or <see cref="pose3DRequested"/> instead.
/// </summary>
[Obsolete("Use pose3DEnabled or pose3DRequested instead. 2020-01-14")]
public bool humanBodyPose3DEstimationEnabled
{
get => m_Pose3D;
set => pose3DRequested = value;
}
[SerializeField, FormerlySerializedAs("m_HumanBodyPose3DEstimationEnabled")]
[Tooltip("Whether to estimate the 3D pose for any human bodies detected.")]
bool m_Pose3D = true;
/// <summary>
/// Whether 3D human pose estimation is requested.
/// </summary>
/// <value>
/// <c>true</c> if 3D human pose estimation is requested. Otherwise, <c>false</c>.
/// </value>
public bool pose3DRequested
{
get => subsystem?.pose3DRequested ?? m_Pose3D;
set
{
m_Pose3D = value;
if (enabled && subsystem != null)
{
subsystem.pose3DRequested = value;
}
}
}
/// <summary>
/// Whether 3D human pose estimation is enabled.
/// </summary>
public bool pose3DEnabled => subsystem?.pose3DEnabled ?? false;
/// <summary>
/// Whether 3D body pose scale estimation is enabled. This method is obsolete.
/// Use <see cref="pose3DScaleEstimationEnabled"/> or <see cref="pose3DScaleEstimationRequested"/> instead.
/// </summary>
[Obsolete("Use pose3DScaleEstimationRequested or pose3DScaleEstimationRequested instead. 2020-01-14")]
public bool humanBodyPose3DScaleEstimationEnabled
{
get => m_Pose3DScaleEstimation;
set => pose3DScaleEstimationRequested = value;
}
[SerializeField, FormerlySerializedAs("m_HumanBodyPose3DScaleEstimationEnabled")]
[Tooltip("Whether to estimate the 3D pose for any human bodies detected.")]
bool m_Pose3DScaleEstimation = false;
/// <summary>
/// Whether 3D human body scale estimation is requested.
/// </summary>
/// <value>
/// <c>true</c> if 3D human body scale estimation is requested. Otherwise, <c>false</c>.
/// </value>
public bool pose3DScaleEstimationRequested
{
get => subsystem?.pose3DScaleEstimationRequested ?? m_Pose3DScaleEstimation;
set
{
m_Pose3DScaleEstimation = value;
if (enabled && subsystem != null)
{
subsystem.pose3DScaleEstimationRequested = value;
}
}
}
/// <summary>
/// Whether 3D human body scale estimation is enabled.
/// </summary>
public bool pose3DScaleEstimationEnabled => subsystem?.pose3DScaleEstimationEnabled ?? false;
/// <summary>
/// The prefab object to instantiate at the location of the human body origin.
/// </summary>
/// <value>
/// The prefab object to instantiate at the location of the human body origin.
/// </value>
public GameObject humanBodyPrefab { get => m_HumanBodyPrefab; set => m_HumanBodyPrefab = value; }
[SerializeField]
[Tooltip("The prefab to instantiate at the origin for the detected human body if human body pose estimation is enabled.")]
GameObject m_HumanBodyPrefab;
/// <summary>
/// The name for any generated game objects.
/// </summary>
/// <value>
/// The name for any generated game objects.
/// </value>
protected override string gameObjectName => "ARHumanBody";
/// <summary>
/// The event that is fired when a change to the detected human bodies is reported.
/// </summary>
public event Action<ARHumanBodiesChangedEventArgs> humanBodiesChanged;
/// <summary>
/// Gets the prefab object to instantiate at the location of the trackable.
/// </summary>
/// <returns>
/// A game object to instantiate at the location of the trackable, or <c>null</c>.
/// </returns>
protected override GameObject GetPrefab() => m_HumanBodyPrefab;
/// <summary>
/// Get the human body matching the trackable identifier.
/// </summary>
/// <param name="trackableId">The trackable identifier for querying a human body trackable.</param>
/// <returns>
/// The human body trackable, if found. Otherwise, <c>null</c>.
/// </returns>
public ARHumanBody GetHumanBody(TrackableId trackableId) => m_Trackables.TryGetValue(trackableId, out ARHumanBody humanBody) ? humanBody : null;
/// <summary>
/// Gets the human body pose 2D joints for the current frame.
/// </summary>
/// <param name="allocator">The allocator to use for the returned array memory.</param>
/// <returns>
/// The array of body pose 2D joints.
/// </returns>
/// <remarks>
/// The returned array may 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.
/// </remarks>
/// <exception cref="System.NotSupportedException">Thrown if the implementation does not support human body
/// pose 2D.</exception>
public NativeArray<XRHumanBodyPose2DJoint> GetHumanBodyPose2DJoints(Allocator allocator)
=> ((subsystem == null) ? new NativeArray<XRHumanBodyPose2DJoint>(0, allocator)
: subsystem.GetHumanBodyPose2DJoints(allocator));
/// <summary>
/// Callback before the subsystem is started (but after it is created).
/// </summary>
protected override void OnBeforeStart()
{
subsystem.pose2DRequested = m_Pose2D;
subsystem.pose3DRequested = m_Pose3D;
subsystem.pose3DScaleEstimationRequested = m_Pose3DScaleEstimation;
}
/// <summary>
/// Callback as the manager is being destroyed.
/// </summary>
protected override void OnDestroy()
{
base.OnDestroy();
m_Trackables.Clear();
}
/// <summary>
/// Callback after the session relative data has been set to update the skeleton for the human body.
/// </summary>
/// <param name="arBody">The human body trackable being updated.</param>
/// <param name="xrBody">The raw human body data from the subsystem.</param>
protected override void OnAfterSetSessionRelativeData(ARHumanBody arBody, XRHumanBody xrBody)
=> arBody.UpdateSkeleton(subsystem);
/// <summary>
/// Callback when the trackable deltas are being reported.
/// </summary>
/// <param name="added">The list of human bodies added to the set of trackables.</param>
/// <param name="updated">The list of human bodies updated in the set of trackables.</param>
/// <param name="removed">The list of human bodies removed to the set of trackables.</param>
protected override void OnTrackablesChanged(List<ARHumanBody> added, List<ARHumanBody> updated, List<ARHumanBody> removed)
{
if (humanBodiesChanged != null)
{
using (new ScopedProfiler("OnHumanBodiesChanged"))
humanBodiesChanged(new ARHumanBodiesChangedEventArgs(added, updated, removed));
}
}
}
}