mirror of
				https://github.com/raysan5/raylib.git
				synced 2025-10-26 12:27:01 +00:00 
			
		
		
		
	Redesigned gestures module to header-only
This commit is contained in:
		| @@ -168,7 +168,7 @@ endif | |||||||
| # compile all modules with their prerequisites | # compile all modules with their prerequisites | ||||||
|  |  | ||||||
| # compile core module | # compile core module | ||||||
| core.o : core.c raylib.h rlgl.h utils.h raymath.h | core.o : core.c raylib.h rlgl.h utils.h raymath.h gestures.h | ||||||
| 	$(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) | 	$(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) | ||||||
|  |  | ||||||
| # compile rlgl module | # compile rlgl module | ||||||
| @@ -207,10 +207,6 @@ utils.o : utils.c utils.h | |||||||
| camera.o : camera.c raylib.h | camera.o : camera.c raylib.h | ||||||
| 	$(CC) -c $< $(CFLAGS) $(INCLUDES) | 	$(CC) -c $< $(CFLAGS) $(INCLUDES) | ||||||
|  |  | ||||||
| #compile gestures module |  | ||||||
| gestures.o : gestures.c raylib.h |  | ||||||
| 	$(CC) -c $< $(CFLAGS) $(INCLUDES) |  | ||||||
|  |  | ||||||
| # It installs generated and needed files to compile projects using raylib. | # It installs generated and needed files to compile projects using raylib. | ||||||
| # The installation works manually. | # The installation works manually. | ||||||
| # TODO: add other platforms. | # TODO: add other platforms. | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								src/core.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/core.c
									
									
									
									
									
								
							| @@ -39,13 +39,15 @@ | |||||||
|  |  | ||||||
| #include "raylib.h"         // raylib main header | #include "raylib.h"         // raylib main header | ||||||
| #include "rlgl.h"           // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2 | #include "rlgl.h"           // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2 | ||||||
| #include "utils.h"          // TraceLog() function | #include "utils.h"          // Includes Android fopen map, InitAssetManager(), TraceLog() | ||||||
|                             // NOTE: Includes Android fopen map, InitAssetManager() |  | ||||||
|  |  | ||||||
| #define RAYMATH_IMPLEMENTATION  // Use raymath as a header-only library (includes implementation) | #define RAYMATH_IMPLEMENTATION  // Use raymath as a header-only library (includes implementation) | ||||||
| #define RAYMATH_EXTERN_INLINE   // Compile raymath functions as static inline (remember, it's a compiler hint) | #define RAYMATH_EXTERN_INLINE   // Compile raymath functions as static inline (remember, it's a compiler hint) | ||||||
| #include "raymath.h"            // Required for Vector3 and Matrix functions | #include "raymath.h"            // Required for Vector3 and Matrix functions | ||||||
|  |  | ||||||
|  | #define GESTURES_IMPLEMENTATION | ||||||
|  | #include "gestures.h"       // Gestures detection functionality | ||||||
|  |  | ||||||
| #include <stdio.h>          // Standard input / output lib | #include <stdio.h>          // Standard input / output lib | ||||||
| #include <stdlib.h>         // Declares malloc() and free() for memory management, rand(), atexit() | #include <stdlib.h>         // Declares malloc() and free() for memory management, rand(), atexit() | ||||||
| #include <stdint.h>         // Required for typedef unsigned long long int uint64_t, used by hi-res timer | #include <stdint.h>         // Required for typedef unsigned long long int uint64_t, used by hi-res timer | ||||||
| @@ -234,6 +236,9 @@ static bool showLogo = false;               // Track if showing logo at init is | |||||||
| extern void LoadDefaultFont(void);          // [Module: text] Loads default font on InitWindow() | extern void LoadDefaultFont(void);          // [Module: text] Loads default font on InitWindow() | ||||||
| extern void UnloadDefaultFont(void);        // [Module: text] Unloads default font from GPU memory | extern void UnloadDefaultFont(void);        // [Module: text] Unloads default font from GPU memory | ||||||
|  |  | ||||||
|  | extern void ProcessGestureEvent(GestureEvent event);    // [Module: gestures] Process gesture event and translate it into gestures | ||||||
|  | extern void UpdateGestures(void);                       // [Module: gestures] Update gestures detected (called in PollInputEvents()) | ||||||
|  |  | ||||||
| //---------------------------------------------------------------------------------- | //---------------------------------------------------------------------------------- | ||||||
| // Module specific Functions Declaration | // Module specific Functions Declaration | ||||||
| //---------------------------------------------------------------------------------- | //---------------------------------------------------------------------------------- | ||||||
| @@ -2052,10 +2057,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i | |||||||
|         // NOTE: Before closing window, while loop must be left! |         // NOTE: Before closing window, while loop must be left! | ||||||
|     } |     } | ||||||
| #if defined(PLATFORM_DESKTOP) | #if defined(PLATFORM_DESKTOP) | ||||||
|     else if (key == GLFW_KEY_F12 && action == GLFW_PRESS) |     else if (key == GLFW_KEY_F12 && action == GLFW_PRESS) TakeScreenshot(); | ||||||
|     { |  | ||||||
|         TakeScreenshot(); |  | ||||||
|     } |  | ||||||
| #endif | #endif | ||||||
|     else  |     else  | ||||||
|     { |     { | ||||||
|   | |||||||
							
								
								
									
										423
									
								
								src/gestures.c
									
									
									
									
									
								
							
							
						
						
									
										423
									
								
								src/gestures.c
									
									
									
									
									
								
							| @@ -1,423 +0,0 @@ | |||||||
| /********************************************************************************************** |  | ||||||
| * |  | ||||||
| *   raylib Gestures System - Gestures Processing based on input gesture events (touch/mouse) |  | ||||||
| * |  | ||||||
| *   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. |  | ||||||
| * |  | ||||||
| *   Permission is granted to anyone to use this software for any purpose, including commercial |  | ||||||
| *   applications, and to alter it and redistribute it freely, subject to the following restrictions: |  | ||||||
| * |  | ||||||
| *     1. The origin of this software must not be misrepresented; you must not claim that you |  | ||||||
| *     wrote the original software. If you use this software in a product, an acknowledgment |  | ||||||
| *     in the product documentation would be appreciated but is not required. |  | ||||||
| * |  | ||||||
| *     2. Altered source versions must be plainly marked as such, and must not be misrepresented |  | ||||||
| *     as being the original software. |  | ||||||
| * |  | ||||||
| *     3. This notice may not be removed or altered from any source distribution. |  | ||||||
| * |  | ||||||
| **********************************************************************************************/ |  | ||||||
|  |  | ||||||
| //#define GESTURES_STANDALONE     // NOTE: To use the gestures module as standalone lib, just uncomment this line |  | ||||||
|  |  | ||||||
| #if defined(GESTURES_STANDALONE) |  | ||||||
|     #include "gestures.h" |  | ||||||
| #else |  | ||||||
|     #include "raylib.h"         // Required for: Vector2, Gestures |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include <math.h>               // Required for: atan2(), sqrt() |  | ||||||
| #include <stdint.h>             // Required for: uint64_t |  | ||||||
|  |  | ||||||
| #if defined(_WIN32) |  | ||||||
|     // Functions required to query time on Windows |  | ||||||
|     int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); |  | ||||||
|     int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); |  | ||||||
| #elif defined(__linux) |  | ||||||
|     #include <sys/time.h>       // Required for: timespec |  | ||||||
|     #include <time.h>           // Required for: clock_gettime() |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
| // Defines and Macros |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
| #define FORCE_TO_SWIPE          0.0005f     // Measured in normalized screen units/time |  | ||||||
| #define MINIMUM_DRAG            0.015f      // Measured in normalized screen units (0.0f to 1.0f) |  | ||||||
| #define MINIMUM_PINCH           0.005f      // Measured in normalized screen units (0.0f to 1.0f) |  | ||||||
| #define TAP_TIMEOUT             300         // Time in milliseconds |  | ||||||
| #define PINCH_TIMEOUT           300         // Time in milliseconds |  | ||||||
| #define DOUBLETAP_RANGE         0.03f       // Measured in normalized screen units (0.0f to 1.0f) |  | ||||||
|  |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
| // Types and Structures Definition |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
| // ... |  | ||||||
|  |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
| // Global Variables Definition |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
|  |  | ||||||
| // Touch gesture variables |  | ||||||
| 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 pointCount = 0; |  | ||||||
| static int firstTouchId = -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 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 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; |  | ||||||
| static int currentGesture = GESTURE_NONE; |  | ||||||
|  |  | ||||||
| // Enabled gestures flags, all gestures enabled by default  |  | ||||||
| static unsigned int enabledGestures = 0b0000001111111111;    |  | ||||||
|  |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
| // Module specific Functions Declaration |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
| static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition); |  | ||||||
| static float Vector2Distance(Vector2 v1, Vector2 v2); |  | ||||||
| static double GetCurrentTime(void); |  | ||||||
|  |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
| // Module Functions Definition |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
|  |  | ||||||
| // Enable only desired getures to be detected |  | ||||||
| void SetGesturesEnabled(unsigned int gestureFlags) |  | ||||||
| { |  | ||||||
|     enabledGestures = gestureFlags; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Check if a gesture have been detected |  | ||||||
| bool IsGestureDetected(int gesture) |  | ||||||
| { |  | ||||||
|     if ((enabledGestures & currentGesture) == gesture) return true; |  | ||||||
|     else return false; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Process gesture event and translate it into gestures |  | ||||||
| void ProcessGestureEvent(GestureEvent event) |  | ||||||
| { |  | ||||||
|     // Reset required variables |  | ||||||
|     previousGesture = currentGesture; |  | ||||||
|      |  | ||||||
|     pointCount = event.pointCount;      // Required on UpdateGestures() |  | ||||||
|      |  | ||||||
|     if (pointCount < 2) |  | ||||||
|     { |  | ||||||
|         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)) |  | ||||||
|             { |  | ||||||
|                 currentGesture = GESTURE_DOUBLETAP; |  | ||||||
|                 numTap = 0; |  | ||||||
|             } |  | ||||||
|             else    // Detect GESTURE_TAP |  | ||||||
|             { |  | ||||||
|                 numTap = 1; |  | ||||||
|                 currentGesture = GESTURE_TAP; |  | ||||||
|             } |  | ||||||
|              |  | ||||||
|             touchDownPosition = event.position[0]; |  | ||||||
|             touchDownDragPosition = event.position[0]; |  | ||||||
|              |  | ||||||
|             touchUpPosition = touchDownPosition; |  | ||||||
|             eventTime = GetCurrentTime(); |  | ||||||
|              |  | ||||||
|             firstTouchId = event.pointerId[0]; |  | ||||||
|              |  | ||||||
|             dragVector = (Vector2){ 0.0f, 0.0f }; |  | ||||||
|         } |  | ||||||
|         else if (event.touchAction == TOUCH_UP) |  | ||||||
|         { |  | ||||||
|             if (currentGesture == GESTURE_DRAG) touchUpPosition = event.position[0]; |  | ||||||
|  |  | ||||||
|             // NOTE: dragIntensity dependend on the resolution of the screen |  | ||||||
|             dragDistance = Vector2Distance(touchDownPosition, touchUpPosition); |  | ||||||
|             dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime)); |  | ||||||
|              |  | ||||||
|             startMoving = false; |  | ||||||
|              |  | ||||||
|             // Detect GESTURE_SWIPE |  | ||||||
|             if ((dragIntensity > FORCE_TO_SWIPE) && firstTouchId == event.pointerId[0]) |  | ||||||
|             { |  | ||||||
|                 // 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 |  | ||||||
|                 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 |  | ||||||
|             { |  | ||||||
|                 dragDistance = 0.0f; |  | ||||||
|                 dragIntensity = 0.0f; |  | ||||||
|                 dragAngle = 0.0f; |  | ||||||
|                  |  | ||||||
|                 currentGesture = GESTURE_NONE; |  | ||||||
|             } |  | ||||||
|              |  | ||||||
|             touchDownDragPosition = (Vector2){ 0.0f, 0.0f }; |  | ||||||
|             pointCount = 0; |  | ||||||
|         } |  | ||||||
|         else if (event.touchAction == TOUCH_MOVE) |  | ||||||
|         { |  | ||||||
|             if (currentGesture == GESTURE_DRAG) eventTime = GetCurrentTime(); |  | ||||||
|              |  | ||||||
|             if (!startMoving) |  | ||||||
|             { |  | ||||||
|                 swipeTime = GetCurrentTime(); |  | ||||||
|                 startMoving = true; |  | ||||||
|             } |  | ||||||
|              |  | ||||||
|             moveDownPosition = event.position[0]; |  | ||||||
|              |  | ||||||
|             if (currentGesture == GESTURE_HOLD) |  | ||||||
|             { |  | ||||||
|                 if (numHold == 1) touchDownPosition = event.position[0]; |  | ||||||
|                  |  | ||||||
|                 numHold = 2; |  | ||||||
|                  |  | ||||||
|                 // Detect GESTURE_DRAG |  | ||||||
|                 if (Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_DRAG) |  | ||||||
|                 { |  | ||||||
|                     eventTime = GetCurrentTime(); |  | ||||||
|                     currentGesture = GESTURE_DRAG; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|          |  | ||||||
|             dragVector.x = moveDownPosition.x - touchDownDragPosition.x; |  | ||||||
|             dragVector.y = moveDownPosition.y - touchDownDragPosition.y; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     else    // Two touch points |  | ||||||
|     { |  | ||||||
|         if (event.touchAction == TOUCH_DOWN) |  | ||||||
|         { |  | ||||||
|             touchDownPosition = event.position[0]; |  | ||||||
|             touchDownPosition2 = event.position[1]; |  | ||||||
|              |  | ||||||
|             //pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2); |  | ||||||
|              |  | ||||||
|             pinchVector.x = touchDownPosition2.x - touchDownPosition.x; |  | ||||||
|             pinchVector.y = touchDownPosition2.y - touchDownPosition.y; |  | ||||||
|              |  | ||||||
|             currentGesture = GESTURE_HOLD; |  | ||||||
|             timeHold = GetCurrentTime(); |  | ||||||
|         } |  | ||||||
|         else if (event.touchAction == TOUCH_MOVE) |  | ||||||
|         { |  | ||||||
|             pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2); |  | ||||||
|              |  | ||||||
|             touchDownPosition = moveDownPosition; |  | ||||||
|             touchDownPosition2 = moveDownPosition2; |  | ||||||
|              |  | ||||||
|             moveDownPosition = event.position[0]; |  | ||||||
|             moveDownPosition2 = event.position[1]; |  | ||||||
|              |  | ||||||
|             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 |  | ||||||
|             { |  | ||||||
|                 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; |  | ||||||
|             pinchVector = (Vector2){ 0.0f, 0.0f }; |  | ||||||
|             pointCount = 0; |  | ||||||
|              |  | ||||||
|             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; |  | ||||||
|         timeHold = GetCurrentTime(); |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     if (((GetCurrentTime() - eventTime) > TAP_TIMEOUT) && (currentGesture == GESTURE_DRAG) && (pointCount < 2)) |  | ||||||
|     { |  | ||||||
|         currentGesture = GESTURE_HOLD; |  | ||||||
|         timeHold = GetCurrentTime(); |  | ||||||
|         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; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get number of touch points |  | ||||||
| int GetTouchPointsCount(void) |  | ||||||
| { |  | ||||||
|     // NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called |  | ||||||
|      |  | ||||||
|     return pointCount; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get latest detected gesture |  | ||||||
| int GetGestureDetected(void) |  | ||||||
| { |  | ||||||
|     // Get current gesture only if enabled |  | ||||||
|     return (enabledGestures & currentGesture); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Hold time measured in ms |  | ||||||
| float GetGestureHoldDuration(void) |  | ||||||
| { |  | ||||||
|     // NOTE: time is calculated on current gesture HOLD |  | ||||||
|      |  | ||||||
|     float time = 0.0f; |  | ||||||
|      |  | ||||||
|     if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold; |  | ||||||
|      |  | ||||||
|     return time; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get drag vector (between initial touch point to current) |  | ||||||
| Vector2 GetGestureDragVector(void) |  | ||||||
| { |  | ||||||
|     // NOTE: drag vector is calculated on one touch points TOUCH_MOVE |  | ||||||
|      |  | ||||||
|     return dragVector; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get drag angle |  | ||||||
| // 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 distance between two pinch points |  | ||||||
| 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 pinchVector; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get angle beween two pinch points |  | ||||||
| // NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise |  | ||||||
| float GetGesturePinchAngle(void) |  | ||||||
| { |  | ||||||
|     // NOTE: pinch angle is calculated on two touch points TOUCH_MOVE |  | ||||||
|      |  | ||||||
|     return pinchAngle; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
| // Module specific Functions Definition |  | ||||||
| //---------------------------------------------------------------------------------- |  | ||||||
|  |  | ||||||
| // Returns angle from two-points vector with X-axis |  | ||||||
| static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition) |  | ||||||
| { |  | ||||||
|     float angle; |  | ||||||
|  |  | ||||||
|     angle = atan2(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x); |  | ||||||
|     angle *= RAD2DEG; |  | ||||||
|      |  | ||||||
|     if (angle < 0) angle += 360.0f; |  | ||||||
|  |  | ||||||
|     return angle; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Calculate distance between two Vector2 |  | ||||||
| static float Vector2Distance(Vector2 v1, Vector2 v2) |  | ||||||
| { |  | ||||||
|     float result; |  | ||||||
|  |  | ||||||
|     float dx = v2.x - v1.x; |  | ||||||
|     float dy = v2.y - v1.y; |  | ||||||
|  |  | ||||||
|     result = sqrt(dx*dx + dy*dy); |  | ||||||
|  |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Time measure returned are milliseconds |  | ||||||
| static double GetCurrentTime(void) |  | ||||||
| { |  | ||||||
|     double time = 0; |  | ||||||
|      |  | ||||||
| #if defined(_WIN32) |  | ||||||
|     unsigned long long int clockFrequency, currentTime; |  | ||||||
|      |  | ||||||
|     QueryPerformanceFrequency(&clockFrequency); |  | ||||||
|     QueryPerformanceCounter(¤tTime); |  | ||||||
|      |  | ||||||
|     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 in nanoseconds |  | ||||||
|      |  | ||||||
|     time = ((double)nowTime/1000000.0);     // Time in miliseconds |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|     return time; |  | ||||||
| } |  | ||||||
							
								
								
									
										430
									
								
								src/gestures.h
									
									
									
									
									
								
							
							
						
						
									
										430
									
								
								src/gestures.h
									
									
									
									
									
								
							| @@ -1,8 +1,21 @@ | |||||||
| /********************************************************************************************** | /********************************************************************************************** | ||||||
| * | * | ||||||
| *   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 | *   #define GESTURES_IMPLEMENTATION | ||||||
|  | *       Generates the implementation of the library into the included file. | ||||||
|  | *       If not defined, the library is in header only mode and can be included in other headers  | ||||||
|  | *       or source files without problems. But only ONE file should hold the implementation. | ||||||
|  | * | ||||||
|  | *   #define GESTURES_STANDALONE | ||||||
|  | *       If defined, the library can be used as standalone to process gesture events with | ||||||
|  | *       no external dependencies. | ||||||
|  | * | ||||||
|  | *   NOTE: Memory footprint of this library is aproximately 128 bytes | ||||||
|  | * | ||||||
|  | *   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 | *   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. | *   will the authors be held liable for any damages arising from the use of this software. | ||||||
| @@ -28,9 +41,6 @@ | |||||||
|     #define PI 3.14159265358979323846 |     #define PI 3.14159265358979323846 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #define DEG2RAD (PI / 180.0f) |  | ||||||
| #define RAD2DEG (180.0f / PI) |  | ||||||
|  |  | ||||||
| //---------------------------------------------------------------------------------- | //---------------------------------------------------------------------------------- | ||||||
| // Defines and Macros | // Defines and Macros | ||||||
| //---------------------------------------------------------------------------------- | //---------------------------------------------------------------------------------- | ||||||
| @@ -40,6 +50,7 @@ | |||||||
| // Types and Structures Definition | // Types and Structures Definition | ||||||
| // NOTE: Below types are required for GESTURES_STANDALONE usage | // NOTE: Below types are required for GESTURES_STANDALONE usage | ||||||
| //---------------------------------------------------------------------------------- | //---------------------------------------------------------------------------------- | ||||||
|  | #if defined(GESTURES_STANDALONE) | ||||||
|     #ifndef __cplusplus |     #ifndef __cplusplus | ||||||
|         // Boolean type |         // Boolean type | ||||||
|         typedef enum { false, true } bool; |         typedef enum { false, true } bool; | ||||||
| @@ -66,6 +77,7 @@ typedef enum { | |||||||
|         GESTURE_PINCH_IN    = 512, |         GESTURE_PINCH_IN    = 512, | ||||||
|         GESTURE_PINCH_OUT   = 1024 |         GESTURE_PINCH_OUT   = 1024 | ||||||
|     } Gestures; |     } Gestures; | ||||||
|  | #endif | ||||||
|  |  | ||||||
| typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction; | typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction; | ||||||
|  |  | ||||||
| @@ -90,22 +102,422 @@ extern "C" {            // Prevents name mangling of functions | |||||||
| //---------------------------------------------------------------------------------- | //---------------------------------------------------------------------------------- | ||||||
| // Module Functions Declaration | // Module Functions Declaration | ||||||
| //---------------------------------------------------------------------------------- | //---------------------------------------------------------------------------------- | ||||||
| void SetGesturesEnabled(unsigned int gestureFlags);     // Enable a set of gestures using flags |  | ||||||
| bool IsGestureDetected(int gesture);                    // Check if a gesture have been detected |  | ||||||
| void ProcessGestureEvent(GestureEvent event);           // Process gesture event and translate it into gestures | void ProcessGestureEvent(GestureEvent event);           // Process gesture event and translate it into gestures | ||||||
| void UpdateGestures(void);                              // Update gestures detected (must be called every frame) | void UpdateGestures(void);                              // Update gestures detected (must be called every frame) | ||||||
|  |  | ||||||
| int GetTouchPointsCount(void);                          // Get touch points count | #if defined(GESTURES_STANDALONE) | ||||||
|  | void SetGesturesEnabled(unsigned int gestureFlags);     // Enable a set of gestures using flags | ||||||
|  | bool IsGestureDetected(int gesture);                    // Check if a gesture have been detected | ||||||
| int GetGestureDetected(void);                           // Get latest detected gesture | int GetGestureDetected(void);                           // Get latest detected gesture | ||||||
|  | int GetTouchPointsCount(void);                          // Get touch points count | ||||||
| float GetGestureHoldDuration(void);                     // Get gesture hold time in milliseconds | float GetGestureHoldDuration(void);                     // Get gesture hold time in milliseconds | ||||||
| Vector2 GetGestureDragVector(void);                     // Get gesture drag vector | Vector2 GetGestureDragVector(void);                     // Get gesture drag vector | ||||||
| float GetGestureDragAngle(void);                        // Get gesture drag angle | float GetGestureDragAngle(void);                        // Get gesture drag angle | ||||||
| Vector2 GetGesturePinchVector(void);                    // Get gesture pinch delta | Vector2 GetGesturePinchVector(void);                    // Get gesture pinch delta | ||||||
| float GetGesturePinchAngle(void);                       // Get gesture pinch angle | float GetGesturePinchAngle(void);                       // Get gesture pinch angle | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #endif // GESTURES_H | #endif // GESTURES_H | ||||||
|  |  | ||||||
|  | /*********************************************************************************** | ||||||
|  | * | ||||||
|  | *   GESTURES IMPLEMENTATION | ||||||
|  | * | ||||||
|  | ************************************************************************************/ | ||||||
|  |  | ||||||
|  | #if defined(GESTURES_IMPLEMENTATION) | ||||||
|  |  | ||||||
|  | #include <math.h>               // Required for: atan2(), sqrt() | ||||||
|  | #include <stdint.h>             // Required for: uint64_t | ||||||
|  |  | ||||||
|  | #if defined(_WIN32) | ||||||
|  |     // Functions required to query time on Windows | ||||||
|  |     int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); | ||||||
|  |     int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); | ||||||
|  | #elif defined(__linux) | ||||||
|  |     #include <sys/time.h>       // Required for: timespec | ||||||
|  |     #include <time.h>           // Required for: clock_gettime() | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Defines and Macros | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | #define FORCE_TO_SWIPE          0.0005f     // Measured in normalized screen units/time | ||||||
|  | #define MINIMUM_DRAG            0.015f      // Measured in normalized screen units (0.0f to 1.0f) | ||||||
|  | #define MINIMUM_PINCH           0.005f      // Measured in normalized screen units (0.0f to 1.0f) | ||||||
|  | #define TAP_TIMEOUT             300         // Time in milliseconds | ||||||
|  | #define PINCH_TIMEOUT           300         // Time in milliseconds | ||||||
|  | #define DOUBLETAP_RANGE         0.03f       // Measured in normalized screen units (0.0f to 1.0f) | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Types and Structures Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // ... | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Global Variables Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | // Touch gesture variables | ||||||
|  | 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 pointCount = 0;                      // Touch points counter | ||||||
|  | static int firstTouchId = -1;                   // Touch id for first touch point | ||||||
|  | static double eventTime = 0.0;                  // Time stamp when an event happened | ||||||
|  |  | ||||||
|  | // Tap gesture variables | ||||||
|  | static int tapCounter = 0;                      // TAP counter (one tap implies TOUCH_DOWN and TOUCH_UP actions) | ||||||
|  |  | ||||||
|  | // Hold gesture variables | ||||||
|  | static bool resetHold = false;                  // HOLD reset to get first touch point again | ||||||
|  | static float timeHold = 0.0f;                   // HOLD duration in milliseconds | ||||||
|  |  | ||||||
|  | // Drag gesture variables | ||||||
|  | static Vector2 dragVector = { 0.0f , 0.0f };    // DRAG vector (between initial and current position) | ||||||
|  | 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) | ||||||
|  |  | ||||||
|  | // Swipe gestures variables | ||||||
|  | static bool startMoving = false;                // SWIPE used to define when start measuring swipeTime | ||||||
|  | static double swipeTime = 0.0;                  // SWIPE time to calculate drag intensity | ||||||
|  |  | ||||||
|  | // Pinch gesture variables | ||||||
|  | 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]) | ||||||
|  |  | ||||||
|  | static int currentGesture = GESTURE_NONE;       // Current detected gesture | ||||||
|  |  | ||||||
|  | // Enabled gestures flags, all gestures enabled by default  | ||||||
|  | static unsigned int enabledGestures = 0b0000001111111111;    | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Module specific Functions Declaration | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition); | ||||||
|  | static float Vector2Distance(Vector2 v1, Vector2 v2); | ||||||
|  | static double GetCurrentTime(void); | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Module Functions Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | // Enable only desired getures to be detected | ||||||
|  | void SetGesturesEnabled(unsigned int gestureFlags) | ||||||
|  | { | ||||||
|  |     enabledGestures = gestureFlags; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Check if a gesture have been detected | ||||||
|  | bool IsGestureDetected(int gesture) | ||||||
|  | { | ||||||
|  |     if ((enabledGestures & currentGesture) == gesture) return true; | ||||||
|  |     else return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Process gesture event and translate it into gestures | ||||||
|  | void ProcessGestureEvent(GestureEvent event) | ||||||
|  | { | ||||||
|  |     // Reset required variables | ||||||
|  |     pointCount = event.pointCount;      // Required on UpdateGestures() | ||||||
|  |      | ||||||
|  |     if (pointCount < 2) | ||||||
|  |     { | ||||||
|  |         if (event.touchAction == TOUCH_DOWN) | ||||||
|  |         { | ||||||
|  |             tapCounter++;    // Tap counter | ||||||
|  |              | ||||||
|  |             // Detect GESTURE_DOUBLE_TAP | ||||||
|  |             if ((currentGesture == GESTURE_NONE) && (tapCounter >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (Vector2Distance(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE)) | ||||||
|  |             { | ||||||
|  |                 currentGesture = GESTURE_DOUBLETAP; | ||||||
|  |                 tapCounter = 0; | ||||||
|  |             } | ||||||
|  |             else    // Detect GESTURE_TAP | ||||||
|  |             { | ||||||
|  |                 tapCounter = 1; | ||||||
|  |                 currentGesture = GESTURE_TAP; | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             touchDownPosition = event.position[0]; | ||||||
|  |             touchDownDragPosition = event.position[0]; | ||||||
|  |              | ||||||
|  |             touchUpPosition = touchDownPosition; | ||||||
|  |             eventTime = GetCurrentTime(); | ||||||
|  |              | ||||||
|  |             firstTouchId = event.pointerId[0]; | ||||||
|  |              | ||||||
|  |             dragVector = (Vector2){ 0.0f, 0.0f }; | ||||||
|  |         } | ||||||
|  |         else if (event.touchAction == TOUCH_UP) | ||||||
|  |         { | ||||||
|  |             if (currentGesture == GESTURE_DRAG) touchUpPosition = event.position[0]; | ||||||
|  |  | ||||||
|  |             // NOTE: dragIntensity dependend on the resolution of the screen | ||||||
|  |             dragDistance = Vector2Distance(touchDownPosition, touchUpPosition); | ||||||
|  |             dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime)); | ||||||
|  |              | ||||||
|  |             startMoving = false; | ||||||
|  |              | ||||||
|  |             // Detect GESTURE_SWIPE | ||||||
|  |             if ((dragIntensity > FORCE_TO_SWIPE) && (firstTouchId == event.pointerId[0])) | ||||||
|  |             { | ||||||
|  |                 // 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 | ||||||
|  |                 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 | ||||||
|  |             { | ||||||
|  |                 dragDistance = 0.0f; | ||||||
|  |                 dragIntensity = 0.0f; | ||||||
|  |                 dragAngle = 0.0f; | ||||||
|  |                  | ||||||
|  |                 currentGesture = GESTURE_NONE; | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             touchDownDragPosition = (Vector2){ 0.0f, 0.0f }; | ||||||
|  |             pointCount = 0; | ||||||
|  |         } | ||||||
|  |         else if (event.touchAction == TOUCH_MOVE) | ||||||
|  |         { | ||||||
|  |             if (currentGesture == GESTURE_DRAG) eventTime = GetCurrentTime(); | ||||||
|  |              | ||||||
|  |             if (!startMoving) | ||||||
|  |             { | ||||||
|  |                 swipeTime = GetCurrentTime(); | ||||||
|  |                 startMoving = true; | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             moveDownPosition = event.position[0]; | ||||||
|  |              | ||||||
|  |             if (currentGesture == GESTURE_HOLD) | ||||||
|  |             { | ||||||
|  |                 if (resetHold) touchDownPosition = event.position[0]; | ||||||
|  |                  | ||||||
|  |                 resetHold = false; | ||||||
|  |                  | ||||||
|  |                 // Detect GESTURE_DRAG | ||||||
|  |                 if (Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_DRAG) | ||||||
|  |                 { | ||||||
|  |                     eventTime = GetCurrentTime(); | ||||||
|  |                     currentGesture = GESTURE_DRAG; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |          | ||||||
|  |             dragVector.x = moveDownPosition.x - touchDownDragPosition.x; | ||||||
|  |             dragVector.y = moveDownPosition.y - touchDownDragPosition.y; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     else    // Two touch points | ||||||
|  |     { | ||||||
|  |         if (event.touchAction == TOUCH_DOWN) | ||||||
|  |         { | ||||||
|  |             touchDownPosition = event.position[0]; | ||||||
|  |             touchDownPosition2 = event.position[1]; | ||||||
|  |              | ||||||
|  |             //pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2); | ||||||
|  |              | ||||||
|  |             pinchVector.x = touchDownPosition2.x - touchDownPosition.x; | ||||||
|  |             pinchVector.y = touchDownPosition2.y - touchDownPosition.y; | ||||||
|  |              | ||||||
|  |             currentGesture = GESTURE_HOLD; | ||||||
|  |             timeHold = GetCurrentTime(); | ||||||
|  |         } | ||||||
|  |         else if (event.touchAction == TOUCH_MOVE) | ||||||
|  |         { | ||||||
|  |             pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2); | ||||||
|  |              | ||||||
|  |             touchDownPosition = moveDownPosition; | ||||||
|  |             touchDownPosition2 = moveDownPosition2; | ||||||
|  |              | ||||||
|  |             moveDownPosition = event.position[0]; | ||||||
|  |             moveDownPosition2 = event.position[1]; | ||||||
|  |              | ||||||
|  |             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 | ||||||
|  |             { | ||||||
|  |                 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; | ||||||
|  |             pinchVector = (Vector2){ 0.0f, 0.0f }; | ||||||
|  |             pointCount = 0; | ||||||
|  |              | ||||||
|  |             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; | ||||||
|  |         timeHold = GetCurrentTime(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if (((GetCurrentTime() - eventTime) > TAP_TIMEOUT) && (currentGesture == GESTURE_DRAG) && (pointCount < 2)) | ||||||
|  |     { | ||||||
|  |         currentGesture = GESTURE_HOLD; | ||||||
|  |         timeHold = GetCurrentTime(); | ||||||
|  |         resetHold = true; | ||||||
|  |     } | ||||||
|  |     | ||||||
|  |     // Detect GESTURE_NONE | ||||||
|  |     if ((currentGesture == GESTURE_SWIPE_RIGHT) || (currentGesture == GESTURE_SWIPE_UP) || (currentGesture == GESTURE_SWIPE_LEFT) || (currentGesture == GESTURE_SWIPE_DOWN)) | ||||||
|  |     { | ||||||
|  |         currentGesture = GESTURE_NONE; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get number of touch points | ||||||
|  | int GetTouchPointsCount(void) | ||||||
|  | { | ||||||
|  |     // NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called | ||||||
|  |      | ||||||
|  |     return pointCount; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get latest detected gesture | ||||||
|  | int GetGestureDetected(void) | ||||||
|  | { | ||||||
|  |     // Get current gesture only if enabled | ||||||
|  |     return (enabledGestures & currentGesture); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Hold time measured in ms | ||||||
|  | float GetGestureHoldDuration(void) | ||||||
|  | { | ||||||
|  |     // NOTE: time is calculated on current gesture HOLD | ||||||
|  |      | ||||||
|  |     float time = 0.0f; | ||||||
|  |      | ||||||
|  |     if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold; | ||||||
|  |      | ||||||
|  |     return time; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get drag vector (between initial touch point to current) | ||||||
|  | Vector2 GetGestureDragVector(void) | ||||||
|  | { | ||||||
|  |     // NOTE: drag vector is calculated on one touch points TOUCH_MOVE | ||||||
|  |      | ||||||
|  |     return dragVector; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get drag angle | ||||||
|  | // 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 distance between two pinch points | ||||||
|  | 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 pinchVector; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get angle beween two pinch points | ||||||
|  | // NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise | ||||||
|  | float GetGesturePinchAngle(void) | ||||||
|  | { | ||||||
|  |     // NOTE: pinch angle is calculated on two touch points TOUCH_MOVE | ||||||
|  |      | ||||||
|  |     return pinchAngle; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  | // Module specific Functions Definition | ||||||
|  | //---------------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | // Returns angle from two-points vector with X-axis | ||||||
|  | static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition) | ||||||
|  | { | ||||||
|  |     float angle; | ||||||
|  |  | ||||||
|  |     angle = atan2(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x)*(180.0f/PI); | ||||||
|  |      | ||||||
|  |     if (angle < 0) angle += 360.0f; | ||||||
|  |  | ||||||
|  |     return angle; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Calculate distance between two Vector2 | ||||||
|  | static float Vector2Distance(Vector2 v1, Vector2 v2) | ||||||
|  | { | ||||||
|  |     float result; | ||||||
|  |  | ||||||
|  |     float dx = v2.x - v1.x; | ||||||
|  |     float dy = v2.y - v1.y; | ||||||
|  |  | ||||||
|  |     result = sqrt(dx*dx + dy*dy); | ||||||
|  |  | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Time measure returned are milliseconds | ||||||
|  | static double GetCurrentTime(void) | ||||||
|  | { | ||||||
|  |     double time = 0; | ||||||
|  |      | ||||||
|  | #if defined(_WIN32) | ||||||
|  |     unsigned long long int clockFrequency, currentTime; | ||||||
|  |      | ||||||
|  |     QueryPerformanceFrequency(&clockFrequency); | ||||||
|  |     QueryPerformanceCounter(¤tTime); | ||||||
|  |      | ||||||
|  |     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 in nanoseconds | ||||||
|  |      | ||||||
|  |     time = ((double)nowTime/1000000.0);     // Time in miliseconds | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     return time; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif // GESTURES_IMPLEMENTATION | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								src/raylib.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/raylib.h
									
									
									
									
									
								
							| @@ -570,18 +570,6 @@ typedef enum { | |||||||
|     GESTURE_PINCH_OUT   = 512 |     GESTURE_PINCH_OUT   = 512 | ||||||
| } Gestures; | } Gestures; | ||||||
|  |  | ||||||
| // Touch action (fingers or mouse) |  | ||||||
| typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction; |  | ||||||
|  |  | ||||||
| // Gesture events |  | ||||||
| // NOTE: MAX_TOUCH_POINTS fixed to 2 |  | ||||||
| typedef struct GestureEvent { |  | ||||||
|     int touchAction; |  | ||||||
|     int pointCount; |  | ||||||
|     int pointerId[MAX_TOUCH_POINTS]; |  | ||||||
|     Vector2 position[MAX_TOUCH_POINTS]; |  | ||||||
| } GestureEvent; |  | ||||||
|  |  | ||||||
| // Camera system modes | // Camera system modes | ||||||
| typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; | typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; | ||||||
|  |  | ||||||
| @@ -711,11 +699,8 @@ bool IsButtonReleased(int button);                      // Detect if an android | |||||||
| //------------------------------------------------------------------------------------ | //------------------------------------------------------------------------------------ | ||||||
| void SetGesturesEnabled(unsigned int gestureFlags);     // Enable a set of gestures using flags | void SetGesturesEnabled(unsigned int gestureFlags);     // Enable a set of gestures using flags | ||||||
| bool IsGestureDetected(int gesture);                    // Check if a gesture have been detected | bool IsGestureDetected(int gesture);                    // Check if a gesture have been detected | ||||||
| void ProcessGestureEvent(GestureEvent event);           // Process gesture event and translate it into gestures |  | ||||||
| void UpdateGestures(void);                              // Update gestures detected (called automatically in PollInputEvents()) |  | ||||||
|  |  | ||||||
| int GetTouchPointsCount(void);                          // Get touch points count |  | ||||||
| int GetGestureDetected(void);                           // Get latest detected gesture | int GetGestureDetected(void);                           // Get latest detected gesture | ||||||
|  | int GetTouchPointsCount(void);                          // Get touch points count | ||||||
| float GetGestureHoldDuration(void);                     // Get gesture hold time in milliseconds | float GetGestureHoldDuration(void);                     // Get gesture hold time in milliseconds | ||||||
| Vector2 GetGestureDragVector(void);                     // Get gesture drag vector | Vector2 GetGestureDragVector(void);                     // Get gesture drag vector | ||||||
| float GetGestureDragAngle(void);                        // Get gesture drag angle | float GetGestureDragAngle(void);                        // Get gesture drag angle | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								src/rlua.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/rlua.h
									
									
									
									
									
								
							| @@ -1313,12 +1313,6 @@ int lua_IsGestureDetected(lua_State* L) | |||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| int lua_UpdateGestures(lua_State* L) |  | ||||||
| { |  | ||||||
| 	UpdateGestures(); |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int lua_GetTouchPointsCount(lua_State* L) | int lua_GetTouchPointsCount(lua_State* L) | ||||||
| { | { | ||||||
| 	int result = GetTouchPointsCount(); | 	int result = GetTouchPointsCount(); | ||||||
| @@ -3576,10 +3570,8 @@ static luaL_Reg raylib_functions[] = { | |||||||
|  |  | ||||||
| 	REG(SetGesturesEnabled) | 	REG(SetGesturesEnabled) | ||||||
| 	REG(IsGestureDetected) | 	REG(IsGestureDetected) | ||||||
| 	//REG(ProcessGestureEvent) |  | ||||||
| 	REG(UpdateGestures) |  | ||||||
| 	REG(GetTouchPointsCount) |  | ||||||
| 	REG(GetGestureDetected) | 	REG(GetGestureDetected) | ||||||
|  |     REG(GetTouchPointsCount) | ||||||
| 	REG(GetGestureHoldDuration) | 	REG(GetGestureHoldDuration) | ||||||
| 	REG(GetGestureDragVector) | 	REG(GetGestureDragVector) | ||||||
| 	REG(GetGestureDragAngle) | 	REG(GetGestureDragAngle) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 raysan5
					raysan5