From 3c63b1e6cc9eb7379e7687a5faec778c5dbfdc98 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sun, 8 Aug 2010 11:07:20 +0200 Subject: Keep both raw and action delta in move model Accumulated values can be obtained either by using the raw_delta, which is the actual (filtered) change between frames, or by using the action delta, which sums up to the same position, but in a non- linear fashion. Use the raw delta for pointer gestures. Signed-off-by: Henrik Rydberg --- src/gestures-combo.c | 8 ++++---- src/gestures-pan.c | 13 +++++++++---- src/gestures-pinch.c | 2 +- src/gestures-rotate.c | 2 +- src/gestures-tapping.c | 2 +- src/grail-gestures.c | 39 +++++++++++++++++++++------------------ src/grail-gestures.h | 7 ++++++- 7 files changed, 43 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/gestures-combo.c b/src/gestures-combo.c index 6ce6197..5b6de5b 100644 --- a/src/gestures-combo.c +++ b/src/gestures-combo.c @@ -61,10 +61,10 @@ int gru_combo(struct grail *ge, } if (!(move->active & fm_mask)) return 0; - prop[0] = move->fm[FM_X].delta; - prop[1] = move->fm[FM_Y].delta; - prop[2] = move->fm[FM_R].delta; - prop[3] = move->fm[FM_A].delta; + prop[0] = move->fm[FM_X].action_delta; + prop[1] = move->fm[FM_Y].action_delta; + prop[2] = move->fm[FM_R].action_delta; + prop[3] = move->fm[FM_A].action_delta; gru_event(ge, state->gid, move, prop, 4); return 1; } diff --git a/src/gestures-pan.c b/src/gestures-pan.c index b8e1751..c951b78 100644 --- a/src/gestures-pan.c +++ b/src/gestures-pan.c @@ -59,10 +59,15 @@ int gru_pan(struct grail *ge, state->gid = gin_gid_begin(ge, type, PRIO_GESTURE, frame); state->active = 1; } - if (!(move->active & fm_mask)) - return 0; - prop[0] = move->fm[FM_X].delta; - prop[1] = move->fm[FM_Y].delta; + if (move->single) { + prop[0] = move->fm[FM_X].raw_delta; + prop[1] = move->fm[FM_Y].raw_delta; + } else { + if (!(move->active & fm_mask)) + return 0; + prop[0] = move->fm[FM_X].action_delta; + prop[1] = move->fm[FM_Y].action_delta; + } gru_event(ge, state->gid, move, prop, 2); return 1; } diff --git a/src/gestures-pinch.c b/src/gestures-pinch.c index 358718d..62f6601 100644 --- a/src/gestures-pinch.c +++ b/src/gestures-pinch.c @@ -61,7 +61,7 @@ int gru_pinch(struct grail *ge, } if (!(move->active & fm_mask)) return 0; - prop[0] = move->fm[FM_R].delta; + prop[0] = move->fm[FM_R].action_delta; gru_event(ge, state->gid, move, prop, 1); return 1; } diff --git a/src/gestures-rotate.c b/src/gestures-rotate.c index 5db4228..fa0db22 100644 --- a/src/gestures-rotate.c +++ b/src/gestures-rotate.c @@ -61,7 +61,7 @@ int gru_rotate(struct grail *ge, } if (!(move->active & fm_mask)) return 0; - prop[0] = move->fm[FM_A].delta; + prop[0] = move->fm[FM_A].action_delta; gru_event(ge, state->gid, move, prop, 1); return 1; } diff --git a/src/gestures-tapping.c b/src/gestures-tapping.c index 0f9b215..ab86c0f 100644 --- a/src/gestures-tapping.c +++ b/src/gestures-tapping.c @@ -86,7 +86,7 @@ int gru_tapping(struct grail *ge, return 0; prop[0] = move->time - state->start; gin_gid_event(ge, state->gid, - move->fm[FM_X].val, move->fm[FM_Y].val, state->ntouch, + move->fm[FM_X].value, move->fm[FM_Y].value, state->ntouch, prop, 1, 1); state->status = TAP_BEGIN; state->ntouch = 0; diff --git a/src/grail-gestures.c b/src/grail-gestures.c index 3daeaec..eda1d38 100644 --- a/src/grail-gestures.c +++ b/src/grail-gestures.c @@ -83,23 +83,25 @@ static float compute_rotation(float x, float y, float r, return da; } +/* Response-augmented EWMA filter, courtesy of Vojtech Pavlik */ static float move_filter(const struct filter_model *m, float val) { - if (val > m->val - m->fuzz / 2 && val < m->val + m->fuzz / 2) - return m->val; - if (val > m->val - m->fuzz && val < m->val + m->fuzz) - return (m->val * 3 + val) / 4; - if (val > m->val - m->fuzz * 2 && val < m->val + m->fuzz * 2) - return (m->val + val) / 2; + if (val > m->value - m->fuzz / 2 && val < m->value + m->fuzz / 2) + return m->value; + if (val > m->value - m->fuzz && val < m->value + m->fuzz) + return (m->value * 3 + val) / 4; + if (val > m->value - m->fuzz * 2 && val < m->value + m->fuzz * 2) + return (m->value + val) / 2; return val; } static void move_reset(struct move_model *m, int i, float val) { struct filter_model *fm = &m->fm[i]; - fm->delta = 0; - fm->val = val; - fm->orig = val; + fm->raw_delta = 0; + fm->action_delta = 0; + fm->value = val; + fm->original = val; m->tickle &= ~(1 << i); m->active &= ~(1 << i); } @@ -107,19 +109,20 @@ static void move_reset(struct move_model *m, int i, float val) static void move_update(struct move_model *m, int i, float val) { struct filter_model *fm = &m->fm[i]; - fm->delta = val - fm->val; - fm->val = val; - if (fabs(fm->delta) > 0.5) + fm->raw_delta = val - fm->value; + fm->action_delta = fm->raw_delta; + fm->value = val; + if (fabs(fm->raw_delta) > 0.5) m->tickle |= (1 << i); else m->tickle &= ~(1 << i); if (m->active & (1 << i)) return; - fm->delta = val - fm->orig; - if (fabs(fm->delta) > fm->bar) + fm->action_delta = val - fm->original; + if (fabs(fm->action_delta) > fm->bar) m->active |= (1 << i); else - fm->delta = 0; + fm->action_delta = 0; } void gru_init_motion(struct grail *ge) @@ -170,7 +173,7 @@ void gru_motion(struct grail *ge, y = move_filter(&m->fm[FM_Y], y); r = compute_radius(x, y, frame); r = move_filter(&m->fm[FM_R], r); - a = m->fm[FM_A].val; + a = m->fm[FM_A].value; a += compute_rotation(x, y, r, &gru->frame, frame); a = move_filter(&m->fm[FM_A], a); move_update(m, FM_X, x); @@ -188,12 +191,12 @@ void gru_event(struct grail *ge, int gid, const struct move_model *m, const grail_prop_t *prop, int nprop) { - gin_gid_event(ge, gid, m->fm[FM_X].val, m->fm[FM_Y].val, m->ntouch, + gin_gid_event(ge, gid, m->fm[FM_X].value, m->fm[FM_Y].value, m->ntouch, prop, nprop, 0); } void gru_end(struct grail *ge, int gid, const struct move_model *m) { - gin_gid_end(ge, gid, m->fm[FM_X].val, m->fm[FM_Y].val, m->ntouch); + gin_gid_end(ge, gid, m->fm[FM_X].value, m->fm[FM_Y].value, m->ntouch); } diff --git a/src/grail-gestures.h b/src/grail-gestures.h index 3ace580..2acbb6d 100644 --- a/src/grail-gestures.h +++ b/src/grail-gestures.h @@ -37,7 +37,12 @@ #define FM_A 3 struct filter_model { - float delta, val, orig, fuzz, bar; + float raw_delta; + float action_delta; + float value; + float original; + float fuzz; + float bar; }; struct move_model { -- cgit v1.2.3