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;