changeset 4683:15dfe42edbfd

Fixed gestureMulti. Disabled dollar gesture temporarily.
author Jim Grandpre <jim.tla@gmail.com>
date Wed, 04 Aug 2010 23:17:30 -0400
parents 4ba1048a324c
children f47c2640c667
files include/SDL_events.h src/events/SDL_gesture.c src/events/SDL_touch.c src/video/x11/SDL_eventtouch.c src/video/x11/SDL_x11events.c touchTest/gestureSDLTest.c
diffstat 6 files changed, 188 insertions(+), 140 deletions(-) [+]
line wrap: on
line diff
--- a/include/SDL_events.h	Tue Aug 03 00:18:00 2010 -0400
+++ b/include/SDL_events.h	Wed Aug 04 23:17:30 2010 -0400
@@ -296,6 +296,8 @@
     Uint8 padding3;
     Uint16 x;
     Uint16 y;
+    Sint16 dx;
+    Sint16 dy;
     Uint16 pressure;
 } SDL_TouchFingerEvent;
 
@@ -328,7 +330,8 @@
     float dDist;
     float x;  //currently 0...1. Change to screen coords?
     float y;  
-
+    Uint16 numFingers;
+    Uint16 padding;
 } SDL_MultiGestureEvent;
 
 typedef struct SDL_DollarGestureEvent
--- a/src/events/SDL_gesture.c	Tue Aug 03 00:18:00 2010 -0400
+++ b/src/events/SDL_gesture.c	Wed Aug 04 23:17:30 2010 -0400
@@ -75,7 +75,7 @@
   Point res;
   Point centroid;
   TouchPoint gestureLast[MAXFINGERS];
-  int numDownFingers;
+  Uint16 numDownFingers;
 
   int numDollarTemplates;
   DollarTemplate dollarTemplate[MAXTEMPLATES];
@@ -406,6 +406,7 @@
   event.mgesture.y = touch->centroid.y;
   event.mgesture.dTheta = dTheta;
   event.mgesture.dDist = dDist;  
+  event.mgesture.numFingers = touch->numDownFingers;
   return SDL_PushEvent(&event) > 0;
 }
 
@@ -441,140 +442,161 @@
      event->type == SDL_FINGERDOWN ||
      event->type == SDL_FINGERUP) {
     GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);
-
+    
     //Shouldn't be possible
     if(inTouch == NULL) return;
     
-    
-    float x = ((float)event->tfinger.x)/inTouch->res.x;
-    float y = ((float)event->tfinger.y)/inTouch->res.y;
-    int j,empty = -1;
-    
-    for(j = 0;j<inTouch->numDownFingers;j++) {
-      if(inTouch->gestureLast[j].f.id != event->tfinger.fingerId) continue;
-      //Finger Up
-      if(event->type == SDL_FINGERUP) {
-	inTouch->numDownFingers--;
+    //printf("@ (%i,%i) with res: (%i,%i)\n",(int)event->tfinger.x,
+    //	   (int)event->tfinger.y,
+    //   (int)inTouch->res.x,(int)inTouch->res.y);
 
-	if(inTouch->recording) {
-	  inTouch->recording = SDL_FALSE;
-	  Point path[DOLLARNPOINTS];
-	  dollarNormalize(inTouch->gestureLast[j].dollarPath,path);
-	  int index;
-	  if(recordAll) {
-	    index = SDL_AddDollarGesture(NULL,path);
-	    int i;
-	    for(i = 0;i < numGestureTouches; i++)
-	      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->gestureLast[j].dollarPath,
-				  &bestTempl,inTouch);
-	  if(bestTempl >= 0){
-	    //Send Event
-	    unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
-	    SDL_SendGestureDollar(inTouch,gestureId,error);
-	    printf("Dollar error: %f\n",error);
-	  }
-	} 
-	inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
-	j = -1;
-	break;
-      }
-      else if(event->type == SDL_FINGERMOTION) {
-	float dx = x - inTouch->gestureLast[j].f.p.x;
-	float dy = y - inTouch->gestureLast[j].f.p.y;
-	DollarPath* path = &inTouch->gestureLast[j].dollarPath;
-	if(path->numPoints < MAXPATHSIZE) {
-	  path->p[path->numPoints].x = x;
-	  path->p[path->numPoints].y = y;
-	  path->length += sqrt(dx*dx + dy*dy);
-	  path->numPoints++;
-	}
+    
+    float x = ((float)event->tfinger.x)/(float)inTouch->res.x;
+    float y = ((float)event->tfinger.y)/(float)inTouch->res.y;   
 
 
-	inTouch->centroid.x += dx/inTouch->numDownFingers;
-	inTouch->centroid.y += dy/inTouch->numDownFingers;    
-	if(inTouch->numDownFingers > 1) {
-	  Point lv; //Vector from centroid to last x,y position
-	  Point v; //Vector from centroid to current x,y position
-	  lv = inTouch->gestureLast[j].cv;
-	  float lDist = 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;
-	  float Dist = sqrt(v.x*v.x+v.y*v.y);
-	  // cos(dTheta) = (v . lv)/(|v| * |lv|)
-	  
-	  //Normalize Vectors to simplify angle calculation
-	  lv.x/=lDist;
-	  lv.y/=lDist;
-	  v.x/=Dist;
-	  v.y/=Dist;
-	  float dtheta = atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
-	  
-	  float 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);
+    //Finger Up
+    if(event->type == SDL_FINGERUP) {
+      inTouch->numDownFingers--;
+      
+#ifdef ENABLE_DOLLAR
+      if(inTouch->recording) {
+	inTouch->recording = SDL_FALSE;
+	Point path[DOLLARNPOINTS];
+	dollarNormalize(inTouch->gestureLast[j].dollarPath,path);
+	int index;
+	if(recordAll) {
+	  index = SDL_AddDollarGesture(NULL,path);
+	  int i;
+	  for(i = 0;i < numGestureTouches; i++)
+	    gestureTouch[i].recording = SDL_FALSE;
+	}
+	else {
+	  index = SDL_AddDollarGesture(inTouch,path);
+	}
+	
+	if(index >= 0) {
+	  SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
 	}
 	else {
-	  inTouch->gestureLast[j].dDist = 0;
-	  inTouch->gestureLast[j].dtheta = 0;
-	  inTouch->gestureLast[j].cv.x = 0;
-	  inTouch->gestureLast[j].cv.y = 0;
+	  SDL_SendDollarRecord(inTouch,-1);
+	}
+      }
+      else {	
+	int bestTempl;
+	float error;
+	error = dollarRecognize(inTouch->gestureLast[j].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);
 	}
-	inTouch->gestureLast[j].f.p.x = x;
-	inTouch->gestureLast[j].f.p.y = y;
-	break;
-	//pressure?
-      }      
+      }
+#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;
+      }
+    }
+    else if(event->type == SDL_FINGERMOTION) {
+      float dx = ((float)event->tfinger.dx)/(float)inTouch->res.x;
+      float dy = ((float)event->tfinger.dy)/(float)inTouch->res.y;
+      //printf("dx,dy: (%f,%f)\n",dx,dy); 
+#ifdef ENABLE_DOLLAR
+      DollarPath* path = &inTouch->gestureLast[j].dollarPath;
+      if(path->numPoints < MAXPATHSIZE) {
+	path->p[path->numPoints].x = x;
+	path->p[path->numPoints].y = y;
+	path->length += sqrt(dx*dx + dy*dy);
+	path->numPoints++;
+      }
+#endif
+      Point lastP;
+      lastP.x = x - dx;
+      lastP.y = y - dy;
+      Point lastCentroid;
+      lastCentroid = inTouch->centroid;
+      
+      inTouch->centroid.x += dx/inTouch->numDownFingers;
+      inTouch->centroid.y += dy/inTouch->numDownFingers;    
+      if(inTouch->numDownFingers > 1) {
+	Point lv; //Vector from centroid to last x,y position
+	Point 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;
+	float lDist = 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;
+	float Dist = sqrt(v.x*v.x+v.y*v.y);
+	// cos(dTheta) = (v . lv)/(|v| * |lv|)
+	
+	//Normalize Vectors to simplify angle calculation
+	lv.x/=lDist;
+	lv.y/=lDist;
+	v.x/=Dist;
+	v.y/=Dist;
+	float dtheta = atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
+	
+	float 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].f.p.x = x;
+      //inTouch->gestureLast[j].f.p.y = y;
+      //break;
+      //pressure?
     }
     
-    if(j == inTouch->numDownFingers) {
-      //printf("Finger Down!!!\n");
+    if(event->type == SDL_FINGERDOWN) {
+
       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;
-      
-      inTouch->gestureLast[j].f.id = event->tfinger.fingerId;
-      inTouch->gestureLast[j].f.p.x  = x;
-      inTouch->gestureLast[j].f.p.y  = y;	
-      inTouch->gestureLast[j].cv.x = 0;
-      inTouch->gestureLast[j].cv.y = 0;
-
+      printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
+	     inTouch->centroid.x,inTouch->centroid.y);
+      /*
+	inTouch->gestureLast[j].f.id = event->tfinger.fingerId;
+	inTouch->gestureLast[j].f.p.x  = x;
+	inTouch->gestureLast[j].f.p.y  = y;	
+	inTouch->gestureLast[j].cv.x = 0;
+	inTouch->gestureLast[j].cv.y = 0;
+      */
+#ifdef ENABlE_DOLLAR
       inTouch->gestureLast[j].dollarPath.length = 0;
       inTouch->gestureLast[j].dollarPath.p[0].x = x;
       inTouch->gestureLast[j].dollarPath.p[0].y = y;
       inTouch->gestureLast[j].dollarPath.numPoints = 1;
+#endif
     }
   }
-}  
-  
+}
+
   /* vi: set ts=4 sw=4 expandtab: */
   
--- a/src/events/SDL_touch.c	Tue Aug 03 00:18:00 2010 -0400
+++ b/src/events/SDL_touch.c	Wed Aug 04 23:17:30 2010 -0400
@@ -318,15 +318,17 @@
     if(!touch) {
       return SDL_TouchNotFoundError(id);
     }
+
+    
     //scale to Integer coordinates
     Uint16 x = (xin+touch->x_min)*(touch->xres)/(touch->native_xres);
     Uint16 y = (yin+touch->y_min)*(touch->yres)/(touch->native_yres);
-	Uint16 pressure = (yin+touch->pressure_min)*(touch->pressureres)/(touch->native_pressureres);
+    Uint16 pressure = (yin+touch->pressure_min)*(touch->pressureres)/(touch->native_pressureres);
+    
+    SDL_Finger *finger = SDL_GetFinger(touch,fingerid);
     if(down) {
-	SDL_Finger *finger = SDL_GetFinger(touch,fingerid);
-	SDL_Finger nf;
 	if(finger == NULL) {
-	    
+	    SDL_Finger nf;
 	    nf.id = fingerid;
 	    nf.x = x;
 	    nf.y = y;
@@ -337,8 +339,8 @@
 	    nf.last_y = y;
 	    nf.last_pressure = pressure;
 	    nf.down = SDL_FALSE;
-	    SDL_AddFinger(touch,&nf);
-	    finger = &nf;
+	    if(SDL_AddFinger(touch,&nf) < 0) return 0;
+	    finger = SDL_GetFinger(touch,fingerid);
 	}
 	else if(finger->down) return 0;
 	if(xin < touch->x_min || yin < touch->y_min) return 0; //should defer if only a partial input
@@ -358,7 +360,7 @@
 	return posted;
     }
     else {
-	if(SDL_DelFinger(touch,fingerid) < 0) return 0;
+        if(finger == NULL) {printf("Finger not found...\n");return 0;}      
 	posted = 0;
 	if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) {
 	    SDL_Event event;
@@ -367,8 +369,15 @@
 	    event.tfinger.state = touch->buttonstate;
 	    event.tfinger.windowID = touch->focus ? touch->focus->id : 0;
 	    event.tfinger.fingerId = fingerid;
+	    //I don't trust the coordinates passed on fingerUp
+	    event.tfinger.x = finger->x; 
+	    event.tfinger.y = finger->y;
+	    event.tfinger.dx = 0;
+	    event.tfinger.dy = 0;
+
+	    if(SDL_DelFinger(touch,fingerid) < 0) return 0;
 	    posted = (SDL_PushEvent(&event) > 0);
-	}
+	}	
 	return posted;
     }
 }
@@ -381,8 +390,7 @@
     SDL_Touch *touch = SDL_GetTouch(id);
     SDL_Finger *finger = SDL_GetFinger(touch,fingerid);
     int posted;
-    float xrel;
-    float yrel;
+    Sint16 xrel, yrel;
     float x_max = 0, y_max = 0;
     
     if (!touch) {
@@ -398,7 +406,7 @@
     }
     
     if(finger == NULL || !finger->down) {
-	return SDL_SendFingerDown(id,fingerid,SDL_TRUE,x,y,pressure);	
+	return SDL_SendFingerDown(id,fingerid,SDL_TRUE,xin,yin,pressurein);	
     } else {
 	/* the relative motion is calculated regarding the last position */
 	if (relative) {
@@ -412,6 +420,7 @@
 	    if(pressurein < touch->pressure_min) pressure = finger->last_pressure;
 	    xrel = x - finger->last_x;
 	    yrel = y - finger->last_y;
+	    //printf("xrel,yrel (%i,%i)\n",(int)xrel,(int)yrel);
 	}
 	
 	/* Drop events that don't change state */
@@ -460,6 +469,9 @@
 	    event.tfinger.fingerId = fingerid;
 	    event.tfinger.x = x;
 	    event.tfinger.y = y;
+	    event.tfinger.dx = xrel;
+	    event.tfinger.dy = yrel;
+	    
 		
 	    event.tfinger.pressure = pressure;
 	    event.tfinger.state = touch->buttonstate;
--- a/src/video/x11/SDL_eventtouch.c	Tue Aug 03 00:18:00 2010 -0400
+++ b/src/video/x11/SDL_eventtouch.c	Wed Aug 04 23:17:30 2010 -0400
@@ -61,6 +61,14 @@
 
 	touch.driverdata = SDL_malloc(sizeof(EventTouchData));
 	EventTouchData* data = (EventTouchData*)(touch.driverdata);
+
+	data->x = -1;
+	data->y = -1;
+	data->pressure = -1;
+	data->finger = 0;
+	data->up = SDL_FALSE;
+	
+
 	printf("Opening device...\n");
 	//printf("New Touch - DataPtr: %i\n",data);
 	data->eventStream = open(tstr, 
--- a/src/video/x11/SDL_x11events.c	Tue Aug 03 00:18:00 2010 -0400
+++ b/src/video/x11/SDL_x11events.c	Wed Aug 04 23:17:30 2010 -0400
@@ -439,8 +439,8 @@
 			    if(data->pressure < 0) data->pressure = 0;
 			    break;
 			case ABS_MISC:
-			    data->up = SDL_TRUE;
-			    data->finger = ev[i].value;
+			    if(ev[i].value == 0)
+			        data->up = SDL_TRUE;			    
 			    break;
 			}
 		    break;
@@ -453,22 +453,22 @@
 		  if(data->up) {
 		      SDL_SendFingerDown(touch->id,data->finger,
 			  	       SDL_FALSE,data->x,data->y,
-				       data->pressure);
+				       data->pressure);		    
 		  }
 		  else if(data->x >= 0 || data->y >= 0)
-		      SDL_SendTouchMotion(touch->id,data->finger, 
+		    SDL_SendTouchMotion(touch->id,data->finger, 
 					SDL_FALSE,data->x,data->y,
-					    data->pressure);
+					data->pressure);
 		  
 		    //printf("Synched: %i tx: %i, ty: %i\n",
 		    //	   data->finger,data->x,data->y);
-		    data->x = -1;
-		    data->y = -1;
-		    data->pressure = -1;
-		    data->finger = 0;
-		    data->up = SDL_FALSE;
+		  data->x = -1;
+		  data->y = -1;
+		  data->pressure = -1;
+		  data->finger = 0;
+		  data->up = SDL_FALSE;
 		    
-		    break;		
+		  break;		
 		}
 	    }
 	}
--- a/touchTest/gestureSDLTest.c	Tue Aug 03 00:18:00 2010 -0400
+++ b/touchTest/gestureSDLTest.c	Wed Aug 04 23:17:30 2010 -0400
@@ -414,11 +414,14 @@
 	    */
 	    break;
 	  case SDL_MULTIGESTURE:
+	    /*
 	    printf("Multi Gesture: x = %f, y = %f, dAng = %f, dR = %f\n",
 		   event.mgesture.x,
 		   event.mgesture.y,
 		   event.mgesture.dTheta,
 		   event.mgesture.dDist);
+	    printf("MG: numDownTouch = %i\n",event.mgesture.numFingers);
+	    */
 	    knob.p.x = event.mgesture.x;
 	    knob.p.y = event.mgesture.y;
 	    knob.ang += event.mgesture.dTheta;
@@ -435,9 +438,9 @@
 	  }
       }
     DrawScreen(screen,h);    
-    for(i = 0; i < 256; i++) 
-      if(keystat[i]) 
-	printf("Key %i down\n",i);
+    //for(i = 0; i < 256; i++) 
+    //  if(keystat[i]) 
+    //  printf("Key %i down\n",i);
   }  
   SDL_Quit();