src/events/SDL_gesture.c
changeset 4683 15dfe42edbfd
parent 4682 4ba1048a324c
child 4684 f47c2640c667
     1.1 --- a/src/events/SDL_gesture.c	Tue Aug 03 00:18:00 2010 -0400
     1.2 +++ b/src/events/SDL_gesture.c	Wed Aug 04 23:17:30 2010 -0400
     1.3 @@ -75,7 +75,7 @@
     1.4    Point res;
     1.5    Point centroid;
     1.6    TouchPoint gestureLast[MAXFINGERS];
     1.7 -  int numDownFingers;
     1.8 +  Uint16 numDownFingers;
     1.9  
    1.10    int numDollarTemplates;
    1.11    DollarTemplate dollarTemplate[MAXTEMPLATES];
    1.12 @@ -406,6 +406,7 @@
    1.13    event.mgesture.y = touch->centroid.y;
    1.14    event.mgesture.dTheta = dTheta;
    1.15    event.mgesture.dDist = dDist;  
    1.16 +  event.mgesture.numFingers = touch->numDownFingers;
    1.17    return SDL_PushEvent(&event) > 0;
    1.18  }
    1.19  
    1.20 @@ -441,140 +442,161 @@
    1.21       event->type == SDL_FINGERDOWN ||
    1.22       event->type == SDL_FINGERUP) {
    1.23      GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);
    1.24 -
    1.25 +    
    1.26      //Shouldn't be possible
    1.27      if(inTouch == NULL) return;
    1.28      
    1.29 +    //printf("@ (%i,%i) with res: (%i,%i)\n",(int)event->tfinger.x,
    1.30 +    //	   (int)event->tfinger.y,
    1.31 +    //   (int)inTouch->res.x,(int)inTouch->res.y);
    1.32 +
    1.33      
    1.34 -    float x = ((float)event->tfinger.x)/inTouch->res.x;
    1.35 -    float y = ((float)event->tfinger.y)/inTouch->res.y;
    1.36 -    int j,empty = -1;
    1.37 -    
    1.38 -    for(j = 0;j<inTouch->numDownFingers;j++) {
    1.39 -      if(inTouch->gestureLast[j].f.id != event->tfinger.fingerId) continue;
    1.40 -      //Finger Up
    1.41 -      if(event->type == SDL_FINGERUP) {
    1.42 -	inTouch->numDownFingers--;
    1.43 +    float x = ((float)event->tfinger.x)/(float)inTouch->res.x;
    1.44 +    float y = ((float)event->tfinger.y)/(float)inTouch->res.y;   
    1.45  
    1.46 -	if(inTouch->recording) {
    1.47 -	  inTouch->recording = SDL_FALSE;
    1.48 -	  Point path[DOLLARNPOINTS];
    1.49 -	  dollarNormalize(inTouch->gestureLast[j].dollarPath,path);
    1.50 -	  int index;
    1.51 -	  if(recordAll) {
    1.52 -	    index = SDL_AddDollarGesture(NULL,path);
    1.53 -	    int i;
    1.54 -	    for(i = 0;i < numGestureTouches; i++)
    1.55 -	      gestureTouch[i].recording = SDL_FALSE;
    1.56 -	  }
    1.57 -	  else {
    1.58 -	    index = SDL_AddDollarGesture(inTouch,path);
    1.59 -	  }
    1.60 -	  
    1.61 -	  if(index >= 0) {
    1.62 -	    SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
    1.63 -	  }
    1.64 -	  else {
    1.65 -	    SDL_SendDollarRecord(inTouch,-1);
    1.66 -	  }
    1.67 -	}
    1.68 -	else {	
    1.69 -	  int bestTempl;
    1.70 -	  float error;
    1.71 -	  error = dollarRecognize(inTouch->gestureLast[j].dollarPath,
    1.72 -				  &bestTempl,inTouch);
    1.73 -	  if(bestTempl >= 0){
    1.74 -	    //Send Event
    1.75 -	    unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
    1.76 -	    SDL_SendGestureDollar(inTouch,gestureId,error);
    1.77 -	    printf("Dollar error: %f\n",error);
    1.78 -	  }
    1.79 -	} 
    1.80 -	inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
    1.81 -	j = -1;
    1.82 -	break;
    1.83 -      }
    1.84 -      else if(event->type == SDL_FINGERMOTION) {
    1.85 -	float dx = x - inTouch->gestureLast[j].f.p.x;
    1.86 -	float dy = y - inTouch->gestureLast[j].f.p.y;
    1.87 -	DollarPath* path = &inTouch->gestureLast[j].dollarPath;
    1.88 -	if(path->numPoints < MAXPATHSIZE) {
    1.89 -	  path->p[path->numPoints].x = x;
    1.90 -	  path->p[path->numPoints].y = y;
    1.91 -	  path->length += sqrt(dx*dx + dy*dy);
    1.92 -	  path->numPoints++;
    1.93 -	}
    1.94  
    1.95 -
    1.96 -	inTouch->centroid.x += dx/inTouch->numDownFingers;
    1.97 -	inTouch->centroid.y += dy/inTouch->numDownFingers;    
    1.98 -	if(inTouch->numDownFingers > 1) {
    1.99 -	  Point lv; //Vector from centroid to last x,y position
   1.100 -	  Point v; //Vector from centroid to current x,y position
   1.101 -	  lv = inTouch->gestureLast[j].cv;
   1.102 -	  float lDist = sqrt(lv.x*lv.x + lv.y*lv.y);
   1.103 -	  //printf("lDist = %f\n",lDist);
   1.104 -	  v.x = x - inTouch->centroid.x;
   1.105 -	  v.y = y - inTouch->centroid.y;
   1.106 -	  inTouch->gestureLast[j].cv = v;
   1.107 -	  float Dist = sqrt(v.x*v.x+v.y*v.y);
   1.108 -	  // cos(dTheta) = (v . lv)/(|v| * |lv|)
   1.109 -	  
   1.110 -	  //Normalize Vectors to simplify angle calculation
   1.111 -	  lv.x/=lDist;
   1.112 -	  lv.y/=lDist;
   1.113 -	  v.x/=Dist;
   1.114 -	  v.y/=Dist;
   1.115 -	  float dtheta = atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
   1.116 -	  
   1.117 -	  float dDist = (Dist - lDist);
   1.118 -	  if(lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values
   1.119 -	  inTouch->gestureLast[j].dDist = dDist;
   1.120 -	  inTouch->gestureLast[j].dtheta = dtheta;
   1.121 -	  
   1.122 -	  //printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
   1.123 -	  //gdtheta = gdtheta*.9 + dtheta*.1;
   1.124 -	  //gdDist  =  gdDist*.9 +  dDist*.1
   1.125 -	  //knob.r += dDist/numDownFingers;
   1.126 -	  //knob.ang += dtheta;
   1.127 -	  //printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
   1.128 -	  //printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
   1.129 -	  SDL_SendGestureMulti(inTouch,dtheta,dDist);
   1.130 +    //Finger Up
   1.131 +    if(event->type == SDL_FINGERUP) {
   1.132 +      inTouch->numDownFingers--;
   1.133 +      
   1.134 +#ifdef ENABLE_DOLLAR
   1.135 +      if(inTouch->recording) {
   1.136 +	inTouch->recording = SDL_FALSE;
   1.137 +	Point path[DOLLARNPOINTS];
   1.138 +	dollarNormalize(inTouch->gestureLast[j].dollarPath,path);
   1.139 +	int index;
   1.140 +	if(recordAll) {
   1.141 +	  index = SDL_AddDollarGesture(NULL,path);
   1.142 +	  int i;
   1.143 +	  for(i = 0;i < numGestureTouches; i++)
   1.144 +	    gestureTouch[i].recording = SDL_FALSE;
   1.145  	}
   1.146  	else {
   1.147 -	  inTouch->gestureLast[j].dDist = 0;
   1.148 -	  inTouch->gestureLast[j].dtheta = 0;
   1.149 -	  inTouch->gestureLast[j].cv.x = 0;
   1.150 -	  inTouch->gestureLast[j].cv.y = 0;
   1.151 +	  index = SDL_AddDollarGesture(inTouch,path);
   1.152  	}
   1.153 -	inTouch->gestureLast[j].f.p.x = x;
   1.154 -	inTouch->gestureLast[j].f.p.y = y;
   1.155 -	break;
   1.156 -	//pressure?
   1.157 -      }      
   1.158 +	
   1.159 +	if(index >= 0) {
   1.160 +	  SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
   1.161 +	}
   1.162 +	else {
   1.163 +	  SDL_SendDollarRecord(inTouch,-1);
   1.164 +	}
   1.165 +      }
   1.166 +      else {	
   1.167 +	int bestTempl;
   1.168 +	float error;
   1.169 +	error = dollarRecognize(inTouch->gestureLast[j].dollarPath,
   1.170 +				&bestTempl,inTouch);
   1.171 +	if(bestTempl >= 0){
   1.172 +	  //Send Event
   1.173 +	  unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
   1.174 +	  SDL_SendGestureDollar(inTouch,gestureId,error);
   1.175 +	    printf ("%s\n",);("Dollar error: %f\n",error);
   1.176 +	}
   1.177 +      }
   1.178 +#endif 
   1.179 +      //inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
   1.180 +      if(inTouch->numDownFingers > 0) {
   1.181 +	inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
   1.182 +			       x)/inTouch->numDownFingers;
   1.183 +	inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
   1.184 +			       y)/inTouch->numDownFingers;
   1.185 +      }
   1.186 +    }
   1.187 +    else if(event->type == SDL_FINGERMOTION) {
   1.188 +      float dx = ((float)event->tfinger.dx)/(float)inTouch->res.x;
   1.189 +      float dy = ((float)event->tfinger.dy)/(float)inTouch->res.y;
   1.190 +      //printf("dx,dy: (%f,%f)\n",dx,dy); 
   1.191 +#ifdef ENABLE_DOLLAR
   1.192 +      DollarPath* path = &inTouch->gestureLast[j].dollarPath;
   1.193 +      if(path->numPoints < MAXPATHSIZE) {
   1.194 +	path->p[path->numPoints].x = x;
   1.195 +	path->p[path->numPoints].y = y;
   1.196 +	path->length += sqrt(dx*dx + dy*dy);
   1.197 +	path->numPoints++;
   1.198 +      }
   1.199 +#endif
   1.200 +      Point lastP;
   1.201 +      lastP.x = x - dx;
   1.202 +      lastP.y = y - dy;
   1.203 +      Point lastCentroid;
   1.204 +      lastCentroid = inTouch->centroid;
   1.205 +      
   1.206 +      inTouch->centroid.x += dx/inTouch->numDownFingers;
   1.207 +      inTouch->centroid.y += dy/inTouch->numDownFingers;    
   1.208 +      if(inTouch->numDownFingers > 1) {
   1.209 +	Point lv; //Vector from centroid to last x,y position
   1.210 +	Point v; //Vector from centroid to current x,y position
   1.211 +	//lv = inTouch->gestureLast[j].cv;
   1.212 +	lv.x = lastP.x - lastCentroid.x;
   1.213 +	lv.y = lastP.y - lastCentroid.y;
   1.214 +	float lDist = sqrt(lv.x*lv.x + lv.y*lv.y);
   1.215 +	//printf("lDist = %f\n",lDist);
   1.216 +	v.x = x - inTouch->centroid.x;
   1.217 +	v.y = y - inTouch->centroid.y;
   1.218 +	//inTouch->gestureLast[j].cv = v;
   1.219 +	float Dist = sqrt(v.x*v.x+v.y*v.y);
   1.220 +	// cos(dTheta) = (v . lv)/(|v| * |lv|)
   1.221 +	
   1.222 +	//Normalize Vectors to simplify angle calculation
   1.223 +	lv.x/=lDist;
   1.224 +	lv.y/=lDist;
   1.225 +	v.x/=Dist;
   1.226 +	v.y/=Dist;
   1.227 +	float dtheta = atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
   1.228 +	
   1.229 +	float dDist = (Dist - lDist);
   1.230 +	if(lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values
   1.231 +	
   1.232 +	//inTouch->gestureLast[j].dDist = dDist;
   1.233 +	//inTouch->gestureLast[j].dtheta = dtheta;
   1.234 +	
   1.235 +	//printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
   1.236 +	//gdtheta = gdtheta*.9 + dtheta*.1;
   1.237 +	//gdDist  =  gdDist*.9 +  dDist*.1
   1.238 +	//knob.r += dDist/numDownFingers;
   1.239 +	//knob.ang += dtheta;
   1.240 +	//printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
   1.241 +	//printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
   1.242 +	SDL_SendGestureMulti(inTouch,dtheta,dDist);
   1.243 +      }
   1.244 +      else {
   1.245 +	//inTouch->gestureLast[j].dDist = 0;
   1.246 +	//inTouch->gestureLast[j].dtheta = 0;
   1.247 +	//inTouch->gestureLast[j].cv.x = 0;
   1.248 +	//inTouch->gestureLast[j].cv.y = 0;
   1.249 +      }
   1.250 +      //inTouch->gestureLast[j].f.p.x = x;
   1.251 +      //inTouch->gestureLast[j].f.p.y = y;
   1.252 +      //break;
   1.253 +      //pressure?
   1.254      }
   1.255      
   1.256 -    if(j == inTouch->numDownFingers) {
   1.257 -      //printf("Finger Down!!!\n");
   1.258 +    if(event->type == SDL_FINGERDOWN) {
   1.259 +
   1.260        inTouch->numDownFingers++;
   1.261        inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+ 
   1.262  			     x)/inTouch->numDownFingers;
   1.263        inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
   1.264  			     y)/inTouch->numDownFingers;
   1.265 -      
   1.266 -      inTouch->gestureLast[j].f.id = event->tfinger.fingerId;
   1.267 -      inTouch->gestureLast[j].f.p.x  = x;
   1.268 -      inTouch->gestureLast[j].f.p.y  = y;	
   1.269 -      inTouch->gestureLast[j].cv.x = 0;
   1.270 -      inTouch->gestureLast[j].cv.y = 0;
   1.271 -
   1.272 +      printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
   1.273 +	     inTouch->centroid.x,inTouch->centroid.y);
   1.274 +      /*
   1.275 +	inTouch->gestureLast[j].f.id = event->tfinger.fingerId;
   1.276 +	inTouch->gestureLast[j].f.p.x  = x;
   1.277 +	inTouch->gestureLast[j].f.p.y  = y;	
   1.278 +	inTouch->gestureLast[j].cv.x = 0;
   1.279 +	inTouch->gestureLast[j].cv.y = 0;
   1.280 +      */
   1.281 +#ifdef ENABlE_DOLLAR
   1.282        inTouch->gestureLast[j].dollarPath.length = 0;
   1.283        inTouch->gestureLast[j].dollarPath.p[0].x = x;
   1.284        inTouch->gestureLast[j].dollarPath.p[0].y = y;
   1.285        inTouch->gestureLast[j].dollarPath.numPoints = 1;
   1.286 +#endif
   1.287      }
   1.288    }
   1.289 -}  
   1.290 -  
   1.291 +}
   1.292 +
   1.293    /* vi: set ts=4 sw=4 expandtab: */
   1.294