@@ -86,8 +86,6 @@ public float ExitPinchDistance
86
86
}
87
87
}
88
88
89
- private bool isPinching = false ;
90
-
91
89
/// <summary>
92
90
/// The articulated hands default interactions.
93
91
/// </summary>
@@ -120,8 +118,14 @@ public MixedRealityInteractionMapping[] DefaultInteractions
120
118
new MixedRealityInputActionMapping ( "Teleport Pose" , AxisType . DualAxis , DeviceInputType . ThumbStick ) ,
121
119
} ;
122
120
121
+
122
+ // Internal calculation of what the HandRay should be
123
+ // Useful as a fallback for hand ray data
124
+ protected virtual IHandRay HandRay { get ; } = new HandRay ( ) ;
125
+
123
126
/// <summary>
124
127
/// Calculates whether the current pose allows for pointing/distant interactions.
128
+ /// Equivalent to the HandRay's ShouldShowRay implementation <see cref="HandRay.ShouldShowRay"/>
125
129
/// </summary>
126
130
public bool IsInPointingPose
127
131
{
@@ -168,13 +172,19 @@ protected bool IsInTeleportPose
168
172
169
173
Transform cameraTransform = mainCamera . transform ;
170
174
175
+ Vector3 palmNormal = - palmPose . Up ;
171
176
// We check if the palm up is roughly in line with the camera up
172
- return Vector3 . Dot ( - palmPose . Up , cameraTransform . up ) > 0.6f
177
+ return Vector3 . Dot ( palmNormal , cameraTransform . up ) > 0.6f
173
178
// Thumb must be extended, and middle must be grabbing
174
179
&& ! isThumbGrabbing && isMiddleGrabbing ;
175
180
}
176
181
}
177
182
183
+ /// <summary>
184
+ /// A bool tracking whether the hand definition is pinch or not
185
+ /// </summary>
186
+ private bool isPinching = false ;
187
+
178
188
/// <summary>
179
189
/// Calculates whether the current the current joint pose is selecting (air tap gesture).
180
190
/// </summary>
@@ -206,12 +216,31 @@ public bool IsPinching
206
216
}
207
217
}
208
218
219
+ public bool IsGrabbing => isIndexGrabbing && isMiddleGrabbing ;
220
+
209
221
private bool isIndexGrabbing ;
210
222
private bool isMiddleGrabbing ;
211
223
private bool isThumbGrabbing ;
212
224
225
+ // Velocity internal states
226
+ private float deltaTimeStart ;
227
+ private const int velocityUpdateInterval = 6 ;
228
+ private int frameOn = 0 ;
229
+
230
+ private readonly Vector3 [ ] velocityPositionsCache = new Vector3 [ velocityUpdateInterval ] ;
231
+ private readonly Vector3 [ ] velocityNormalsCache = new Vector3 [ velocityUpdateInterval ] ;
232
+ private Vector3 velocityPositionsSum = Vector3 . zero ;
233
+ private Vector3 velocityNormalsSum = Vector3 . zero ;
234
+
235
+ public Vector3 AngularVelocity { get ; protected set ; }
236
+
237
+ public Vector3 Velocity { get ; protected set ; }
238
+
239
+
213
240
private static readonly ProfilerMarker UpdateHandJointsPerfMarker = new ProfilerMarker ( "[MRTK] ArticulatedHandDefinition.UpdateHandJoints" ) ;
214
241
242
+ #region Hand Definition Update functions
243
+
215
244
/// <summary>
216
245
/// Updates the current hand joints with new data.
217
246
/// </summary>
@@ -257,6 +286,10 @@ public void UpdateCurrentIndexPose(MixedRealityInteractionMapping interactionMap
257
286
258
287
private static readonly ProfilerMarker UpdateCurrentTeleportPosePerfMarker = new ProfilerMarker ( "[MRTK] ArticulatedHandDefinition.UpdateCurrentTeleportPose" ) ;
259
288
289
+ /// <summary>
290
+ /// Updates the MixedRealityInteractionMapping with the lastest teleport pose status and fires an event when appropriate
291
+ /// </summary>
292
+ /// <param name="interactionMapping">The teleport action's interaction mapping.</param>
260
293
public void UpdateCurrentTeleportPose ( MixedRealityInteractionMapping interactionMapping )
261
294
{
262
295
using ( UpdateCurrentTeleportPosePerfMarker . Auto ( ) )
@@ -311,5 +344,80 @@ public void UpdateCurrentTeleportPose(MixedRealityInteractionMapping interaction
311
344
previousReadyToTeleport = isReadyForTeleport ;
312
345
}
313
346
}
347
+
348
+ /// <summary>
349
+ /// Updates the MixedRealityInteractionMapping with the lastest pointer pose status and fires a corresponding pose event.
350
+ /// </summary>
351
+ /// <param name="interactionMapping">The pointer pose's interaction mapping.</param>
352
+ public void UpdatePointerPose ( MixedRealityInteractionMapping interactionMapping )
353
+ {
354
+ if ( ! unityJointPoses . TryGetValue ( TrackedHandJoint . IndexKnuckle , out var knucklePose ) ) return ;
355
+ if ( ! unityJointPoses . TryGetValue ( TrackedHandJoint . Palm , out var palmPose ) ) return ;
356
+
357
+ Vector3 rayPosition = knucklePose . Position ;
358
+ Vector3 palmNormal = - palmPose . Up ;
359
+
360
+ HandRay . Update ( rayPosition , palmNormal , CameraCache . Main . transform , Handedness ) ;
361
+ Ray ray = HandRay . Ray ;
362
+
363
+ MixedRealityPose pointerPose = new MixedRealityPose ( ) ;
364
+ pointerPose . Position = ray . origin ;
365
+ pointerPose . Rotation = Quaternion . LookRotation ( ray . direction ) ;
366
+
367
+ // Update the interaction data source
368
+ interactionMapping . PoseData = pointerPose ;
369
+
370
+ // If our value changed raise it
371
+ if ( interactionMapping . Changed )
372
+ {
373
+ // Raise input system event if it's enabled
374
+ CoreServices . InputSystem ? . RaisePoseInputChanged ( InputSource , Handedness , interactionMapping . MixedRealityInputAction , pointerPose ) ;
375
+ }
376
+ }
377
+
378
+ /// <summary>
379
+ /// Updates the hand definition with its velocity
380
+ /// </summary>
381
+ public void UpdateVelocity ( )
382
+ {
383
+ if ( unityJointPoses . TryGetValue ( TrackedHandJoint . Palm , out var currentPalmPose ) )
384
+ {
385
+ Vector3 palmPosition = currentPalmPose . Position ;
386
+ Vector3 palmNormal = - currentPalmPose . Up ;
387
+
388
+ if ( frameOn < velocityUpdateInterval )
389
+ {
390
+ velocityPositionsCache [ frameOn ] = palmPosition ;
391
+ velocityPositionsSum += velocityPositionsCache [ frameOn ] ;
392
+ velocityNormalsCache [ frameOn ] = palmNormal ;
393
+ velocityNormalsSum += velocityNormalsCache [ frameOn ] ;
394
+ }
395
+ else
396
+ {
397
+ int frameIndex = frameOn % velocityUpdateInterval ;
398
+
399
+ float deltaTime = Time . unscaledTime - deltaTimeStart ;
400
+
401
+ Vector3 newPositionsSum = velocityPositionsSum - velocityPositionsCache [ frameIndex ] + palmPosition ;
402
+ Vector3 newNormalsSum = velocityNormalsSum - velocityNormalsCache [ frameIndex ] + palmNormal ;
403
+
404
+ Velocity = ( newPositionsSum - velocityPositionsSum ) / deltaTime / velocityUpdateInterval ;
405
+
406
+ Quaternion rotation = Quaternion . FromToRotation ( velocityNormalsSum / velocityUpdateInterval , newNormalsSum / velocityUpdateInterval ) ;
407
+ Vector3 rotationRate = rotation . eulerAngles * Mathf . Deg2Rad ;
408
+ AngularVelocity = rotationRate / deltaTime ;
409
+
410
+ velocityPositionsCache [ frameIndex ] = palmPosition ;
411
+ velocityNormalsCache [ frameIndex ] = palmNormal ;
412
+ velocityPositionsSum = newPositionsSum ;
413
+ velocityNormalsSum = newNormalsSum ;
414
+ }
415
+
416
+ deltaTimeStart = Time . unscaledTime ;
417
+ frameOn ++ ;
418
+ }
419
+ }
420
+
421
+ #endregion
314
422
}
315
423
}
0 commit comments