From 7c3628976808a20ce9bcac046c4b88bffd475241 Mon Sep 17 00:00:00 2001 From: Constantine Tarasenkov Date: Fri, 4 Sep 2015 15:38:14 +0300 Subject: Fix compiling on Linux --- src/gestures.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gestures.c') diff --git a/src/gestures.c b/src/gestures.c index 27e3830a..4cb61222 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -37,6 +37,7 @@ #if defined(_WIN32) //#include #elif defined(__linux) + #include // Declares storage size of ‘now’ #include // Used for clock functions #endif @@ -659,4 +660,4 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent return 1; } -#endif \ No newline at end of file +#endif -- cgit v1.2.3 From 728e1715cc52fb25081f3ce17cb5b3f72f7eb218 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 2 Feb 2016 16:43:42 +0100 Subject: Redesigned gestures system... ...and improved mouse gestures support Some testing still required... --- src/gestures.c | 300 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 152 insertions(+), 148 deletions(-) (limited to 'src/gestures.c') diff --git a/src/gestures.c b/src/gestures.c index ea744555..59f2c5b7 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -46,7 +46,11 @@ // Defines and Macros //---------------------------------------------------------------------------------- #define FORCE_TO_SWIPE 20 -#define TAP_TIMEOUT 300 +#define FORCE_TO_DRAG 20 +#define FORCE_TO_PINCH 5 +#define TAP_TIMEOUT 300 // Time in milliseconds +#define PINCH_TIMEOUT 300 // Time in milliseconds +#define DOUBLETAP_RANGE 30 //#define MAX_TOUCH_POINTS 4 //---------------------------------------------------------------------------------- @@ -61,10 +65,6 @@ typedef enum { //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -static GestureType gestureType = TYPE_MOTIONLESS; -static double eventTime = 0; -//static int32_t touchId; // Not used... - // Tap gesture variables static Vector2 initialTapPosition = { 0, 0 }; @@ -78,6 +78,21 @@ static Vector2 endDragPosition = { 0, 0 }; static Vector2 lastDragPosition = { 0, 0 }; static Vector2 dragVector = { 0, 0 }; +// Albert&Ian +static Vector2 touchDownPosition = { 0, 0 }; +static Vector2 touchDownPosition2 = { 0, 0 }; +static Vector2 touchUpPosition = { 0, 0 }; +static Vector2 moveDownPosition = { 0, 0 }; +static Vector2 moveDownPosition2 = { 0, 0 }; + +static int numTap = 0; +static int numHold = 0; +static int numPinch = 0; +static int pointCount = 0; +static int touchId = -1; + +static double eventTime = 0; + static float magnitude = 0; // Distance traveled dragging static float angle = 0; // Angle direction of the drag static float intensity = 0; // How fast we did the drag (pixels per frame) @@ -95,7 +110,7 @@ static int previousGesture = GESTURE_NONE; static int currentGesture = GESTURE_NONE; // Enabled gestures flags, all gestures enabled by default -static unsigned int enabledGestures = 0b0000011111111111; +static unsigned int enabledGestures = 0b0000001111111111; //---------------------------------------------------------------------------------- // Module specific Functions Declaration @@ -105,6 +120,7 @@ static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, flo static float VectorDistance(Vector2 v1, Vector2 v2); static float VectorDotProduct(Vector2 v1, Vector2 v2); static double GetCurrentTime(); +static float Vector2Distance(); //---------------------------------------------------------------------------------- // Module Functions Definition @@ -119,173 +135,160 @@ void ProcessGestureEvent(GestureEvent event) previousGesture = currentGesture; - switch (gestureType) - { - case TYPE_MOTIONLESS: // Detect TAP, DOUBLE_TAP and HOLD events + pointCount = event.pointCount; + + // Albert&Ian + if (pointCount < 2) + { + touchId = event.pointerId[0]; + if (event.touchAction == TOUCH_DOWN) { - if (event.touchAction == TOUCH_DOWN) + numTap++; // Tap counter + + // Detect GESTURE_DOUBLE_TAP + if ((currentGesture == GESTURE_NONE) && (numTap >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (GetMagnitude(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE)) { - if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]); - else - { - // Set the press position - initialTapPosition = event.position[0]; - - // If too much time have passed, we reset the double tap - if (GetCurrentTime() - eventTime > TAP_TIMEOUT) untap = false; - - // If we are in time, we detect the double tap - if (untap) doubleTapping = true; - - // Update our event time - eventTime = GetCurrentTime(); - - // Set hold - if (doubleTapping) currentGesture = GESTURE_DOUBLETAP; - else currentGesture = GESTURE_TAP; - } + currentGesture = GESTURE_DOUBLETAP; + numTap = 0; } - else if (event.touchAction == TOUCH_UP) + else // Detect GESTURE_TAP { - currentGesture = GESTURE_NONE; - - // Detect that we are tapping instead of holding - if (GetCurrentTime() - eventTime < TAP_TIMEOUT) - { - if (doubleTapping) untap = false; - else untap = true; - } - - // Tap finished - doubleTapping = false; - - // Update our event time - eventTime = GetCurrentTime(); + numTap = 1; + currentGesture = GESTURE_TAP; } - // Begin dragging - else if (event.touchAction == TOUCH_MOVE) + + touchDownPosition = event.position[0]; + + touchUpPosition = touchDownPosition; + eventTime = GetCurrentTime(); + } + else if (event.touchAction == TOUCH_UP) + { + if (currentGesture = GESTURE_DRAG) { - if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]); - else - { - // Set the drag starting position - initialDragPosition = initialTapPosition; - endDragPosition = initialDragPosition; - - // Initialize drag - draggingTimeCounter = 0; - gestureType = TYPE_DRAG; - currentGesture = GESTURE_NONE; - } + touchUpPosition = event.position[0]; } - } break; - case TYPE_DRAG: // Detect DRAG and SWIPE events - { - // end of the drag - if (event.touchAction == TOUCH_UP) + + // Calculate for swipe + magnitude = GetMagnitude(touchDownPosition, touchUpPosition); + intensity = magnitude / (float)draggingTimeCounter; + + // Detect GESTURE_SWIPE + if ((intensity > FORCE_TO_SWIPE) && (touchId == 0)) + { + angle = CalculateAngle(touchDownPosition, touchUpPosition, magnitude); + if ((angle < 30) || (angle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right + else if ((angle > 30) && (angle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up + else if ((angle > 120) && (angle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left + else if ((angle > 210) && (angle < 300)) currentGesture = GESTURE_SWIPE_DOWN; // Down + else currentGesture = GESTURE_NONE; + } + else { - // Return Swipe if we have enough sensitivity - if (intensity > FORCE_TO_SWIPE) - { - if (angle < 30 || angle > 330) currentGesture = GESTURE_SWIPE_RIGHT; // Right - else if (angle > 60 && angle < 120) currentGesture = GESTURE_SWIPE_UP; // Up - else if (angle > 150 && angle < 210) currentGesture = GESTURE_SWIPE_LEFT; // Left - else if (angle > 240 && angle < 300) currentGesture = GESTURE_SWIPE_DOWN; // Down - } - magnitude = 0; angle = 0; intensity = 0; - gestureType = TYPE_MOTIONLESS; + currentGesture = GESTURE_NONE; } - // Update while we are dragging - else if (event.touchAction == TOUCH_MOVE) + + draggingTimeCounter = 0; + } + else if (event.touchAction == TOUCH_MOVE) + { + if (GetMagnitude(moveDownPosition, event.position[0]) > 5) eventTime = GetCurrentTime(); + moveDownPosition = event.position[0]; + + if (currentGesture == GESTURE_HOLD) { - if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]); - else - { - lastDragPosition = endDragPosition; - endDragPosition = event.position[0]; - - //endDragPosition.x = AMotionEvent_getX(event, 0); - //endDragPosition.y = AMotionEvent_getY(event, 0); - - // Calculate attributes - dragVector = (Vector2){ endDragPosition.x - lastDragPosition.x, endDragPosition.y - lastDragPosition.y }; - magnitude = sqrt(pow(endDragPosition.x - initialDragPosition.x, 2) + pow(endDragPosition.y - initialDragPosition.y, 2)); - angle = CalculateAngle(initialDragPosition, endDragPosition, magnitude); - intensity = magnitude / (float)draggingTimeCounter; - - // Check if drag movement is less than minimum to keep it as hold state or switch to drag state - if(magnitude > FORCE_TO_SWIPE) - { - currentGesture = GESTURE_DRAG; - draggingTimeCounter++; - } - else currentGesture = GESTURE_HOLD; - } + if (numHold == 1) touchDownPosition = event.position[0]; + + numHold = 2; + + magnitude = GetMagnitude(touchDownPosition, moveDownPosition); + + // Detect GESTURE_DRAG + if (magnitude >= FORCE_TO_DRAG) currentGesture = GESTURE_DRAG; } - } break; - case TYPE_DUAL_INPUT: + + draggingTimeCounter++; + } + } + else + { + // two fingers + + if (event.touchAction == TOUCH_DOWN) + { + touchDownPosition = event.position[0]; + touchDownPosition2 = event.position[1]; + + currentGesture = GESTURE_HOLD; + } + else if (event.touchAction == TOUCH_MOVE) { - if (event.touchAction == TOUCH_UP) + magnitude = GetMagnitude(moveDownPosition, moveDownPosition2); + + touchDownPosition = moveDownPosition; + touchDownPosition2 = moveDownPosition2; + + moveDownPosition = event.position[0]; + moveDownPosition2 = event.position[1]; + + if ( (GetMagnitude(touchDownPosition, moveDownPosition) > FORCE_TO_PINCH) || (GetMagnitude(touchDownPosition2, moveDownPosition2) > FORCE_TO_PINCH)) { - if (event.pointCount == 1) - { - // Set the drag starting position - initialTapPosition = event.position[0]; - } - gestureType = TYPE_MOTIONLESS; + if ((GetMagnitude(moveDownPosition, moveDownPosition2) - magnitude) < 0) currentGesture = GESTURE_PINCH_IN; + else currentGesture = GESTURE_PINCH_OUT; } - else if (event.touchAction == TOUCH_MOVE) + else { - // Adapt the ending position of the inputs - firstEndPinchPosition = event.position[0]; - secondEndPinchPosition = event.position[1]; - - // If there is no more than two inputs - if (event.pointCount == 2) - { - // Calculate distances - float initialDistance = VectorDistance(firstInitialPinchPosition, secondInitialPinchPosition); - float endDistance = VectorDistance(firstEndPinchPosition, secondEndPinchPosition); - - // Calculate Vectors - Vector2 firstTouchVector = { firstEndPinchPosition.x - firstInitialPinchPosition.x, firstEndPinchPosition.y - firstInitialPinchPosition.y }; - Vector2 secondTouchVector = { secondEndPinchPosition.x - secondInitialPinchPosition.x, secondEndPinchPosition.y - secondInitialPinchPosition.y }; - - // Detect the pinch gesture - if (VectorDotProduct(firstTouchVector, secondTouchVector) < -0.5) pinchDelta = initialDistance - endDistance; - else pinchDelta = 0; - - // Pinch gesture resolution - if (pinchDelta != 0) - { - if (pinchDelta > 0) currentGesture = GESTURE_PINCH_IN; - else currentGesture = GESTURE_PINCH_OUT; - } - } - else - { - // Set the drag starting position - initialTapPosition = event.position[0]; - - gestureType = TYPE_MOTIONLESS; - } - - // Readapt the initial position of the inputs - firstInitialPinchPosition = firstEndPinchPosition; - secondInitialPinchPosition = secondEndPinchPosition; + currentGesture = GESTURE_HOLD; } - } break; + } + else if (event.touchAction == TOUCH_UP) + { + currentGesture = GESTURE_NONE; + } + } +} + +// Update gestures detected (must be called every frame) +void UpdateGestures(void) +{ + // NOTE: Gestures are processed through system callbacks on touch events + + // Detect GESTURE_HOLD + if (((currentGesture == GESTURE_TAP) || (currentGesture == GESTURE_DOUBLETAP)) && pointCount < 2) currentGesture = GESTURE_HOLD; + if ((GetCurrentTime() - eventTime) > TAP_TIMEOUT && (currentGesture == GESTURE_DRAG) && pointCount < 2) + { + currentGesture = GESTURE_HOLD; + numHold = 1; } + + // Detect GESTURE_NONE + if ((currentGesture == GESTURE_SWIPE_RIGHT) || (currentGesture == GESTURE_SWIPE_UP) || (currentGesture == GESTURE_SWIPE_LEFT) || (currentGesture == GESTURE_SWIPE_DOWN)) + { + currentGesture = GESTURE_NONE; + } +} + +// Calculate distance between two vectors +float Vector2Distance(Vector2 v1, Vector3 v2) +{ + float result; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + + result = sqrt(dx*dx + dy*dy); + + return result; } // Check if a gesture have been detected bool IsGestureDetected(void) { - if (currentGesture != GESTURE_NONE) return true; + if ((enabledGestures & currentGesture) != GESTURE_NONE) return true; else return false; } @@ -298,7 +301,7 @@ int GetGestureType(void) void SetGesturesEnabled(unsigned int gestureFlags) { - enabledGestures = enabledGestures | gestureFlags; + enabledGestures = gestureFlags; } // Get drag intensity (pixels per frame) @@ -440,6 +443,7 @@ static float VectorDotProduct(Vector2 v1, Vector2 v2) return result; } +// Time measure returned are milliseconds static double GetCurrentTime() { double time = 0; -- cgit v1.2.3 From 65ecde1e75bd9e2738c8640e966328abeaa5658e Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 2 Feb 2016 17:59:13 +0100 Subject: Cleaned code a little bit --- src/gestures.c | 118 +++++++++------------------------------------------------ 1 file changed, 18 insertions(+), 100 deletions(-) (limited to 'src/gestures.c') diff --git a/src/gestures.c b/src/gestures.c index 59f2c5b7..8c690066 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -65,20 +65,11 @@ typedef enum { //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -// Tap gesture variables -static Vector2 initialTapPosition = { 0, 0 }; - -// Double Tap gesture variables -static bool doubleTapping = false; -static bool untap = false; // Check if recently done a tap // Drag gesture variables -static Vector2 initialDragPosition = { 0, 0 }; -static Vector2 endDragPosition = { 0, 0 }; -static Vector2 lastDragPosition = { 0, 0 }; static Vector2 dragVector = { 0, 0 }; -// Albert&Ian +// Touch gesture variables static Vector2 touchDownPosition = { 0, 0 }; static Vector2 touchDownPosition2 = { 0, 0 }; static Vector2 touchUpPosition = { 0, 0 }; @@ -87,7 +78,6 @@ static Vector2 moveDownPosition2 = { 0, 0 }; static int numTap = 0; static int numHold = 0; -static int numPinch = 0; static int pointCount = 0; static int touchId = -1; @@ -99,10 +89,6 @@ static float intensity = 0; // How fast we did the drag (pixels per static int draggingTimeCounter = 0; // Time that have passed while dragging // Pinch gesture variables -static Vector2 firstInitialPinchPosition = { 0, 0 }; -static Vector2 secondInitialPinchPosition = { 0, 0 }; -static Vector2 firstEndPinchPosition = { 0, 0 }; -static Vector2 secondEndPinchPosition = { 0, 0 }; static float pinchDelta = 0; // Pinch delta displacement // Detected gestures @@ -115,12 +101,9 @@ static unsigned int enabledGestures = 0b0000001111111111; //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static void InitPinchGesture(Vector2 posA, Vector2 posB); static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, float magnitude); -static float VectorDistance(Vector2 v1, Vector2 v2); -static float VectorDotProduct(Vector2 v1, Vector2 v2); +static float Vector2Distance(Vector2 v1, Vector2 v2); static double GetCurrentTime(); -static float Vector2Distance(); //---------------------------------------------------------------------------------- // Module Functions Definition @@ -135,18 +118,18 @@ void ProcessGestureEvent(GestureEvent event) previousGesture = currentGesture; - pointCount = event.pointCount; + pointCount = event.pointCount; // Required on UpdateGestures() - // Albert&Ian if (pointCount < 2) { touchId = event.pointerId[0]; + if (event.touchAction == TOUCH_DOWN) { numTap++; // Tap counter // Detect GESTURE_DOUBLE_TAP - if ((currentGesture == GESTURE_NONE) && (numTap >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (GetMagnitude(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE)) + if ((currentGesture == GESTURE_NONE) && (numTap >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (Vector2Distance(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE)) { currentGesture = GESTURE_DOUBLETAP; numTap = 0; @@ -164,19 +147,17 @@ void ProcessGestureEvent(GestureEvent event) } else if (event.touchAction == TOUCH_UP) { - if (currentGesture = GESTURE_DRAG) - { - touchUpPosition = event.position[0]; - } - + if (currentGesture == GESTURE_DRAG) touchUpPosition = event.position[0]; + // Calculate for swipe - magnitude = GetMagnitude(touchDownPosition, touchUpPosition); + magnitude = Vector2Distance(touchDownPosition, touchUpPosition); intensity = magnitude / (float)draggingTimeCounter; // Detect GESTURE_SWIPE if ((intensity > FORCE_TO_SWIPE) && (touchId == 0)) { angle = CalculateAngle(touchDownPosition, touchUpPosition, magnitude); + if ((angle < 30) || (angle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right else if ((angle > 30) && (angle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up else if ((angle > 120) && (angle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left @@ -196,7 +177,8 @@ void ProcessGestureEvent(GestureEvent event) } else if (event.touchAction == TOUCH_MOVE) { - if (GetMagnitude(moveDownPosition, event.position[0]) > 5) eventTime = GetCurrentTime(); + if (Vector2Distance(moveDownPosition, event.position[0]) > 5) eventTime = GetCurrentTime(); + moveDownPosition = event.position[0]; if (currentGesture == GESTURE_HOLD) @@ -205,7 +187,7 @@ void ProcessGestureEvent(GestureEvent event) numHold = 2; - magnitude = GetMagnitude(touchDownPosition, moveDownPosition); + magnitude = Vector2Distance(touchDownPosition, moveDownPosition); // Detect GESTURE_DRAG if (magnitude >= FORCE_TO_DRAG) currentGesture = GESTURE_DRAG; @@ -214,10 +196,8 @@ void ProcessGestureEvent(GestureEvent event) draggingTimeCounter++; } } - else + else // Two touch points { - // two fingers - if (event.touchAction == TOUCH_DOWN) { touchDownPosition = event.position[0]; @@ -227,7 +207,7 @@ void ProcessGestureEvent(GestureEvent event) } else if (event.touchAction == TOUCH_MOVE) { - magnitude = GetMagnitude(moveDownPosition, moveDownPosition2); + magnitude = Vector2Distance(moveDownPosition, moveDownPosition2); touchDownPosition = moveDownPosition; touchDownPosition2 = moveDownPosition2; @@ -235,9 +215,9 @@ void ProcessGestureEvent(GestureEvent event) moveDownPosition = event.position[0]; moveDownPosition2 = event.position[1]; - if ( (GetMagnitude(touchDownPosition, moveDownPosition) > FORCE_TO_PINCH) || (GetMagnitude(touchDownPosition2, moveDownPosition2) > FORCE_TO_PINCH)) + if ((Vector2Distance(touchDownPosition, moveDownPosition) > FORCE_TO_PINCH) || (Vector2Distance(touchDownPosition2, moveDownPosition2) > FORCE_TO_PINCH)) { - if ((GetMagnitude(moveDownPosition, moveDownPosition2) - magnitude) < 0) currentGesture = GESTURE_PINCH_IN; + if ((Vector2Distance(moveDownPosition, moveDownPosition2) - magnitude) < 0) currentGesture = GESTURE_PINCH_IN; else currentGesture = GESTURE_PINCH_OUT; } else @@ -259,6 +239,7 @@ void UpdateGestures(void) // Detect GESTURE_HOLD if (((currentGesture == GESTURE_TAP) || (currentGesture == GESTURE_DOUBLETAP)) && pointCount < 2) currentGesture = GESTURE_HOLD; + if ((GetCurrentTime() - eventTime) > TAP_TIMEOUT && (currentGesture == GESTURE_DRAG) && pointCount < 2) { currentGesture = GESTURE_HOLD; @@ -272,19 +253,6 @@ void UpdateGestures(void) } } -// Calculate distance between two vectors -float Vector2Distance(Vector2 v1, Vector3 v2) -{ - float result; - - float dx = v2.x - v1.x; - float dy = v2.y - v1.y; - - result = sqrt(dx*dx + dy*dy); - - return result; -} - // Check if a gesture have been detected bool IsGestureDetected(void) { @@ -342,20 +310,6 @@ float GetGesturePinchAngle(void) return 0; } -// Update gestures detected (must be called every frame) -void UpdateGestures(void) -{ - // NOTE: Gestures are processed through system callbacks on touch events - - // When screen is touched, in first frame GESTURE_TAP is called but in next frame touch event callback is not called (if touch position doesn't change), - // so we need to store previous frame gesture type manually in this update function to switch to HOLD if current gesture is - // GESTURE_TAP two frames in a row. Due to current gesture is set to HOLD, current gesture doesn't need to be reset to NONE every frame. - // It will be reset when UP is called. - if(currentGesture == GESTURE_TAP) previousGesture = currentGesture; - - if(previousGesture == GESTURE_TAP && currentGesture == GESTURE_TAP) currentGesture = GESTURE_HOLD; -} - //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- @@ -395,28 +349,7 @@ static float CalculateAngle(Vector2 initialPosition, Vector2 finalPosition, floa return angle; } -static void InitPinchGesture(Vector2 posA, Vector2 posB) -{ - initialDragPosition = (Vector2){ 0, 0 }; - endDragPosition = (Vector2){ 0, 0 }; - lastDragPosition = (Vector2){ 0, 0 }; - - // Initialize positions - firstInitialPinchPosition = posA; - secondInitialPinchPosition = posB; - - firstEndPinchPosition = firstInitialPinchPosition; - secondEndPinchPosition = secondInitialPinchPosition; - - // Resets - magnitude = 0; - angle = 0; - intensity = 0; - - gestureType = TYPE_DUAL_INPUT; -} - -static float VectorDistance(Vector2 v1, Vector2 v2) +static float Vector2Distance(Vector2 v1, Vector2 v2) { float result; @@ -428,21 +361,6 @@ static float VectorDistance(Vector2 v1, Vector2 v2) return result; } -static float VectorDotProduct(Vector2 v1, Vector2 v2) -{ - float result; - - float v1Module = sqrt(v1.x*v1.x + v1.y*v1.y); - float v2Module = sqrt(v2.x*v2.x + v2.y*v2.y); - - Vector2 v1Normalized = { v1.x / v1Module, v1.y / v1Module }; - Vector2 v2Normalized = { v2.x / v2Module, v2.y / v2Module }; - - result = v1Normalized.x*v2Normalized.x + v1Normalized.y*v2Normalized.y; - - return result; -} - // Time measure returned are milliseconds static double GetCurrentTime() { -- cgit v1.2.3 From e98ea900cfc3b20bc4c09424a58893524f90534d Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 3 Feb 2016 19:29:59 +0100 Subject: Reviewing gestures module (IN PROGRESS) --- src/gestures.c | 99 ++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 41 deletions(-) (limited to 'src/gestures.c') diff --git a/src/gestures.c b/src/gestures.c index 8c690066..13c7845a 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -1,8 +1,10 @@ /********************************************************************************************** * -* raylib Gestures System - Gestures Detection and Usage Functions (Android and HTML5) +* raylib Gestures System - Gestures Processing based on input gesture events (touch/mouse) * -* Copyright (c) 2015 Marc Palau and Ramon Santamaria +* Reviewed by Ramon Santamaria +* Redesigned by Albert Martos and Ian Eito +* Initial design by Marc Palau * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. @@ -56,18 +58,14 @@ //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -typedef enum { - TYPE_MOTIONLESS, - TYPE_DRAG, - TYPE_DUAL_INPUT -} GestureType; +// ... //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- // Drag gesture variables -static Vector2 dragVector = { 0, 0 }; +static Vector2 dragVector = { 0.0f , 0.0f }; // Touch gesture variables static Vector2 touchDownPosition = { 0, 0 }; @@ -81,15 +79,15 @@ static int numHold = 0; static int pointCount = 0; static int touchId = -1; -static double eventTime = 0; +static double eventTime = 0.0; -static float magnitude = 0; // Distance traveled dragging -static float angle = 0; // Angle direction of the drag -static float intensity = 0; // How fast we did the drag (pixels per frame) -static int draggingTimeCounter = 0; // Time that have passed while dragging +static float dragDistance = 0.0f; // DRAG distance (from initial touch point to current) +static float dragAngle = 0; // DRAG angle direction +static float dragIntensity = 0; // DRAG intensity, how far why did the DRAG (pixels per frame) +static int draggingTimeCounter = 0; // DRAG time // RAY: WTF!!! Counting... frames??? // Pinch gesture variables -static float pinchDelta = 0; // Pinch delta displacement +static float pinchDistance = 0.0f; // Pinch displacement distance // RAY: Not used! o__O // Detected gestures static int previousGesture = GESTURE_NONE; @@ -112,9 +110,9 @@ static double GetCurrentTime(); // Process gesture event and translate it into gestures void ProcessGestureEvent(GestureEvent event) { - // Resets - dragVector = (Vector2){ 0, 0 }; - pinchDelta = 0; + // Reset required variables + dragVector = (Vector2){ 0.0f, 0.0f }; // RAY: Not used??? + pinchDistance = 0.0f; previousGesture = currentGesture; @@ -150,25 +148,25 @@ void ProcessGestureEvent(GestureEvent event) if (currentGesture == GESTURE_DRAG) touchUpPosition = event.position[0]; // Calculate for swipe - magnitude = Vector2Distance(touchDownPosition, touchUpPosition); - intensity = magnitude / (float)draggingTimeCounter; + dragDistance = Vector2Distance(touchDownPosition, touchUpPosition); + dragIntensity = dragDistance/(float)draggingTimeCounter; // RAY: WTF!!! Counting frames??? // Detect GESTURE_SWIPE - if ((intensity > FORCE_TO_SWIPE) && (touchId == 0)) + if ((dragIntensity > FORCE_TO_SWIPE) && (touchId == 0)) // RAY: why check (touchId == 0)??? { - angle = CalculateAngle(touchDownPosition, touchUpPosition, magnitude); + dragAngle = CalculateAngle(touchDownPosition, touchUpPosition, dragDistance); - if ((angle < 30) || (angle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right - else if ((angle > 30) && (angle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up - else if ((angle > 120) && (angle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left - else if ((angle > 210) && (angle < 300)) currentGesture = GESTURE_SWIPE_DOWN; // Down + if ((dragAngle < 30) || (dragAngle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right + else if ((dragAngle > 30) && (dragAngle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up + else if ((dragAngle > 120) && (dragAngle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left + else if ((dragAngle > 210) && (dragAngle < 300)) currentGesture = GESTURE_SWIPE_DOWN; // Down else currentGesture = GESTURE_NONE; } else { - magnitude = 0; - angle = 0; - intensity = 0; + dragDistance = 0.0f; + dragIntensity = 0.0f; + dragAngle = 0.0f; currentGesture = GESTURE_NONE; } @@ -187,13 +185,13 @@ void ProcessGestureEvent(GestureEvent event) numHold = 2; - magnitude = Vector2Distance(touchDownPosition, moveDownPosition); + dragDistance = Vector2Distance(touchDownPosition, moveDownPosition); // Detect GESTURE_DRAG - if (magnitude >= FORCE_TO_DRAG) currentGesture = GESTURE_DRAG; + if (dragDistance >= FORCE_TO_DRAG) currentGesture = GESTURE_DRAG; } - draggingTimeCounter++; + draggingTimeCounter++; // RAY: What do you count??? Move event actions? } } else // Two touch points @@ -207,7 +205,7 @@ void ProcessGestureEvent(GestureEvent event) } else if (event.touchAction == TOUCH_MOVE) { - magnitude = Vector2Distance(moveDownPosition, moveDownPosition2); + pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2); touchDownPosition = moveDownPosition; touchDownPosition2 = moveDownPosition2; @@ -217,7 +215,7 @@ void ProcessGestureEvent(GestureEvent event) if ((Vector2Distance(touchDownPosition, moveDownPosition) > FORCE_TO_PINCH) || (Vector2Distance(touchDownPosition2, moveDownPosition2) > FORCE_TO_PINCH)) { - if ((Vector2Distance(moveDownPosition, moveDownPosition2) - magnitude) < 0) currentGesture = GESTURE_PINCH_IN; + if ((Vector2Distance(moveDownPosition, moveDownPosition2) - pinchDistance) < 0) currentGesture = GESTURE_PINCH_IN; else currentGesture = GESTURE_PINCH_OUT; } else @@ -227,6 +225,8 @@ void ProcessGestureEvent(GestureEvent event) } else if (event.touchAction == TOUCH_UP) { + pinchDistance = 0.0f; + currentGesture = GESTURE_NONE; } } @@ -272,41 +272,47 @@ void SetGesturesEnabled(unsigned int gestureFlags) enabledGestures = gestureFlags; } -// Get drag intensity (pixels per frame) -float GetGestureDragIntensity(void) +// Get drag dragIntensity (pixels per frame) +float GetGestureDragdragIntensity(void) { - return intensity; + return dragIntensity; } // Get drag angle // NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise float GetGestureDragAngle(void) { - return angle; + return dragAngle; } // Get drag vector (between initial and final position) Vector2 GetGestureDragVector(void) { + // TODO: Calculate DRAG vector + return dragVector; } -// Hold time measured in frames +// Hold time measured in ms int GetGestureHoldDuration(void) { + // TODO: Return last hold time in ms + return 0; } -// Get magnitude between two pinch points +// Get distance between two pinch points float GetGesturePinchDelta(void) { - return pinchDelta; + return pinchDistance; } // Get angle beween two pinch points // NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise float GetGesturePinchAngle(void) { + // TODO: Calculate pinch angle + return 0; } @@ -314,13 +320,23 @@ float GetGesturePinchAngle(void) // Module specific Functions Definition //---------------------------------------------------------------------------------- +// RAY: Do we really need magnitude??? why??? +// TODO: Remove magnitude dependency... static float CalculateAngle(Vector2 initialPosition, Vector2 finalPosition, float magnitude) { float angle; - // Calculate arcsinus of the movement + // Calculate arcsinus of the movement // RAY: o__O angle = asin((finalPosition.y - initialPosition.y)/magnitude); angle *= RAD2DEG; + + // RAY: review this (better) solution + //angle = atan2(p1.y - p2.y, p1.x - p2.x); + //angle *= RAD2DEG; + + // http://stackoverflow.com/questions/21483999/using-atan2-to-find-angle-between-two-vectors + + // TODO: Remove sector dependency (self-note: check moving eyes exercise) // Calculate angle depending on the sector if ((finalPosition.x - initialPosition.x) >= 0) @@ -349,6 +365,7 @@ static float CalculateAngle(Vector2 initialPosition, Vector2 finalPosition, floa return angle; } +// Calculate distance between two Vector2 static float Vector2Distance(Vector2 v1, Vector2 v2) { float result; -- cgit v1.2.3 From 687fe2c3c79bac68e6eab3ae393fefed0a7a4b07 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 8 Feb 2016 09:04:33 +0100 Subject: Updated --- src/gestures.c | 54 +++++++++++++----------------------------------------- 1 file changed, 13 insertions(+), 41 deletions(-) (limited to 'src/gestures.c') diff --git a/src/gestures.c b/src/gestures.c index 13c7845a..09c18fc4 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -99,7 +99,7 @@ static unsigned int enabledGestures = 0b0000001111111111; //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, float magnitude); +static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition); static float Vector2Distance(Vector2 v1, Vector2 v2); static double GetCurrentTime(); @@ -152,9 +152,9 @@ void ProcessGestureEvent(GestureEvent event) dragIntensity = dragDistance/(float)draggingTimeCounter; // RAY: WTF!!! Counting frames??? // Detect GESTURE_SWIPE - if ((dragIntensity > FORCE_TO_SWIPE) && (touchId == 0)) // RAY: why check (touchId == 0)??? + if ((dragIntensity > FORCE_TO_SWIPE) && (touchId == 0)) // RAY: why check (touchId == 0)??? { - dragAngle = CalculateAngle(touchDownPosition, touchUpPosition, dragDistance); + dragAngle = Vector2Angle(touchDownPosition, touchUpPosition); if ((dragAngle < 30) || (dragAngle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right else if ((dragAngle > 30) && (dragAngle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up @@ -322,46 +322,18 @@ float GetGesturePinchAngle(void) // RAY: Do we really need magnitude??? why??? // TODO: Remove magnitude dependency... -static float CalculateAngle(Vector2 initialPosition, Vector2 finalPosition, float magnitude) +static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition) { float angle; - - // Calculate arcsinus of the movement // RAY: o__O - angle = asin((finalPosition.y - initialPosition.y)/magnitude); - angle *= RAD2DEG; - + // RAY: review this (better) solution - //angle = atan2(p1.y - p2.y, p1.x - p2.x); - //angle *= RAD2DEG; - - // http://stackoverflow.com/questions/21483999/using-atan2-to-find-angle-between-two-vectors - - // TODO: Remove sector dependency (self-note: check moving eyes exercise) + angle = atan2(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x); + angle *= RAD2DEG; - // Calculate angle depending on the sector - if ((finalPosition.x - initialPosition.x) >= 0) - { - // Sector 4 - if ((finalPosition.y - initialPosition.y) >= 0) - { - angle *= -1; - angle += 360; - } - // Sector 1 - else angle *= -1; - } - else - { - // Sector 3 - if ((finalPosition.y - initialPosition.y) >= 0) angle += 180; - // Sector 2 - else - { - angle *= -1; - angle = 180 - angle; - } - } + if (angle < 0) angle += 360; + // http://stackoverflow.com/questions/21483999/using-atan2-to-find-angle-between-two-vectors + return angle; } @@ -389,16 +361,16 @@ static double GetCurrentTime() QueryPerformanceFrequency(&clockFrequency); QueryPerformanceCounter(¤tTime); - time = (double)currentTime/clockFrequency*1000.0f; // time in miliseconds + time = (double)currentTime/clockFrequency*1000.0f; // Time in miliseconds #endif #if defined(__linux) // NOTE: Only for Linux-based systems struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); - uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time provided in nanoseconds + uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time in nanoseconds - time = ((double)nowTime/1000000.0); // time in miliseconds + time = ((double)nowTime/1000000.0); // Time in miliseconds #endif return time; -- cgit v1.2.3 From a847df921f94a7fd118fcb608b23f11d8255c236 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 10 Feb 2016 10:31:06 +0100 Subject: Reviewed gestures module --- src/gestures.c | 110 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 42 deletions(-) (limited to 'src/gestures.c') diff --git a/src/gestures.c b/src/gestures.c index 09c18fc4..e5a8eb9e 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -31,9 +31,7 @@ #include "raylib.h" // Required for typedef(s): Vector2, Gestures #endif -#include // malloc(), free() -#include // printf(), fprintf() -#include // Used for ... +#include // Used for: atan2(), sqrt() #include // Defines int32_t, int64_t #if defined(_WIN32) @@ -47,13 +45,12 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define FORCE_TO_SWIPE 20 +#define FORCE_TO_SWIPE 1 #define FORCE_TO_DRAG 20 #define FORCE_TO_PINCH 5 #define TAP_TIMEOUT 300 // Time in milliseconds #define PINCH_TIMEOUT 300 // Time in milliseconds #define DOUBLETAP_RANGE 30 -//#define MAX_TOUCH_POINTS 4 //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -64,30 +61,33 @@ // Global Variables Definition //---------------------------------------------------------------------------------- -// Drag gesture variables -static Vector2 dragVector = { 0.0f , 0.0f }; - // Touch gesture variables -static Vector2 touchDownPosition = { 0, 0 }; -static Vector2 touchDownPosition2 = { 0, 0 }; -static Vector2 touchUpPosition = { 0, 0 }; -static Vector2 moveDownPosition = { 0, 0 }; -static Vector2 moveDownPosition2 = { 0, 0 }; +static Vector2 touchDownPosition = { 0.0f, 0.0f }; +static Vector2 touchDownPosition2 = { 0.0f, 0.0f }; +static Vector2 touchDownDragPosition = { 0.0f, 0.0f }; +static Vector2 touchUpPosition = { 0.0f, 0.0f }; +static Vector2 moveDownPosition = { 0.0f, 0.0f }; +static Vector2 moveDownPosition2 = { 0.0f, 0.0f }; static int numTap = 0; static int numHold = 0; +static bool isMoving = false; +static float timeHold = 0.0f; static int pointCount = 0; static int touchId = -1; static double eventTime = 0.0; +static double swipeTime = 0.0; +// Drag gesture variables +static Vector2 dragVector = { 0.0f , 0.0f }; static float dragDistance = 0.0f; // DRAG distance (from initial touch point to current) -static float dragAngle = 0; // DRAG angle direction -static float dragIntensity = 0; // DRAG intensity, how far why did the DRAG (pixels per frame) -static int draggingTimeCounter = 0; // DRAG time // RAY: WTF!!! Counting... frames??? +static float dragAngle = 0.0f; // DRAG angle direction +static float dragIntensity = 0.0f; // DRAG intensity, how far why did the DRAG (pixels per frame) // Pinch gesture variables static float pinchDistance = 0.0f; // Pinch displacement distance // RAY: Not used! o__O +static float pinchAngle = 0.0f; // Pinch displacement distance // RAY: Not used! o__O // Detected gestures static int previousGesture = GESTURE_NONE; @@ -111,9 +111,6 @@ static double GetCurrentTime(); void ProcessGestureEvent(GestureEvent event) { // Reset required variables - dragVector = (Vector2){ 0.0f, 0.0f }; // RAY: Not used??? - pinchDistance = 0.0f; - previousGesture = currentGesture; pointCount = event.pointCount; // Required on UpdateGestures() @@ -139,9 +136,12 @@ void ProcessGestureEvent(GestureEvent event) } touchDownPosition = event.position[0]; + touchDownDragPosition = event.position[0]; touchUpPosition = touchDownPosition; eventTime = GetCurrentTime(); + + dragVector = (Vector2){ 0.0f, 0.0f }; } else if (event.touchAction == TOUCH_UP) { @@ -149,12 +149,15 @@ void ProcessGestureEvent(GestureEvent event) // Calculate for swipe dragDistance = Vector2Distance(touchDownPosition, touchUpPosition); - dragIntensity = dragDistance/(float)draggingTimeCounter; // RAY: WTF!!! Counting frames??? + dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime)); + + isMoving = false; // Detect GESTURE_SWIPE if ((dragIntensity > FORCE_TO_SWIPE) && (touchId == 0)) // RAY: why check (touchId == 0)??? { - dragAngle = Vector2Angle(touchDownPosition, touchUpPosition); + // NOTE: Angle should be inverted in Y + dragAngle = 360.0f - Vector2Angle(touchDownPosition, touchUpPosition);; if ((dragAngle < 30) || (dragAngle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right else if ((dragAngle > 30) && (dragAngle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up @@ -171,12 +174,18 @@ void ProcessGestureEvent(GestureEvent event) currentGesture = GESTURE_NONE; } - draggingTimeCounter = 0; + touchDownPosition = (Vector2){ 0.0f, 0.0f }; } else if (event.touchAction == TOUCH_MOVE) { if (Vector2Distance(moveDownPosition, event.position[0]) > 5) eventTime = GetCurrentTime(); + if (!isMoving) + { + swipeTime = GetCurrentTime(); + isMoving = true; + } + moveDownPosition = event.position[0]; if (currentGesture == GESTURE_HOLD) @@ -190,8 +199,9 @@ void ProcessGestureEvent(GestureEvent event) // Detect GESTURE_DRAG if (dragDistance >= FORCE_TO_DRAG) currentGesture = GESTURE_DRAG; } - - draggingTimeCounter++; // RAY: What do you count??? Move event actions? + + dragVector.x = moveDownPosition.x - touchDownDragPosition.x; + dragVector.y = moveDownPosition.y - touchDownDragPosition.y; } } else // Two touch points @@ -200,13 +210,15 @@ void ProcessGestureEvent(GestureEvent event) { touchDownPosition = event.position[0]; touchDownPosition2 = event.position[1]; + pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2); currentGesture = GESTURE_HOLD; + timeHold = GetCurrentTime(); } else if (event.touchAction == TOUCH_MOVE) { pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2); - + touchDownPosition = moveDownPosition; touchDownPosition2 = moveDownPosition2; @@ -220,12 +232,17 @@ void ProcessGestureEvent(GestureEvent event) } else { - currentGesture = GESTURE_HOLD; + currentGesture = GESTURE_HOLD; + timeHold = GetCurrentTime(); } + + // NOTE: Angle should be inverted in Y + pinchAngle = 360.0f - Vector2Angle(moveDownPosition, moveDownPosition2); } else if (event.touchAction == TOUCH_UP) { pinchDistance = 0.0f; + pinchAngle = 0.0f; currentGesture = GESTURE_NONE; } @@ -238,11 +255,16 @@ void UpdateGestures(void) // NOTE: Gestures are processed through system callbacks on touch events // Detect GESTURE_HOLD - if (((currentGesture == GESTURE_TAP) || (currentGesture == GESTURE_DOUBLETAP)) && pointCount < 2) currentGesture = GESTURE_HOLD; + if (((currentGesture == GESTURE_TAP) || (currentGesture == GESTURE_DOUBLETAP)) && (pointCount < 2)) + { + currentGesture = GESTURE_HOLD; + timeHold = GetCurrentTime(); + } - if ((GetCurrentTime() - eventTime) > TAP_TIMEOUT && (currentGesture == GESTURE_DRAG) && pointCount < 2) + if (((GetCurrentTime() - eventTime) > TAP_TIMEOUT) && (currentGesture == GESTURE_DRAG) && (pointCount < 2)) { currentGesture = GESTURE_HOLD; + timeHold = GetCurrentTime(); numHold = 1; } @@ -288,17 +310,19 @@ float GetGestureDragAngle(void) // Get drag vector (between initial and final position) Vector2 GetGestureDragVector(void) { - // TODO: Calculate DRAG vector - + // NOTE: Calculated in... return dragVector; } // Hold time measured in ms -int GetGestureHoldDuration(void) +float GetGestureHoldDuration(void) { - // TODO: Return last hold time in ms + float time = 0.0f; + + // DONE: Return last hold time in ms + if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold; - return 0; + return time; } // Get distance between two pinch points @@ -307,32 +331,34 @@ float GetGesturePinchDelta(void) return pinchDistance; } +// Get number of touch points +int GetTouchPointsCount(void) +{ + return pointCount; +} + // Get angle beween two pinch points // NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise float GetGesturePinchAngle(void) { - // TODO: Calculate pinch angle + // NOTE: pinch angle is calculated on two touch points TOUCH_MOVE - return 0; + return pinchAngle; } //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- -// RAY: Do we really need magnitude??? why??? -// TODO: Remove magnitude dependency... +// Returns angle from two-points vector with X-axis static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition) { float angle; - - // RAY: review this (better) solution + angle = atan2(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x); angle *= RAD2DEG; - if (angle < 0) angle += 360; - - // http://stackoverflow.com/questions/21483999/using-atan2-to-find-angle-between-two-vectors + if (angle < 0) angle += 360.0f; return angle; } -- cgit v1.2.3 From c69ce1d7504b94108721403c867bddbf50d7b890 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 10 Feb 2016 13:54:32 +0100 Subject: Updated comments --- src/gestures.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'src/gestures.c') diff --git a/src/gestures.c b/src/gestures.c index e5a8eb9e..a2744460 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -45,7 +45,7 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define FORCE_TO_SWIPE 1 +#define FORCE_TO_SWIPE 1 // Time in milliseconds #define FORCE_TO_DRAG 20 #define FORCE_TO_PINCH 5 #define TAP_TIMEOUT 300 // Time in milliseconds @@ -80,14 +80,14 @@ static double eventTime = 0.0; static double swipeTime = 0.0; // Drag gesture variables -static Vector2 dragVector = { 0.0f , 0.0f }; -static float dragDistance = 0.0f; // DRAG distance (from initial touch point to current) -static float dragAngle = 0.0f; // DRAG angle direction -static float dragIntensity = 0.0f; // DRAG intensity, how far why did the DRAG (pixels per frame) +static Vector2 dragVector = { 0.0f , 0.0f }; // DRAG vector (between initial and current position) +static float dragDistance = 0.0f; // DRAG distance (from initial touch point to final) for SWIPE GESTURE +static float dragAngle = 0.0f; // DRAG angle direction for SWIPE GESTURE +static float dragIntensity = 0.0f; // DRAG intensity, how far why did the DRAG (pixels per frame) for SWIPE GESTURE // Pinch gesture variables -static float pinchDistance = 0.0f; // Pinch displacement distance // RAY: Not used! o__O -static float pinchAngle = 0.0f; // Pinch displacement distance // RAY: Not used! o__O +static float pinchDistance = 0.0f; // Pinch displacement distance +static float pinchAngle = 0.0f; // Pinch displacement distance // Detected gestures static int previousGesture = GESTURE_NONE; @@ -122,7 +122,7 @@ void ProcessGestureEvent(GestureEvent event) if (event.touchAction == TOUCH_DOWN) { numTap++; // Tap counter - + // Detect GESTURE_DOUBLE_TAP if ((currentGesture == GESTURE_NONE) && (numTap >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (Vector2Distance(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE)) { @@ -174,7 +174,7 @@ void ProcessGestureEvent(GestureEvent event) currentGesture = GESTURE_NONE; } - touchDownPosition = (Vector2){ 0.0f, 0.0f }; + touchDownDragPosition = (Vector2){ 0.0f, 0.0f }; } else if (event.touchAction == TOUCH_MOVE) { @@ -297,6 +297,8 @@ void SetGesturesEnabled(unsigned int gestureFlags) // Get drag dragIntensity (pixels per frame) float GetGestureDragdragIntensity(void) { + // NOTE: drag intensity is calculated on one touch points TOUCH_UP + return dragIntensity; } @@ -304,22 +306,26 @@ float GetGestureDragdragIntensity(void) // NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise float GetGestureDragAngle(void) { + // NOTE: drag angle is calculated on one touch points TOUCH_UP + return dragAngle; } -// Get drag vector (between initial and final position) +// Get drag vector (between initial touch point to current) Vector2 GetGestureDragVector(void) { - // NOTE: Calculated in... + // NOTE: drag vector is calculated on one touch points TOUCH_MOVE + return dragVector; } // Hold time measured in ms float GetGestureHoldDuration(void) { + // NOTE: time is calculated on current gesture HOLD + float time = 0.0f; - // DONE: Return last hold time in ms if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold; return time; @@ -328,12 +334,17 @@ float GetGestureHoldDuration(void) // Get distance between two pinch points float GetGesturePinchDelta(void) { + // NOTE: The position values used for pinchDistance are not modified like the position values of [core.c]-->GetTouchPosition(int index) + // NOTE: pinch distance is calculated on two touch points TOUCH_MOVE + return pinchDistance; } // Get number of touch points int GetTouchPointsCount(void) { + // NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called + return pointCount; } -- cgit v1.2.3 From 94c92a58a1a8131c4d71ba32f18e836f6178231c Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 13 Feb 2016 17:08:09 +0100 Subject: Some tweaks --- src/gestures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gestures.c') diff --git a/src/gestures.c b/src/gestures.c index a2744460..16442e45 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -2,9 +2,9 @@ * * raylib Gestures System - Gestures Processing based on input gesture events (touch/mouse) * -* Reviewed by Ramon Santamaria -* Redesigned by Albert Martos and Ian Eito * Initial design by Marc Palau +* Redesigned by Albert Martos and Ian Eito +* Reviewed by Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. -- cgit v1.2.3 From afd2ffb74a84bf48b9129c613e1673ceae0bd46b Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 17 Feb 2016 13:00:48 +0100 Subject: Updated gestures module Using normalized [0..1] input points --- src/gestures.c | 134 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 71 insertions(+), 63 deletions(-) (limited to 'src/gestures.c') diff --git a/src/gestures.c b/src/gestures.c index 16442e45..af92ba3d 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -45,12 +45,12 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define FORCE_TO_SWIPE 1 // Time in milliseconds -#define FORCE_TO_DRAG 20 -#define FORCE_TO_PINCH 5 -#define TAP_TIMEOUT 300 // Time in milliseconds -#define PINCH_TIMEOUT 300 // Time in milliseconds -#define DOUBLETAP_RANGE 30 +#define FORCE_TO_SWIPE 0.0005f // Measured in normalized pixels / time +#define MINIMUM_DRAG 0.015f // Measured in normalized pixels [0..1] +#define MINIMUM_PINCH 0.005f // Measured in normalized pixels [0..1] +#define TAP_TIMEOUT 300 // Time in milliseconds +#define PINCH_TIMEOUT 300 // Time in milliseconds +#define DOUBLETAP_RANGE 0.03f //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -68,26 +68,29 @@ static Vector2 touchDownDragPosition = { 0.0f, 0.0f }; static Vector2 touchUpPosition = { 0.0f, 0.0f }; static Vector2 moveDownPosition = { 0.0f, 0.0f }; static Vector2 moveDownPosition2 = { 0.0f, 0.0f }; - static int numTap = 0; -static int numHold = 0; -static bool isMoving = false; -static float timeHold = 0.0f; + static int pointCount = 0; static int touchId = -1; static double eventTime = 0.0; static double swipeTime = 0.0; +// Hold gesture variables +static int numHold = 0; +static float timeHold = 0.0f; + // Drag gesture variables static Vector2 dragVector = { 0.0f , 0.0f }; // DRAG vector (between initial and current position) -static float dragDistance = 0.0f; // DRAG distance (from initial touch point to final) for SWIPE GESTURE -static float dragAngle = 0.0f; // DRAG angle direction for SWIPE GESTURE -static float dragIntensity = 0.0f; // DRAG intensity, how far why did the DRAG (pixels per frame) for SWIPE GESTURE +static float dragAngle = 0.0f; // DRAG angle (relative to x-axis) +static float dragDistance = 0.0f; // DRAG distance (from initial touch point to final) (normalized [0..1]) +static float dragIntensity = 0.0f; // DRAG intensity, how far why did the DRAG (pixels per frame) +static bool startMoving = false; // SWIPE used to define when start measuring swipeTime // Pinch gesture variables -static float pinchDistance = 0.0f; // Pinch displacement distance -static float pinchAngle = 0.0f; // Pinch displacement distance +static Vector2 pinchVector = { 0.0f , 0.0f }; // PINCH vector (between first and second touch points) +static float pinchAngle = 0.0f; // PINCH angle (relative to x-axis) +static float pinchDistance = 0.0f; // PINCH displacement distance (normalized [0..1]) // Detected gestures static int previousGesture = GESTURE_NONE; @@ -101,7 +104,7 @@ static unsigned int enabledGestures = 0b0000001111111111; //---------------------------------------------------------------------------------- static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition); static float Vector2Distance(Vector2 v1, Vector2 v2); -static double GetCurrentTime(); +static double GetCurrentTime(void); //---------------------------------------------------------------------------------- // Module Functions Definition @@ -147,17 +150,19 @@ void ProcessGestureEvent(GestureEvent event) { if (currentGesture == GESTURE_DRAG) touchUpPosition = event.position[0]; - // Calculate for swipe + // NOTE: dragIntensity dependend on the resolution of the screen dragDistance = Vector2Distance(touchDownPosition, touchUpPosition); dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime)); + + // TODO: Make getures detection resolution independant - isMoving = false; + startMoving = false; // Detect GESTURE_SWIPE if ((dragIntensity > FORCE_TO_SWIPE) && (touchId == 0)) // RAY: why check (touchId == 0)??? { // NOTE: Angle should be inverted in Y - dragAngle = 360.0f - Vector2Angle(touchDownPosition, touchUpPosition);; + dragAngle = 360.0f - Vector2Angle(touchDownPosition, touchUpPosition); if ((dragAngle < 30) || (dragAngle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right else if ((dragAngle > 30) && (dragAngle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up @@ -178,26 +183,28 @@ void ProcessGestureEvent(GestureEvent event) } else if (event.touchAction == TOUCH_MOVE) { - if (Vector2Distance(moveDownPosition, event.position[0]) > 5) eventTime = GetCurrentTime(); + if ((currentGesture == GESTURE_DRAG)) eventTime = GetCurrentTime(); - if (!isMoving) + if (!startMoving) { swipeTime = GetCurrentTime(); - isMoving = true; + startMoving = true; } moveDownPosition = event.position[0]; - if (currentGesture == GESTURE_HOLD) + if (currentGesture == GESTURE_HOLD) { if (numHold == 1) touchDownPosition = event.position[0]; numHold = 2; - - dragDistance = Vector2Distance(touchDownPosition, moveDownPosition); // Detect GESTURE_DRAG - if (dragDistance >= FORCE_TO_DRAG) currentGesture = GESTURE_DRAG; + if (Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_DRAG) + { + eventTime = GetCurrentTime(); + currentGesture = GESTURE_DRAG; + } } dragVector.x = moveDownPosition.x - touchDownDragPosition.x; @@ -210,7 +217,11 @@ void ProcessGestureEvent(GestureEvent event) { touchDownPosition = event.position[0]; touchDownPosition2 = event.position[1]; - pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2); + + //pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2); + + pinchVector.x = touchDownPosition2.x - touchDownPosition.x; + pinchVector.y = touchDownPosition2.y - touchDownPosition.y; currentGesture = GESTURE_HOLD; timeHold = GetCurrentTime(); @@ -218,22 +229,25 @@ void ProcessGestureEvent(GestureEvent event) else if (event.touchAction == TOUCH_MOVE) { pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2); - + touchDownPosition = moveDownPosition; touchDownPosition2 = moveDownPosition2; moveDownPosition = event.position[0]; moveDownPosition2 = event.position[1]; - if ((Vector2Distance(touchDownPosition, moveDownPosition) > FORCE_TO_PINCH) || (Vector2Distance(touchDownPosition2, moveDownPosition2) > FORCE_TO_PINCH)) + pinchVector.x = moveDownPosition2.x - moveDownPosition.x; + pinchVector.y = moveDownPosition2.y - moveDownPosition.y; + + if ((Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_PINCH) || (Vector2Distance(touchDownPosition2, moveDownPosition2) >= MINIMUM_PINCH)) { if ((Vector2Distance(moveDownPosition, moveDownPosition2) - pinchDistance) < 0) currentGesture = GESTURE_PINCH_IN; else currentGesture = GESTURE_PINCH_OUT; } - else + else { - currentGesture = GESTURE_HOLD; - timeHold = GetCurrentTime(); + currentGesture = GESTURE_HOLD; + timeHold = GetCurrentTime(); } // NOTE: Angle should be inverted in Y @@ -243,6 +257,7 @@ void ProcessGestureEvent(GestureEvent event) { pinchDistance = 0.0f; pinchAngle = 0.0f; + pinchVector = (Vector2){ 0.0f, 0.0f }; currentGesture = GESTURE_NONE; } @@ -289,26 +304,30 @@ int GetGestureType(void) return (enabledGestures & currentGesture); } -void SetGesturesEnabled(unsigned int gestureFlags) +// Get number of touch points +int GetTouchPointsCount(void) { - enabledGestures = gestureFlags; + // NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called + + return pointCount; } -// Get drag dragIntensity (pixels per frame) -float GetGestureDragdragIntensity(void) +// Enable only desired getures to be detected +void SetGesturesEnabled(unsigned int gestureFlags) { - // NOTE: drag intensity is calculated on one touch points TOUCH_UP - - return dragIntensity; + enabledGestures = gestureFlags; } -// Get drag angle -// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise -float GetGestureDragAngle(void) +// Hold time measured in ms +float GetGestureHoldDuration(void) { - // NOTE: drag angle is calculated on one touch points TOUCH_UP + // NOTE: time is calculated on current gesture HOLD - return dragAngle; + float time = 0.0f; + + if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold; + + return time; } // Get drag vector (between initial touch point to current) @@ -319,33 +338,22 @@ Vector2 GetGestureDragVector(void) return dragVector; } -// Hold time measured in ms -float GetGestureHoldDuration(void) +// Get drag angle +// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise +float GetGestureDragAngle(void) { - // NOTE: time is calculated on current gesture HOLD - - float time = 0.0f; - - if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold; + // NOTE: drag angle is calculated on one touch points TOUCH_UP - return time; + return dragAngle; } // Get distance between two pinch points -float GetGesturePinchDelta(void) +Vector2 GetGesturePinchVector(void) { // NOTE: The position values used for pinchDistance are not modified like the position values of [core.c]-->GetTouchPosition(int index) // NOTE: pinch distance is calculated on two touch points TOUCH_MOVE - return pinchDistance; -} - -// Get number of touch points -int GetTouchPointsCount(void) -{ - // NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called - - return pointCount; + return pinchVector; } // Get angle beween two pinch points @@ -388,7 +396,7 @@ static float Vector2Distance(Vector2 v1, Vector2 v2) } // Time measure returned are milliseconds -static double GetCurrentTime() +static double GetCurrentTime(void) { double time = 0; -- cgit v1.2.3 From 83459159f4c8622cefe93a062138e7e2391b6761 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 20 Feb 2016 19:01:41 +0100 Subject: Corrected compiler complaint --- src/gestures.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gestures.c') diff --git a/src/gestures.c b/src/gestures.c index 9028f43b..3638f23e 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -184,7 +184,7 @@ void ProcessGestureEvent(GestureEvent event) } else if (event.touchAction == TOUCH_MOVE) { - if ((currentGesture == GESTURE_DRAG)) eventTime = GetCurrentTime(); + if (currentGesture == GESTURE_DRAG) eventTime = GetCurrentTime(); if (!startMoving) { -- cgit v1.2.3 From 0dfc7fffff68b0bfafd30a86fb322073daf7fc0e Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 23 Feb 2016 00:57:50 +0100 Subject: Removed a couple of TODOs --- src/gestures.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gestures.c') diff --git a/src/gestures.c b/src/gestures.c index 3638f23e..e615c06d 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -155,8 +155,6 @@ void ProcessGestureEvent(GestureEvent event) dragDistance = Vector2Distance(touchDownPosition, touchUpPosition); dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime)); - // TODO: Make getures detection resolution independant - startMoving = false; // Detect GESTURE_SWIPE -- cgit v1.2.3