src/events/SDL_gesture.c
author Captain Lex <kimonline@126.com>
Sun, 17 Mar 2013 20:07:02 +0800
changeset 7009 161b7b6a5303
parent 6951 7833f01322b3
child 7037 3fedf1f25b94
permissions -rw-r--r--
Add PSP support
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14   claim that you wrote the original software. If you use this software
    15   in a product, an acknowledgment in the product documentation would be
    16   appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18   misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 
    22 #include "SDL_config.h"
    23 
    24 /* General mouse handling code for SDL */
    25 
    26 #include "SDL_events.h"
    27 #include "SDL_events_c.h"
    28 #include "SDL_gesture_c.h"
    29 
    30 #if !defined(__PSP__)
    31 #include <memory.h>
    32 #endif
    33 
    34 #include <string.h>
    35 #include <stdio.h>
    36 #include <math.h>
    37 
    38 //TODO: Replace with malloc
    39 
    40 #define MAXPATHSIZE 1024
    41 
    42 
    43 
    44 
    45 #define DOLLARNPOINTS 64
    46 #define DOLLARSIZE 256
    47 
    48 #define ENABLE_DOLLAR
    49 
    50 #define PHI 0.618033989
    51 
    52 typedef struct {
    53     float x,y;
    54 } SDL_FloatPoint;
    55 
    56 typedef struct {
    57     float length;
    58 
    59     int numPoints;
    60     SDL_FloatPoint p[MAXPATHSIZE];
    61 } SDL_DollarPath;
    62 
    63 typedef struct {
    64     SDL_FloatPoint path[DOLLARNPOINTS];
    65     unsigned long hash;
    66 } SDL_DollarTemplate;
    67 
    68 typedef struct {
    69     SDL_TouchID id;
    70     SDL_FloatPoint centroid;
    71     SDL_DollarPath dollarPath;
    72     Uint16 numDownFingers;
    73 
    74     int numDollarTemplates;
    75     SDL_DollarTemplate *dollarTemplate;
    76 
    77     SDL_bool recording;
    78 } SDL_GestureTouch;
    79 
    80 SDL_GestureTouch *SDL_gestureTouch;
    81 int SDL_numGestureTouches = 0;
    82 SDL_bool recordAll;
    83 
    84 #if 0
    85 static void PrintPath(SDL_FloatPoint *path)
    86 {
    87     int i;
    88     printf("Path:");
    89     for (i=0; i<DOLLARNPOINTS; i++) {
    90         printf(" (%f,%f)",path[i].x,path[i].y);
    91     }
    92     printf("\n");
    93 }
    94 #endif
    95 
    96 int SDL_RecordGesture(SDL_TouchID touchId)
    97 {
    98     int i;
    99     if (touchId < 0) recordAll = SDL_TRUE;
   100     for (i = 0; i < SDL_numGestureTouches; i++) {
   101         if ((touchId < 0) || (SDL_gestureTouch[i].id == touchId)) {
   102             SDL_gestureTouch[i].recording = SDL_TRUE;
   103             if (touchId >= 0)
   104                 return 1;
   105         }
   106     }
   107     return (touchId < 0);
   108 }
   109 
   110 static unsigned long SDL_HashDollar(SDL_FloatPoint* points)
   111 {
   112     unsigned long hash = 5381;
   113     int i;
   114     for (i = 0; i < DOLLARNPOINTS; i++) {
   115         hash = ((hash<<5) + hash) + (unsigned long)points[i].x;
   116         hash = ((hash<<5) + hash) + (unsigned long)points[i].y;
   117     }
   118     return hash;
   119 }
   120 
   121 
   122 static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops * src)
   123 {
   124     if (src == NULL) return 0;
   125 
   126 
   127     //No Longer storing the Hash, rehash on load
   128     //if(SDL_RWops.write(src,&(templ->hash),sizeof(templ->hash),1) != 1) return 0;
   129 
   130     if (SDL_RWwrite(src,templ->path,
   131                     sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS)
   132         return 0;
   133 
   134     return 1;
   135 }
   136 
   137 
   138 int SDL_SaveAllDollarTemplates(SDL_RWops *src)
   139 {
   140     int i,j,rtrn = 0;
   141     for (i = 0; i < SDL_numGestureTouches; i++) {
   142         SDL_GestureTouch* touch = &SDL_gestureTouch[i];
   143         for (j = 0; j < touch->numDollarTemplates; j++) {
   144             rtrn += SaveTemplate(&touch->dollarTemplate[i],src);
   145         }
   146     }
   147     return rtrn;
   148 }
   149 
   150 int SDL_SaveDollarTemplate(SDL_GestureID gestureId, SDL_RWops *src)
   151 {
   152     int i,j;
   153     for (i = 0; i < SDL_numGestureTouches; i++) {
   154         SDL_GestureTouch* touch = &SDL_gestureTouch[i];
   155         for (j = 0; j < touch->numDollarTemplates; j++) {
   156             if (touch->dollarTemplate[i].hash == gestureId) {
   157                 return SaveTemplate(&touch->dollarTemplate[i],src);
   158             }
   159         }
   160     }
   161     SDL_SetError("Unknown gestureId");
   162     return -1;
   163 }
   164 
   165 //path is an already sampled set of points
   166 //Returns the index of the gesture on success, or -1
   167 static int SDL_AddDollarGesture_one(SDL_GestureTouch* inTouch, SDL_FloatPoint* path)
   168 {
   169     SDL_DollarTemplate* dollarTemplate;
   170     SDL_DollarTemplate *templ;
   171     int index;
   172 
   173     index = inTouch->numDollarTemplates;
   174     dollarTemplate =
   175         (SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
   176                                           (index + 1) *
   177                                           sizeof(SDL_DollarTemplate));
   178     if (!dollarTemplate) {
   179         SDL_OutOfMemory();
   180         return -1;
   181     }
   182     inTouch->dollarTemplate = dollarTemplate;
   183 
   184     templ = &inTouch->dollarTemplate[index];
   185     SDL_memcpy(templ->path, path, DOLLARNPOINTS*sizeof(SDL_FloatPoint));
   186     templ->hash = SDL_HashDollar(templ->path);
   187     inTouch->numDollarTemplates++;
   188 
   189     return index;
   190 }
   191 
   192 static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch, SDL_FloatPoint* path)
   193 {
   194     int index = -1;
   195     int i = 0;
   196     if (inTouch == NULL) {
   197         if (SDL_numGestureTouches == 0) return -1;
   198         for (i = 0; i < SDL_numGestureTouches; i++) {
   199             inTouch = &SDL_gestureTouch[i];
   200             index = SDL_AddDollarGesture_one(inTouch, path);
   201             if (index < 0)
   202                 return -1;
   203         }
   204         // Use the index of the last one added.
   205         return index;
   206     } else {
   207         return SDL_AddDollarGesture_one(inTouch, path);
   208     }
   209     return -1;
   210 }
   211 
   212 int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src)
   213 {
   214     int i,loaded = 0;
   215     SDL_GestureTouch *touch = NULL;
   216     if (src == NULL) return 0;
   217     if (touchId >= 0) {
   218         for (i = 0; i < SDL_numGestureTouches; i++)
   219             if (SDL_gestureTouch[i].id == touchId)
   220                 touch = &SDL_gestureTouch[i];
   221         if (touch == NULL) return -1;
   222     }
   223 
   224     while (1) {
   225         SDL_DollarTemplate templ;
   226 
   227         if (SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) <
   228            DOLLARNPOINTS) break;
   229 
   230         if (touchId >= 0) {
   231             //printf("Adding loaded gesture to 1 touch\n");
   232             if (SDL_AddDollarGesture(touch, templ.path) >= 0)
   233                 loaded++;
   234         }
   235         else {
   236             //printf("Adding to: %i touches\n",SDL_numGestureTouches);
   237             for (i = 0; i < SDL_numGestureTouches; i++) {
   238                 touch = &SDL_gestureTouch[i];
   239                 //printf("Adding loaded gesture to + touches\n");
   240                 //TODO: What if this fails?
   241                 SDL_AddDollarGesture(touch,templ.path);
   242             }
   243             loaded++;
   244         }
   245     }
   246 
   247     return loaded;
   248 }
   249 
   250 
   251 static float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float ang)
   252 {
   253     //  SDL_FloatPoint p[DOLLARNPOINTS];
   254     float dist = 0;
   255     SDL_FloatPoint p;
   256     int i;
   257     for (i = 0; i < DOLLARNPOINTS; i++) {
   258         p.x = (float)(points[i].x * SDL_cos(ang) - points[i].y * SDL_sin(ang));
   259         p.y = (float)(points[i].x * SDL_sin(ang) + points[i].y * SDL_cos(ang));
   260         dist += (float)(SDL_sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
   261                                  (p.y-templ[i].y)*(p.y-templ[i].y)));
   262     }
   263     return dist/DOLLARNPOINTS;
   264 
   265 }
   266 
   267 static float bestDollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ)
   268 {
   269     //------------BEGIN DOLLAR BLACKBOX----------------//
   270     //-TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-//
   271     //-"http://depts.washington.edu/aimgroup/proj/dollar/"-//
   272     double ta = -M_PI/4;
   273     double tb = M_PI/4;
   274     double dt = M_PI/90;
   275     float x1 = (float)(PHI*ta + (1-PHI)*tb);
   276     float f1 = dollarDifference(points,templ,x1);
   277     float x2 = (float)((1-PHI)*ta + PHI*tb);
   278     float f2 = dollarDifference(points,templ,x2);
   279     while (SDL_fabs(ta-tb) > dt) {
   280         if (f1 < f2) {
   281             tb = x2;
   282             x2 = x1;
   283             f2 = f1;
   284             x1 = (float)(PHI*ta + (1-PHI)*tb);
   285             f1 = dollarDifference(points,templ,x1);
   286         }
   287         else {
   288             ta = x1;
   289             x1 = x2;
   290             f1 = f2;
   291             x2 = (float)((1-PHI)*ta + PHI*tb);
   292             f2 = dollarDifference(points,templ,x2);
   293         }
   294     }
   295     /*
   296       if (f1 <= f2)
   297           printf("Min angle (x1): %f\n",x1);
   298       else if (f1 >  f2)
   299           printf("Min angle (x2): %f\n",x2);
   300     */
   301     return SDL_min(f1,f2);
   302 }
   303 
   304 //DollarPath contains raw points, plus (possibly) the calculated length
   305 static int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points)
   306 {
   307     int i;
   308     float interval;
   309     float dist;
   310     int numPoints = 0;
   311     SDL_FloatPoint centroid;
   312     float xmin,xmax,ymin,ymax;
   313     float ang;
   314     float w,h;
   315     float length = path->length;
   316 
   317     //Calculate length if it hasn't already been done
   318     if (length <= 0) {
   319         for (i=1;i < path->numPoints; i++) {
   320             float dx = path->p[i  ].x - path->p[i-1].x;
   321             float dy = path->p[i  ].y - path->p[i-1].y;
   322             length += (float)(SDL_sqrt(dx*dx+dy*dy));
   323         }
   324     }
   325 
   326     //Resample
   327     interval = length/(DOLLARNPOINTS - 1);
   328     dist = interval;
   329 
   330     centroid.x = 0;centroid.y = 0;
   331 
   332     //printf("(%f,%f)\n",path->p[path->numPoints-1].x,path->p[path->numPoints-1].y);
   333     for (i = 1; i < path->numPoints; i++) {
   334         float d = (float)(SDL_sqrt((path->p[i-1].x-path->p[i].x)*(path->p[i-1].x-path->p[i].x)+
   335                                    (path->p[i-1].y-path->p[i].y)*(path->p[i-1].y-path->p[i].y)));
   336         //printf("d = %f dist = %f/%f\n",d,dist,interval);
   337         while (dist + d > interval) {
   338             points[numPoints].x = path->p[i-1].x +
   339                 ((interval-dist)/d)*(path->p[i].x-path->p[i-1].x);
   340             points[numPoints].y = path->p[i-1].y +
   341                 ((interval-dist)/d)*(path->p[i].y-path->p[i-1].y);
   342             centroid.x += points[numPoints].x;
   343             centroid.y += points[numPoints].y;
   344             numPoints++;
   345 
   346             dist -= interval;
   347         }
   348         dist += d;
   349     }
   350     if (numPoints < DOLLARNPOINTS-1) {
   351         SDL_SetError("ERROR: NumPoints = %i\n",numPoints);
   352         return 0;
   353     }
   354     //copy the last point
   355     points[DOLLARNPOINTS-1] = path->p[path->numPoints-1];
   356     numPoints = DOLLARNPOINTS;
   357 
   358     centroid.x /= numPoints;
   359     centroid.y /= numPoints;
   360 
   361     //printf("Centroid (%f,%f)",centroid.x,centroid.y);
   362     //Rotate Points so point 0 is left of centroid and solve for the bounding box
   363     xmin = centroid.x;
   364     xmax = centroid.x;
   365     ymin = centroid.y;
   366     ymax = centroid.y;
   367 
   368     ang = (float)(SDL_atan2(centroid.y - points[0].y,
   369                             centroid.x - points[0].x));
   370 
   371     for (i = 0; i<numPoints; i++) {
   372         float px = points[i].x;
   373         float py = points[i].y;
   374         points[i].x = (float)((px - centroid.x)*SDL_cos(ang) -
   375                               (py - centroid.y)*SDL_sin(ang) + centroid.x);
   376         points[i].y = (float)((px - centroid.x)*SDL_sin(ang) +
   377                               (py - centroid.y)*SDL_cos(ang) + centroid.y);
   378 
   379 
   380         if (points[i].x < xmin) xmin = points[i].x;
   381         if (points[i].x > xmax) xmax = points[i].x;
   382         if (points[i].y < ymin) ymin = points[i].y;
   383         if (points[i].y > ymax) ymax = points[i].y;
   384     }
   385 
   386     //Scale points to DOLLARSIZE, and translate to the origin
   387     w = xmax-xmin;
   388     h = ymax-ymin;
   389 
   390     for (i=0; i<numPoints; i++) {
   391         points[i].x = (points[i].x - centroid.x)*DOLLARSIZE/w;
   392         points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h;
   393     }
   394     return numPoints;
   395 }
   396 
   397 static float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_GestureTouch* touch)
   398 {
   399 
   400     SDL_FloatPoint points[DOLLARNPOINTS];
   401     int i;
   402     float bestDiff = 10000;
   403 
   404     dollarNormalize(path,points);
   405 
   406     //PrintPath(points);
   407     *bestTempl = -1;
   408     for (i = 0; i < touch->numDollarTemplates; i++) {
   409         float diff = bestDollarDifference(points,touch->dollarTemplate[i].path);
   410         if (diff < bestDiff) {bestDiff = diff; *bestTempl = i;}
   411     }
   412     return bestDiff;
   413 }
   414 
   415 int SDL_GestureAddTouch(SDL_TouchID touchId)
   416 {
   417     SDL_GestureTouch *gestureTouch = (SDL_GestureTouch *)SDL_realloc(SDL_gestureTouch,
   418                                                                      (SDL_numGestureTouches + 1) *
   419                                                                      sizeof(SDL_GestureTouch));
   420 
   421     if (!gestureTouch) {
   422         SDL_OutOfMemory();
   423         return -1;
   424     }
   425 
   426     SDL_gestureTouch = gestureTouch;
   427 
   428     SDL_gestureTouch[SDL_numGestureTouches].numDownFingers = 0;
   429     SDL_gestureTouch[SDL_numGestureTouches].id = touchId;
   430 
   431     SDL_gestureTouch[SDL_numGestureTouches].numDollarTemplates = 0;
   432 
   433     SDL_gestureTouch[SDL_numGestureTouches].recording = SDL_FALSE;
   434 
   435     SDL_numGestureTouches++;
   436     return 0;
   437 }
   438 
   439 static SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id)
   440 {
   441     int i;
   442     for (i = 0; i < SDL_numGestureTouches; i++) {
   443         //printf("%i ?= %i\n",SDL_gestureTouch[i].id,id);
   444         if (SDL_gestureTouch[i].id == id)
   445             return &SDL_gestureTouch[i];
   446     }
   447     return NULL;
   448 }
   449 
   450 int SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist)
   451 {
   452     SDL_Event event;
   453     event.mgesture.type = SDL_MULTIGESTURE;
   454     event.mgesture.touchId = touch->id;
   455     event.mgesture.x = touch->centroid.x;
   456     event.mgesture.y = touch->centroid.y;
   457     event.mgesture.dTheta = dTheta;
   458     event.mgesture.dDist = dDist;
   459     event.mgesture.numFingers = touch->numDownFingers;
   460     return SDL_PushEvent(&event) > 0;
   461 }
   462 
   463 static int SDL_SendGestureDollar(SDL_GestureTouch* touch,
   464                           SDL_GestureID gestureId,float error)
   465 {
   466     SDL_Event event;
   467     event.dgesture.type = SDL_DOLLARGESTURE;
   468     event.dgesture.touchId = touch->id;
   469     event.mgesture.x = touch->centroid.x;
   470     event.mgesture.y = touch->centroid.y;
   471     event.dgesture.gestureId = gestureId;
   472     event.dgesture.error = error;
   473     //A finger came up to trigger this event.
   474     event.dgesture.numFingers = touch->numDownFingers + 1;
   475     return SDL_PushEvent(&event) > 0;
   476 }
   477 
   478 
   479 static int SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId)
   480 {
   481     SDL_Event event;
   482     event.dgesture.type = SDL_DOLLARRECORD;
   483     event.dgesture.touchId = touch->id;
   484     event.dgesture.gestureId = gestureId;
   485     return SDL_PushEvent(&event) > 0;
   486 }
   487 
   488 
   489 void SDL_GestureProcessEvent(SDL_Event* event)
   490 {
   491     float x,y;
   492     SDL_FloatPoint path[DOLLARNPOINTS];
   493     int index;
   494     int i;
   495     float pathDx, pathDy;
   496     SDL_FloatPoint lastP;
   497     SDL_FloatPoint lastCentroid;
   498     float lDist;
   499     float Dist;
   500     float dtheta;
   501     float dDist;
   502 
   503     if (event->type == SDL_FINGERMOTION ||
   504         event->type == SDL_FINGERDOWN ||
   505         event->type == SDL_FINGERUP) {
   506         SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);
   507 
   508         //Shouldn't be possible
   509         if (inTouch == NULL) return;
   510 
   511         x = event->tfinger.x;
   512         y = event->tfinger.y;
   513 
   514         //Finger Up
   515         if (event->type == SDL_FINGERUP) {
   516             inTouch->numDownFingers--;
   517 
   518 #ifdef ENABLE_DOLLAR
   519             if (inTouch->recording) {
   520                 inTouch->recording = SDL_FALSE;
   521                 dollarNormalize(&inTouch->dollarPath,path);
   522                 //PrintPath(path);
   523                 if (recordAll) {
   524                     index = SDL_AddDollarGesture(NULL,path);
   525                     for (i = 0; i < SDL_numGestureTouches; i++)
   526                         SDL_gestureTouch[i].recording = SDL_FALSE;
   527                 }
   528                 else {
   529                     index = SDL_AddDollarGesture(inTouch,path);
   530                 }
   531 
   532                 if (index >= 0) {
   533                     SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
   534                 }
   535                 else {
   536                     SDL_SendDollarRecord(inTouch,-1);
   537                 }
   538             }
   539             else {
   540                 int bestTempl;
   541                 float error;
   542                 error = dollarRecognize(&inTouch->dollarPath,
   543                                         &bestTempl,inTouch);
   544                 if (bestTempl >= 0){
   545                     //Send Event
   546                     unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
   547                     SDL_SendGestureDollar(inTouch,gestureId,error);
   548                     //printf ("%s\n",);("Dollar error: %f\n",error);
   549                 }
   550             }
   551 #endif
   552             //inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
   553             if (inTouch->numDownFingers > 0) {
   554                 inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
   555                                        x)/inTouch->numDownFingers;
   556                 inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
   557                                        y)/inTouch->numDownFingers;
   558             }
   559         }
   560         else if (event->type == SDL_FINGERMOTION) {
   561             float dx = event->tfinger.dx;
   562             float dy = event->tfinger.dy;
   563 #ifdef ENABLE_DOLLAR
   564             SDL_DollarPath* path = &inTouch->dollarPath;
   565             if (path->numPoints < MAXPATHSIZE) {
   566                 path->p[path->numPoints].x = inTouch->centroid.x;
   567                 path->p[path->numPoints].y = inTouch->centroid.y;
   568                 pathDx =
   569                     (path->p[path->numPoints].x-path->p[path->numPoints-1].x);
   570                 pathDy =
   571                     (path->p[path->numPoints].y-path->p[path->numPoints-1].y);
   572                 path->length += (float)SDL_sqrt(pathDx*pathDx + pathDy*pathDy);
   573                 path->numPoints++;
   574             }
   575 #endif
   576             lastP.x = x - dx;
   577             lastP.y = y - dy;
   578             lastCentroid = inTouch->centroid;
   579 
   580             inTouch->centroid.x += dx/inTouch->numDownFingers;
   581             inTouch->centroid.y += dy/inTouch->numDownFingers;
   582             //printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y);
   583             if (inTouch->numDownFingers > 1) {
   584                 SDL_FloatPoint lv; //Vector from centroid to last x,y position
   585                 SDL_FloatPoint v; //Vector from centroid to current x,y position
   586                 //lv = inTouch->gestureLast[j].cv;
   587                 lv.x = lastP.x - lastCentroid.x;
   588                 lv.y = lastP.y - lastCentroid.y;
   589                 lDist = (float)SDL_sqrt(lv.x*lv.x + lv.y*lv.y);
   590                 //printf("lDist = %f\n",lDist);
   591                 v.x = x - inTouch->centroid.x;
   592                 v.y = y - inTouch->centroid.y;
   593                 //inTouch->gestureLast[j].cv = v;
   594                 Dist = (float)SDL_sqrt(v.x*v.x+v.y*v.y);
   595                 // SDL_cos(dTheta) = (v . lv)/(|v| * |lv|)
   596 
   597                 //Normalize Vectors to simplify angle calculation
   598                 lv.x/=lDist;
   599                 lv.y/=lDist;
   600                 v.x/=Dist;
   601                 v.y/=Dist;
   602                 dtheta = (float)SDL_atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
   603 
   604                 dDist = (Dist - lDist);
   605                 if (lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values
   606 
   607                 //inTouch->gestureLast[j].dDist = dDist;
   608                 //inTouch->gestureLast[j].dtheta = dtheta;
   609 
   610                 //printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
   611                 //gdtheta = gdtheta*.9 + dtheta*.1;
   612                 //gdDist  =  gdDist*.9 +  dDist*.1
   613                 //knob.r += dDist/numDownFingers;
   614                 //knob.ang += dtheta;
   615                 //printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
   616                 //printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
   617                 SDL_SendGestureMulti(inTouch,dtheta,dDist);
   618             }
   619             else {
   620                 //inTouch->gestureLast[j].dDist = 0;
   621                 //inTouch->gestureLast[j].dtheta = 0;
   622                 //inTouch->gestureLast[j].cv.x = 0;
   623                 //inTouch->gestureLast[j].cv.y = 0;
   624             }
   625             //inTouch->gestureLast[j].f.p.x = x;
   626             //inTouch->gestureLast[j].f.p.y = y;
   627             //break;
   628             //pressure?
   629         }
   630 
   631         if (event->type == SDL_FINGERDOWN) {
   632 
   633             inTouch->numDownFingers++;
   634             inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+
   635                                    x)/inTouch->numDownFingers;
   636             inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
   637                                    y)/inTouch->numDownFingers;
   638             //printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
   639             //     inTouch->centroid.x,inTouch->centroid.y);
   640 
   641 #ifdef ENABLE_DOLLAR
   642             inTouch->dollarPath.length = 0;
   643             inTouch->dollarPath.p[0].x = x;
   644             inTouch->dollarPath.p[0].y = y;
   645             inTouch->dollarPath.numPoints = 1;
   646 #endif
   647         }
   648     }
   649 }
   650 
   651 /* vi: set ts=4 sw=4 expandtab: */