Skip to content

Commit d39f98c

Browse files
authored
Assorted perf improvements in hot code paths (#10601)
* Initial perf pass * Update BaseHandVisualizer.cs * Don't call Commands so many times * More inline caching * Return early in pointers that don't depend on OnPreSceneQuery for their interaction state * Update HandJoint.mat * Update hand visualizers for perf considerations * Return correct value for TryGetJoint * Adjust MicrosoftArticulatedHand to be robust to different InputDevice patterns Currently, there are two InputDevices: one with interaction data and one with hand joint data. Going forward, there may only be one 👀 * Update ArticulatedHandDefinition.cs * Update BaseHandVisualizer.cs * Improve RiggedHandLogic for returning early * Add braces * Update casting pattern for readability
1 parent e79bbfc commit d39f98c

File tree

19 files changed

+441
-303
lines changed

19 files changed

+441
-303
lines changed

Assets/MRTK/Core/Definitions/Devices/ArticulatedHandDefinition.cs

Lines changed: 94 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,21 @@ public ArticulatedHandDefinition(IMixedRealityInputSource source, Handedness han
3131
private readonly float cursorBeamBackwardTolerance = 0.5f;
3232
private readonly float cursorBeamUpTolerance = 0.8f;
3333

34-
private Dictionary<TrackedHandJoint, MixedRealityPose> unityJointPoses = new Dictionary<TrackedHandJoint, MixedRealityPose>();
34+
private IDictionary<TrackedHandJoint, MixedRealityPose> unityJointPoseDictionary = new Dictionary<TrackedHandJoint, MixedRealityPose>();
35+
private MixedRealityPose[] unityJointPoses = null;
3536
private MixedRealityPose currentIndexPose = MixedRealityPose.ZeroIdentity;
37+
private Vector3 currentPalmNormal = Vector3.zero;
38+
39+
private const int PalmIndex = (int)TrackedHandJoint.Palm;
40+
private const int ThumbTipIndex = (int)TrackedHandJoint.ThumbTip;
41+
private const int IndexKnuckleIndex = (int)TrackedHandJoint.IndexKnuckle;
42+
private const int IndexTipIndex = (int)TrackedHandJoint.IndexTip;
3643

3744
// Minimum distance between the index and the thumb tip required to enter a pinch
38-
private readonly float minimumPinchDistance = 0.015f;
45+
private const float MinimumPinchDistance = 0.015f;
3946

4047
// Maximum distance between the index and thumb tip required to exit the pinch gesture
41-
private readonly float maximumPinchDistance = 0.1f;
48+
private const float MaximumPinchDistance = 0.1f;
4249

4350
// Default enterPinchDistance value
4451
private float enterPinchDistance = 0.02f;
@@ -52,13 +59,13 @@ public float EnterPinchDistance
5259
get => enterPinchDistance;
5360
set
5461
{
55-
if (value >= minimumPinchDistance && value <= maximumPinchDistance)
62+
if (value >= MinimumPinchDistance && value <= MaximumPinchDistance)
5663
{
5764
enterPinchDistance = value;
5865
}
5966
else
6067
{
61-
Debug.LogError("EnterPinchDistance must be between 0.015 and 0.1, please change Enter Pinch Distance in the Leap Motion Device Manager Profile");
68+
Debug.LogError($"EnterPinchDistance must be between {MinimumPinchDistance} and {MaximumPinchDistance}.");
6269
}
6370
}
6471
}
@@ -75,13 +82,13 @@ public float ExitPinchDistance
7582
get => exitPinchDistance;
7683
set
7784
{
78-
if (value >= minimumPinchDistance && value <= maximumPinchDistance)
85+
if (value >= MinimumPinchDistance && value <= MaximumPinchDistance)
7986
{
8087
exitPinchDistance = value;
8188
}
8289
else
8390
{
84-
Debug.LogError("ExitPinchDistance must be between 0.015 and 0.1, please change Exit Pinch Distance in the Leap Motion Device Manager Profile");
91+
Debug.LogError($"ExitPinchDistance must be between {MinimumPinchDistance} and {MaximumPinchDistance}.");
8592
}
8693
}
8794
}
@@ -131,23 +138,19 @@ public bool IsInPointingPose
131138
{
132139
get
133140
{
134-
MixedRealityPose palmJoint;
135-
if (unityJointPoses.TryGetValue(TrackedHandJoint.Palm, out palmJoint))
141+
if (unityJointPoses != null)
136142
{
137-
Vector3 palmNormal = palmJoint.Rotation * (-1 * Vector3.up);
138-
if (cursorBeamBackwardTolerance >= 0 && CameraCache.Main != null)
143+
if (cursorBeamBackwardTolerance >= 0
144+
&& CameraCache.Main != null
145+
&& Vector3.Dot(currentPalmNormal.normalized, -CameraCache.Main.transform.forward) > cursorBeamBackwardTolerance)
139146
{
140-
if (Vector3.Dot(palmNormal.normalized, -CameraCache.Main.transform.forward) > cursorBeamBackwardTolerance)
141-
{
142-
return false;
143-
}
147+
return false;
144148
}
145-
if (cursorBeamUpTolerance >= 0)
149+
150+
if (cursorBeamUpTolerance >= 0
151+
&& Vector3.Dot(currentPalmNormal, Vector3.up) > cursorBeamUpTolerance)
146152
{
147-
if (Vector3.Dot(palmNormal, Vector3.up) > cursorBeamUpTolerance)
148-
{
149-
return false;
150-
}
153+
return false;
151154
}
152155
}
153156
return !IsInTeleportPose;
@@ -161,7 +164,10 @@ protected bool IsInTeleportPose
161164
{
162165
get
163166
{
164-
if (!unityJointPoses.TryGetValue(TrackedHandJoint.Palm, out var palmPose)) return false;
167+
if (unityJointPoses == null)
168+
{
169+
return false;
170+
}
165171

166172
Camera mainCamera = CameraCache.Main;
167173

@@ -172,9 +178,8 @@ protected bool IsInTeleportPose
172178

173179
Transform cameraTransform = mainCamera.transform;
174180

175-
Vector3 palmNormal = -palmPose.Up;
176181
// We check if the palm up is roughly in line with the camera up
177-
return Vector3.Dot(palmNormal, cameraTransform.up) > 0.6f
182+
return Vector3.Dot(currentPalmNormal, cameraTransform.up) > 0.6f
178183
// Thumb must be extended, and middle must be grabbing
179184
&& !isThumbGrabbing && isMiddleGrabbing;
180185
}
@@ -192,11 +197,9 @@ public bool IsPinching
192197
{
193198
get
194199
{
195-
MixedRealityPose thumbTip;
196-
MixedRealityPose indexTip;
197-
if (unityJointPoses.TryGetValue(TrackedHandJoint.ThumbTip, out thumbTip) && unityJointPoses.TryGetValue(TrackedHandJoint.IndexTip, out indexTip))
200+
if (unityJointPoses != null)
198201
{
199-
float distance = Vector3.Distance(thumbTip.Position, indexTip.Position);
202+
float distance = Vector3.Distance(unityJointPoses[ThumbTipIndex].Position, currentIndexPose.Position);
200203

201204
if (isPinching && distance > ExitPinchDistance)
202205
{
@@ -224,19 +227,18 @@ public bool IsPinching
224227

225228
// Velocity internal states
226229
private float deltaTimeStart;
227-
private const int velocityUpdateInterval = 6;
230+
private const int VelocityUpdateInterval = 6;
228231
private int frameOn = 0;
229232

230-
private readonly Vector3[] velocityPositionsCache = new Vector3[velocityUpdateInterval];
231-
private readonly Vector3[] velocityNormalsCache = new Vector3[velocityUpdateInterval];
233+
private readonly Vector3[] velocityPositionsCache = new Vector3[VelocityUpdateInterval];
234+
private readonly Vector3[] velocityNormalsCache = new Vector3[VelocityUpdateInterval];
232235
private Vector3 velocityPositionsSum = Vector3.zero;
233236
private Vector3 velocityNormalsSum = Vector3.zero;
234237

235238
public Vector3 AngularVelocity { get; protected set; }
236239

237240
public Vector3 Velocity { get; protected set; }
238241

239-
240242
private static readonly ProfilerMarker UpdateHandJointsPerfMarker = new ProfilerMarker("[MRTK] ArticulatedHandDefinition.UpdateHandJoints");
241243

242244
#region Hand Definition Update functions
@@ -246,11 +248,54 @@ public bool IsPinching
246248
/// </summary>
247249
/// <param name="jointPoses">The new joint poses.</param>
248250
public void UpdateHandJoints(Dictionary<TrackedHandJoint, MixedRealityPose> jointPoses)
251+
{
252+
using (UpdateHandJointsPerfMarker.Auto())
253+
{
254+
unityJointPoseDictionary = jointPoses;
255+
_ = unityJointPoseDictionary.TryGetValue(TrackedHandJoint.IndexTip, out currentIndexPose);
256+
if (unityJointPoseDictionary.TryGetValue(TrackedHandJoint.Palm, out MixedRealityPose palmPose))
257+
{
258+
currentPalmNormal = palmPose.Rotation * Vector3.down;
259+
}
260+
261+
if (unityJointPoses == null)
262+
{
263+
unityJointPoses = new MixedRealityPose[ArticulatedHandPose.JointCount];
264+
}
265+
266+
for (int i = 1; i < ArticulatedHandPose.JointCount; i++)
267+
{
268+
unityJointPoseDictionary.TryGetValue((TrackedHandJoint)i, out unityJointPoses[i]);
269+
}
270+
271+
CoreServices.InputSystem?.RaiseHandJointsUpdated(InputSource, Handedness, unityJointPoseDictionary);
272+
}
273+
}
274+
275+
/// <summary>
276+
/// Updates the current hand joints with new data.
277+
/// </summary>
278+
/// <param name="jointPoses">The new joint poses.</param>
279+
public void UpdateHandJoints(MixedRealityPose[] jointPoses)
249280
{
250281
using (UpdateHandJointsPerfMarker.Auto())
251282
{
252283
unityJointPoses = jointPoses;
253-
CoreServices.InputSystem?.RaiseHandJointsUpdated(InputSource, Handedness, unityJointPoses);
284+
285+
if (unityJointPoses == null)
286+
{
287+
return;
288+
}
289+
290+
currentIndexPose = unityJointPoses[IndexTipIndex];
291+
currentPalmNormal = unityJointPoses[PalmIndex].Rotation * Vector3.down;
292+
293+
for (int i = 1; i < ArticulatedHandPose.JointCount; i++)
294+
{
295+
unityJointPoseDictionary[(TrackedHandJoint)i] = unityJointPoses[i];
296+
}
297+
298+
CoreServices.InputSystem?.RaiseHandJointsUpdated(InputSource, Handedness, unityJointPoseDictionary);
254299
}
255300
}
256301

@@ -264,7 +309,7 @@ public void UpdateCurrentIndexPose(MixedRealityInteractionMapping interactionMap
264309
{
265310
using (UpdateCurrentIndexPosePerfMarker.Auto())
266311
{
267-
if (unityJointPoses.TryGetValue(TrackedHandJoint.IndexTip, out currentIndexPose))
312+
if (unityJointPoses != null)
268313
{
269314
// Update the interaction data source
270315
interactionMapping.PoseData = currentIndexPose;
@@ -287,7 +332,7 @@ public void UpdateCurrentIndexPose(MixedRealityInteractionMapping interactionMap
287332
private static readonly ProfilerMarker UpdateCurrentTeleportPosePerfMarker = new ProfilerMarker("[MRTK] ArticulatedHandDefinition.UpdateCurrentTeleportPose");
288333

289334
/// <summary>
290-
/// Updates the MixedRealityInteractionMapping with the lastest teleport pose status and fires an event when appropriate
335+
/// Updates the MixedRealityInteractionMapping with the latest teleport pose status and fires an event when appropriate
291336
/// </summary>
292337
/// <param name="interactionMapping">The teleport action's interaction mapping.</param>
293338
public void UpdateCurrentTeleportPose(MixedRealityInteractionMapping interactionMapping)
@@ -346,32 +391,26 @@ public void UpdateCurrentTeleportPose(MixedRealityInteractionMapping interaction
346391
}
347392

348393
/// <summary>
349-
/// Updates the MixedRealityInteractionMapping with the lastest pointer pose status and fires a corresponding pose event.
394+
/// Updates the MixedRealityInteractionMapping with the latest pointer pose status and fires a corresponding pose event.
350395
/// </summary>
351396
/// <param name="interactionMapping">The pointer pose's interaction mapping.</param>
352397
public void UpdatePointerPose(MixedRealityInteractionMapping interactionMapping)
353398
{
354-
if (!unityJointPoses.TryGetValue(TrackedHandJoint.IndexKnuckle, out var knucklePose)) return;
355-
if (!unityJointPoses.TryGetValue(TrackedHandJoint.Palm, out var palmPose)) return;
399+
if (unityJointPoses == null) return;
356400

357-
Vector3 rayPosition = knucklePose.Position;
358-
Vector3 palmNormal = -palmPose.Up;
401+
Vector3 rayPosition = unityJointPoses[IndexKnuckleIndex].Position;
359402

360-
HandRay.Update(rayPosition, palmNormal, CameraCache.Main.transform, Handedness);
403+
HandRay.Update(rayPosition, currentPalmNormal, CameraCache.Main.transform, Handedness);
361404
Ray ray = HandRay.Ray;
362405

363-
MixedRealityPose pointerPose = new MixedRealityPose();
364-
pointerPose.Position = ray.origin;
365-
pointerPose.Rotation = Quaternion.LookRotation(ray.direction);
366-
367406
// Update the interaction data source
368-
interactionMapping.PoseData = pointerPose;
407+
interactionMapping.PoseData = new MixedRealityPose(ray.origin, Quaternion.LookRotation(ray.direction));
369408

370409
// If our value changed raise it
371410
if (interactionMapping.Changed)
372411
{
373412
// Raise input system event if it's enabled
374-
CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, Handedness, interactionMapping.MixedRealityInputAction, pointerPose);
413+
CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, Handedness, interactionMapping.MixedRealityInputAction, interactionMapping.PoseData);
375414
}
376415
}
377416

@@ -380,35 +419,34 @@ public void UpdatePointerPose(MixedRealityInteractionMapping interactionMapping)
380419
/// </summary>
381420
public void UpdateVelocity()
382421
{
383-
if (unityJointPoses.TryGetValue(TrackedHandJoint.Palm, out var currentPalmPose))
422+
if (unityJointPoses != null)
384423
{
385-
Vector3 palmPosition = currentPalmPose.Position;
386-
Vector3 palmNormal = -currentPalmPose.Up;
424+
Vector3 palmPosition = unityJointPoses[PalmIndex].Position;
387425

388-
if (frameOn < velocityUpdateInterval)
426+
if (frameOn < VelocityUpdateInterval)
389427
{
390428
velocityPositionsCache[frameOn] = palmPosition;
391429
velocityPositionsSum += velocityPositionsCache[frameOn];
392-
velocityNormalsCache[frameOn] = palmNormal;
430+
velocityNormalsCache[frameOn] = currentPalmNormal;
393431
velocityNormalsSum += velocityNormalsCache[frameOn];
394432
}
395433
else
396434
{
397-
int frameIndex = frameOn % velocityUpdateInterval;
435+
int frameIndex = frameOn % VelocityUpdateInterval;
398436

399437
float deltaTime = Time.unscaledTime - deltaTimeStart;
400438

401439
Vector3 newPositionsSum = velocityPositionsSum - velocityPositionsCache[frameIndex] + palmPosition;
402-
Vector3 newNormalsSum = velocityNormalsSum - velocityNormalsCache[frameIndex] + palmNormal;
440+
Vector3 newNormalsSum = velocityNormalsSum - velocityNormalsCache[frameIndex] + currentPalmNormal;
403441

404-
Velocity = (newPositionsSum - velocityPositionsSum) / deltaTime / velocityUpdateInterval;
442+
Velocity = (newPositionsSum - velocityPositionsSum) / deltaTime / VelocityUpdateInterval;
405443

406-
Quaternion rotation = Quaternion.FromToRotation(velocityNormalsSum / velocityUpdateInterval, newNormalsSum / velocityUpdateInterval);
444+
Quaternion rotation = Quaternion.FromToRotation(velocityNormalsSum / VelocityUpdateInterval, newNormalsSum / VelocityUpdateInterval);
407445
Vector3 rotationRate = rotation.eulerAngles * Mathf.Deg2Rad;
408446
AngularVelocity = rotationRate / deltaTime;
409447

410448
velocityPositionsCache[frameIndex] = palmPosition;
411-
velocityNormalsCache[frameIndex] = palmNormal;
449+
velocityNormalsCache[frameIndex] = currentPalmNormal;
412450
velocityPositionsSum = newPositionsSum;
413451
velocityNormalsSum = newNormalsSum;
414452
}

0 commit comments

Comments
 (0)