Tanoda
LeapXRPinchLocomotion.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using UnityEngine;
10
11namespace Leap.Unity {
12
15 public class LeapXRPinchLocomotion : MonoBehaviour {
16
17 [Tooltip("Your Leap Hand Provider. Ensure the Pinch Locomotion script " +
18 "is set to execute before this provider in the 'Script Execution Order'")]
20 [Range(0.00f, 50f)]
21 public float pinchThreshold = 25f;
22 [Range(0.0f, 0.2f)]
23 public float momentum = 0.125f;
24 public bool horizontalRotation = true;
25 public bool enableScaling = true;
26
27 bool isLeftPinching, isRightPinching;
28 Vector3 rootA = Vector3.zero, rootB = Vector3.one; // The stationary world-space anchors
29 Vector3 curA = Vector3.zero, curB = Vector3.one; // The dynamic world-space pinch points
30
31 void Update() {
32 Hand left = HandUtils.Get(provider.CurrentFrame, Chirality.Left);
33 Hand right = HandUtils.Get(provider.CurrentFrame, Chirality.Right);
34 bool leftPinching = left != null && left.PinchDistance < pinchThreshold;
35 bool rightPinching = right != null && right.PinchDistance < pinchThreshold;
36
37 if (leftPinching && rightPinching) { // Set Points when Both Pinched
38 curA = left .GetPinchPosition();
39 curB = right.GetPinchPosition();
40
41 if (!isLeftPinching || !isRightPinching) {
42 rootA = curA;
43 rootB = curB;
44 }
45 } else if (leftPinching) { // Set Points when Left Pinched
46 oneHandedPinchMove(left, isLeftPinching, isRightPinching,
47 ref rootA, ref curA, rootB, ref curB);
48 } else if (rightPinching) { // Set Points when Right Pinched
49 oneHandedPinchMove(right, isRightPinching, isLeftPinching,
50 ref rootB, ref curB, rootA, ref curA);
51 } else { // Apply Momentum to Dynamic Points when Unpinched
52 curA = Vector3.Lerp(curA, rootA, momentum);
53 curB = Vector3.Lerp(curB, rootB, momentum);
54 }
55 isLeftPinching = leftPinching;
56 isRightPinching = rightPinching;
57
58 // Transform the root so the (dynamic) cur points match the (stationary) root points
59 Vector3 pivot = ((rootA + rootB) / 2);
60 Vector3 translation = pivot - ((curA + curB) / 2);
61 Quaternion rotation = Quaternion.FromToRotation(Vector3.Scale(new Vector3(1f, horizontalRotation ? 0 : 1f, 1f), curB - curA),
62 Vector3.Scale(new Vector3(1f, horizontalRotation ? 0 : 1f, 1f), rootB - rootA));
63 float scale = (rootA - rootB).magnitude / (curA - curB).magnitude;
64
65 // Apply Translation
66 transform.root.position += translation;
67
68 if (rootA != rootB) {
69 // Apply Rotation
70 Pose curTrans = new Pose(transform.root.position, transform.root.rotation);
71 curTrans = curTrans.Pivot(rotation, pivot);
72 transform.root.position = curTrans.position; transform.root.rotation = curTrans.rotation;
73
74 // Apply Scale about Pivot
75 if (!float.IsNaN(scale) && enableScaling) {
76 transform.root.position = ((transform.root.position - pivot) * scale) + pivot;
77 transform.root.localScale *= scale;
78 }
79 }
80
82 }
83
85 Vector3 residualMomentum = Vector3.zero;
87 void oneHandedPinchMove(Hand thisHand, bool thisIsPinching, bool otherIsPinching,
88 ref Vector3 thisRoot, ref Vector3 thisCur, Vector3 otherRoot, ref Vector3 otherCur) {
89 thisCur = thisHand.GetPinchPosition();
90
91 if (!thisIsPinching || otherIsPinching) {
92 residualMomentum = otherCur - otherRoot;
93 thisRoot = thisCur;
94 } else {
95 otherCur = (otherRoot + (thisCur - thisRoot)) + residualMomentum;
96 }
97 residualMomentum *= 1f - momentum;
98 }
99
100 }
101
102}
The Hand class reports the physical characteristics of a detected hand.
Definition: Hand.cs:26
float PinchDistance
The distance between the thumb and index finger of a pinch hand pose.
Definition: Hand.cs:253
void RetransformFrames()
Retransforms hand data from Leap space to the space of the Unity transform. This is only necessary if...
Ensure this script is on your player object and set to execute before the LeapXRServiceProvider
The LeapXRServiceProvider expands on the standard LeapServiceProvider to account for the offset of th...
A position and rotation. You can multiply two poses; this acts like Matrix4x4 multiplication,...
Definition: Pose.cs:21
Quaternion rotation
Definition: Pose.cs:24
Vector3 position
Definition: Pose.cs:23