ExtendedFingerDetector.cs
6.75 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
/******************************************************************************
* 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 System.Collections;
using System;
using Leap.Unity.Attributes;
namespace Leap.Unity {
/**
* Detects when specified fingers are in an extended or non-extended state.
*
* You can specify whether each finger is extended, not extended, or in either state.
* This detector activates when every finger on the observed hand meets these conditions.
*
* If added to a HandModelBase instance or one of its children, this detector checks the
* finger state at the interval specified by the Period variable. You can also specify
* which hand model to observe explicitly by setting handModel in the Unity editor or
* in code.
*
* @since 4.1.2
*/
public class ExtendedFingerDetector : Detector {
/**
* The interval at which to check finger state.
* @since 4.1.2
*/
[Tooltip("The interval in seconds at which to check this detector's conditions.")]
[Units("seconds")]
[MinValue(0)]
public float Period = .1f; //seconds
/**
* The HandModelBase instance to observe.
* Set automatically if not explicitly set in the editor.
* @since 4.1.2
*/
[Tooltip("The hand model to watch. Set automatically if detector is on a hand.")]
public HandModelBase HandModel = null;
/** The required thumb state. */
[Header("Finger States")]
[Tooltip("Required state of the thumb.")]
public PointingState Thumb = PointingState.Either;
/** The required index finger state. */
[Tooltip("Required state of the index finger.")]
public PointingState Index = PointingState.Either;
/** The required middle finger state. */
[Tooltip("Required state of the middle finger.")]
public PointingState Middle = PointingState.Either;
/** The required ring finger state. */
[Tooltip("Required state of the ring finger.")]
public PointingState Ring = PointingState.Either;
/** The required pinky finger state. */
[Tooltip("Required state of the little finger.")]
public PointingState Pinky = PointingState.Either;
/** How many fingers must be extended for the detector to activate. */
[Header("Min and Max Finger Counts")]
[Range(0,5)]
[Tooltip("The minimum number of fingers extended.")]
public int MinimumExtendedCount = 0;
/** The most fingers allowed to be extended for the detector to activate. */
[Range(0, 5)]
[Tooltip("The maximum number of fingers extended.")]
public int MaximumExtendedCount = 5;
/** Whether to draw the detector's Gizmos for debugging. (Not every detector provides gizmos.)
* @since 4.1.2
*/
[Header("")]
[Tooltip("Draw this detector's Gizmos, if any. (Gizmos must be on in Unity edtor, too.)")]
public bool ShowGizmos = true;
private IEnumerator watcherCoroutine;
void OnValidate() {
int required = 0, forbidden = 0;
PointingState[] stateArray = { Thumb, Index, Middle, Ring, Pinky };
for(int i=0; i<stateArray.Length; i++) {
var state = stateArray[i];
switch (state) {
case PointingState.Extended:
required++;
break;
case PointingState.NotExtended:
forbidden++;
break;
default:
break;
}
MinimumExtendedCount = Math.Max(required, MinimumExtendedCount);
MaximumExtendedCount = Math.Min(5 - forbidden, MaximumExtendedCount);
MaximumExtendedCount = Math.Max(required, MaximumExtendedCount);
}
}
void Awake () {
watcherCoroutine = extendedFingerWatcher();
}
void OnEnable () {
StartCoroutine(watcherCoroutine);
}
void OnDisable () {
StopCoroutine(watcherCoroutine);
Deactivate();
}
IEnumerator extendedFingerWatcher() {
Hand hand;
while(true){
bool fingerState = false;
if(HandModel != null && HandModel.IsTracked){
hand = HandModel.GetLeapHand();
if(hand != null){
fingerState = matchFingerState(hand.Fingers[0], Thumb)
&& matchFingerState(hand.Fingers[1], Index)
&& matchFingerState(hand.Fingers[2], Middle)
&& matchFingerState(hand.Fingers[3], Ring)
&& matchFingerState(hand.Fingers[4], Pinky);
int extendedCount = 0;
for (int f = 0; f < 5; f++) {
if (hand.Fingers[f].IsExtended) {
extendedCount++;
}
}
fingerState = fingerState &&
(extendedCount <= MaximumExtendedCount) &&
(extendedCount >= MinimumExtendedCount);
if(HandModel.IsTracked && fingerState){
Activate();
} else if(!HandModel.IsTracked || !fingerState) {
Deactivate();
}
}
} else if(IsActive){
Deactivate();
}
yield return new WaitForSeconds(Period);
}
}
private bool matchFingerState (Finger finger, PointingState requiredState) {
return (requiredState == PointingState.Either) ||
(requiredState == PointingState.Extended && finger.IsExtended) ||
(requiredState == PointingState.NotExtended && !finger.IsExtended);
}
#if UNITY_EDITOR
void OnDrawGizmos () {
if (ShowGizmos && HandModel != null && HandModel.IsTracked) {
PointingState[] state = { Thumb, Index, Middle, Ring, Pinky };
Hand hand = HandModel.GetLeapHand();
int extendedCount = 0;
int notExtendedCount = 0;
for (int f = 0; f < 5; f++) {
Finger finger = hand.Fingers[f];
if (finger.IsExtended) extendedCount++;
else notExtendedCount++;
if (matchFingerState(finger, state[f]) &&
(extendedCount <= MaximumExtendedCount) &&
(extendedCount >= MinimumExtendedCount)) {
Gizmos.color = OnColor;
} else {
Gizmos.color = OffColor;
}
Gizmos.DrawWireSphere(finger.TipPosition.ToVector3(), finger.Width);
}
}
}
#endif
}
/** Defines the settings for comparing extended finger states */
public enum PointingState{Extended, NotExtended, Either}
}