Mercurial > sdl-ios-xcode
comparison src/events/SDL_gesture.c @ 4868:d6adaafcfb10
Fixed compiling with Visual Studio 2008
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 29 Aug 2010 14:22:22 -0700 |
parents | fff50e86c891 |
children | 716b2cbf4c9e |
comparison
equal
deleted
inserted
replaced
4867:ba7492f9e2b8 | 4868:d6adaafcfb10 |
---|---|
42 #define DOLLARNPOINTS 64 | 42 #define DOLLARNPOINTS 64 |
43 #define DOLLARSIZE 256 | 43 #define DOLLARSIZE 256 |
44 | 44 |
45 #define ENABLE_DOLLAR | 45 #define ENABLE_DOLLAR |
46 | 46 |
47 //PHI = ((sqrt(5)-1)/2) | |
48 #define PHI 0.618033989 | 47 #define PHI 0.618033989 |
49 | 48 |
50 typedef struct { | 49 typedef struct { |
51 float x,y; | 50 float x,y; |
52 } SDL_FloatPoint; | 51 } SDL_FloatPoint; |
78 | 77 |
79 SDL_GestureTouch *SDL_gestureTouch; | 78 SDL_GestureTouch *SDL_gestureTouch; |
80 int SDL_numGestureTouches = 0; | 79 int SDL_numGestureTouches = 0; |
81 SDL_bool recordAll; | 80 SDL_bool recordAll; |
82 | 81 |
83 void SDL_PrintPath(SDL_FloatPoint *path) { | 82 #if 0 |
83 static void PrintPath(SDL_FloatPoint *path) { | |
84 int i; | 84 int i; |
85 printf("Path:"); | 85 printf("Path:"); |
86 for(i=0;i<DOLLARNPOINTS;i++) { | 86 for(i=0;i<DOLLARNPOINTS;i++) { |
87 printf(" (%f,%f)",path[i].x,path[i].y); | 87 printf(" (%f,%f)",path[i].x,path[i].y); |
88 } | 88 } |
89 printf("\n"); | 89 printf("\n"); |
90 } | 90 } |
91 #endif | |
91 | 92 |
92 int SDL_RecordGesture(SDL_TouchID touchId) { | 93 int SDL_RecordGesture(SDL_TouchID touchId) { |
93 int i; | 94 int i; |
94 if(touchId < 0) recordAll = SDL_TRUE; | 95 if(touchId < 0) recordAll = SDL_TRUE; |
95 for(i = 0;i < SDL_numGestureTouches; i++) { | 96 for(i = 0;i < SDL_numGestureTouches; i++) { |
175 | 176 |
176 inTouch->dollarTemplate = dollarTemplate; | 177 inTouch->dollarTemplate = dollarTemplate; |
177 | 178 |
178 templ = | 179 templ = |
179 &inTouch->dollarTemplate[inTouch->numDollarTemplates]; | 180 &inTouch->dollarTemplate[inTouch->numDollarTemplates]; |
180 memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint)); | 181 SDL_memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint)); |
181 templ->hash = SDL_HashDollar(templ->path); | 182 templ->hash = SDL_HashDollar(templ->path); |
182 inTouch->numDollarTemplates++; | 183 inTouch->numDollarTemplates++; |
183 } | 184 } |
184 return inTouch->numDollarTemplates - 1; | 185 return inTouch->numDollarTemplates - 1; |
185 } else { | 186 } else { |
194 | 195 |
195 inTouch->dollarTemplate = dollarTemplate; | 196 inTouch->dollarTemplate = dollarTemplate; |
196 | 197 |
197 templ = | 198 templ = |
198 &inTouch->dollarTemplate[inTouch->numDollarTemplates]; | 199 &inTouch->dollarTemplate[inTouch->numDollarTemplates]; |
199 memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint)); | 200 SDL_memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint)); |
200 templ->hash = SDL_HashDollar(templ->path); | 201 templ->hash = SDL_HashDollar(templ->path); |
201 inTouch->numDollarTemplates++; | 202 inTouch->numDollarTemplates++; |
202 return inTouch->numDollarTemplates - 1; | 203 return inTouch->numDollarTemplates - 1; |
203 } | 204 } |
204 return -1; | 205 return -1; |
220 | 221 |
221 if(SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < | 222 if(SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < |
222 DOLLARNPOINTS) break; | 223 DOLLARNPOINTS) break; |
223 | 224 |
224 if(touchId >= 0) { | 225 if(touchId >= 0) { |
225 printf("Adding loaded gesture to 1 touch\n"); | 226 //printf("Adding loaded gesture to 1 touch\n"); |
226 if(SDL_AddDollarGesture(touch,templ.path)) loaded++; | 227 if(SDL_AddDollarGesture(touch,templ.path)) loaded++; |
227 } | 228 } |
228 else { | 229 else { |
229 printf("Adding to: %i touches\n",SDL_numGestureTouches); | 230 //printf("Adding to: %i touches\n",SDL_numGestureTouches); |
230 for(i = 0;i < SDL_numGestureTouches; i++) { | 231 for(i = 0;i < SDL_numGestureTouches; i++) { |
231 touch = &SDL_gestureTouch[i]; | 232 touch = &SDL_gestureTouch[i]; |
232 printf("Adding loaded gesture to + touches\n"); | 233 //printf("Adding loaded gesture to + touches\n"); |
233 //TODO: What if this fails? | 234 //TODO: What if this fails? |
234 SDL_AddDollarGesture(touch,templ.path); | 235 SDL_AddDollarGesture(touch,templ.path); |
235 } | 236 } |
236 loaded++; | 237 loaded++; |
237 } | 238 } |
245 // SDL_FloatPoint p[DOLLARNPOINTS]; | 246 // SDL_FloatPoint p[DOLLARNPOINTS]; |
246 float dist = 0; | 247 float dist = 0; |
247 SDL_FloatPoint p; | 248 SDL_FloatPoint p; |
248 int i; | 249 int i; |
249 for(i = 0; i < DOLLARNPOINTS; i++) { | 250 for(i = 0; i < DOLLARNPOINTS; i++) { |
250 p.x = (float)(points[i].x * cos(ang) - points[i].y * sin(ang)); | 251 p.x = (float)(points[i].x * SDL_cos(ang) - points[i].y * SDL_sin(ang)); |
251 p.y = (float)(points[i].x * sin(ang) + points[i].y * cos(ang)); | 252 p.y = (float)(points[i].x * SDL_sin(ang) + points[i].y * SDL_cos(ang)); |
252 dist += (float)(sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+ | 253 dist += (float)(SDL_sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+ |
253 (p.y-templ[i].y)*(p.y-templ[i].y))); | 254 (p.y-templ[i].y)*(p.y-templ[i].y))); |
254 } | 255 } |
255 return dist/DOLLARNPOINTS; | 256 return dist/DOLLARNPOINTS; |
256 | 257 |
257 } | 258 } |
265 double dt = M_PI/90; | 266 double dt = M_PI/90; |
266 float x1 = (float)(PHI*ta + (1-PHI)*tb); | 267 float x1 = (float)(PHI*ta + (1-PHI)*tb); |
267 float f1 = dollarDifference(points,templ,x1); | 268 float f1 = dollarDifference(points,templ,x1); |
268 float x2 = (float)((1-PHI)*ta + PHI*tb); | 269 float x2 = (float)((1-PHI)*ta + PHI*tb); |
269 float f2 = dollarDifference(points,templ,x2); | 270 float f2 = dollarDifference(points,templ,x2); |
270 while(fabs(ta-tb) > dt) { | 271 while(SDL_fabs(ta-tb) > dt) { |
271 if(f1 < f2) { | 272 if(f1 < f2) { |
272 tb = x2; | 273 tb = x2; |
273 x2 = x1; | 274 x2 = x1; |
274 f2 = f1; | 275 f2 = f1; |
275 x1 = (float)(PHI*ta + (1-PHI)*tb); | 276 x1 = (float)(PHI*ta + (1-PHI)*tb); |
308 for(i=1;i<path.numPoints;i++) { | 309 for(i=1;i<path.numPoints;i++) { |
309 float dx = path.p[i ].x - | 310 float dx = path.p[i ].x - |
310 path.p[i-1].x; | 311 path.p[i-1].x; |
311 float dy = path.p[i ].y - | 312 float dy = path.p[i ].y - |
312 path.p[i-1].y; | 313 path.p[i-1].y; |
313 path.length += (float)(sqrt(dx*dx+dy*dy)); | 314 path.length += (float)(SDL_sqrt(dx*dx+dy*dy)); |
314 } | 315 } |
315 } | 316 } |
316 | 317 |
317 //Resample | 318 //Resample |
318 interval = path.length/(DOLLARNPOINTS - 1); | 319 interval = path.length/(DOLLARNPOINTS - 1); |
320 | 321 |
321 centroid.x = 0;centroid.y = 0; | 322 centroid.x = 0;centroid.y = 0; |
322 | 323 |
323 //printf("(%f,%f)\n",path.p[path.numPoints-1].x,path.p[path.numPoints-1].y); | 324 //printf("(%f,%f)\n",path.p[path.numPoints-1].x,path.p[path.numPoints-1].y); |
324 for(i = 1;i < path.numPoints;i++) { | 325 for(i = 1;i < path.numPoints;i++) { |
325 float d = (float)(sqrt((path.p[i-1].x-path.p[i].x)*(path.p[i-1].x-path.p[i].x)+ | 326 float d = (float)(SDL_sqrt((path.p[i-1].x-path.p[i].x)*(path.p[i-1].x-path.p[i].x)+ |
326 (path.p[i-1].y-path.p[i].y)*(path.p[i-1].y-path.p[i].y))); | 327 (path.p[i-1].y-path.p[i].y)*(path.p[i-1].y-path.p[i].y))); |
327 //printf("d = %f dist = %f/%f\n",d,dist,interval); | 328 //printf("d = %f dist = %f/%f\n",d,dist,interval); |
328 while(dist + d > interval) { | 329 while(dist + d > interval) { |
329 points[numPoints].x = path.p[i-1].x + | 330 points[numPoints].x = path.p[i-1].x + |
330 ((interval-dist)/d)*(path.p[i].x-path.p[i-1].x); | 331 ((interval-dist)/d)*(path.p[i].x-path.p[i-1].x); |
337 dist -= interval; | 338 dist -= interval; |
338 } | 339 } |
339 dist += d; | 340 dist += d; |
340 } | 341 } |
341 if(numPoints < DOLLARNPOINTS-1) { | 342 if(numPoints < DOLLARNPOINTS-1) { |
342 printf("ERROR: NumPoints = %i\n",numPoints); | 343 SDL_SetError("ERROR: NumPoints = %i\n",numPoints); |
343 return 0; | 344 return 0; |
344 } | 345 } |
345 //copy the last point | 346 //copy the last point |
346 points[DOLLARNPOINTS-1] = path.p[path.numPoints-1]; | 347 points[DOLLARNPOINTS-1] = path.p[path.numPoints-1]; |
347 numPoints = DOLLARNPOINTS; | 348 numPoints = DOLLARNPOINTS; |
354 xmin = centroid.x; | 355 xmin = centroid.x; |
355 xmax = centroid.x; | 356 xmax = centroid.x; |
356 ymin = centroid.y; | 357 ymin = centroid.y; |
357 ymax = centroid.y; | 358 ymax = centroid.y; |
358 | 359 |
359 ang = (float)(atan2(centroid.y - points[0].y, | 360 ang = (float)(SDL_atan2(centroid.y - points[0].y, |
360 centroid.x - points[0].x)); | 361 centroid.x - points[0].x)); |
361 | 362 |
362 for(i = 0;i<numPoints;i++) { | 363 for(i = 0;i<numPoints;i++) { |
363 float px = points[i].x; | 364 float px = points[i].x; |
364 float py = points[i].y; | 365 float py = points[i].y; |
365 points[i].x = (float)((px - centroid.x)*cos(ang) - | 366 points[i].x = (float)((px - centroid.x)*SDL_cos(ang) - |
366 (py - centroid.y)*sin(ang) + centroid.x); | 367 (py - centroid.y)*SDL_sin(ang) + centroid.x); |
367 points[i].y = (float)((px - centroid.x)*sin(ang) + | 368 points[i].y = (float)((px - centroid.x)*SDL_sin(ang) + |
368 (py - centroid.y)*cos(ang) + centroid.y); | 369 (py - centroid.y)*SDL_cos(ang) + centroid.y); |
369 | 370 |
370 | 371 |
371 if(points[i].x < xmin) xmin = points[i].x; | 372 if(points[i].x < xmin) xmin = points[i].x; |
372 if(points[i].x > xmax) xmax = points[i].x; | 373 if(points[i].x > xmax) xmax = points[i].x; |
373 if(points[i].y < ymin) ymin = points[i].y; | 374 if(points[i].y < ymin) ymin = points[i].y; |
387 | 388 |
388 float dollarRecognize(SDL_DollarPath path,int *bestTempl,SDL_GestureTouch* touch) { | 389 float dollarRecognize(SDL_DollarPath path,int *bestTempl,SDL_GestureTouch* touch) { |
389 | 390 |
390 SDL_FloatPoint points[DOLLARNPOINTS]; | 391 SDL_FloatPoint points[DOLLARNPOINTS]; |
391 int numPoints = dollarNormalize(path,points); | 392 int numPoints = dollarNormalize(path,points); |
392 //SDL_PrintPath(points); | |
393 int i; | 393 int i; |
394 | |
395 float bestDiff = 10000; | 394 float bestDiff = 10000; |
395 | |
396 //PrintPath(points); | |
396 *bestTempl = -1; | 397 *bestTempl = -1; |
397 for(i = 0;i < touch->numDollarTemplates;i++) { | 398 for(i = 0;i < touch->numDollarTemplates;i++) { |
398 float diff = bestDollarDifference(points,touch->dollarTemplate[i].path); | 399 float diff = bestDollarDifference(points,touch->dollarTemplate[i].path); |
399 if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;} | 400 if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;} |
400 } | 401 } |
428 return 0; | 429 return 0; |
429 } | 430 } |
430 | 431 |
431 int SDL_GestureRemoveTouch(SDL_TouchID id) { | 432 int SDL_GestureRemoveTouch(SDL_TouchID id) { |
432 int i; | 433 int i; |
433 for(i = 0;i < SDL_numGestureTouches; i++) { | 434 for (i = 0; i < SDL_numGestureTouches; i++) { |
434 if(SDL_gestureTouch[i].id == id) { | 435 if (SDL_gestureTouch[i].id == id) { |
435 SDL_numGestureTouches--; | 436 SDL_numGestureTouches--; |
436 SDL_gestureTouch[i] = SDL_gestureTouch[SDL_numGestureTouches]; | 437 SDL_memcpy(&SDL_gestureTouch[i], &SDL_gestureTouch[SDL_numGestureTouches], sizeof(SDL_gestureTouch[i])); |
437 return 1; | 438 return 1; |
438 } | 439 } |
439 } | 440 } |
440 return -1; | 441 return -1; |
441 } | 442 } |
526 | 527 |
527 #ifdef ENABLE_DOLLAR | 528 #ifdef ENABLE_DOLLAR |
528 if(inTouch->recording) { | 529 if(inTouch->recording) { |
529 inTouch->recording = SDL_FALSE; | 530 inTouch->recording = SDL_FALSE; |
530 dollarNormalize(inTouch->dollarPath,path); | 531 dollarNormalize(inTouch->dollarPath,path); |
531 //SDL_PrintPath(path); | 532 //PrintPath(path); |
532 if(recordAll) { | 533 if(recordAll) { |
533 index = SDL_AddDollarGesture(NULL,path); | 534 index = SDL_AddDollarGesture(NULL,path); |
534 for(i = 0;i < SDL_numGestureTouches; i++) | 535 for(i = 0;i < SDL_numGestureTouches; i++) |
535 SDL_gestureTouch[i].recording = SDL_FALSE; | 536 SDL_gestureTouch[i].recording = SDL_FALSE; |
536 } | 537 } |
577 path->p[path->numPoints].y = inTouch->centroid.y; | 578 path->p[path->numPoints].y = inTouch->centroid.y; |
578 pathDx = | 579 pathDx = |
579 (path->p[path->numPoints].x-path->p[path->numPoints-1].x); | 580 (path->p[path->numPoints].x-path->p[path->numPoints-1].x); |
580 pathDy = | 581 pathDy = |
581 (path->p[path->numPoints].y-path->p[path->numPoints-1].y); | 582 (path->p[path->numPoints].y-path->p[path->numPoints-1].y); |
582 path->length += (float)sqrt(pathDx*pathDx + pathDy*pathDy); | 583 path->length += (float)SDL_sqrt(pathDx*pathDx + pathDy*pathDy); |
583 path->numPoints++; | 584 path->numPoints++; |
584 } | 585 } |
585 #endif | 586 #endif |
586 lastP.x = x - dx; | 587 lastP.x = x - dx; |
587 lastP.y = y - dy; | 588 lastP.y = y - dy; |
594 SDL_FloatPoint lv; //Vector from centroid to last x,y position | 595 SDL_FloatPoint lv; //Vector from centroid to last x,y position |
595 SDL_FloatPoint v; //Vector from centroid to current x,y position | 596 SDL_FloatPoint v; //Vector from centroid to current x,y position |
596 //lv = inTouch->gestureLast[j].cv; | 597 //lv = inTouch->gestureLast[j].cv; |
597 lv.x = lastP.x - lastCentroid.x; | 598 lv.x = lastP.x - lastCentroid.x; |
598 lv.y = lastP.y - lastCentroid.y; | 599 lv.y = lastP.y - lastCentroid.y; |
599 lDist = (float)sqrt(lv.x*lv.x + lv.y*lv.y); | 600 lDist = (float)SDL_sqrt(lv.x*lv.x + lv.y*lv.y); |
600 //printf("lDist = %f\n",lDist); | 601 //printf("lDist = %f\n",lDist); |
601 v.x = x - inTouch->centroid.x; | 602 v.x = x - inTouch->centroid.x; |
602 v.y = y - inTouch->centroid.y; | 603 v.y = y - inTouch->centroid.y; |
603 //inTouch->gestureLast[j].cv = v; | 604 //inTouch->gestureLast[j].cv = v; |
604 Dist = (float)sqrt(v.x*v.x+v.y*v.y); | 605 Dist = (float)SDL_sqrt(v.x*v.x+v.y*v.y); |
605 // cos(dTheta) = (v . lv)/(|v| * |lv|) | 606 // SDL_cos(dTheta) = (v . lv)/(|v| * |lv|) |
606 | 607 |
607 //Normalize Vectors to simplify angle calculation | 608 //Normalize Vectors to simplify angle calculation |
608 lv.x/=lDist; | 609 lv.x/=lDist; |
609 lv.y/=lDist; | 610 lv.y/=lDist; |
610 v.x/=Dist; | 611 v.x/=Dist; |
611 v.y/=Dist; | 612 v.y/=Dist; |
612 dtheta = (float)atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y); | 613 dtheta = (float)SDL_atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y); |
613 | 614 |
614 dDist = (Dist - lDist); | 615 dDist = (Dist - lDist); |
615 if(lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values | 616 if(lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values |
616 | 617 |
617 //inTouch->gestureLast[j].dDist = dDist; | 618 //inTouch->gestureLast[j].dDist = dDist; |