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 /src/grail-gestures.c | |
| 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>
Diffstat (limited to 'src/grail-gestures.c')
| -rw-r--r-- | src/grail-gestures.c | 39 |
1 files changed, 21 insertions, 18 deletions
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 | ||
