summaryrefslogtreecommitdiff
path: root/src/grail-gestures.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-08-07 18:28:29 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-08-07 18:28:29 +0200
commitee4a0c6821a1b79c3d18c6ef6d7ed6d37df74755 (patch)
tree6516f6f92f572a60eca0fe6a43bc93a7f9570a2c /src/grail-gestures.c
parent5b1126b08faa91bbe26d89c63e5c514911088a0a (diff)
gesture: Improved tickle/active logic
Reorganize the mode model to use bitmasks for tickle and active, and refine the tickle logic for each gesture.
Diffstat (limited to 'src/grail-gestures.c')
-rw-r--r--src/grail-gestures.c134
1 files changed, 66 insertions, 68 deletions
diff --git a/src/grail-gestures.c b/src/grail-gestures.c
index 3c95d6f..67ceacf 100644
--- a/src/grail-gestures.c
+++ b/src/grail-gestures.c
@@ -23,12 +23,8 @@
23#include "grail-recognizer.h" 23#include "grail-recognizer.h"
24#include <math.h> 24#include <math.h>
25 25
26static const float SN_MOVE = 200; 26static const float FM_SN[DIM_FM] = { 200, 200, 200, 1000 };
27static const float SN_ZOOM = 200; 27static const float FM_BAR[DIM_FM] = { 50, 50, 40, 50 };
28static const float SN_ROTATE = 200;
29static const float BAR_MOVE = 4;
30static const float BAR_ZOOM = 12;
31static const float BAR_ROTATE = 12;
32 28
33static void compute_position(float *x, float *y, 29static void compute_position(float *x, float *y,
34 const struct touch_frame *frame) 30 const struct touch_frame *frame)
@@ -98,105 +94,107 @@ static float move_filter(const struct filter_model *m, float val)
98 return val; 94 return val;
99} 95}
100 96
101static int move_reset(struct filter_model *m, float val) 97static void move_reset(struct move_model *m, int i, float val)
102{ 98{
103 m->delta = 0; 99 struct filter_model *fm = &m->fm[i];
104 m->tickle = 0; 100 fm->delta = 0;
105 m->active = 0; 101 fm->val = val;
106 m->val = val; 102 fm->orig = val;
107 m->orig = val; 103 m->tickle &= ~(1 << i);
104 m->active &= ~(1 << i);
108} 105}
109 106
110static int move_update(struct filter_model *m, float val) 107static void move_update(struct move_model *m, int i, float val)
111{ 108{
112 float dval = val - m->orig; 109 struct filter_model *fm = &m->fm[i];
113 m->delta = val - m->val; 110 fm->delta = val - fm->val;
114 m->tickle = fabs(m->delta) > 0.5; 111 fm->val = val;
115 m->val = val; 112 if (fabs(fm->delta) > 0.5)
116 if (!m->active) { 113 m->tickle |= (1 << i);
117 if (fabs(dval) > m->bar) 114 else
118 m->active = 1; 115 m->tickle &= ~(1 << i);
119 else 116 if (m->active & (1 << i))
120 m->delta = dval; 117 return;
121 } 118 fm->delta = val - fm->orig;
122 return m->active; 119 if (fabs(fm->delta) > fm->bar)
120 m->active |= (1 << i);
121 else
122 fm->delta = 0;
123} 123}
124 124
125void gru_init_motion(struct grail *ge) 125void gru_init_motion(struct grail *ge)
126{ 126{
127 struct gesture_recognizer *gru = ge->gru; 127 struct gesture_recognizer *gru = ge->gru;
128 struct move_model *state = &gru->move; 128 struct move_model *m = &gru->move;
129 struct grail_coord min, max; 129 struct grail_coord min, max;
130 float D[DIM_FM];
131 int i;
130 grail_get_units(&min, &max, ge); 132 grail_get_units(&min, &max, ge);
131 float x = max.x - min.x; 133 D[FM_X] = max.x - min.x;
132 float y = max.y - min.y; 134 D[FM_Y] = max.y - min.y;
133 float r = sqrt(x * x + y * y); 135 D[FM_R] = sqrt(D[FM_X] * D[FM_X] + D[FM_Y] * D[FM_Y]);
134 state->x.fuzz = x / SN_MOVE; 136 D[FM_A] = D[FM_R];
135 state->y.fuzz = y / SN_MOVE; 137 for (i = 0; i < DIM_FM; i++) {
136 state->r.fuzz = r / SN_ZOOM; 138 m->fm[i].fuzz = D[i] / FM_SN[i];
137 state->a.fuzz = r / SN_ROTATE; 139 m->fm[i].bar = D[i] / FM_BAR[i];
138 state->x.bar = BAR_MOVE * state->x.fuzz; 140 }
139 state->y.bar = BAR_MOVE * state->y.fuzz;
140 state->r.bar = BAR_ZOOM * state->r.fuzz;
141 state->a.bar = BAR_ROTATE * state->a.fuzz;
142 state->multi = 0;
143} 141}
144 142
145void gru_motion(struct grail *ge, 143void gru_motion(struct grail *ge,
146 const struct touch_frame *frame) 144 const struct touch_frame *frame)
147{ 145{
148 struct gesture_recognizer *gru = ge->gru; 146 struct gesture_recognizer *gru = ge->gru;
149 struct move_model *state = &gru->move; 147 struct move_model *m = &gru->move;
150 float x, y, r, a; 148 float x, y, r, a;
151 compute_position(&x, &y, frame); 149 compute_position(&x, &y, frame);
152 if (frame->ncreate || frame->ndestroy) { 150 if (frame->ncreate || frame->ndestroy) {
153 r = compute_radius(x, y, frame); 151 r = compute_radius(x, y, frame);
154 a = 0; 152 a = 0;
155 move_reset(&state->x, x); 153 move_reset(m, FM_X, x);
156 move_reset(&state->y, y); 154 move_reset(m, FM_Y, y);
157 move_reset(&state->r, r); 155 move_reset(m, FM_R, r);
158 move_reset(&state->a, a); 156 move_reset(m, FM_A, a);
159 state->single = 0; 157 m->single = 0;
160 state->multi = 0; 158 m->multi = 0;
161 } else if (frame->nactive < 2) { 159 } else if (frame->nactive < 2) {
162 r = 0; 160 r = 0;
163 a = 0; 161 a = 0;
164 move_update(&state->x, x); 162 move_update(m, FM_X, x);
165 move_update(&state->y, y); 163 move_update(m, FM_Y, y);
166 move_reset(&state->r, r); 164 move_reset(m, FM_R, r);
167 move_reset(&state->a, a); 165 move_reset(m, FM_A, a);
168 state->single = 1; 166 m->single = 1;
169 state->multi = 0; 167 m->multi = 0;
170 } else { 168 } else {
171 x = move_filter(&state->x, x); 169 x = move_filter(&m->fm[FM_X], x);
172 y = move_filter(&state->y, y); 170 y = move_filter(&m->fm[FM_Y], y);
173 r = compute_radius(x, y, frame); 171 r = compute_radius(x, y, frame);
174 r = move_filter(&state->r, r); 172 r = move_filter(&m->fm[FM_R], r);
175 a = state->a.val + compute_rotation(x, y, r, &gru->frame, frame); 173 a = m->fm[FM_A].val;
176 //a = move_filter(&state->a, a); 174 a += compute_rotation(x, y, r, &gru->frame, frame);
177 move_update(&state->x, x); 175 a = move_filter(&m->fm[FM_A], a);
178 move_update(&state->y, y); 176 move_update(m, FM_X, x);
179 move_update(&state->r, r); 177 move_update(m, FM_Y, y);
180 move_update(&state->a, a); 178 move_update(m, FM_R, r);
181 state->single = 0; 179 move_update(m, FM_A, a);
182 state->multi = 1; 180 m->single = 0;
181 m->multi = 1;
183 } 182 }
184 state->ntouch = frame->nactive; 183 m->ntouch = frame->nactive;
185 state->time = frame->time; 184 m->time = frame->time;
186} 185}
187 186
188void gru_event(struct grail *ge, int gid, 187void gru_event(struct grail *ge, int gid,
189 const struct move_model *move, 188 const struct move_model *m,
190 const grail_prop_t *prop, int nprop) 189 const grail_prop_t *prop, int nprop)
191{ 190{
192 gin_gid_event(ge, gid, 191 gin_gid_event(ge, gid, m->fm[FM_X].val, m->fm[FM_Y].val, m->ntouch,
193 move->x.val, move->y.val, move->ntouch,
194 prop, nprop, 192 prop, nprop,
195 GRAIL_STATUS_UPDATE); 193 GRAIL_STATUS_UPDATE);
196} 194}
197 195
198void gru_end(struct grail *ge, int gid, const struct move_model *move) 196void gru_end(struct grail *ge, int gid, const struct move_model *m)
199{ 197{
200 gin_gid_end(ge, gid, move->x.val, move->y.val, move->ntouch); 198 gin_gid_end(ge, gid, m->fm[FM_X].val, m->fm[FM_Y].val, m->ntouch);
201} 199}
202 200