static float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_GestureTouch* touch) { SDL_FloatPoint points[DOLLARNPOINTS]; int i; float bestDiff = 10000; dollarNormalize(path,points); //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; }
void SDL_GestureProcessEvent(SDL_Event* event) { float x,y; SDL_FloatPoint path[DOLLARNPOINTS]; int index; int i; float pathDx, pathDy; SDL_FloatPoint lastP; SDL_FloatPoint lastCentroid; float lDist; float Dist; float dtheta; float dDist; if (event->type == SDL_FINGERMOTION || event->type == SDL_FINGERDOWN || event->type == SDL_FINGERUP) { SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId); /* Shouldn't be possible */ if (inTouch == NULL) return; x = event->tfinger.x; y = event->tfinger.y; /* Finger Up */ if (event->type == SDL_FINGERUP) { inTouch->numDownFingers--; #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); } } 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; } } else if (event->type == SDL_FINGERMOTION) { float dx = event->tfinger.dx; float dy = event->tfinger.dy; #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++; } #endif lastP.x = x - dx; lastP.y = y - dy; lastCentroid = inTouch->centroid; inTouch->centroid.x += dx/inTouch->numDownFingers; 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); } 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 (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; /* printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y, inTouch->centroid.x,inTouch->centroid.y); */ #ifdef ENABLE_DOLLAR inTouch->dollarPath.length = 0; inTouch->dollarPath.p[0].x = x; inTouch->dollarPath.p[0].y = y; inTouch->dollarPath.numPoints = 1; #endif } } }