From da425afd6199995ac7b6f23bf8744a435cc02e23 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Tue, 10 Aug 2010 12:45:52 +0100 Subject: Add property declarations to grail-types Also add accumulated values for delta and velocity properties. Signed-off-by: Henrik Rydberg --- src/gestures-drag.c | 34 ++++++++++++++++++---------- src/gestures-pinch.c | 16 ++++++++++---- src/gestures-rotate.c | 16 ++++++++++---- src/gestures-tapping.c | 2 +- src/grail-gestures.c | 60 +++++++++++++++++++++++++++++++------------------- src/grail-gestures.h | 8 +++++++ src/grail-inserter.c | 6 +++-- src/grail-inserter.h | 3 ++- 8 files changed, 98 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/gestures-drag.c b/src/gestures-drag.c index 3f21041..a02943e 100644 --- a/src/gestures-drag.c +++ b/src/gestures-drag.c @@ -33,6 +33,22 @@ static const int getype[DIM_TOUCH + 1] = { GRAIL_TYPE_DRAG5, }; +static void set_props(struct combo_model *s, const struct move_model *m) +{ + if (m->single) { + s->prop[GRAIL_PROP_DRAG_DX] = m->fm[FM_X].raw_delta; + s->prop[GRAIL_PROP_DRAG_DY] = m->fm[FM_Y].raw_delta; + } else { + s->prop[GRAIL_PROP_DRAG_DX] = m->fm[FM_X].action_delta; + s->prop[GRAIL_PROP_DRAG_DY] = m->fm[FM_Y].action_delta; + } + s->prop[GRAIL_PROP_DRAG_VX] = m->fm[FM_X].velocity; + s->prop[GRAIL_PROP_DRAG_VY] = m->fm[FM_Y].velocity; + s->prop[GRAIL_PROP_DRAG_X] = m->fm[FM_X].value; + s->prop[GRAIL_PROP_DRAG_Y] = m->fm[FM_Y].value; + s->nprop = 6; +} + static const int fm_mask = 0x03; int gru_drag(struct grail *ge, @@ -41,11 +57,11 @@ int gru_drag(struct grail *ge, struct gesture_recognizer *gru = ge->gru; struct combo_model *state = &gru->drag; struct move_model *move = &gru->move; - grail_prop_t prop[DIM_GRAIL_PROP]; int mask = state->active ? (move->active & fm_mask) : fm_mask; if (!move->multi && (!gru->pointer_gesture || !move->single)) { if (state->active) { - gru_end(ge, state->gid, move); + gru_end(ge, state->gid, move, + state->prop, state->nprop); state->active = 0; } return 0; @@ -59,16 +75,10 @@ int gru_drag(struct grail *ge, state->gid = gin_gid_begin(ge, type, PRIO_GESTURE, frame); state->active = 1; } - 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); + if (!move->single && !(move->active & fm_mask)) + return 0; + set_props(state, move); + gru_event(ge, state->gid, move, state->prop, state->nprop); return 1; } diff --git a/src/gestures-pinch.c b/src/gestures-pinch.c index 3b94a66..18007de 100644 --- a/src/gestures-pinch.c +++ b/src/gestures-pinch.c @@ -35,17 +35,25 @@ static const int getype[DIM_TOUCH + 1] = { static const int fm_mask = 0x04; +static void set_props(struct combo_model *s, const struct move_model *m) +{ + s->prop[GRAIL_PROP_PINCH_DR] = m->fm[FM_R].action_delta; + s->prop[GRAIL_PROP_PINCH_VR] = m->fm[FM_R].velocity; + s->prop[GRAIL_PROP_PINCH_R] = m->fm[FM_R].value; + s->nprop = 3; +} + int gru_pinch(struct grail *ge, const struct touch_frame *frame) { struct gesture_recognizer *gru = ge->gru; struct combo_model *state = &gru->pinch; struct move_model *move = &gru->move; - grail_prop_t prop[DIM_GRAIL_PROP]; int mask = state->active ? (move->active & fm_mask) : fm_mask; if (!move->multi) { if (state->active) { - gru_end(ge, state->gid, move); + gru_end(ge, state->gid, move, + state->prop, state->nprop); state->active = 0; } return 0; @@ -61,7 +69,7 @@ int gru_pinch(struct grail *ge, } if (!(move->active & fm_mask)) return 0; - prop[0] = move->fm[FM_R].action_delta; - gru_event(ge, state->gid, move, prop, 1); + set_props(state, move); + gru_event(ge, state->gid, move, state->prop, state->nprop); return 1; } diff --git a/src/gestures-rotate.c b/src/gestures-rotate.c index ebab6d3..52b5004 100644 --- a/src/gestures-rotate.c +++ b/src/gestures-rotate.c @@ -35,17 +35,25 @@ static const int getype[DIM_TOUCH + 1] = { static const int fm_mask = 0x08; +static void set_props(struct combo_model *s, const struct move_model *m) +{ + s->prop[GRAIL_PROP_ROTATE_DA] = m->fm[FM_A].action_delta; + s->prop[GRAIL_PROP_ROTATE_VA] = m->fm[FM_A].velocity; + s->prop[GRAIL_PROP_ROTATE_A] = m->fm[FM_A].value; + s->nprop = 3; +} + int gru_rotate(struct grail *ge, const struct touch_frame *frame) { struct gesture_recognizer *gru = ge->gru; struct combo_model *state = &gru->rotate; struct move_model *move = &gru->move; - grail_prop_t prop[DIM_GRAIL_PROP]; int mask = state->active ? (move->active & fm_mask) : fm_mask; if (!move->multi) { if (state->active) { - gru_end(ge, state->gid, move); + gru_end(ge, state->gid, move, + state->prop, state->nprop); state->active = 0; } return 0; @@ -61,7 +69,7 @@ int gru_rotate(struct grail *ge, } if (!(move->active & fm_mask)) return 0; - prop[0] = move->fm[FM_A].action_delta; - gru_event(ge, state->gid, move, prop, 1); + set_props(state, move); + gru_event(ge, state->gid, move, state->prop, state->nprop); return 1; } diff --git a/src/gestures-tapping.c b/src/gestures-tapping.c index ab86c0f..d8a580f 100644 --- a/src/gestures-tapping.c +++ b/src/gestures-tapping.c @@ -84,7 +84,7 @@ int gru_tapping(struct grail *ge, if (state->status != TAP_END || move->time - state->start < TAP_MIN_GAP_MS) return 0; - prop[0] = move->time - state->start; + prop[GRAIL_PROP_TAP_DT] = move->time - state->start; gin_gid_event(ge, state->gid, move->fm[FM_X].value, move->fm[FM_Y].value, state->ntouch, prop, 1, 1); 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 @@ static const float FM_SN[DIM_FM] = { 1000, 1000, 200, 1000 }; static const float FM_BAR[DIM_FM] = { 50, 50, 30, 50 }; +static const grail_time_t SAMPLE_MS = 10; +static const float EPS = 1e-5; static void compute_position(float *x, float *y, const struct touch_frame *frame) @@ -95,30 +97,39 @@ static float move_filter(const struct filter_model *m, float val) return val; } -static void move_reset(struct move_model *m, int i, float val) +static void move_reset(struct move_model *m, int i, float x, grail_time_t t) { struct filter_model *fm = &m->fm[i]; fm->raw_delta = 0; fm->action_delta = 0; - fm->value = val; - fm->original = val; + fm->velocity = 0; + fm->value = x; + fm->original = x; + fm->sample = x; + fm->sample_ms = t; m->tickle &= ~(1 << i); m->active &= ~(1 << i); } -static void move_update(struct move_model *m, int i, float val) +static void move_update(struct move_model *m, int i, float x, grail_time_t t) { struct filter_model *fm = &m->fm[i]; - fm->raw_delta = val - fm->value; + float dt = t - fm->sample_ms; + fm->raw_delta = x - fm->value; fm->action_delta = fm->raw_delta; - fm->value = val; - if (fabs(fm->raw_delta) > 0.5) + fm->velocity = dt > EPS ? (x - fm->sample) / dt : 0; + fm->value = x; + if (dt > SAMPLE_MS) { + fm->sample = x; + fm->sample_ms = t; + } + if (fabs(fm->raw_delta) > EPS) m->tickle |= (1 << i); else m->tickle &= ~(1 << i); if (m->active & (1 << i)) return; - fm->action_delta = val - fm->original; + fm->action_delta = x - fm->original; if (fabs(fm->action_delta) > fm->bar) m->active |= (1 << i); else @@ -148,24 +159,25 @@ void gru_motion(struct grail *ge, { struct gesture_recognizer *gru = ge->gru; struct move_model *m = &gru->move; + grail_time_t t = frame->time; float x, y, r, a; compute_position(&x, &y, frame); if (frame->ncreate || frame->ndestroy) { r = compute_radius(x, y, frame); a = 0; - move_reset(m, FM_X, x); - move_reset(m, FM_Y, y); - move_reset(m, FM_R, r); - move_reset(m, FM_A, a); + move_reset(m, FM_X, x, t); + move_reset(m, FM_Y, y, t); + move_reset(m, FM_R, r, t); + move_reset(m, FM_A, a, t); m->single = 0; m->multi = 0; } else if (frame->nactive < 2) { r = 0; a = 0; - move_update(m, FM_X, x); - move_update(m, FM_Y, y); - move_reset(m, FM_R, r); - move_reset(m, FM_A, a); + move_update(m, FM_X, x, t); + move_update(m, FM_Y, y, t); + move_reset(m, FM_R, r, t); + move_reset(m, FM_A, a, t); m->single = 1; m->multi = 0; } else { @@ -176,15 +188,15 @@ void gru_motion(struct grail *ge, 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); - move_update(m, FM_Y, y); - move_update(m, FM_R, r); - move_update(m, FM_A, a); + move_update(m, FM_X, x, t); + move_update(m, FM_Y, y, t); + move_update(m, FM_R, r, t); + move_update(m, FM_A, a, t); m->single = 0; m->multi = 1; } m->ntouch = frame->nactive; - m->time = frame->time; + m->time = t; } void gru_event(struct grail *ge, int gid, @@ -195,8 +207,10 @@ void gru_event(struct grail *ge, int gid, prop, nprop, 0); } -void gru_end(struct grail *ge, int gid, const struct move_model *m) +void gru_end(struct grail *ge, int gid, const struct move_model *m, + const grail_prop_t *prop, int nprop) { - gin_gid_end(ge, gid, m->fm[FM_X].value, m->fm[FM_Y].value, m->ntouch); + gin_gid_end(ge, gid, m->fm[FM_X].value, m->fm[FM_Y].value, m->ntouch, + prop, nprop); } diff --git a/src/grail-gestures.h b/src/grail-gestures.h index 6846ed0..658b548 100644 --- a/src/grail-gestures.h +++ b/src/grail-gestures.h @@ -39,10 +39,13 @@ struct filter_model { float raw_delta; float action_delta; + float velocity; float value; float original; float fuzz; float bar; + float sample; + grail_time_t sample_ms; }; struct move_model { @@ -58,9 +61,14 @@ void gru_motion(struct grail *ge, void gru_event(struct grail *ge, int gid, const struct move_model *move, const grail_prop_t *prop, int nprop); +void gru_end(struct grail *ge, int gid, + const struct move_model *move, + const grail_prop_t *prop, int nprop); struct combo_model { int active, gid; + int nprop; + grail_prop_t prop[DIM_GRAIL_PROP]; }; int gru_drag(struct grail *ge, diff --git a/src/grail-inserter.c b/src/grail-inserter.c index 6ba9662..d982808 100644 --- a/src/grail-inserter.c +++ b/src/grail-inserter.c @@ -262,7 +262,8 @@ void gin_gid_event(struct grail *ge, int gid, } void gin_gid_end(struct grail *ge, int gid, - float x, float y, int ntouch) + float x, float y, int ntouch, + const grail_prop_t *prop, int nprop) { struct gesture_inserter *gin = ge->gin; struct gesture_event ev; @@ -274,10 +275,11 @@ void gin_gid_end(struct grail *ge, int gid, if (s->status != GRAIL_STATUS_BEGIN) { ev.status = GRAIL_STATUS_END; ev.ntouch = ntouch; - ev.nprop = 0; + ev.nprop = nprop; ev.time = gin->time; ev.pos.x = x; ev.pos.y = y; + memcpy(ev.prop, prop, nprop * sizeof(grail_prop_t)); gebuf_put(&s->buf, &ev); } s->status = GRAIL_STATUS_END; diff --git a/src/grail-inserter.h b/src/grail-inserter.h index 04626af..a81e431 100644 --- a/src/grail-inserter.h +++ b/src/grail-inserter.h @@ -64,6 +64,7 @@ void gin_gid_event(struct grail *ge, int gid, const grail_prop_t *prop, int nprop, int transient); void gin_gid_end(struct grail *ge, int gid, - float x, float y, int ntouch); + float x, float y, int ntouch, + const grail_prop_t *prop, int nprop); #endif -- cgit v1.2.3