diff options
Diffstat (limited to 'src/grail-gestures.c')
| -rw-r--r-- | src/grail-gestures.c | 60 |
1 files changed, 37 insertions, 23 deletions
diff --git a/src/grail-gestures.c b/src/grail-gestures.c index 04ff976..c743544 100644 --- a/src/grail-gestures.c +++ b/src/grail-gestures.c | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | 25 | ||
| 26 | static const float FM_SN[DIM_FM] = { 1000, 1000, 200, 1000 }; | 26 | static const float FM_SN[DIM_FM] = { 1000, 1000, 200, 1000 }; |
| 27 | static const float FM_BAR[DIM_FM] = { 50, 50, 30, 50 }; | 27 | static const float FM_BAR[DIM_FM] = { 50, 50, 30, 50 }; |
| 28 | static const grail_time_t SAMPLE_MS = 10; | ||
| 29 | static const float EPS = 1e-5; | ||
| 28 | 30 | ||
| 29 | static void compute_position(float *x, float *y, | 31 | static void compute_position(float *x, float *y, |
| 30 | const struct touch_frame *frame) | 32 | const struct touch_frame *frame) |
| @@ -95,30 +97,39 @@ static float move_filter(const struct filter_model *m, float val) | |||
| 95 | return val; | 97 | return val; |
| 96 | } | 98 | } |
| 97 | 99 | ||
| 98 | static void move_reset(struct move_model *m, int i, float val) | 100 | static void move_reset(struct move_model *m, int i, float x, grail_time_t t) |
| 99 | { | 101 | { |
| 100 | struct filter_model *fm = &m->fm[i]; | 102 | struct filter_model *fm = &m->fm[i]; |
| 101 | fm->raw_delta = 0; | 103 | fm->raw_delta = 0; |
| 102 | fm->action_delta = 0; | 104 | fm->action_delta = 0; |
| 103 | fm->value = val; | 105 | fm->velocity = 0; |
| 104 | fm->original = val; | 106 | fm->value = x; |
| 107 | fm->original = x; | ||
| 108 | fm->sample = x; | ||
| 109 | fm->sample_ms = t; | ||
| 105 | m->tickle &= ~(1 << i); | 110 | m->tickle &= ~(1 << i); |
| 106 | m->active &= ~(1 << i); | 111 | m->active &= ~(1 << i); |
| 107 | } | 112 | } |
| 108 | 113 | ||
| 109 | static void move_update(struct move_model *m, int i, float val) | 114 | static void move_update(struct move_model *m, int i, float x, grail_time_t t) |
| 110 | { | 115 | { |
| 111 | struct filter_model *fm = &m->fm[i]; | 116 | struct filter_model *fm = &m->fm[i]; |
| 112 | fm->raw_delta = val - fm->value; | 117 | float dt = t - fm->sample_ms; |
| 118 | fm->raw_delta = x - fm->value; | ||
| 113 | fm->action_delta = fm->raw_delta; | 119 | fm->action_delta = fm->raw_delta; |
| 114 | fm->value = val; | 120 | fm->velocity = dt > EPS ? (x - fm->sample) / dt : 0; |
| 115 | if (fabs(fm->raw_delta) > 0.5) | 121 | fm->value = x; |
| 122 | if (dt > SAMPLE_MS) { | ||
| 123 | fm->sample = x; | ||
| 124 | fm->sample_ms = t; | ||
| 125 | } | ||
| 126 | if (fabs(fm->raw_delta) > EPS) | ||
| 116 | m->tickle |= (1 << i); | 127 | m->tickle |= (1 << i); |
| 117 | else | 128 | else |
| 118 | m->tickle &= ~(1 << i); | 129 | m->tickle &= ~(1 << i); |
| 119 | if (m->active & (1 << i)) | 130 | if (m->active & (1 << i)) |
| 120 | return; | 131 | return; |
| 121 | fm->action_delta = val - fm->original; | 132 | fm->action_delta = x - fm->original; |
| 122 | if (fabs(fm->action_delta) > fm->bar) | 133 | if (fabs(fm->action_delta) > fm->bar) |
| 123 | m->active |= (1 << i); | 134 | m->active |= (1 << i); |
| 124 | else | 135 | else |
| @@ -148,24 +159,25 @@ void gru_motion(struct grail *ge, | |||
| 148 | { | 159 | { |
| 149 | struct gesture_recognizer *gru = ge->gru; | 160 | struct gesture_recognizer *gru = ge->gru; |
| 150 | struct move_model *m = &gru->move; | 161 | struct move_model *m = &gru->move; |
| 162 | grail_time_t t = frame->time; | ||
| 151 | float x, y, r, a; | 163 | float x, y, r, a; |
| 152 | compute_position(&x, &y, frame); | 164 | compute_position(&x, &y, frame); |
| 153 | if (frame->ncreate || frame->ndestroy) { | 165 | if (frame->ncreate || frame->ndestroy) { |
| 154 | r = compute_radius(x, y, frame); | 166 | r = compute_radius(x, y, frame); |
| 155 | a = 0; | 167 | a = 0; |
| 156 | move_reset(m, FM_X, x); | 168 | move_reset(m, FM_X, x, t); |
| 157 | move_reset(m, FM_Y, y); | 169 | move_reset(m, FM_Y, y, t); |
| 158 | move_reset(m, FM_R, r); | 170 | move_reset(m, FM_R, r, t); |
| 159 | move_reset(m, FM_A, a); | 171 | move_reset(m, FM_A, a, t); |
| 160 | m->single = 0; | 172 | m->single = 0; |
| 161 | m->multi = 0; | 173 | m->multi = 0; |
| 162 | } else if (frame->nactive < 2) { | 174 | } else if (frame->nactive < 2) { |
| 163 | r = 0; | 175 | r = 0; |
| 164 | a = 0; | 176 | a = 0; |
| 165 | move_update(m, FM_X, x); | 177 | move_update(m, FM_X, x, t); |
| 166 | move_update(m, FM_Y, y); | 178 | move_update(m, FM_Y, y, t); |
| 167 | move_reset(m, FM_R, r); | 179 | move_reset(m, FM_R, r, t); |
| 168 | move_reset(m, FM_A, a); | 180 | move_reset(m, FM_A, a, t); |
| 169 | m->single = 1; | 181 | m->single = 1; |
| 170 | m->multi = 0; | 182 | m->multi = 0; |
| 171 | } else { | 183 | } else { |
| @@ -176,15 +188,15 @@ void gru_motion(struct grail *ge, | |||
| 176 | a = m->fm[FM_A].value; | 188 | a = m->fm[FM_A].value; |
| 177 | a += compute_rotation(x, y, r, &gru->frame, frame); | 189 | a += compute_rotation(x, y, r, &gru->frame, frame); |
| 178 | a = move_filter(&m->fm[FM_A], a); | 190 | a = move_filter(&m->fm[FM_A], a); |
| 179 | move_update(m, FM_X, x); | 191 | move_update(m, FM_X, x, t); |
| 180 | move_update(m, FM_Y, y); | 192 | move_update(m, FM_Y, y, t); |
| 181 | move_update(m, FM_R, r); | 193 | move_update(m, FM_R, r, t); |
| 182 | move_update(m, FM_A, a); | 194 | move_update(m, FM_A, a, t); |
| 183 | m->single = 0; | 195 | m->single = 0; |
| 184 | m->multi = 1; | 196 | m->multi = 1; |
| 185 | } | 197 | } |
| 186 | m->ntouch = frame->nactive; | 198 | m->ntouch = frame->nactive; |
| 187 | m->time = frame->time; | 199 | m->time = t; |
| 188 | } | 200 | } |
| 189 | 201 | ||
| 190 | void gru_event(struct grail *ge, int gid, | 202 | void gru_event(struct grail *ge, int gid, |
| @@ -195,8 +207,10 @@ void gru_event(struct grail *ge, int gid, | |||
| 195 | prop, nprop, 0); | 207 | prop, nprop, 0); |
| 196 | } | 208 | } |
| 197 | 209 | ||
| 198 | void gru_end(struct grail *ge, int gid, const struct move_model *m) | 210 | void gru_end(struct grail *ge, int gid, const struct move_model *m, |
| 211 | const grail_prop_t *prop, int nprop) | ||
| 199 | { | 212 | { |
| 200 | gin_gid_end(ge, gid, m->fm[FM_X].value, m->fm[FM_Y].value, m->ntouch); | 213 | gin_gid_end(ge, gid, m->fm[FM_X].value, m->fm[FM_Y].value, m->ntouch, |
| 214 | prop, nprop); | ||
| 201 | } | 215 | } |
| 202 | 216 | ||
