From d32feaa6685584e9856aa94f4d5bf80b7f5b861c Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 3 Jan 2016 13:01:21 +0100 Subject: Reviewed Android inputs and gestures system Corrected Android processing for some inputs (BACK button, VOLUME buttons) Redesigned Gestures system (some work still required) SetEnabledGestures() - Only support desired gestures (requires some review) --- src/gestures.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/gestures.h') diff --git a/src/gestures.h b/src/gestures.h index 896f3028..b5cf2767 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -67,6 +67,17 @@ typedef enum { GESTURE_PINCH_OUT = 1024 } Gestures; +typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction; + +// Gesture events +// NOTE: MAX_TOUCH_POINTS fixed to 4 +typedef struct { + int touchAction; + int pointCount; + int pointerId[4]; + Vector2 position[4]; +} GestureEvent; + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -79,19 +90,11 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- -int GetTouchX(void); // Returns touch position X (relative to screen size) -int GetTouchY(void); // Returns touch position Y (relative to screen size) -Vector2 GetTouchPosition(void); // Returns touch position XY (relative to screen size) - -#if defined(PLATFORM_WEB) -void InitGesturesSystem(void); // Init gestures system (web) -#elif defined(PLATFORM_ANDROID) -void InitGesturesSystem(struct android_app *app); // Init gestures system (android) -#endif void UpdateGestures(void); // Update gestures detected (must be called every frame) bool IsGestureDetected(void); // Check if a gesture have been detected int GetGestureType(void); // Get latest detected gesture void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags +void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures float GetGestureDragIntensity(void); // Get gesture drag intensity float GetGestureDragAngle(void); // Get gesture drag angle -- 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/core.c | 30 ++++++++++------ src/gestures.c | 110 +++++++++++++++++++++++++++++++++++---------------------- src/gestures.h | 1 + src/raylib.h | 9 ++--- 4 files changed, 94 insertions(+), 56 deletions(-) (limited to 'src/gestures.h') diff --git a/src/core.c b/src/core.c index 699cc2b7..05ec0c0a 100644 --- a/src/core.c +++ b/src/core.c @@ -117,7 +117,8 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define STORAGE_FILENAME "storage.data" +#define STORAGE_FILENAME "storage.data" +#define MAX_TOUCH_POINTS 2 //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -182,7 +183,7 @@ static bool fullscreen = false; // Fullscreen mode (useful only for static Matrix downscaleView; // Matrix to downscale view (in case screen size bigger than display size) #if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) -static Vector2 touchPosition; // Touch position on screen +static Vector2 touchPosition[MAX_TOUCH_POINTS]; // Touch position on screen #endif #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) @@ -1228,7 +1229,7 @@ bool IsGamepadButtonUp(int gamepad, int button) int GetTouchX(void) { #if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) - return (int)touchPosition.x; + return (int)touchPosition[0].x; #else // PLATFORM_DESKTOP, PLATFORM_RPI return GetMouseX(); #endif @@ -1238,7 +1239,7 @@ int GetTouchX(void) int GetTouchY(void) { #if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) - return (int)touchPosition.y; + return (int)touchPosition[0].y; #else // PLATFORM_DESKTOP, PLATFORM_RPI return GetMouseY(); #endif @@ -1246,10 +1247,13 @@ int GetTouchY(void) // Returns touch position XY // TODO: touch position should be scaled depending on display size and render size -Vector2 GetTouchPosition(void) +Vector2 GetTouchPosition(int index) { + Vector2 position = { -1.0f, -1.0f }; + #if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) - Vector2 position = touchPosition; + if (index < MAX_TOUCH_POINTS) position = touchPosition[index]; + else TraceLog(WARNING, "Required touch point out of range (Max touch points: %i)", MAX_TOUCH_POINTS); if ((screenWidth > displayWidth) || (screenHeight > displayHeight)) { @@ -1263,7 +1267,7 @@ Vector2 GetTouchPosition(void) position.y = position.y*((float)renderHeight/(float)displayHeight) - renderOffsetY/2; } #else // PLATFORM_DESKTOP, PLATFORM_RPI - Vector2 position = GetMousePosition(); + if (index == 0) position = GetMousePosition(); #endif return position; @@ -1916,8 +1920,13 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) if (type == AINPUT_EVENT_TYPE_MOTION) { - touchPosition.x = AMotionEvent_getX(event, 0); - touchPosition.y = AMotionEvent_getY(event, 0); + // Get first touch position + touchPosition[0].x = AMotionEvent_getX(event, 0); + touchPosition[0].y = AMotionEvent_getY(event, 0); + + // Get second touch position + touchPosition[1].x = AMotionEvent_getX(event, 1); + touchPosition[1].y = AMotionEvent_getY(event, 1); } else if (type == AINPUT_EVENT_TYPE_KEY) { @@ -2535,7 +2544,8 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent gestureEvent.position[0] = (Vector2){ touchEvent->touches[0].targetX, touchEvent->touches[0].targetY }; gestureEvent.position[1] = (Vector2){ touchEvent->touches[1].targetX, touchEvent->touches[1].targetY }; - touchPosition = gestureEvent.position[0]; + touchPosition[0] = gestureEvent.position[0]; + touchPosition[1] = gestureEvent.position[1]; // Gesture data is sent to gestures system for processing ProcessGestureEvent(gestureEvent); // Process obtained gestures data 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; } diff --git a/src/gestures.h b/src/gestures.h index b5cf2767..52f778be 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -102,6 +102,7 @@ Vector2 GetGestureDragVector(void); // Get gesture drag vect int GetGestureHoldDuration(void); // Get gesture hold time in frames float GetGesturePinchDelta(void); // Get gesture pinch delta float GetGesturePinchAngle(void); // Get gesture pinch angle +int GetTouchPointsCount(void); // Get touch points count #ifdef __cplusplus } diff --git a/src/raylib.h b/src/raylib.h index 3d8100b3..55a68ad1 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -600,9 +600,9 @@ bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad b bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed #endif -int GetTouchX(void); // Returns touch position X (relative to screen size) -int GetTouchY(void); // Returns touch position Y (relative to screen size) -Vector2 GetTouchPosition(void); // Returns touch position XY (relative to screen size) +int GetTouchX(void); // Returns touch position X for touch point 0 (relative to screen size) +int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size) +Vector2 GetTouchPosition(int index) // Returns touch position XY for a touch point index (relative to screen size) #if defined(PLATFORM_ANDROID) bool IsButtonPressed(int button); // Detect if an android physic button has been pressed @@ -622,9 +622,10 @@ void ProcessGestureEvent(GestureEvent event); // Process gesture event float GetGestureDragIntensity(void); // Get gesture drag intensity float GetGestureDragAngle(void); // Get gesture drag angle Vector2 GetGestureDragVector(void); // Get gesture drag vector -int GetGestureHoldDuration(void); // Get gesture hold time in frames +float GetGestureHoldDuration(void); // Get gesture hold time in ms float GetGesturePinchDelta(void); // Get gesture pinch delta float GetGesturePinchAngle(void); // Get gesture pinch angle +int GetTouchPointsCount(void); // Get touch points count //------------------------------------------------------------------------------------ // Camera System Functions (Module: camera) -- 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/core.c | 28 +++++++++++- src/gestures.c | 134 ++++++++++++++++++++++++++++++--------------------------- src/gestures.h | 12 +++--- src/raylib.h | 11 +++-- 4 files changed, 109 insertions(+), 76 deletions(-) (limited to 'src/gestures.h') diff --git a/src/core.c b/src/core.c index 0c85ab26..7b981097 100644 --- a/src/core.c +++ b/src/core.c @@ -1700,14 +1700,22 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int // Register touch actions if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) gestureEvent.touchAction = TOUCH_DOWN; - //else if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) gestureEvent.touchAction = TOUCH_MOVE; else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) gestureEvent.touchAction = TOUCH_UP; + // NOTE: TOUCH_MOVE event is registered in MouseCursorPosCallback() + + // Assign a pointer ID + gestureEvent.pointerId[0] = 0; + // Register touch points count gestureEvent.pointCount = 1; // Register touch points position, only one point registered gestureEvent.position[0] = GetMousePosition(); + + // Normalize gestureEvent.position[0] for screenWidth and screenHeight + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); // Gesture data is sent to gestures system for processing ProcessGestureEvent(gestureEvent); @@ -1729,6 +1737,10 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y) // Register touch points position, only one point registered gestureEvent.position[0] = (Vector2){ (float)x, (float)y }; + + // Normalize gestureEvent.position[0] for screenWidth and screenHeight + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); // Gesture data is sent to gestures system for processing ProcessGestureEvent(gestureEvent); @@ -1992,6 +2004,13 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) gestureEvent.position[0] = (Vector2){ AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0) }; gestureEvent.position[1] = (Vector2){ AMotionEvent_getX(event, 1), AMotionEvent_getY(event, 1) }; + // Normalize gestureEvent.position[x] for screenWidth and screenHeight + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); + + gestureEvent.position[1].x /= (float)GetScreenWidth(); + gestureEvent.position[1].y /= (float)GetScreenHeight(); + // Gesture data is sent to gestures system for processing ProcessGestureEvent(gestureEvent); @@ -2564,6 +2583,13 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent touchPosition[0] = gestureEvent.position[0]; touchPosition[1] = gestureEvent.position[1]; + // Normalize gestureEvent.position[x] for screenWidth and screenHeight + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); + + gestureEvent.position[1].x /= (float)GetScreenWidth(); + gestureEvent.position[1].y /= (float)GetScreenHeight(); + // Gesture data is sent to gestures system for processing ProcessGestureEvent(gestureEvent); // Process obtained gestures data 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; diff --git a/src/gestures.h b/src/gestures.h index 52f778be..5468eb54 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -90,19 +90,19 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- +void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures void UpdateGestures(void); // Update gestures detected (must be called every frame) bool IsGestureDetected(void); // Check if a gesture have been detected int GetGestureType(void); // Get latest detected gesture void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags -void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures +int GetTouchPointsCount(void); // Get touch points count -float GetGestureDragIntensity(void); // Get gesture drag intensity -float GetGestureDragAngle(void); // Get gesture drag angle +float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds Vector2 GetGestureDragVector(void); // Get gesture drag vector -int GetGestureHoldDuration(void); // Get gesture hold time in frames -float GetGesturePinchDelta(void); // Get gesture pinch delta +float GetGestureDragAngle(void); // Get gesture drag angle +Vector2 GetGesturePinchVector(void); // Get gesture pinch delta float GetGesturePinchAngle(void); // Get gesture pinch angle -int GetTouchPointsCount(void); // Get touch points count + #ifdef __cplusplus } diff --git a/src/raylib.h b/src/raylib.h index f5a3cc31..def56ee2 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -607,19 +607,18 @@ bool IsButtonReleased(int button); // Detect if an android //------------------------------------------------------------------------------------ // Gestures and Touch Handling Functions (Module: gestures) //------------------------------------------------------------------------------------ +void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures void UpdateGestures(void); // Update gestures detected (must be called every frame) bool IsGestureDetected(void); // Check if a gesture have been detected int GetGestureType(void); // Get latest detected gesture void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags -void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures +int GetTouchPointsCount(void); // Get touch points count -float GetGestureDragIntensity(void); // Get gesture drag intensity -float GetGestureDragAngle(void); // Get gesture drag angle +float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds Vector2 GetGestureDragVector(void); // Get gesture drag vector -float GetGestureHoldDuration(void); // Get gesture hold time in ms -float GetGesturePinchDelta(void); // Get gesture pinch delta +float GetGestureDragAngle(void); // Get gesture drag angle +Vector2 GetGesturePinchVector(void); // Get gesture pinch delta float GetGesturePinchAngle(void); // Get gesture pinch angle -int GetTouchPointsCount(void); // Get touch points count //------------------------------------------------------------------------------------ // Camera System Functions (Module: camera) -- cgit v1.2.3