-
Notifications
You must be signed in to change notification settings - Fork 14
/
HandSelector.cpp
93 lines (73 loc) · 3.6 KB
/
HandSelector.cpp
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
#include "HandSelector.h"
using namespace LeapOsvr;
//TODO: Improve this selection process, probably by looking at the hands over time. For example, if a
// candidate hand maintains a higher confidence than the current winner, across several frames of data,
// then that candidate could become the new winner.
////////////////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------------------------------------------------------------------------*/
HandSelector::HandSelector(bool pIsLeft) :
mIsLeft(pIsLeft), mWinningHandId(NoHandFound), mWinningHandIndex(NoHandFound)
{
//do nothing...
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------------------------------------------------------------------------*/
void HandSelector::update(const std::vector<LEAP_HAND> &pHands) {
int candidateIndex = getCandidateIndex(pHands);
if (candidateIndex == NoHandFound) {
setNoWinner();
return;
}
const LEAP_HAND &candidate = pHands[candidateIndex];
if (!canCandidateBecomeWinner(candidate)) {
setNoWinner();
return;
}
mWinningHandId = candidate.id;
mWinningHandIndex = candidateIndex;
}
/*----------------------------------------------------------------------------------------------------*/
const int HandSelector::getBestHandIndex() const {
return mWinningHandIndex;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------------------------------------------------------------------------*/
const int HandSelector::getCandidateIndex(const std::vector<LEAP_HAND> &pHands) const {
int handCount = static_cast<int>(pHands.size());
int candidateIndex = NoHandFound;
for (int i = 0; i < handCount; ++i) {
const LEAP_HAND &hand = pHands[i];
// Ignore invalid/mismatched hands
// Note: I'm not assuming hand.isLeft() implies !hand.isRight() or the reverse, and assuming that
// !hand.isLeft() && !hand.isRight() is possible
bool isValid = true; // the C API doesn't have this, so... always valid?
if (isValid && ((hand.type == eLeapHandType_Left && mIsLeft) || (hand.type == eLeapHandType_Right && !mIsLeft))) {
//Capture first candidate
if (candidateIndex == NoHandFound) {
candidateIndex = i;
continue;
}
//If there are multiple candidates, choose the best one
const LEAP_HAND &prevCandidate = pHands[candidateIndex];
if (isNewCandidateBetterThanPrevious(hand, prevCandidate)) {
candidateIndex = i;
continue;
}
}
}
return candidateIndex;
}
/*----------------------------------------------------------------------------------------------------*/
const bool HandSelector::isNewCandidateBetterThanPrevious(
const LEAP_HAND &pNewCandidate, const LEAP_HAND &pPrevCandidate) const {
return (pNewCandidate.confidence > pPrevCandidate.confidence);
}
/*----------------------------------------------------------------------------------------------------*/
const bool HandSelector::canCandidateBecomeWinner(const LEAP_HAND &pCandidate) const {
return (pCandidate.confidence >= MinimumWinningConfidence / 100.0f);
}
/*----------------------------------------------------------------------------------------------------*/
void HandSelector::setNoWinner() {
mWinningHandId = NoHandFound;
mWinningHandIndex = NoHandFound;
}