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