diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2010-08-08 11:07:20 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2010-08-08 12:05:16 +0200 |
| commit | 3c63b1e6cc9eb7379e7687a5faec778c5dbfdc98 (patch) | |
| tree | fad5937d1c16d5d97f704867969fe10880280025 | |
| parent | 301cb7f95a4ca67b42410e65c71ddeefc379cb63 (diff) | |
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 <rydberg@euromail.se>
| -rw-r--r-- | src/gestures-combo.c | 8 | ||||
| -rw-r--r-- | src/gestures-pan.c | 13 | ||||
| -rw-r--r-- | src/gestures-pinch.c | 2 | ||||
| -rw-r--r-- | src/gestures-rotate.c | 2 | ||||
| -rw-r--r-- | src/gestures-tapping.c | 2 | ||||
| -rw-r--r-- | src/grail-gestures.c | 39 | ||||
| -rw-r--r-- | src/grail-gestures.h | 7 |
7 files changed, 43 insertions, 30 deletions
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, | |||
| 61 | } | 61 | } |
| 62 | if (!(move->active & fm_mask)) | 62 | if (!(move->active & fm_mask)) |
| 63 | return 0; | 63 | return 0; |
| 64 | prop[0] = move->fm[FM_X].delta; | 64 | prop[0] = move->fm[FM_X].action_delta; |
| 65 | prop[1] = move->fm[FM_Y].delta; | 65 | prop[1] = move->fm[FM_Y].action_delta; |
| 66 | prop[2] = move->fm[FM_R].delta; | 66 | prop[2] = move->fm[FM_R].action_delta; |
| 67 | prop[3] = move->fm[FM_A].delta; | 67 | prop[3] = move->fm[FM_A].action_delta; |
| 68 | gru_event(ge, state->gid, move, prop, 4); | 68 | gru_event(ge, state->gid, move, prop, 4); |
| 69 | return 1; | 69 | return 1; |
| 70 | } | 70 | } |
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, | |||
| 59 | state->gid = gin_gid_begin(ge, type, PRIO_GESTURE, frame); | 59 | state->gid = gin_gid_begin(ge, type, PRIO_GESTURE, frame); |
| 60 | state->active = 1; | 60 | state->active = 1; |
| 61 | } | 61 | } |
| 62 | if (!(move->active & fm_mask)) | 62 | if (move->single) { |
| 63 | return 0; | 63 | prop[0] = move->fm[FM_X].raw_delta; |
| 64 | prop[0] = move->fm[FM_X].delta; | 64 | prop[1] = move->fm[FM_Y].raw_delta; |
| 65 | prop[1] = move->fm[FM_Y].delta; | 65 | } else { |
| 66 | if (!(move->active & fm_mask)) | ||
| 67 | return 0; | ||
| 68 | prop[0] = move->fm[FM_X].action_delta; | ||
| 69 | prop[1] = move->fm[FM_Y].action_delta; | ||
| 70 | } | ||
| 66 | gru_event(ge, state->gid, move, prop, 2); | 71 | gru_event(ge, state->gid, move, prop, 2); |
| 67 | return 1; | 72 | return 1; |
| 68 | } | 73 | } |
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, | |||
| 61 | } | 61 | } |
| 62 | if (!(move->active & fm_mask)) | 62 | if (!(move->active & fm_mask)) |
| 63 | return 0; | 63 | return 0; |
| 64 | prop[0] = move->fm[FM_R].delta; | 64 | prop[0] = move->fm[FM_R].action_delta; |
| 65 | gru_event(ge, state->gid, move, prop, 1); | 65 | gru_event(ge, state->gid, move, prop, 1); |
| 66 | return 1; | 66 | return 1; |
| 67 | } | 67 | } |
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, | |||
| 61 | } | 61 | } |
| 62 | if (!(move->active & fm_mask)) | 62 | if (!(move->active & fm_mask)) |
| 63 | return 0; | 63 | return 0; |
| 64 | prop[0] = move->fm[FM_A].delta; | 64 | prop[0] = move->fm[FM_A].action_delta; |
| 65 | gru_event(ge, state->gid, move, prop, 1); | 65 | gru_event(ge, state->gid, move, prop, 1); |
| 66 | return 1; | 66 | return 1; |
| 67 | } | 67 | } |
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, | |||
| 86 | return 0; | 86 | return 0; |
| 87 | prop[0] = move->time - state->start; | 87 | prop[0] = move->time - state->start; |
| 88 | gin_gid_event(ge, state->gid, | 88 | gin_gid_event(ge, state->gid, |
| 89 | move->fm[FM_X].val, move->fm[FM_Y].val, state->ntouch, | 89 | move->fm[FM_X].value, move->fm[FM_Y].value, state->ntouch, |
| 90 | prop, 1, 1); | 90 | prop, 1, 1); |
| 91 | state->status = TAP_BEGIN; | 91 | state->status = TAP_BEGIN; |
| 92 | state->ntouch = 0; | 92 | 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, | |||
| 83 | return da; | 83 | return da; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | /* Response-augmented EWMA filter, courtesy of Vojtech Pavlik */ | ||
| 86 | static float move_filter(const struct filter_model *m, float val) | 87 | static float move_filter(const struct filter_model *m, float val) |
| 87 | { | 88 | { |
| 88 | if (val > m->val - m->fuzz / 2 && val < m->val + m->fuzz / 2) | 89 | if (val > m->value - m->fuzz / 2 && val < m->value + m->fuzz / 2) |
| 89 | return m->val; | 90 | return m->value; |
| 90 | if (val > m->val - m->fuzz && val < m->val + m->fuzz) | 91 | if (val > m->value - m->fuzz && val < m->value + m->fuzz) |
| 91 | return (m->val * 3 + val) / 4; | 92 | return (m->value * 3 + val) / 4; |
| 92 | if (val > m->val - m->fuzz * 2 && val < m->val + m->fuzz * 2) | 93 | if (val > m->value - m->fuzz * 2 && val < m->value + m->fuzz * 2) |
| 93 | return (m->val + val) / 2; | 94 | return (m->value + val) / 2; |
| 94 | return val; | 95 | return val; |
| 95 | } | 96 | } |
| 96 | 97 | ||
| 97 | static void move_reset(struct move_model *m, int i, float val) | 98 | static void move_reset(struct move_model *m, int i, float val) |
| 98 | { | 99 | { |
| 99 | struct filter_model *fm = &m->fm[i]; | 100 | struct filter_model *fm = &m->fm[i]; |
| 100 | fm->delta = 0; | 101 | fm->raw_delta = 0; |
| 101 | fm->val = val; | 102 | fm->action_delta = 0; |
| 102 | fm->orig = val; | 103 | fm->value = val; |
| 104 | fm->original = val; | ||
| 103 | m->tickle &= ~(1 << i); | 105 | m->tickle &= ~(1 << i); |
| 104 | m->active &= ~(1 << i); | 106 | m->active &= ~(1 << i); |
| 105 | } | 107 | } |
| @@ -107,19 +109,20 @@ static void move_reset(struct move_model *m, int i, float val) | |||
| 107 | static void move_update(struct move_model *m, int i, float val) | 109 | static void move_update(struct move_model *m, int i, float val) |
| 108 | { | 110 | { |
| 109 | struct filter_model *fm = &m->fm[i]; | 111 | struct filter_model *fm = &m->fm[i]; |
| 110 | fm->delta = val - fm->val; | 112 | fm->raw_delta = val - fm->value; |
| 111 | fm->val = val; | 113 | fm->action_delta = fm->raw_delta; |
| 112 | if (fabs(fm->delta) > 0.5) | 114 | fm->value = val; |
| 115 | if (fabs(fm->raw_delta) > 0.5) | ||
| 113 | m->tickle |= (1 << i); | 116 | m->tickle |= (1 << i); |
| 114 | else | 117 | else |
| 115 | m->tickle &= ~(1 << i); | 118 | m->tickle &= ~(1 << i); |
| 116 | if (m->active & (1 << i)) | 119 | if (m->active & (1 << i)) |
| 117 | return; | 120 | return; |
| 118 | fm->delta = val - fm->orig; | 121 | fm->action_delta = val - fm->original; |
| 119 | if (fabs(fm->delta) > fm->bar) | 122 | if (fabs(fm->action_delta) > fm->bar) |
| 120 | m->active |= (1 << i); | 123 | m->active |= (1 << i); |
| 121 | else | 124 | else |
| 122 | fm->delta = 0; | 125 | fm->action_delta = 0; |
| 123 | } | 126 | } |
| 124 | 127 | ||
| 125 | void gru_init_motion(struct grail *ge) | 128 | void gru_init_motion(struct grail *ge) |
| @@ -170,7 +173,7 @@ void gru_motion(struct grail *ge, | |||
| 170 | y = move_filter(&m->fm[FM_Y], y); | 173 | y = move_filter(&m->fm[FM_Y], y); |
| 171 | r = compute_radius(x, y, frame); | 174 | r = compute_radius(x, y, frame); |
| 172 | r = move_filter(&m->fm[FM_R], r); | 175 | r = move_filter(&m->fm[FM_R], r); |
| 173 | a = m->fm[FM_A].val; | 176 | a = m->fm[FM_A].value; |
| 174 | a += compute_rotation(x, y, r, &gru->frame, frame); | 177 | a += compute_rotation(x, y, r, &gru->frame, frame); |
| 175 | a = move_filter(&m->fm[FM_A], a); | 178 | a = move_filter(&m->fm[FM_A], a); |
| 176 | move_update(m, FM_X, x); | 179 | move_update(m, FM_X, x); |
| @@ -188,12 +191,12 @@ void gru_event(struct grail *ge, int gid, | |||
| 188 | const struct move_model *m, | 191 | const struct move_model *m, |
| 189 | const grail_prop_t *prop, int nprop) | 192 | const grail_prop_t *prop, int nprop) |
| 190 | { | 193 | { |
| 191 | gin_gid_event(ge, gid, m->fm[FM_X].val, m->fm[FM_Y].val, m->ntouch, | 194 | gin_gid_event(ge, gid, m->fm[FM_X].value, m->fm[FM_Y].value, m->ntouch, |
| 192 | prop, nprop, 0); | 195 | prop, nprop, 0); |
| 193 | } | 196 | } |
| 194 | 197 | ||
| 195 | void gru_end(struct grail *ge, int gid, const struct move_model *m) | 198 | void gru_end(struct grail *ge, int gid, const struct move_model *m) |
| 196 | { | 199 | { |
| 197 | gin_gid_end(ge, gid, m->fm[FM_X].val, m->fm[FM_Y].val, m->ntouch); | 200 | gin_gid_end(ge, gid, m->fm[FM_X].value, m->fm[FM_Y].value, m->ntouch); |
| 198 | } | 201 | } |
| 199 | 202 | ||
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 @@ | |||
| 37 | #define FM_A 3 | 37 | #define FM_A 3 |
| 38 | 38 | ||
| 39 | struct filter_model { | 39 | struct filter_model { |
| 40 | float delta, val, orig, fuzz, bar; | 40 | float raw_delta; |
| 41 | float action_delta; | ||
| 42 | float value; | ||
| 43 | float original; | ||
| 44 | float fuzz; | ||
| 45 | float bar; | ||
| 41 | }; | 46 | }; |
| 42 | 47 | ||
| 43 | struct move_model { | 48 | struct move_model { |
