PinchDetector.cs
4.4 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
/******************************************************************************
* Copyright (C) Leap Motion, Inc. 2011-2017. *
* Leap Motion proprietary and confidential. *
* *
* Use subject to the terms of the Leap Motion SDK Agreement available at *
* https://developer.leapmotion.com/sdk_agreement, or another agreement *
* between Leap Motion and you, your company or other organization. *
******************************************************************************/
using UnityEngine;
using Leap.Unity.Attributes;
using UnityEngine.Serialization;
namespace Leap.Unity {
/// <summary>
/// A basic utility class to aid in creating pinch based actions. Once linked with a HandModelBase, it can
/// be used to detect pinch gestures that the hand makes.
/// </summary>
public class PinchDetector : AbstractHoldDetector {
protected const float MM_TO_M = 0.001f;
[Tooltip("The distance at which to enter the pinching state.")]
[Header("Distance Settings")]
[MinValue(0)]
[Units("meters")]
[FormerlySerializedAs("_activatePinchDist")]
public float ActivateDistance = .03f; //meters
[Tooltip("The distance at which to leave the pinching state.")]
[MinValue(0)]
[Units("meters")]
[FormerlySerializedAs("_deactivatePinchDist")]
public float DeactivateDistance = .04f; //meters
public bool IsPinching { get { return this.IsHolding; } }
public bool DidStartPinch { get { return this.DidStartHold; } }
public bool DidEndPinch { get { return this.DidRelease; } }
protected bool _isPinching = false;
protected float _lastPinchTime = 0.0f;
protected float _lastUnpinchTime = 0.0f;
protected Vector3 _pinchPos;
protected Quaternion _pinchRotation;
protected virtual void OnValidate() {
ActivateDistance = Mathf.Max(0, ActivateDistance);
DeactivateDistance = Mathf.Max(0, DeactivateDistance);
//Activate value cannot be less than deactivate value
if (DeactivateDistance < ActivateDistance) {
DeactivateDistance = ActivateDistance;
}
}
protected override void ensureUpToDate() {
if (Time.frameCount == _lastUpdateFrame) {
return;
}
_lastUpdateFrame = Time.frameCount;
_didChange = false;
Hand hand = _handModel.GetLeapHand();
if (hand == null || !_handModel.IsTracked) {
changeState(false);
return;
}
_distance = hand.PinchDistance * MM_TO_M;
_rotation = hand.Basis.CalculateRotation();
_position = ((hand.Fingers[0].TipPosition + hand.Fingers[1].TipPosition) * .5f).ToVector3();
if (IsActive) {
if (_distance > DeactivateDistance) {
changeState(false);
//return;
}
} else {
if (_distance < ActivateDistance) {
changeState(true);
}
}
if (IsActive) {
_lastPosition = _position;
_lastRotation = _rotation;
_lastDistance = _distance;
_lastDirection = _direction;
_lastNormal = _normal;
}
if (ControlsTransform) {
transform.position = _position;
transform.rotation = _rotation;
}
}
#if UNITY_EDITOR
protected override void OnDrawGizmos () {
if (ShowGizmos && _handModel != null && _handModel.IsTracked) {
Color centerColor = Color.clear;
Vector3 centerPosition = Vector3.zero;
Quaternion circleRotation = Quaternion.identity;
if (IsHolding) {
centerColor = Color.green;
centerPosition = Position;
circleRotation = Rotation;
} else {
Hand hand = _handModel.GetLeapHand();
if (hand != null) {
Finger thumb = hand.Fingers[0];
Finger index = hand.Fingers[1];
centerColor = Color.red;
centerPosition = ((thumb.Bone(Bone.BoneType.TYPE_DISTAL).NextJoint + index.Bone(Bone.BoneType.TYPE_DISTAL).NextJoint) / 2).ToVector3();
circleRotation = hand.Basis.CalculateRotation();
}
}
Vector3 axis;
float angle;
circleRotation.ToAngleAxis(out angle, out axis);
Utils.DrawCircle(centerPosition, axis, ActivateDistance / 2, centerColor);
Utils.DrawCircle(centerPosition, axis, DeactivateDistance / 2, Color.blue);
}
}
#endif
}
}