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/grail-gestures.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) (limited to 'src/grail-gestures.c') 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); } -- cgit v1.2.3