This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_gesture.c
664 lines (560 loc) · 19.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2010 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
16
License along with this library; if not, write to the Free Software Founation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18
19
20
Sam Lantinga
slouken@libsdl.org
*/
21
22
23
24
25
26
27
28
29
#include "SDL_config.h"
/* General mouse handling code for SDL */
#include "SDL_events.h"
#include "SDL_events_c.h"
#include "SDL_gesture_c.h"
30
31
32
33
34
#include <memory.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
35
//TODO: Replace with malloc
36
37
38
#define MAXPATHSIZE 1024
39
40
41
42
43
44
#define DOLLARNPOINTS 64
#define DOLLARSIZE 256
45
46
#define ENABLE_DOLLAR
47
#define PHI 0.618033989
48
49
50
typedef struct {
float x,y;
51
} SDL_FloatPoint;
52
53
54
55
56
typedef struct {
float length;
int numPoints;
57
58
SDL_FloatPoint p[MAXPATHSIZE];
} SDL_DollarPath;
59
60
typedef struct {
61
SDL_FloatPoint path[DOLLARNPOINTS];
62
unsigned long hash;
63
} SDL_DollarTemplate;
64
65
typedef struct {
66
SDL_GestureID id;
67
68
69
SDL_FloatPoint res;
SDL_FloatPoint centroid;
SDL_DollarPath dollarPath;
70
Uint16 numDownFingers;
71
72
int numDollarTemplates;
73
SDL_DollarTemplate *dollarTemplate;
74
75
SDL_bool recording;
76
} SDL_GestureTouch;
77
78
79
SDL_GestureTouch *SDL_gestureTouch;
int SDL_numGestureTouches = 0;
80
81
SDL_bool recordAll;
82
83
#if 0
static void PrintPath(SDL_FloatPoint *path) {
84
85
86
87
88
89
90
int i;
printf("Path:");
for(i=0;i<DOLLARNPOINTS;i++) {
printf(" (%f,%f)",path[i].x,path[i].y);
}
printf("\n");
}
91
#endif
92
93
int SDL_RecordGesture(SDL_TouchID touchId) {
94
95
int i;
if(touchId < 0) recordAll = SDL_TRUE;
96
97
98
for(i = 0;i < SDL_numGestureTouches; i++) {
if((touchId < 0) || (SDL_gestureTouch[i].id == touchId)) {
SDL_gestureTouch[i].recording = SDL_TRUE;
99
if(touchId >= 0)
100
return 1;
101
102
103
104
105
}
}
return (touchId < 0);
}
106
unsigned long SDL_HashDollar(SDL_FloatPoint* points) {
107
108
109
unsigned long hash = 5381;
int i;
for(i = 0;i < DOLLARNPOINTS; i++) {
110
111
hash = ((hash<<5) + hash) + (unsigned long)points[i].x;
hash = ((hash<<5) + hash) + (unsigned long)points[i].y;
112
113
114
115
}
return hash;
}
116
117
static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops * src) {
118
if(src == NULL) return 0;
119
120
121
122
//No Longer storing the Hash, rehash on load
//if(SDL_RWops.write(src,&(templ->hash),sizeof(templ->hash),1) != 1) return 0;
123
124
if(SDL_RWwrite(src,templ->path,
125
sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS)
126
127
return 0;
128
return 1;
129
130
131
}
132
int SDL_SaveAllDollarTemplates(SDL_RWops *src) {
133
int i,j,rtrn = 0;
134
135
for(i = 0; i < SDL_numGestureTouches; i++) {
SDL_GestureTouch* touch = &SDL_gestureTouch[i];
136
for(j = 0;j < touch->numDollarTemplates; j++) {
137
rtrn += SaveTemplate(&touch->dollarTemplate[i],src);
138
139
140
141
142
}
}
return rtrn;
}
143
int SDL_SaveDollarTemplate(SDL_GestureID gestureId, SDL_RWops *src) {
144
int i,j;
145
146
for(i = 0; i < SDL_numGestureTouches; i++) {
SDL_GestureTouch* touch = &SDL_gestureTouch[i];
147
148
for(j = 0;j < touch->numDollarTemplates; j++) {
if(touch->dollarTemplate[i].hash == gestureId) {
149
return SaveTemplate(&touch->dollarTemplate[i],src);
150
151
152
}
}
}
153
154
155
156
157
158
SDL_SetError("Unknown gestureId");
return -1;
}
//path is an already sampled set of points
//Returns the index of the gesture on success, or -1
159
static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch,SDL_FloatPoint* path) {
160
161
162
SDL_DollarTemplate* dollarTemplate;
SDL_DollarTemplate *templ;
int i = 0;
163
if(inTouch == NULL) {
164
165
166
167
if(SDL_numGestureTouches == 0) return -1;
for(i = 0;i < SDL_numGestureTouches; i++) {
inTouch = &SDL_gestureTouch[i];
168
dollarTemplate =
169
170
171
(SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
(inTouch->numDollarTemplates + 1) *
sizeof(SDL_DollarTemplate));
172
if(!dollarTemplate) {
173
174
SDL_OutOfMemory();
return -1;
175
}
176
177
178
inTouch->dollarTemplate = dollarTemplate;
179
templ =
180
&inTouch->dollarTemplate[inTouch->numDollarTemplates];
181
SDL_memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
182
183
templ->hash = SDL_HashDollar(templ->path);
inTouch->numDollarTemplates++;
184
185
}
return inTouch->numDollarTemplates - 1;
186
187
} else {
SDL_DollarTemplate* dollarTemplate =
188
( SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
189
190
(inTouch->numDollarTemplates + 1) *
sizeof(SDL_DollarTemplate));
191
192
193
194
195
196
197
if(!dollarTemplate) {
SDL_OutOfMemory();
return -1;
}
inTouch->dollarTemplate = dollarTemplate;
198
templ =
199
&inTouch->dollarTemplate[inTouch->numDollarTemplates];
200
SDL_memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
201
202
203
204
205
templ->hash = SDL_HashDollar(templ->path);
inTouch->numDollarTemplates++;
return inTouch->numDollarTemplates - 1;
}
return -1;
206
207
}
208
int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src) {
209
int i,loaded = 0;
210
SDL_GestureTouch *touch = NULL;
211
if(src == NULL) return 0;
212
if(touchId >= 0) {
213
214
for(i = 0;i < SDL_numGestureTouches; i++)
if(SDL_gestureTouch[i].id == touchId)
215
touch = &SDL_gestureTouch[i];
216
217
218
if(touch == NULL) return -1;
}
219
while(1) {
220
221
222
223
SDL_DollarTemplate templ;
if(SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) <
DOLLARNPOINTS) break;
224
225
if(touchId >= 0) {
226
//printf("Adding loaded gesture to 1 touch\n");
227
if(SDL_AddDollarGesture(touch,templ.path)) loaded++;
228
229
}
else {
230
//printf("Adding to: %i touches\n",SDL_numGestureTouches);
231
for(i = 0;i < SDL_numGestureTouches; i++) {
232
233
234
235
touch = &SDL_gestureTouch[i];
//printf("Adding loaded gesture to + touches\n");
//TODO: What if this fails?
SDL_AddDollarGesture(touch,templ.path);
236
237
238
239
240
}
loaded++;
}
}
241
return loaded;
242
243
244
}
245
246
float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float ang) {
// SDL_FloatPoint p[DOLLARNPOINTS];
247
float dist = 0;
248
SDL_FloatPoint p;
249
250
int i;
for(i = 0; i < DOLLARNPOINTS; i++) {
251
252
253
p.x = (float)(points[i].x * SDL_cos(ang) - points[i].y * SDL_sin(ang));
p.y = (float)(points[i].x * SDL_sin(ang) + points[i].y * SDL_cos(ang));
dist += (float)(SDL_sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
254
(p.y-templ[i].y)*(p.y-templ[i].y)));
255
256
257
258
259
}
return dist/DOLLARNPOINTS;
}
260
float bestDollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ) {
261
262
263
//------------BEGIN DOLLAR BLACKBOX----------------//
//-TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-//
//-"http://depts.washington.edu/aimgroup/proj/dollar/"-//
264
265
266
267
double ta = -M_PI/4;
double tb = M_PI/4;
double dt = M_PI/90;
float x1 = (float)(PHI*ta + (1-PHI)*tb);
268
float f1 = dollarDifference(points,templ,x1);
269
float x2 = (float)((1-PHI)*ta + PHI*tb);
270
float f2 = dollarDifference(points,templ,x2);
271
while(SDL_fabs(ta-tb) > dt) {
272
273
274
275
if(f1 < f2) {
tb = x2;
x2 = x1;
f2 = f1;
276
x1 = (float)(PHI*ta + (1-PHI)*tb);
277
278
279
280
281
282
f1 = dollarDifference(points,templ,x1);
}
else {
ta = x1;
x1 = x2;
f1 = f2;
283
x2 = (float)((1-PHI)*ta + PHI*tb);
284
285
286
287
288
289
290
291
292
293
294
295
296
f2 = dollarDifference(points,templ,x2);
}
}
/*
if(f1 <= f2)
printf("Min angle (x1): %f\n",x1);
else if(f1 > f2)
printf("Min angle (x2): %f\n",x2);
*/
return SDL_min(f1,f2);
}
//DollarPath contains raw points, plus (possibly) the calculated length
297
int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points) {
298
int i;
299
300
301
302
303
304
305
float interval;
float dist;
int numPoints = 0;
SDL_FloatPoint centroid;
float xmin,xmax,ymin,ymax;
float ang;
float w,h;
306
float length = path->length;
307
308
//Calculate length if it hasn't already been done
309
310
311
312
313
314
315
if(length <= 0) {
for(i=1;i<path->numPoints;i++) {
float dx = path->p[i ].x -
path->p[i-1].x;
float dy = path->p[i ].y -
path->p[i-1].y;
length += (float)(SDL_sqrt(dx*dx+dy*dy));
316
317
318
319
}
}
//Resample
320
interval = length/(DOLLARNPOINTS - 1);
321
dist = interval;
322
323
324
centroid.x = 0;centroid.y = 0;
325
326
327
328
//printf("(%f,%f)\n",path->p[path->numPoints-1].x,path->p[path->numPoints-1].y);
for(i = 1;i < path->numPoints;i++) {
float d = (float)(SDL_sqrt((path->p[i-1].x-path->p[i].x)*(path->p[i-1].x-path->p[i].x)+
(path->p[i-1].y-path->p[i].y)*(path->p[i-1].y-path->p[i].y)));
329
330
//printf("d = %f dist = %f/%f\n",d,dist,interval);
while(dist + d > interval) {
331
332
333
334
points[numPoints].x = path->p[i-1].x +
((interval-dist)/d)*(path->p[i].x-path->p[i-1].x);
points[numPoints].y = path->p[i-1].y +
((interval-dist)/d)*(path->p[i].y-path->p[i-1].y);
335
336
337
338
339
340
341
342
centroid.x += points[numPoints].x;
centroid.y += points[numPoints].y;
numPoints++;
dist -= interval;
}
dist += d;
}
343
if(numPoints < DOLLARNPOINTS-1) {
344
SDL_SetError("ERROR: NumPoints = %i\n",numPoints);
345
346
347
return 0;
}
//copy the last point
348
points[DOLLARNPOINTS-1] = path->p[path->numPoints-1];
349
350
numPoints = DOLLARNPOINTS;
351
352
353
354
355
356
357
358
359
360
centroid.x /= numPoints;
centroid.y /= numPoints;
//printf("Centroid (%f,%f)",centroid.x,centroid.y);
//Rotate Points so point 0 is left of centroid and solve for the bounding box
xmin = centroid.x;
xmax = centroid.x;
ymin = centroid.y;
ymax = centroid.y;
361
ang = (float)(SDL_atan2(centroid.y - points[0].y,
362
centroid.x - points[0].x));
363
364
for(i = 0;i<numPoints;i++) {
365
366
float px = points[i].x;
float py = points[i].y;
367
368
369
370
points[i].x = (float)((px - centroid.x)*SDL_cos(ang) -
(py - centroid.y)*SDL_sin(ang) + centroid.x);
points[i].y = (float)((px - centroid.x)*SDL_sin(ang) +
(py - centroid.y)*SDL_cos(ang) + centroid.y);
371
372
373
374
375
376
377
378
379
if(points[i].x < xmin) xmin = points[i].x;
if(points[i].x > xmax) xmax = points[i].x;
if(points[i].y < ymin) ymin = points[i].y;
if(points[i].y > ymax) ymax = points[i].y;
}
//Scale points to DOLLARSIZE, and translate to the origin
380
381
w = xmax-xmin;
h = ymax-ymin;
382
383
384
385
386
387
388
389
for(i=0;i<numPoints;i++) {
points[i].x = (points[i].x - centroid.x)*DOLLARSIZE/w;
points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h;
}
return numPoints;
}
390
float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_GestureTouch* touch) {
391
392
393
394
395
396
397
398
399
400
401
402
403
SDL_FloatPoint points[DOLLARNPOINTS];
int numPoints = dollarNormalize(path,points);
int i;
float bestDiff = 10000;
//PrintPath(points);
*bestTempl = -1;
for(i = 0;i < touch->numDollarTemplates;i++) {
float diff = bestDollarDifference(points,touch->dollarTemplate[i].path);
if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;}
}
return bestDiff;
404
405
}
406
int SDL_GestureAddTouch(SDL_Touch* touch) {
407
SDL_GestureTouch *gestureTouch = (SDL_GestureTouch *)SDL_realloc(SDL_gestureTouch,
408
409
(SDL_numGestureTouches + 1) *
sizeof(SDL_GestureTouch));
410
411
412
413
414
415
416
417
418
419
420
if(!gestureTouch) {
SDL_OutOfMemory();
return -1;
}
SDL_gestureTouch = gestureTouch;
SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
SDL_gestureTouch[SDL_numGestureTouches].res.y = touch->yres;
SDL_gestureTouch[SDL_numGestureTouches].numDownFingers = 0;
421
422
423
SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
SDL_gestureTouch[SDL_numGestureTouches].id = touch->id;
424
425
SDL_gestureTouch[SDL_numGestureTouches].numDollarTemplates = 0;
426
427
SDL_gestureTouch[SDL_numGestureTouches].recording = SDL_FALSE;
428
429
SDL_numGestureTouches++;
430
431
432
return 0;
}
433
int SDL_GestureRemoveTouch(SDL_TouchID id) {
434
int i;
435
436
for (i = 0; i < SDL_numGestureTouches; i++) {
if (SDL_gestureTouch[i].id == id) {
437
SDL_numGestureTouches--;
438
SDL_memcpy(&SDL_gestureTouch[i], &SDL_gestureTouch[SDL_numGestureTouches], sizeof(SDL_gestureTouch[i]));
439
440
441
442
443
444
445
446
447
448
449
450
return 1;
}
}
return -1;
}
SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id) {
int i;
for(i = 0;i < SDL_numGestureTouches; i++) {
//printf("%i ?= %i\n",SDL_gestureTouch[i].id,id);
if(SDL_gestureTouch[i].id == id) return &SDL_gestureTouch[i];
451
452
453
454
}
return NULL;
}
455
int SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist) {
456
457
458
459
460
461
462
SDL_Event event;
event.mgesture.type = SDL_MULTIGESTURE;
event.mgesture.touchId = touch->id;
event.mgesture.x = touch->centroid.x;
event.mgesture.y = touch->centroid.y;
event.mgesture.dTheta = dTheta;
event.mgesture.dDist = dDist;
463
event.mgesture.numFingers = touch->numDownFingers;
464
465
466
return SDL_PushEvent(&event) > 0;
}
467
int SDL_SendGestureDollar(SDL_GestureTouch* touch,
468
SDL_GestureID gestureId,float error) {
469
470
471
472
473
474
475
476
477
478
SDL_Event event;
event.dgesture.type = SDL_DOLLARGESTURE;
event.dgesture.touchId = touch->id;
/*
//TODO: Add this to give location of gesture?
event.mgesture.x = touch->centroid.x;
event.mgesture.y = touch->centroid.y;
*/
event.dgesture.gestureId = gestureId;
event.dgesture.error = error;
479
480
//A finger came up to trigger this event.
event.dgesture.numFingers = touch->numDownFingers + 1;
481
482
483
return SDL_PushEvent(&event) > 0;
}
484
485
int SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId) {
486
487
488
489
490
491
492
493
SDL_Event event;
event.dgesture.type = SDL_DOLLARRECORD;
event.dgesture.touchId = touch->id;
event.dgesture.gestureId = gestureId;
return SDL_PushEvent(&event) > 0;
}
494
495
void SDL_GestureProcessEvent(SDL_Event* event)
{
496
497
498
499
500
501
502
503
504
505
506
507
float x,y;
SDL_FloatPoint path[DOLLARNPOINTS];
int index;
int i;
float pathDx, pathDy;
SDL_FloatPoint lastP;
SDL_FloatPoint lastCentroid;
float lDist;
float Dist;
float dtheta;
float dDist;
508
509
510
if(event->type == SDL_FINGERMOTION ||
event->type == SDL_FINGERDOWN ||
event->type == SDL_FINGERUP) {
511
SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);
512
513
514
515
//Shouldn't be possible
if(inTouch == NULL) return;
516
//printf("@ (%i,%i) with res: (%i,%i)\n",(int)event->tfinger.x,
517
// (int)event->tfinger.y,
518
519
// (int)inTouch->res.x,(int)inTouch->res.y);
520
521
522
x = ((float)event->tfinger.x)/(float)inTouch->res.x;
y = ((float)event->tfinger.y)/(float)inTouch->res.y;
523
524
525
526
527
528
529
530
//Finger Up
if(event->type == SDL_FINGERUP) {
inTouch->numDownFingers--;
#ifdef ENABLE_DOLLAR
if(inTouch->recording) {
531
inTouch->recording = SDL_FALSE;
532
dollarNormalize(&inTouch->dollarPath,path);
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
//PrintPath(path);
if(recordAll) {
index = SDL_AddDollarGesture(NULL,path);
for(i = 0;i < SDL_numGestureTouches; i++)
SDL_gestureTouch[i].recording = SDL_FALSE;
}
else {
index = SDL_AddDollarGesture(inTouch,path);
}
if(index >= 0) {
SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
}
else {
SDL_SendDollarRecord(inTouch,-1);
}
549
}
550
551
552
else {
int bestTempl;
float error;
553
error = dollarRecognize(&inTouch->dollarPath,
554
555
556
557
558
559
560
&bestTempl,inTouch);
if(bestTempl >= 0){
//Send Event
unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
SDL_SendGestureDollar(inTouch,gestureId,error);
//printf ("%s\n",);("Dollar error: %f\n",error);
}
561
562
563
564
}
#endif
//inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
if(inTouch->numDownFingers > 0) {
565
566
567
568
inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
x)/inTouch->numDownFingers;
inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
y)/inTouch->numDownFingers;
569
570
571
572
573
574
575
}
}
else if(event->type == SDL_FINGERMOTION) {
float dx = ((float)event->tfinger.dx)/(float)inTouch->res.x;
float dy = ((float)event->tfinger.dy)/(float)inTouch->res.y;
//printf("dx,dy: (%f,%f)\n",dx,dy);
#ifdef ENABLE_DOLLAR
576
SDL_DollarPath* path = &inTouch->dollarPath;
577
if(path->numPoints < MAXPATHSIZE) {
578
579
580
581
582
583
584
585
path->p[path->numPoints].x = inTouch->centroid.x;
path->p[path->numPoints].y = inTouch->centroid.y;
pathDx =
(path->p[path->numPoints].x-path->p[path->numPoints-1].x);
pathDy =
(path->p[path->numPoints].y-path->p[path->numPoints-1].y);
path->length += (float)SDL_sqrt(pathDx*pathDx + pathDy*pathDy);
path->numPoints++;
586
587
588
589
590
591
592
}
#endif
lastP.x = x - dx;
lastP.y = y - dy;
lastCentroid = inTouch->centroid;
inTouch->centroid.x += dx/inTouch->numDownFingers;
593
594
inTouch->centroid.y += dy/inTouch->numDownFingers;
//printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y);
595
if(inTouch->numDownFingers > 1) {
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
SDL_FloatPoint lv; //Vector from centroid to last x,y position
SDL_FloatPoint v; //Vector from centroid to current x,y position
//lv = inTouch->gestureLast[j].cv;
lv.x = lastP.x - lastCentroid.x;
lv.y = lastP.y - lastCentroid.y;
lDist = (float)SDL_sqrt(lv.x*lv.x + lv.y*lv.y);
//printf("lDist = %f\n",lDist);
v.x = x - inTouch->centroid.x;
v.y = y - inTouch->centroid.y;
//inTouch->gestureLast[j].cv = v;
Dist = (float)SDL_sqrt(v.x*v.x+v.y*v.y);
// SDL_cos(dTheta) = (v . lv)/(|v| * |lv|)
//Normalize Vectors to simplify angle calculation
lv.x/=lDist;
lv.y/=lDist;
v.x/=Dist;
v.y/=Dist;
dtheta = (float)SDL_atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
dDist = (Dist - lDist);
if(lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values
//inTouch->gestureLast[j].dDist = dDist;
//inTouch->gestureLast[j].dtheta = dtheta;
//printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
//gdtheta = gdtheta*.9 + dtheta*.1;
//gdDist = gdDist*.9 + dDist*.1
//knob.r += dDist/numDownFingers;
//knob.ang += dtheta;
//printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
//printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
SDL_SendGestureMulti(inTouch,dtheta,dDist);
630
631
}
else {
632
633
634
635
//inTouch->gestureLast[j].dDist = 0;
//inTouch->gestureLast[j].dtheta = 0;
//inTouch->gestureLast[j].cv.x = 0;
//inTouch->gestureLast[j].cv.y = 0;
636
637
638
639
640
}
//inTouch->gestureLast[j].f.p.x = x;
//inTouch->gestureLast[j].f.p.y = y;
//break;
//pressure?
641
642
}
643
644
if(event->type == SDL_FINGERDOWN) {
645
646
inTouch->numDownFingers++;
inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+
647
x)/inTouch->numDownFingers;
648
inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
649
y)/inTouch->numDownFingers;
650
651
652
//printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
// inTouch->centroid.x,inTouch->centroid.y);
653
654
655
656
657
#ifdef ENABLE_DOLLAR
inTouch->dollarPath.length = 0;
inTouch->dollarPath.p[0].x = x;
inTouch->dollarPath.p[0].y = y;
inTouch->dollarPath.numPoints = 1;
658
#endif
659
660
}
}
661
662
}
663
664
/* vi: set ts=4 sw=4 expandtab: */