Mercurial > sdl-ios-xcode
comparison src/events/SDL_gesture.c @ 4688:494f71f57a80
Fixed bugs related to keyboard handling in gestureSDLTest. Fixed gesture code (dynamic memory allocation). Cleaned up gesture and test code.
author | Jim Grandpre <jim.tla@gmail.com> |
---|---|
date | Fri, 13 Aug 2010 23:08:32 -0400 |
parents | 463cd74304b9 |
children | f9ab8df6d45a |
comparison
equal
deleted
inserted
replaced
4687:257bdf117af8 | 4688:494f71f57a80 |
---|---|
25 #include "SDL_events.h" | 25 #include "SDL_events.h" |
26 #include "SDL_events_c.h" | 26 #include "SDL_events_c.h" |
27 #include "SDL_gesture_c.h" | 27 #include "SDL_gesture_c.h" |
28 | 28 |
29 //TODO: Replace with malloc | 29 //TODO: Replace with malloc |
30 #define MAXFINGERS 5 | 30 |
31 #define MAXTOUCHES 2 | |
32 #define MAXTEMPLATES 4 | |
33 #define MAXPATHSIZE 1024 | 31 #define MAXPATHSIZE 1024 |
32 | |
33 | |
34 | |
34 | 35 |
35 #define DOLLARNPOINTS 64 | 36 #define DOLLARNPOINTS 64 |
36 #define DOLLARSIZE 256 | 37 #define DOLLARSIZE 256 |
37 | 38 |
38 #define ENABLE_DOLLAR | 39 #define ENABLE_DOLLAR |
40 //PHI = ((sqrt(5)-1)/2) | 41 //PHI = ((sqrt(5)-1)/2) |
41 #define PHI 0.618033989 | 42 #define PHI 0.618033989 |
42 | 43 |
43 typedef struct { | 44 typedef struct { |
44 float x,y; | 45 float x,y; |
45 } Point; | 46 } SDL_FloatPoint; |
46 | |
47 | |
48 typedef struct { | |
49 Point p; | |
50 float pressure; | |
51 SDL_FingerID id; | |
52 } Finger; | |
53 | |
54 | 47 |
55 typedef struct { | 48 typedef struct { |
56 float length; | 49 float length; |
57 | 50 |
58 int numPoints; | 51 int numPoints; |
59 Point p[MAXPATHSIZE]; | 52 SDL_FloatPoint p[MAXPATHSIZE]; |
60 } DollarPath; | 53 } SDL_DollarPath; |
61 | 54 |
62 /* | |
63 typedef struct { | 55 typedef struct { |
64 Finger f; | 56 SDL_FloatPoint path[DOLLARNPOINTS]; |
65 Point cv; | |
66 float dtheta,dDist; | |
67 DollarPath dollarPath; | |
68 } TouchPoint; | |
69 */ | |
70 typedef struct { | |
71 Point path[DOLLARNPOINTS]; | |
72 unsigned long hash; | 57 unsigned long hash; |
73 } DollarTemplate; | 58 } SDL_DollarTemplate; |
74 | 59 |
75 typedef struct { | 60 typedef struct { |
76 SDL_GestureID id; | 61 SDL_GestureID id; |
77 Point res; | 62 SDL_FloatPoint res; |
78 Point centroid; | 63 SDL_FloatPoint centroid; |
79 //TouchPoint gestureLast[MAXFINGERS]; | 64 SDL_DollarPath dollarPath; |
80 DollarPath dollarPath; | |
81 Uint16 numDownFingers; | 65 Uint16 numDownFingers; |
82 | 66 |
83 int numDollarTemplates; | 67 int numDollarTemplates; |
84 DollarTemplate dollarTemplate[MAXTEMPLATES]; | 68 SDL_DollarTemplate *dollarTemplate; |
85 | 69 |
86 SDL_bool recording; | 70 SDL_bool recording; |
87 } GestureTouch; | 71 } SDL_GestureTouch; |
88 | 72 |
89 GestureTouch gestureTouch[MAXTOUCHES]; | 73 SDL_GestureTouch *SDL_gestureTouch; |
90 int numGestureTouches = 0; | 74 int SDL_numGestureTouches = 0; |
91 SDL_bool recordAll; | 75 SDL_bool recordAll; |
92 | 76 |
93 void SDL_PrintPath(Point *path) { | 77 void SDL_PrintPath(SDL_FloatPoint *path) { |
94 int i; | 78 int i; |
95 printf("Path:"); | 79 printf("Path:"); |
96 for(i=0;i<DOLLARNPOINTS;i++) { | 80 for(i=0;i<DOLLARNPOINTS;i++) { |
97 printf(" (%f,%f)",path[i].x,path[i].y); | 81 printf(" (%f,%f)",path[i].x,path[i].y); |
98 } | 82 } |
100 } | 84 } |
101 | 85 |
102 int SDL_RecordGesture(SDL_TouchID touchId) { | 86 int SDL_RecordGesture(SDL_TouchID touchId) { |
103 int i; | 87 int i; |
104 if(touchId < 0) recordAll = SDL_TRUE; | 88 if(touchId < 0) recordAll = SDL_TRUE; |
105 for(i = 0;i < numGestureTouches; i++) { | 89 for(i = 0;i < SDL_numGestureTouches; i++) { |
106 if((touchId < 0) || (gestureTouch[i].id == touchId)) { | 90 if((touchId < 0) || (SDL_gestureTouch[i].id == touchId)) { |
107 gestureTouch[i].recording = SDL_TRUE; | 91 SDL_gestureTouch[i].recording = SDL_TRUE; |
108 if(touchId >= 0) | 92 if(touchId >= 0) |
109 return 1; | 93 return 1; |
110 } | 94 } |
111 } | 95 } |
112 return (touchId < 0); | 96 return (touchId < 0); |
113 } | 97 } |
114 | 98 |
115 unsigned long SDL_HashDollar(Point* points) { | 99 unsigned long SDL_HashDollar(SDL_FloatPoint* points) { |
116 unsigned long hash = 5381; | 100 unsigned long hash = 5381; |
117 int i; | 101 int i; |
118 for(i = 0;i < DOLLARNPOINTS; i++) { | 102 for(i = 0;i < DOLLARNPOINTS; i++) { |
119 hash = ((hash<<5) + hash) + points[i].x; | 103 hash = ((hash<<5) + hash) + points[i].x; |
120 hash = ((hash<<5) + hash) + points[i].y; | 104 hash = ((hash<<5) + hash) + points[i].y; |
121 } | 105 } |
122 return hash; | 106 return hash; |
123 } | 107 } |
124 | 108 |
125 | 109 |
126 static int SaveTemplate(DollarTemplate *templ, SDL_RWops * src) { | 110 static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops * src) { |
127 if(src == NULL) return 0; | 111 if(src == NULL) return 0; |
128 | 112 |
129 int i; | 113 int i; |
130 | 114 |
131 //No Longer storing the Hash, rehash on load | 115 //No Longer storing the Hash, rehash on load |
132 //if(SDL_RWops.write(src,&(templ->hash),sizeof(templ->hash),1) != 1) return 0; | 116 //if(SDL_RWops.write(src,&(templ->hash),sizeof(templ->hash),1) != 1) return 0; |
133 | 117 |
134 if(SDL_RWwrite(src,templ->path, | 118 if(SDL_RWwrite(src,templ->path, |
135 sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) | 119 sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) |
136 return 0; | 120 return 0; |
137 | 121 |
138 return 1; | 122 return 1; |
139 } | 123 } |
140 | 124 |
141 | 125 |
142 int SDL_SaveAllDollarTemplates(SDL_RWops *src) { | 126 int SDL_SaveAllDollarTemplates(SDL_RWops *src) { |
143 int i,j,rtrn = 0; | 127 int i,j,rtrn = 0; |
144 for(i = 0; i < numGestureTouches; i++) { | 128 for(i = 0; i < SDL_numGestureTouches; i++) { |
145 GestureTouch* touch = &gestureTouch[i]; | 129 SDL_GestureTouch* touch = &SDL_gestureTouch[i]; |
146 for(j = 0;j < touch->numDollarTemplates; j++) { | 130 for(j = 0;j < touch->numDollarTemplates; j++) { |
147 rtrn += SaveTemplate(&touch->dollarTemplate[i],src); | 131 rtrn += SaveTemplate(&touch->dollarTemplate[i],src); |
148 } | 132 } |
149 } | 133 } |
150 return rtrn; | 134 return rtrn; |
151 } | 135 } |
152 | 136 |
153 int SDL_SaveDollarTemplate(SDL_GestureID gestureId, SDL_RWops *src) { | 137 int SDL_SaveDollarTemplate(SDL_GestureID gestureId, SDL_RWops *src) { |
154 int i,j; | 138 int i,j; |
155 for(i = 0; i < numGestureTouches; i++) { | 139 for(i = 0; i < SDL_numGestureTouches; i++) { |
156 GestureTouch* touch = &gestureTouch[i]; | 140 SDL_GestureTouch* touch = &SDL_gestureTouch[i]; |
157 for(j = 0;j < touch->numDollarTemplates; j++) { | 141 for(j = 0;j < touch->numDollarTemplates; j++) { |
158 if(touch->dollarTemplate[i].hash == gestureId) { | 142 if(touch->dollarTemplate[i].hash == gestureId) { |
159 return SaveTemplate(&touch->dollarTemplate[i],src); | 143 return SaveTemplate(&touch->dollarTemplate[i],src); |
160 } | 144 } |
161 } | 145 } |
164 return -1; | 148 return -1; |
165 } | 149 } |
166 | 150 |
167 //path is an already sampled set of points | 151 //path is an already sampled set of points |
168 //Returns the index of the gesture on success, or -1 | 152 //Returns the index of the gesture on success, or -1 |
169 static int SDL_AddDollarGesture(GestureTouch* inTouch,Point* path) { | 153 static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch,SDL_FloatPoint* path) { |
170 if(inTouch == NULL) { | 154 if(inTouch == NULL) { |
171 if(numGestureTouches == 0) return -1; | 155 if(SDL_numGestureTouches == 0) return -1; |
172 int i = 0; | 156 int i = 0; |
173 for(i = 0;i < numGestureTouches; i++) { | 157 for(i = 0;i < SDL_numGestureTouches; i++) { |
174 inTouch = &gestureTouch[i]; | 158 inTouch = &SDL_gestureTouch[i]; |
175 if(inTouch->numDollarTemplates < MAXTEMPLATES) { | 159 |
176 DollarTemplate *templ = | 160 SDL_DollarTemplate* dollarTemplate = |
177 &inTouch->dollarTemplate[inTouch->numDollarTemplates]; | 161 SDL_realloc(inTouch->dollarTemplate, |
178 memcpy(templ->path,path,DOLLARNPOINTS*sizeof(Point)); | 162 (inTouch->numDollarTemplates + 1) * |
179 templ->hash = SDL_HashDollar(templ->path); | 163 sizeof(SDL_DollarTemplate)); |
180 inTouch->numDollarTemplates++; | 164 if(!dollarTemplate) { |
181 } | 165 SDL_OutOfMemory(); |
166 return -1; | |
167 } | |
168 | |
169 inTouch->dollarTemplate = dollarTemplate; | |
170 | |
171 SDL_DollarTemplate *templ = | |
172 &inTouch->dollarTemplate[inTouch->numDollarTemplates]; | |
173 memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint)); | |
174 templ->hash = SDL_HashDollar(templ->path); | |
175 inTouch->numDollarTemplates++; | |
182 } | 176 } |
183 return inTouch->numDollarTemplates - 1; | 177 return inTouch->numDollarTemplates - 1; |
184 }else if(inTouch->numDollarTemplates < MAXTEMPLATES) { | 178 } else { |
185 DollarTemplate *templ = | 179 SDL_DollarTemplate* dollarTemplate = |
180 SDL_realloc(inTouch->dollarTemplate, | |
181 (inTouch->numDollarTemplates + 1) * | |
182 sizeof(SDL_DollarTemplate)); | |
183 if(!dollarTemplate) { | |
184 SDL_OutOfMemory(); | |
185 return -1; | |
186 } | |
187 | |
188 inTouch->dollarTemplate = dollarTemplate; | |
189 | |
190 SDL_DollarTemplate *templ = | |
186 &inTouch->dollarTemplate[inTouch->numDollarTemplates]; | 191 &inTouch->dollarTemplate[inTouch->numDollarTemplates]; |
187 memcpy(templ->path,path,DOLLARNPOINTS*sizeof(Point)); | 192 memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint)); |
188 templ->hash = SDL_HashDollar(templ->path); | 193 templ->hash = SDL_HashDollar(templ->path); |
189 inTouch->numDollarTemplates++; | 194 inTouch->numDollarTemplates++; |
190 return inTouch->numDollarTemplates - 1; | 195 return inTouch->numDollarTemplates - 1; |
191 } | 196 } |
192 return -1; | 197 return -1; |
193 } | 198 } |
194 | 199 |
195 int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src) { | 200 int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src) { |
196 if(src == NULL) return 0; | 201 if(src == NULL) return 0; |
197 int i,loaded = 0; | 202 int i,loaded = 0; |
198 GestureTouch *touch = NULL; | 203 SDL_GestureTouch *touch = NULL; |
199 if(touchId >= 0) { | 204 if(touchId >= 0) { |
200 for(i = 0;i < numGestureTouches; i++) | 205 for(i = 0;i < SDL_numGestureTouches; i++) |
201 if(gestureTouch[i].id == touchId) | 206 if(SDL_gestureTouch[i].id == touchId) |
202 touch = &gestureTouch[i]; | 207 touch = &SDL_gestureTouch[i]; |
203 if(touch == NULL) return -1; | 208 if(touch == NULL) return -1; |
204 } | 209 } |
205 | 210 |
206 while(1) { | 211 while(1) { |
207 DollarTemplate templ; | 212 SDL_DollarTemplate templ; |
208 //fscanf(fp,"%lu ",&templ.hash); | 213 |
209 /* | 214 if(SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < |
210 for(i = 0;i < DOLLARNPOINTS; i++) { | 215 DOLLARNPOINTS) break; |
211 int x,y; | |
212 if(fscanf(fp,"%i %i ",&x,&y) != 2) break; | |
213 templ.path[i].x = x; | |
214 templ.path[i].y = y; | |
215 } | |
216 fscanf(fp,"\n"); | |
217 */ | |
218 if(SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < DOLLARNPOINTS) break; | |
219 | 216 |
220 if(touchId >= 0) { | 217 if(touchId >= 0) { |
221 printf("Adding loaded gesture to 1 touch\n"); | 218 printf("Adding loaded gesture to 1 touch\n"); |
222 if(SDL_AddDollarGesture(touch,templ.path)) loaded++; | 219 if(SDL_AddDollarGesture(touch,templ.path)) loaded++; |
223 } | 220 } |
224 else { | 221 else { |
225 printf("Adding to: %i touches\n",numGestureTouches); | 222 printf("Adding to: %i touches\n",SDL_numGestureTouches); |
226 for(i = 0;i < numGestureTouches; i++) { | 223 for(i = 0;i < SDL_numGestureTouches; i++) { |
227 touch = &gestureTouch[i]; | 224 touch = &SDL_gestureTouch[i]; |
228 printf("Adding loaded gesture to + touches\n"); | 225 printf("Adding loaded gesture to + touches\n"); |
229 //TODO: What if this fails? | 226 //TODO: What if this fails? |
230 SDL_AddDollarGesture(touch,templ.path); | 227 SDL_AddDollarGesture(touch,templ.path); |
231 } | 228 } |
232 loaded++; | 229 loaded++; |
235 | 232 |
236 return loaded; | 233 return loaded; |
237 } | 234 } |
238 | 235 |
239 | 236 |
240 float dollarDifference(Point* points,Point* templ,float ang) { | 237 float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float ang) { |
241 // Point p[DOLLARNPOINTS]; | 238 // SDL_FloatPoint p[DOLLARNPOINTS]; |
242 float dist = 0; | 239 float dist = 0; |
243 Point p; | 240 SDL_FloatPoint p; |
244 int i; | 241 int i; |
245 for(i = 0; i < DOLLARNPOINTS; i++) { | 242 for(i = 0; i < DOLLARNPOINTS; i++) { |
246 p.x = points[i].x * cos(ang) - points[i].y * sin(ang); | 243 p.x = points[i].x * cos(ang) - points[i].y * sin(ang); |
247 p.y = points[i].x * sin(ang) + points[i].y * cos(ang); | 244 p.y = points[i].x * sin(ang) + points[i].y * cos(ang); |
248 dist += sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+ | 245 dist += sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+ |
250 } | 247 } |
251 return dist/DOLLARNPOINTS; | 248 return dist/DOLLARNPOINTS; |
252 | 249 |
253 } | 250 } |
254 | 251 |
255 float bestDollarDifference(Point* points,Point* templ) { | 252 float bestDollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ) { |
256 //------------BEGIN DOLLAR BLACKBOX----------------// | 253 //------------BEGIN DOLLAR BLACKBOX----------------// |
257 //-TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-// | 254 //-TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-// |
258 //-"http://depts.washington.edu/aimgroup/proj/dollar/"-// | 255 //-"http://depts.washington.edu/aimgroup/proj/dollar/"-// |
259 float ta = -M_PI/4; | 256 float ta = -M_PI/4; |
260 float tb = M_PI/4; | 257 float tb = M_PI/4; |
287 */ | 284 */ |
288 return SDL_min(f1,f2); | 285 return SDL_min(f1,f2); |
289 } | 286 } |
290 | 287 |
291 //DollarPath contains raw points, plus (possibly) the calculated length | 288 //DollarPath contains raw points, plus (possibly) the calculated length |
292 int dollarNormalize(DollarPath path,Point *points) { | 289 int dollarNormalize(SDL_DollarPath path,SDL_FloatPoint *points) { |
293 int i; | 290 int i; |
294 //Calculate length if it hasn't already been done | 291 //Calculate length if it hasn't already been done |
295 printf("length: %f\n",path.length); | |
296 if(path.length <= 0) { | 292 if(path.length <= 0) { |
297 for(i=1;i<path.numPoints;i++) { | 293 for(i=1;i<path.numPoints;i++) { |
298 float dx = path.p[i ].x - | 294 float dx = path.p[i ].x - |
299 path.p[i-1].x; | 295 path.p[i-1].x; |
300 float dy = path.p[i ].y - | 296 float dy = path.p[i ].y - |
301 path.p[i-1].y; | 297 path.p[i-1].y; |
302 path.length += sqrt(dx*dx+dy*dy); | 298 path.length += sqrt(dx*dx+dy*dy); |
303 } | 299 } |
304 } | 300 } |
305 printf("New length: %f\n",path.length); | |
306 | 301 |
307 //Resample | 302 //Resample |
308 float interval = path.length/(DOLLARNPOINTS - 1); | 303 float interval = path.length/(DOLLARNPOINTS - 1); |
309 float dist = interval; | 304 float dist = interval; |
310 | 305 |
311 int numPoints = 0; | 306 int numPoints = 0; |
312 Point centroid; | 307 SDL_FloatPoint centroid; |
313 centroid.x = 0;centroid.y = 0; | 308 centroid.x = 0;centroid.y = 0; |
314 | 309 |
315 //printf("(%f,%f)\n",path.p[path.numPoints-1].x,path.p[path.numPoints-1].y); | 310 //printf("(%f,%f)\n",path.p[path.numPoints-1].x,path.p[path.numPoints-1].y); |
316 for(i = 1;i < path.numPoints;i++) { | 311 for(i = 1;i < path.numPoints;i++) { |
317 float d = sqrt((path.p[i-1].x-path.p[i].x)*(path.p[i-1].x-path.p[i].x)+ | 312 float d = sqrt((path.p[i-1].x-path.p[i].x)*(path.p[i-1].x-path.p[i].x)+ |
376 points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h; | 371 points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h; |
377 } | 372 } |
378 return numPoints; | 373 return numPoints; |
379 } | 374 } |
380 | 375 |
381 float dollarRecognize(DollarPath path,int *bestTempl,GestureTouch* touch) { | 376 float dollarRecognize(SDL_DollarPath path,int *bestTempl,SDL_GestureTouch* touch) { |
382 | 377 |
383 Point points[DOLLARNPOINTS]; | 378 SDL_FloatPoint points[DOLLARNPOINTS]; |
384 int numPoints = dollarNormalize(path,points); | 379 int numPoints = dollarNormalize(path,points); |
385 //SDL_PrintPath(points); | 380 //SDL_PrintPath(points); |
386 int i; | 381 int i; |
387 | 382 |
388 int bestDiff = 10000; | 383 int bestDiff = 10000; |
392 if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;} | 387 if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;} |
393 } | 388 } |
394 return bestDiff; | 389 return bestDiff; |
395 } | 390 } |
396 | 391 |
397 int SDL_GestureAddTouch(SDL_Touch* touch) { | 392 int SDL_GestureAddTouch(SDL_Touch* touch) { |
398 if(numGestureTouches >= MAXTOUCHES) return -1; | 393 SDL_GestureTouch *gestureTouch = SDL_realloc(SDL_gestureTouch, |
399 | 394 (SDL_numGestureTouches + 1) * |
400 gestureTouch[numGestureTouches].res.x = touch->xres; | 395 sizeof(SDL_GestureTouch)); |
401 gestureTouch[numGestureTouches].res.y = touch->yres; | 396 |
402 gestureTouch[numGestureTouches].numDownFingers = 0; | 397 if(!gestureTouch) { |
403 | 398 SDL_OutOfMemory(); |
404 gestureTouch[numGestureTouches].res.x = touch->xres; | 399 return -1; |
405 gestureTouch[numGestureTouches].id = touch->id; | 400 } |
406 | 401 |
407 gestureTouch[numGestureTouches].numDollarTemplates = 0; | 402 SDL_gestureTouch = gestureTouch; |
408 | 403 |
409 gestureTouch[numGestureTouches].recording = SDL_FALSE; | 404 SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres; |
410 | 405 SDL_gestureTouch[SDL_numGestureTouches].res.y = touch->yres; |
411 numGestureTouches++; | 406 SDL_gestureTouch[SDL_numGestureTouches].numDownFingers = 0; |
407 | |
408 SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres; | |
409 SDL_gestureTouch[SDL_numGestureTouches].id = touch->id; | |
410 | |
411 SDL_gestureTouch[SDL_numGestureTouches].numDollarTemplates = 0; | |
412 | |
413 SDL_gestureTouch[SDL_numGestureTouches].recording = SDL_FALSE; | |
414 | |
415 SDL_numGestureTouches++; | |
412 return 0; | 416 return 0; |
413 } | 417 } |
414 | 418 |
415 GestureTouch * SDL_GetGestureTouch(SDL_TouchID id) { | 419 int SDL_GestureRemoveTouch(SDL_TouchID id) { |
416 int i; | 420 int i; |
417 for(i = 0;i < numGestureTouches; i++) { | 421 for(i = 0;i < SDL_numGestureTouches; i++) { |
418 //printf("%i ?= %i\n",gestureTouch[i].id,id); | 422 if(SDL_gestureTouch[i].id == id) { |
419 if(gestureTouch[i].id == id) return &gestureTouch[i]; | 423 SDL_numGestureTouches--; |
424 SDL_gestureTouch[i] = SDL_gestureTouch[SDL_numGestureTouches]; | |
425 return 1; | |
426 } | |
427 } | |
428 return -1; | |
429 } | |
430 | |
431 | |
432 SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id) { | |
433 int i; | |
434 for(i = 0;i < SDL_numGestureTouches; i++) { | |
435 //printf("%i ?= %i\n",SDL_gestureTouch[i].id,id); | |
436 if(SDL_gestureTouch[i].id == id) return &SDL_gestureTouch[i]; | |
420 } | 437 } |
421 return NULL; | 438 return NULL; |
422 } | 439 } |
423 | 440 |
424 int SDL_SendGestureMulti(GestureTouch* touch,float dTheta,float dDist) { | 441 int SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist) { |
425 SDL_Event event; | 442 SDL_Event event; |
426 event.mgesture.type = SDL_MULTIGESTURE; | 443 event.mgesture.type = SDL_MULTIGESTURE; |
427 event.mgesture.touchId = touch->id; | 444 event.mgesture.touchId = touch->id; |
428 event.mgesture.x = touch->centroid.x; | 445 event.mgesture.x = touch->centroid.x; |
429 event.mgesture.y = touch->centroid.y; | 446 event.mgesture.y = touch->centroid.y; |
431 event.mgesture.dDist = dDist; | 448 event.mgesture.dDist = dDist; |
432 event.mgesture.numFingers = touch->numDownFingers; | 449 event.mgesture.numFingers = touch->numDownFingers; |
433 return SDL_PushEvent(&event) > 0; | 450 return SDL_PushEvent(&event) > 0; |
434 } | 451 } |
435 | 452 |
436 int SDL_SendGestureDollar(GestureTouch* touch, | 453 int SDL_SendGestureDollar(SDL_GestureTouch* touch, |
437 SDL_GestureID gestureId,float error) { | 454 SDL_GestureID gestureId,float error) { |
438 SDL_Event event; | 455 SDL_Event event; |
439 event.dgesture.type = SDL_DOLLARGESTURE; | 456 event.dgesture.type = SDL_DOLLARGESTURE; |
440 event.dgesture.touchId = touch->id; | 457 event.dgesture.touchId = touch->id; |
441 /* | 458 /* |
447 event.dgesture.error = error; | 464 event.dgesture.error = error; |
448 return SDL_PushEvent(&event) > 0; | 465 return SDL_PushEvent(&event) > 0; |
449 } | 466 } |
450 | 467 |
451 | 468 |
452 int SDL_SendDollarRecord(GestureTouch* touch,SDL_GestureID gestureId) { | 469 int SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId) { |
453 SDL_Event event; | 470 SDL_Event event; |
454 event.dgesture.type = SDL_DOLLARRECORD; | 471 event.dgesture.type = SDL_DOLLARRECORD; |
455 event.dgesture.touchId = touch->id; | 472 event.dgesture.touchId = touch->id; |
456 event.dgesture.gestureId = gestureId; | 473 event.dgesture.gestureId = gestureId; |
457 | 474 |
462 void SDL_GestureProcessEvent(SDL_Event* event) | 479 void SDL_GestureProcessEvent(SDL_Event* event) |
463 { | 480 { |
464 if(event->type == SDL_FINGERMOTION || | 481 if(event->type == SDL_FINGERMOTION || |
465 event->type == SDL_FINGERDOWN || | 482 event->type == SDL_FINGERDOWN || |
466 event->type == SDL_FINGERUP) { | 483 event->type == SDL_FINGERUP) { |
467 GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId); | 484 SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId); |
468 | 485 |
469 //Shouldn't be possible | 486 //Shouldn't be possible |
470 if(inTouch == NULL) return; | 487 if(inTouch == NULL) return; |
471 | 488 |
472 //printf("@ (%i,%i) with res: (%i,%i)\n",(int)event->tfinger.x, | 489 //printf("@ (%i,%i) with res: (%i,%i)\n",(int)event->tfinger.x, |
483 inTouch->numDownFingers--; | 500 inTouch->numDownFingers--; |
484 | 501 |
485 #ifdef ENABLE_DOLLAR | 502 #ifdef ENABLE_DOLLAR |
486 if(inTouch->recording) { | 503 if(inTouch->recording) { |
487 inTouch->recording = SDL_FALSE; | 504 inTouch->recording = SDL_FALSE; |
488 Point path[DOLLARNPOINTS]; | 505 SDL_FloatPoint path[DOLLARNPOINTS]; |
489 dollarNormalize(inTouch->dollarPath,path); | 506 dollarNormalize(inTouch->dollarPath,path); |
490 //SDL_PrintPath(path); | 507 //SDL_PrintPath(path); |
491 int index; | 508 int index; |
492 if(recordAll) { | 509 if(recordAll) { |
493 index = SDL_AddDollarGesture(NULL,path); | 510 index = SDL_AddDollarGesture(NULL,path); |
494 int i; | 511 int i; |
495 for(i = 0;i < numGestureTouches; i++) | 512 for(i = 0;i < SDL_numGestureTouches; i++) |
496 gestureTouch[i].recording = SDL_FALSE; | 513 SDL_gestureTouch[i].recording = SDL_FALSE; |
497 } | 514 } |
498 else { | 515 else { |
499 index = SDL_AddDollarGesture(inTouch,path); | 516 index = SDL_AddDollarGesture(inTouch,path); |
500 } | 517 } |
501 | 518 |
530 else if(event->type == SDL_FINGERMOTION) { | 547 else if(event->type == SDL_FINGERMOTION) { |
531 float dx = ((float)event->tfinger.dx)/(float)inTouch->res.x; | 548 float dx = ((float)event->tfinger.dx)/(float)inTouch->res.x; |
532 float dy = ((float)event->tfinger.dy)/(float)inTouch->res.y; | 549 float dy = ((float)event->tfinger.dy)/(float)inTouch->res.y; |
533 //printf("dx,dy: (%f,%f)\n",dx,dy); | 550 //printf("dx,dy: (%f,%f)\n",dx,dy); |
534 #ifdef ENABLE_DOLLAR | 551 #ifdef ENABLE_DOLLAR |
535 DollarPath* path = &inTouch->dollarPath; | 552 SDL_DollarPath* path = &inTouch->dollarPath; |
536 if(path->numPoints < MAXPATHSIZE) { | 553 if(path->numPoints < MAXPATHSIZE) { |
537 path->p[path->numPoints].x = inTouch->centroid.x; | 554 path->p[path->numPoints].x = inTouch->centroid.x; |
538 path->p[path->numPoints].y = inTouch->centroid.y; | 555 path->p[path->numPoints].y = inTouch->centroid.y; |
539 float pathDx = | 556 float pathDx = |
540 (path->p[path->numPoints].x-path->p[path->numPoints-1].x); | 557 (path->p[path->numPoints].x-path->p[path->numPoints-1].x); |
542 (path->p[path->numPoints].y-path->p[path->numPoints-1].y); | 559 (path->p[path->numPoints].y-path->p[path->numPoints-1].y); |
543 path->length += sqrt(pathDx*pathDx + pathDy*pathDy); | 560 path->length += sqrt(pathDx*pathDx + pathDy*pathDy); |
544 path->numPoints++; | 561 path->numPoints++; |
545 } | 562 } |
546 #endif | 563 #endif |
547 Point lastP; | 564 SDL_FloatPoint lastP; |
548 lastP.x = x - dx; | 565 lastP.x = x - dx; |
549 lastP.y = y - dy; | 566 lastP.y = y - dy; |
550 Point lastCentroid; | 567 SDL_FloatPoint lastCentroid; |
551 lastCentroid = inTouch->centroid; | 568 lastCentroid = inTouch->centroid; |
552 | 569 |
553 inTouch->centroid.x += dx/inTouch->numDownFingers; | 570 inTouch->centroid.x += dx/inTouch->numDownFingers; |
554 inTouch->centroid.y += dy/inTouch->numDownFingers; | 571 inTouch->centroid.y += dy/inTouch->numDownFingers; |
555 //printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y); | 572 //printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y); |
556 if(inTouch->numDownFingers > 1) { | 573 if(inTouch->numDownFingers > 1) { |
557 Point lv; //Vector from centroid to last x,y position | 574 SDL_FloatPoint lv; //Vector from centroid to last x,y position |
558 Point v; //Vector from centroid to current x,y position | 575 SDL_FloatPoint v; //Vector from centroid to current x,y position |
559 //lv = inTouch->gestureLast[j].cv; | 576 //lv = inTouch->gestureLast[j].cv; |
560 lv.x = lastP.x - lastCentroid.x; | 577 lv.x = lastP.x - lastCentroid.x; |
561 lv.y = lastP.y - lastCentroid.y; | 578 lv.y = lastP.y - lastCentroid.y; |
562 float lDist = sqrt(lv.x*lv.x + lv.y*lv.y); | 579 float lDist = sqrt(lv.x*lv.x + lv.y*lv.y); |
563 //printf("lDist = %f\n",lDist); | 580 //printf("lDist = %f\n",lDist); |
606 inTouch->numDownFingers++; | 623 inTouch->numDownFingers++; |
607 inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+ | 624 inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+ |
608 x)/inTouch->numDownFingers; | 625 x)/inTouch->numDownFingers; |
609 inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+ | 626 inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+ |
610 y)/inTouch->numDownFingers; | 627 y)/inTouch->numDownFingers; |
611 printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y, | 628 //printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y, |
612 inTouch->centroid.x,inTouch->centroid.y); | 629 // inTouch->centroid.x,inTouch->centroid.y); |
613 /* | 630 |
614 inTouch->gestureLast[j].f.id = event->tfinger.fingerId; | |
615 inTouch->gestureLast[j].f.p.x = x; | |
616 inTouch->gestureLast[j].f.p.y = y; | |
617 inTouch->gestureLast[j].cv.x = 0; | |
618 inTouch->gestureLast[j].cv.y = 0; | |
619 */ | |
620 #ifdef ENABLE_DOLLAR | 631 #ifdef ENABLE_DOLLAR |
621 inTouch->dollarPath.length = 0; | 632 inTouch->dollarPath.length = 0; |
622 inTouch->dollarPath.p[0].x = x; | 633 inTouch->dollarPath.p[0].x = x; |
623 inTouch->dollarPath.p[0].y = y; | 634 inTouch->dollarPath.p[0].y = y; |
624 inTouch->dollarPath.numPoints = 1; | 635 inTouch->dollarPath.numPoints = 1; |