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
|
#include <stdio.h>
#include "vubars.h"
static void heuristics_getGesture( int const amount, int const off, int const * const values,
int *dxl, int *dyl, int *dxr, int *dyr );
int heuristics_getEnergy( int const amount, int const * const values ) {
int energy = 0;
int i;
for( i = 0; i < amount-1; ++i )
energy += values[i]*values[i+1];
return energy;
}
// Gets the two longest consecutive gestures found
// in frames. -1 in off[ab] means no gesture found
// Here what counts: the bigger abs(dx[ab]), the longer the gesture
// the bigger dy[ab]/dx[ab], the slower the gesture
void heuristics_getGestures( int const amount, int const * const values,
int *offa, int *dxa, int *dya, int *dda,
int *offb, int *dxb, int *dyb, int *ddb )
{
int i, l = 0;
int dxl [ amount ], dyl [ amount ], dxr [ amount ], dyr [ amount ];
// Get the longest gestures for each point - both into left and rite
for( i=0; i<amount; ++i )
heuristics_getGesture( amount, i, values, dxl + i, dyl + i, dxr + i, dyr + i );
// "Sort" gesture by length
*offa = *dxa = *dya = 0;
for( i=0; i<amount; ++i ) {
if( dxr[ i ] > *dxa ) { *offa = i; *dxa = dxr[ i ]; *dya = dyr[ i ]; *dda = 1; }
if( dxl[ i ] > *dxa ) { *offa = i; *dxa = dxl[ i ]; *dya = dyl[ i ]; *dda =-1; }
}
// If no gesture found at all, invalidate off
// and return... second run wouldnt suddenly find a gesture
if( *dxa == 0 ) { *offa = *offb = -1; return; }
// Now clear the best result - this will find us the second best result
i = *offa;
if( *dda == 1 ) {
for( i=*offa; i < *offa + dxr[ *offa ]; ++i )
dxr[ i ] = 0;
} else {
for( i=*offa; i > *offa - dxl[ *offa ]; --i )
dxl[ i ] = 0;
}
// "Sort" remaining gestures by length
*offb = *dxb = *dyb = 0;
for( i=0; i<amount; ++i ) {
if( dxr[ i ] > *dxb ) { *offb = i; *dxb = dxr[ i ]; *dyb = dyr[ i ]; *ddb = 1;}
if( dxl[ i ] > *dxb ) { *offb = i; *dxb = -dxl[ i ]; *dyb = dyl[ i ]; *ddb =-1;}
}
// If no secondary gesture found, invalidate off
if( *dxb == 0 ) *offb = -1;
}
static void heuristics_getGesture( int const amount, int const off, int const * const values,
int * const dxl, int * const dyl, int * const dxr, int * const dyr )
{
int i;
// Initialize as "nothing happened"
*dxl = *dxr = *dyl = *dyr = 0;
// if this didn't peak in last frame, we're not starting
// a gesture here.
if( values[off] != VU_PEAK ) return;
if( off > 0 ) *dyl = values[off]-values[off-1];
if( off < amount-1 ) *dyr = values[off]-values[off+1];
if( !*dyl && !*dyr ) return;
// Depending on where this peaks seems to have come from,
// chose direction where to follow it
// try to collect enough monotonic samples and calculate a
// slope. Since our sample peaks, all others cant be larger
if( (*dyl) && (*dyl < *dyr) ) {
(*dxl)++;
for( i=off-1; i>=0; --i ) {
int dy = values[i+1] - values[i];
// If it scrolled out of scope, ignore it
if( !values[i] || dy < 0 ) break;
(*dxl)++;
(*dyl) += dy;
}
} else {
(*dxr)++;
// Do the same when going right
for( i=off+1; i<amount; ++i ) {
int dy = values[i-1] - values[i];
// If it scrolled out of scope, ignore it
if( !values[i] || dy < 0 ) break;
(*dxr)++;
(*dyr) += dy;
}
}
}
|