src/events/SDL_gesture.c
changeset 4688 494f71f57a80
parent 4686 463cd74304b9
child 4689 f9ab8df6d45a
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;