diff src/events/SDL_gesture.c @ 4919:716b2cbf4c9e

First pass at Windows multi-touch gesture support
author Sam Lantinga <slouken@libsdl.org>
date Tue, 30 Nov 2010 17:58:51 -0800
parents d6adaafcfb10
children a4032241deb5
line wrap: on
line diff
--- a/src/events/SDL_gesture.c	Tue Nov 30 12:38:46 2010 -0800
+++ b/src/events/SDL_gesture.c	Tue Nov 30 17:58:51 2010 -0800
@@ -97,7 +97,7 @@
     if((touchId < 0) || (SDL_gestureTouch[i].id == touchId)) {
       SDL_gestureTouch[i].recording = SDL_TRUE;
       if(touchId >= 0)
-	return 1;
+        return 1;
     }      
   }
   return (touchId < 0);
@@ -122,7 +122,7 @@
   //if(SDL_RWops.write(src,&(templ->hash),sizeof(templ->hash),1) != 1) return 0;
   
   if(SDL_RWwrite(src,templ->path,
-		 sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) 
+                 sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) 
     return 0;
 
   return 1;
@@ -134,7 +134,7 @@
   for(i = 0; i < SDL_numGestureTouches; i++) {
     SDL_GestureTouch* touch = &SDL_gestureTouch[i];
     for(j = 0;j < touch->numDollarTemplates; j++) {
-	rtrn += SaveTemplate(&touch->dollarTemplate[i],src);
+        rtrn += SaveTemplate(&touch->dollarTemplate[i],src);
     }
   }
   return rtrn;  
@@ -146,7 +146,7 @@
     SDL_GestureTouch* touch = &SDL_gestureTouch[i];
     for(j = 0;j < touch->numDollarTemplates; j++) {
       if(touch->dollarTemplate[i].hash == gestureId) {
-	return SaveTemplate(&touch->dollarTemplate[i],src);
+        return SaveTemplate(&touch->dollarTemplate[i],src);
       }
     }
   }
@@ -166,18 +166,18 @@
       inTouch = &SDL_gestureTouch[i];
 
     dollarTemplate = 
-	(SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
-		    (inTouch->numDollarTemplates + 1) * 
-		    sizeof(SDL_DollarTemplate));
+        (SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
+                    (inTouch->numDollarTemplates + 1) * 
+                    sizeof(SDL_DollarTemplate));
       if(!dollarTemplate) {
-	SDL_OutOfMemory();
-	return -1;
+        SDL_OutOfMemory();
+        return -1;
       }
-	
+        
       inTouch->dollarTemplate = dollarTemplate;
 
     templ = 
-	&inTouch->dollarTemplate[inTouch->numDollarTemplates];
+        &inTouch->dollarTemplate[inTouch->numDollarTemplates];
       SDL_memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
       templ->hash = SDL_HashDollar(templ->path);
       inTouch->numDollarTemplates++;    
@@ -186,8 +186,8 @@
   } else {
     SDL_DollarTemplate* dollarTemplate = 
       ( SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
-		  (inTouch->numDollarTemplates + 1) * 
-		  sizeof(SDL_DollarTemplate));
+                  (inTouch->numDollarTemplates + 1) * 
+                  sizeof(SDL_DollarTemplate));
     if(!dollarTemplate) {
       SDL_OutOfMemory();
       return -1;
@@ -212,7 +212,7 @@
   if(touchId >= 0) {
     for(i = 0;i < SDL_numGestureTouches; i++)
       if(SDL_gestureTouch[i].id == touchId)
-	touch = &SDL_gestureTouch[i];
+        touch = &SDL_gestureTouch[i];
     if(touch == NULL) return -1;
   }
 
@@ -229,10 +229,10 @@
     else {
       //printf("Adding to: %i touches\n",SDL_numGestureTouches);
       for(i = 0;i < SDL_numGestureTouches; i++) {
-	touch = &SDL_gestureTouch[i];
-	//printf("Adding loaded gesture to + touches\n");
-	//TODO: What if this fails?
-	SDL_AddDollarGesture(touch,templ.path);	
+        touch = &SDL_gestureTouch[i];
+        //printf("Adding loaded gesture to + touches\n");
+        //TODO: What if this fails?
+        SDL_AddDollarGesture(touch,templ.path);        
       }
       loaded++;
     }
@@ -251,7 +251,7 @@
     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)+
-		 (p.y-templ[i].y)*(p.y-templ[i].y)));
+                 (p.y-templ[i].y)*(p.y-templ[i].y)));
   }
   return dist/DOLLARNPOINTS;
   
@@ -308,9 +308,9 @@
   if(path.length <= 0) {
     for(i=1;i<path.numPoints;i++) {
       float dx = path.p[i  ].x - 
-	         path.p[i-1].x;
+                 path.p[i-1].x;
       float dy = path.p[i  ].y - 
-	         path.p[i-1].y;
+                 path.p[i-1].y;
       path.length += (float)(SDL_sqrt(dx*dx+dy*dy));
     }
   }
@@ -324,13 +324,13 @@
   //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)));
+                             (path.p[i-1].y-path.p[i].y)*(path.p[i-1].y-path.p[i].y)));
     //printf("d = %f dist = %f/%f\n",d,dist,interval);
     while(dist + d > interval) {
       points[numPoints].x = path.p[i-1].x + 
-	((interval-dist)/d)*(path.p[i].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);
+        ((interval-dist)/d)*(path.p[i].y-path.p[i-1].y);
       centroid.x += points[numPoints].x;
       centroid.y += points[numPoints].y;
       numPoints++;
@@ -358,9 +358,9 @@
   ymax = centroid.y;
   
   ang = (float)(SDL_atan2(centroid.y - points[0].y,
-		    centroid.x - points[0].x));
+                    centroid.x - points[0].x));
 
-  for(i = 0;i<numPoints;i++) {					       
+  for(i = 0;i<numPoints;i++) {                                               
     float px = points[i].x;
     float py = points[i].y;
     points[i].x = (float)((px - centroid.x)*SDL_cos(ang) - 
@@ -387,25 +387,25 @@
 }
 
 float dollarRecognize(SDL_DollarPath path,int *bestTempl,SDL_GestureTouch* touch) {
-	
-	SDL_FloatPoint points[DOLLARNPOINTS];
-	int numPoints = dollarNormalize(path,points);
-	int i;
-	float bestDiff = 10000;
+        
+        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;
+        //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;
 }
 
 int SDL_GestureAddTouch(SDL_Touch* touch) {  
   SDL_GestureTouch *gestureTouch = (SDL_GestureTouch *)SDL_realloc(SDL_gestureTouch,
-					       (SDL_numGestureTouches + 1) *
-					       sizeof(SDL_GestureTouch));
+                                               (SDL_numGestureTouches + 1) *
+                                               sizeof(SDL_GestureTouch));
 
   if(!gestureTouch) {
     SDL_OutOfMemory();
@@ -464,7 +464,7 @@
 }
 
 int SDL_SendGestureDollar(SDL_GestureTouch* touch,
-			  SDL_GestureID gestureId,float error) {
+                          SDL_GestureID gestureId,float error) {
   SDL_Event event;
   event.dgesture.type = SDL_DOLLARGESTURE;
   event.dgesture.touchId = touch->id;
@@ -513,7 +513,7 @@
     if(inTouch == NULL) return;
     
     //printf("@ (%i,%i) with res: (%i,%i)\n",(int)event->tfinger.x,
-    //	   (int)event->tfinger.y,
+    //           (int)event->tfinger.y,
     //   (int)inTouch->res.x,(int)inTouch->res.y);
 
     
@@ -527,44 +527,44 @@
       
 #ifdef ENABLE_DOLLAR
       if(inTouch->recording) {
-	inTouch->recording = SDL_FALSE;	
-	dollarNormalize(inTouch->dollarPath,path);
-	//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);
-	}
+        inTouch->recording = SDL_FALSE;        
+        dollarNormalize(inTouch->dollarPath,path);
+        //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);
+        }
       }
-      else {	
-	int bestTempl;
-	float error;
-	error = dollarRecognize(inTouch->dollarPath,
-				&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);
-	}
+      else {        
+        int bestTempl;
+        float error;
+        error = dollarRecognize(inTouch->dollarPath,
+                                &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);
+        }
       }
 #endif 
       //inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
       if(inTouch->numDownFingers > 0) {
-	inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
-			       x)/inTouch->numDownFingers;
-	inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
-			       y)/inTouch->numDownFingers;
+        inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
+                               x)/inTouch->numDownFingers;
+        inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
+                               y)/inTouch->numDownFingers;
       }
     }
     else if(event->type == SDL_FINGERMOTION) {
@@ -574,14 +574,14 @@
 #ifdef ENABLE_DOLLAR
       SDL_DollarPath* path = &inTouch->dollarPath;
       if(path->numPoints < MAXPATHSIZE) {
-	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++;
+        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++;
       }
 #endif
       lastP.x = x - dx;
@@ -592,46 +592,46 @@
       inTouch->centroid.y += dy/inTouch->numDownFingers;
       //printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y);
       if(inTouch->numDownFingers > 1) {
-	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);
+        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);
       }
       else {
-	//inTouch->gestureLast[j].dDist = 0;
-	//inTouch->gestureLast[j].dtheta = 0;
-	//inTouch->gestureLast[j].cv.x = 0;
-	//inTouch->gestureLast[j].cv.y = 0;
+        //inTouch->gestureLast[j].dDist = 0;
+        //inTouch->gestureLast[j].dtheta = 0;
+        //inTouch->gestureLast[j].cv.x = 0;
+        //inTouch->gestureLast[j].cv.y = 0;
       }
       //inTouch->gestureLast[j].f.p.x = x;
       //inTouch->gestureLast[j].f.p.y = y;
@@ -643,9 +643,9 @@
 
       inTouch->numDownFingers++;
       inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+ 
-			     x)/inTouch->numDownFingers;
+                             x)/inTouch->numDownFingers;
       inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
-			     y)/inTouch->numDownFingers;
+                             y)/inTouch->numDownFingers;
       //printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
       //     inTouch->centroid.x,inTouch->centroid.y);