From 6e9d3eb0f99c8ce00b769dbd03cc011216b97068 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 23 Jan 2016 12:37:42 +0100 Subject: Review comments --- src/raylib.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/raylib.h') diff --git a/src/raylib.h b/src/raylib.h index bebf4bc5..49a320d4 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -7,10 +7,10 @@ * Features: * Library written in plain C code (C99) * Uses C# PascalCase/camelCase notation -* Hardware accelerated with OpenGL (1.1, 3.3+ or ES2) +* Hardware accelerated with OpenGL (1.1, 3.3 or ES2) * Unique OpenGL abstraction layer [rlgl] -* Powerful fonts module with SpriteFonts support -* Multiple textures support, including DDS and mipmaps generation +* Powerful fonts module with SpriteFonts support (including AngelCode fonts and TTF) +* Multiple textures support, including compressed formats and mipmaps generation * Basic 3d support for Shapes, Models, Heightmaps and Billboards * Powerful math module for Vector and Matrix operations [raymath] * Audio loading and playing with streaming support (WAV and OGG) @@ -18,20 +18,21 @@ * * Used external libs: * GLFW3 (www.glfw.org) for window/context management and input -* GLEW for OpenGL extensions loading (3.3+ and ES2) +* GLAD for OpenGL extensions loading (3.3 Core profile) * stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC) * stb_image_write (Sean Barret) for image writting (PNG) * stb_vorbis (Sean Barret) for ogg audio loading +* stb_truetype (Sean Barret) for ttf fonts loading * OpenAL Soft for audio device/context management * tinfl for data decompression (DEFLATE algorithm) * * Some design decisions: -* 32bit Colors - All defined color are always RGBA -* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures +* 32bit Colors - All defined color are always RGBA (struct Color is 4 byte) * One custom default font is loaded automatically when InitWindow() -* If using OpenGL 3.3+ or ES2, one default shader is loaded automatically (internally defined) +* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads +* If using OpenGL 3.3 or ES2, two default shaders are loaded automatically (internally defined) * -* -- LICENSE (raylib v1.2, September 2014) -- +* -- LICENSE -- * * raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software: -- cgit v1.2.3 From 08da91047e8a2c593c3bc40b31c4796ae6cbb26d Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 23 Jan 2016 13:22:13 +0100 Subject: Some code tweaks --- src/audio.c | 17 +++++------------ src/core.c | 2 ++ src/models.c | 2 +- src/raylib.h | 2 +- src/shapes.c | 4 ++-- 5 files changed, 11 insertions(+), 16 deletions(-) (limited to 'src/raylib.h') diff --git a/src/audio.c b/src/audio.c index 6313c9dc..e40fdd41 100644 --- a/src/audio.c +++ b/src/audio.c @@ -166,15 +166,8 @@ void CloseAudioDevice(void) // Load sound to memory Sound LoadSound(char *fileName) { - Sound sound; - Wave wave; - - // Init some default values for wave... - wave.data = NULL; - wave.dataSize = 0; - wave.sampleRate = 0; - wave.bitsPerSample = 0; - wave.channels = 0; + Sound sound = { 0 }; + Wave wave = { 0 }; // NOTE: The entire file is loaded to memory to play it all at once (no-streaming) @@ -236,7 +229,7 @@ Sound LoadSound(char *fileName) // Load sound from wave data Sound LoadSoundFromWave(Wave wave) { - Sound sound; + Sound sound = { 0 }; if (wave.data != NULL) { @@ -290,7 +283,7 @@ Sound LoadSoundFromWave(Wave wave) Sound LoadSoundFromRES(const char *rresName, int resId) { // NOTE: rresName could be directly a char array with all the data!!! --> TODO - Sound sound; + Sound sound = { 0 }; #if defined(AUDIO_STANDALONE) TraceLog(WARNING, "Sound loading from rRES resource file not supported on standalone mode"); @@ -791,7 +784,7 @@ static Wave LoadWAV(const char *fileName) WaveFormat waveFormat; WaveData waveData; - Wave wave; + Wave wave = { 0 }; FILE *wavFile; wavFile = fopen(fileName, "rb"); diff --git a/src/core.c b/src/core.c index 9b068300..7a5de04e 100644 --- a/src/core.c +++ b/src/core.c @@ -1230,7 +1230,9 @@ Vector2 GetTouchPosition(void) return position; } +#endif +#if defined(PLATFORM_ANDROID) // Detect if a button has been pressed once bool IsButtonPressed(int button) { diff --git a/src/models.c b/src/models.c index 80d9a13a..e90f455a 100644 --- a/src/models.c +++ b/src/models.c @@ -557,7 +557,7 @@ void DrawGizmo(Vector3 position) // Load a 3d model (from file) Model LoadModel(const char *fileName) { - Model model; + Model model = { 0 }; Mesh mesh = { 0 }; // NOTE: Initialize default data for model in case loading fails, maybe a cube? diff --git a/src/raylib.h b/src/raylib.h index 49a320d4..73200556 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -18,7 +18,7 @@ * * Used external libs: * GLFW3 (www.glfw.org) for window/context management and input -* GLAD for OpenGL extensions loading (3.3 Core profile) +* GLAD for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP) * stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC) * stb_image_write (Sean Barret) for image writting (PNG) * stb_vorbis (Sean Barret) for ogg audio loading diff --git a/src/shapes.c b/src/shapes.c index a4761536..3b4be071 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -397,8 +397,8 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec) int recCenterX = rec.x + rec.width/2; int recCenterY = rec.y + rec.height/2; - float dx = abs(center.x - recCenterX); - float dy = abs(center.y - recCenterY); + float dx = fabs(center.x - recCenterX); + float dy = fabs(center.y - recCenterY); if (dx > (rec.width/2 + radius)) { return false; } if (dy > (rec.height/2 + radius)) { return false; } -- cgit v1.2.3 From 41959eeae10d7d01fbd2abc19ccae4fc65aae031 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 24 Jan 2016 19:17:08 +0100 Subject: Added support for mouse gestures (need testing) Mouse input is interpreted as touches to allow mouse gestures detection... and get an unified inputs system for all platforms! --- src/core.c | 42 ++++++++++++++++++++++++++++++++++++------ src/raylib.h | 5 +++-- 2 files changed, 39 insertions(+), 8 deletions(-) (limited to 'src/raylib.h') diff --git a/src/core.c b/src/core.c index 7a5de04e..811f082a 100644 --- a/src/core.c +++ b/src/core.c @@ -1197,23 +1197,31 @@ bool IsGamepadButtonUp(int gamepad, int button) } #endif -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) // Returns touch position X int GetTouchX(void) { +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) return (int)touchPosition.x; +#else // PLATFORM_DESKTOP, PLATFORM_RPI + return GetMouseX(); +#endif } // Returns touch position Y int GetTouchY(void) { +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) return (int)touchPosition.y; +#else // PLATFORM_DESKTOP, PLATFORM_RPI + return GetMouseY(); +#endif } // Returns touch position XY // TODO: touch position should be scaled depending on display size and render size Vector2 GetTouchPosition(void) { +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) Vector2 position = touchPosition; if ((screenWidth > displayWidth) || (screenHeight > displayHeight)) @@ -1227,10 +1235,12 @@ Vector2 GetTouchPosition(void) position.x = position.x*((float)renderWidth/(float)displayWidth) - renderOffsetX/2; position.y = position.y*((float)renderHeight/(float)displayHeight) - renderOffsetY/2; } +#else // PLATFORM_DESKTOP, PLATFORM_RPI + Vector2 position = GetMousePosition(); +#endif return position; } -#endif #if defined(PLATFORM_ANDROID) // Detect if a button has been pressed once @@ -1633,6 +1643,28 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods) { currentMouseState[button] = action; + + // TODO: Test mouse gestures + +#define ENABLE_MOUSE_GESTURES +#if defined(ENABLE_MOUSE_GESTURES) + // Process mouse events as touches to be able to use mouse-gestures + GestureEvent gestureEvent; + + // 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; + + // Register touch points count + gestureEvent.pointCount = 1; + + // Register touch points position, only one point registered + gestureEvent.position[0] = GetMousePosition(); + + // Gesture data is sent to gestures system for processing + ProcessGestureEvent(gestureEvent); +#endif } // GLFW3 Char Key Callback, runs on key pressed (get char value) @@ -1976,11 +2008,9 @@ static bool GetMouseButtonStatus(int button) // Poll (store) all input events static void PollInputEvents(void) { -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) - - // TODO: Remove this requirement... + // NOTE: Gestures update must be called every frame to reset gestures correctly + // because ProcessGestureEvent() is just called on an event, not every frame UpdateGestures(); -#endif #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) // Mouse input polling diff --git a/src/raylib.h b/src/raylib.h index 73200556..41fa3f7d 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -598,13 +598,15 @@ 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 -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) 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_ANDROID) bool IsButtonPressed(int button); // Detect if an android physic button has been pressed bool IsButtonDown(int button); // Detect if an android physic button is being pressed bool IsButtonReleased(int button); // Detect if an android physic button has been released +#endif //------------------------------------------------------------------------------------ // Gestures and Touch Handling Functions (Module: gestures) @@ -621,7 +623,6 @@ 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 -#endif //------------------------------------------------------------------------------------ // Camera System Functions (Module: camera) -- cgit v1.2.3 From 3113a20390a1e4d81e9f832e7aa1d022afdb56d1 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 25 Jan 2016 11:12:31 +0100 Subject: Added bounding box calculation --- src/models.c | 29 ++++++++++++++++++----------- src/raylib.h | 2 ++ src/raymath.h | 26 ++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 11 deletions(-) (limited to 'src/raylib.h') diff --git a/src/models.c b/src/models.c index e90f455a..2d78963e 100644 --- a/src/models.c +++ b/src/models.c @@ -1275,6 +1275,20 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec rlDisableTexture(); } +// Draw a bounding box with wires +void DrawBoundingBox(BoundingBox box) +{ + Vector3 size; + + size.x = fabsf(box.max.x - box.min.x); + size.y = fabsf(box.max.y - box.min.y); + size.z = fabsf(box.max.z - box.min.z); + + Vector3 center = { box.min.x + size.x/2.0f, box.min.y + size.y/2.0f, box.min.z + size.z/2.0f }; + + DrawCubeWires(center, size.x, size.y, size.z, GREEN); +} + // Detect collision between two spheres bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB) { @@ -1401,10 +1415,8 @@ bool CheckCollisionRayBox(Ray ray, Vector3 minBBox, Vector3 maxBBox) return collision; } -// TODO: Useful function to check collision area? -//BoundingBox GetCollisionArea(BoundingBox box1, BoundingBox box2) - // Calculate mesh bounding box limits +// NOTE: minVertex and maxVertex should be transformed by model transform matrix (position, scale, rotate) BoundingBox CalculateBoundingBox(Mesh mesh) { // Get min and max vertex to construct bounds (AABB) @@ -1413,15 +1425,10 @@ BoundingBox CalculateBoundingBox(Mesh mesh) for (int i = 1; i < mesh.vertexCount; i++) { - // TODO: Compare min and max with previous vertex - //minVertex = Vector3.Min(minVertex, mesh.vertices[i]); - //maxVertex = Vector3.Max(maxVertex, mesh.vertices[i]); + minVertex = VectorMin(minVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] }); + maxVertex = VectorMax(maxVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] }); } - - // NOTE: For OBB, transform mesh by model transform matrix - //minVertex = VectorTransform(meshMin, mesh.transform); - //maxVertex = VectorTransform(meshMax, mesh.transform); - + // Create the bounding box BoundingBox box; box.min = minVertex; diff --git a/src/raylib.h b/src/raylib.h index 41fa3f7d..097c8865 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -765,10 +765,12 @@ void DrawModel(Model model, Vector3 position, float scale, Color tint); void DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint); // Draw a model with extended parameters void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires (with texture if set) void DrawModelWiresEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters +void DrawBoundingBox(BoundingBox box); // Draw bounding box (wires) void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec +BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2); // Detect collision between two boxes bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere diff --git a/src/raymath.h b/src/raymath.h index f5448504..46fab356 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -126,6 +126,8 @@ RMDEF Vector3 VectorLerp(Vector3 v1, Vector3 v2, float amount); // Calculate lin RMDEF Vector3 VectorReflect(Vector3 vector, Vector3 normal); // Calculate reflected vector to normal RMDEF void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Vector3 by a given Matrix RMDEF Vector3 VectorZero(void); // Return a Vector3 init to zero +RMDEF Vector3 VectorMin(Vector3 vec1, Vector3 vec2); // Return min value for each pair of components +RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2); // Return max value for each pair of components //------------------------------------------------------------------------------------ // Functions Declaration to work with Matrix @@ -361,6 +363,30 @@ RMDEF Vector3 VectorZero(void) return zero; } +// Return min value for each pair of components +RMDEF Vector3 VectorMin(Vector3 vec1, Vector3 vec2) +{ + Vector3 result; + + result.x = fminf(vec1.x, vec2.x); + result.y = fminf(vec1.y, vec2.y); + result.z = fminf(vec1.z, vec2.z); + + return result; +} + +// Return max value for each pair of components +RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2) +{ + Vector3 result; + + result.x = fmaxf(vec1.x, vec2.x); + result.y = fmaxf(vec1.y, vec2.y); + result.z = fmaxf(vec1.z, vec2.z); + + return result; +} + //---------------------------------------------------------------------------------- // Module Functions Definition - Matrix math //---------------------------------------------------------------------------------- -- cgit v1.2.3 From 99f99bea470ace9577950db8976aa092a678635d Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 25 Jan 2016 13:54:09 +0100 Subject: Simplified shader matrix uniforms --- src/raylib.h | 42 +++++++++++++++++++++--------------------- src/rlgl.c | 25 ++++++++++++++----------- 2 files changed, 35 insertions(+), 32 deletions(-) (limited to 'src/raylib.h') diff --git a/src/raylib.h b/src/raylib.h index 097c8865..48aeda54 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -358,12 +358,31 @@ typedef struct Shader { int mapSpecularLoc; // Specular map texture uniform location point (fragment shader) } Shader; +// Material type +// TODO: Redesign material-shaders-textures system +typedef struct Material { + //Shader shader; + + //Texture2D texDiffuse; // Diffuse texture + //Texture2D texNormal; // Normal texture + //Texture2D texSpecular; // Specular texture + + Color colDiffuse; + Color colAmbient; + Color colSpecular; + + float glossiness; + float normalDepth; +} Material; + // 3d Model type +// TODO: Replace shader/testure by material typedef struct Model { Mesh mesh; Matrix transform; Texture2D texture; // Only for OpenGL 1.1, on newer versions this should be in the shader Shader shader; + //Material material; } Model; // Ray type (useful for raycast) @@ -387,26 +406,6 @@ typedef struct Wave { short channels; } Wave; -// Light type -typedef struct Light { - Vector3 position; - Vector3 direction; - float intensity; - float specIntensity; - Color diffuse; - Color ambient; - Color specular; -} Light; - -// Material type -typedef struct Material { - Color diffuse; - Color ambient; - Color specular; - float glossiness; - float normalDepth; -} Material; - // Texture formats // NOTE: Support depends on OpenGL version and platform typedef enum { @@ -535,11 +534,12 @@ void BeginDrawing(void); // Setup drawing can void BeginDrawingEx(int blendMode, Shader shader, Matrix transform); // Setup drawing canvas with extended parameters void EndDrawing(void); // End canvas drawing and Swap Buffers (Double Buffering) -void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup) +void Begin3dMode(Camera camera); // Initializes 3D mode for drawing (Camera setup) void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position Vector2 WorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position +Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) void SetTargetFPS(int fps); // Set target FPS (maximum) float GetFPS(void); // Returns current FPS diff --git a/src/rlgl.c b/src/rlgl.c index ec909385..49300054 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1477,8 +1477,8 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r // NOTE: Drawing in OpenGL 3.3+, matrices are passed to shader // TODO: Reduce number of matrices passed to shaders, use only matMVP - glUniformMatrix4fv(model.shader.modelLoc, 1, false, MatrixToFloat(matModel)); - glUniformMatrix4fv(model.shader.viewLoc, 1, false, MatrixToFloat(matView)); + //glUniformMatrix4fv(model.material.shader.modelLoc, 1, false, MatrixToFloat(matModel)); + //glUniformMatrix4fv(model.material.shader.viewLoc, 1, false, MatrixToFloat(matView)); glUniformMatrix4fv(model.shader.mvpLoc, 1, false, MatrixToFloat(matMVP)); @@ -2201,9 +2201,6 @@ Shader LoadShader(char *vsFileName, char *fsFileName) // Get handles to GLSL uniform locations (vertex shader) shader.mvpLoc = glGetUniformLocation(shader.id, "mvpMatrix"); - - shader.modelLoc = glGetUniformLocation(shader.id, "modelMatrix"); - shader.viewLoc = glGetUniformLocation(shader.id, "viewMatrix"); // Get handles to GLSL uniform locations (fragment shader) shader.tintColorLoc = glGetUniformLocation(shader.id, "fragTintColor"); @@ -2503,6 +2500,18 @@ void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size) #endif } +// Set shader uniform value (matrix 4x4) +void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glUseProgram(shader.id); + + glUniformMatrix4fv(uniformLoc, 1, false, MatrixToFloat(mat)); + + glUseProgram(0); +#endif +} + // Default diffuse shader map texture assignment void SetShaderMapDiffuse(Shader *shader, Texture2D texture) { @@ -2741,9 +2750,6 @@ static Shader LoadDefaultShader(void) // Get handles to GLSL uniform locations (vertex shader) shader.mvpLoc = glGetUniformLocation(shader.id, "mvpMatrix"); - - shader.modelLoc = glGetUniformLocation(shader.id, "modelMatrix"); - shader.viewLoc = glGetUniformLocation(shader.id, "viewMatrix"); // Get handles to GLSL uniform locations (fragment shader) shader.tintColorLoc = -1; @@ -2822,9 +2828,6 @@ static Shader LoadSimpleShader(void) // Get handles to GLSL uniform locations (vertex shader) shader.mvpLoc = glGetUniformLocation(shader.id, "mvpMatrix"); - - shader.modelLoc = glGetUniformLocation(shader.id, "modelMatrix"); - shader.viewLoc = glGetUniformLocation(shader.id, "viewMatrix"); // Get handles to GLSL uniform locations (fragment shader) shader.tintColorLoc = glGetUniformLocation(shader.id, "fragTintColor"); -- cgit v1.2.3 From 13925f7bd4ad6b71f03a24024057819eb1032e05 Mon Sep 17 00:00:00 2001 From: Constantine Tarasenkov Date: Fri, 29 Jan 2016 09:09:18 +0300 Subject: Add functions to disable and enable cursor --- src/core.c | 18 ++++++++++++++++++ src/raylib.h | 2 ++ 2 files changed, 20 insertions(+) (limited to 'src/raylib.h') diff --git a/src/core.c b/src/core.c index 8b36e1ea..cf6fcf33 100644 --- a/src/core.c +++ b/src/core.c @@ -1097,6 +1097,24 @@ void ShowCursor() cursorHidden = false; } +// Disable mouse cursor +void DisableCursor() +{ +#if defined(PLATFORM_DESKTOP) + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); +#endif + cursorHidden = true; +} + +// Enable mouse cursor +void EnableCursor() +{ +#if defined(PLATFORM_DESKTOP) + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); +#endif + cursorHidden = false; +} + // Check if mouse cursor is hidden bool IsCursorHidden() { diff --git a/src/raylib.h b/src/raylib.h index 48aeda54..6c1a8999 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -586,6 +586,8 @@ int GetMouseWheelMove(void); // Returns mouse wheel m void ShowCursor(void); // Shows cursor void HideCursor(void); // Hides cursor +void EnableCursor(void); // Enables cursor +void DisableCursor(void); // Disables cursor bool IsCursorHidden(void); // Returns true if cursor is not visible #endif -- cgit v1.2.3 From 728e1715cc52fb25081f3ce17cb5b3f72f7eb218 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 2 Feb 2016 16:43:42 +0100 Subject: Redesigned gestures system... ...and improved mouse gestures support Some testing still required... --- src/core.c | 29 +++++- src/gestures.c | 300 +++++++++++++++++++++++++++++---------------------------- src/raylib.h | 23 +++-- 3 files changed, 189 insertions(+), 163 deletions(-) (limited to 'src/raylib.h') diff --git a/src/core.c b/src/core.c index cf6fcf33..1c9e16ae 100644 --- a/src/core.c +++ b/src/core.c @@ -253,6 +253,7 @@ static void InitGamepad(void); // Init raw gamepad inpu static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods); // GLFW3 Mouse Button Callback, runs on mouse button pressed +static void MouseCursorPosCallback(GLFWwindow *window, double x, double y); // GLFW3 Cursor Position Callback, runs on mouse move static void CharCallback(GLFWwindow *window, unsigned int key); // GLFW3 Char Key Callback, runs on key pressed (get char value) static void ScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel static void CursorEnterCallback(GLFWwindow *window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area @@ -1415,6 +1416,7 @@ static void InitDisplay(int width, int height) glfwSetCursorEnterCallback(window, CursorEnterCallback); glfwSetKeyCallback(window, KeyCallback); glfwSetMouseButtonCallback(window, MouseButtonCallback); + glfwSetCursorPosCallback(window, MouseCursorPosCallback); // Track mouse position changes glfwSetCharCallback(window, CharCallback); glfwSetScrollCallback(window, ScrollCallback); glfwSetWindowIconifyCallback(window, WindowIconifyCallback); @@ -1677,7 +1679,7 @@ 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 (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) gestureEvent.touchAction = TOUCH_MOVE; else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) gestureEvent.touchAction = TOUCH_UP; // Register touch points count @@ -1685,7 +1687,28 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int // Register touch points position, only one point registered gestureEvent.position[0] = GetMousePosition(); + + // Gesture data is sent to gestures system for processing + ProcessGestureEvent(gestureEvent); +#endif +} + +// GLFW3 Cursor Position Callback, runs on mouse move +static void MouseCursorPosCallback(GLFWwindow *window, double x, double y) +{ +#define ENABLE_MOUSE_GESTURES +#if defined(ENABLE_MOUSE_GESTURES) + // Process mouse events as touches to be able to use mouse-gestures + GestureEvent gestureEvent; + + gestureEvent.touchAction = TOUCH_MOVE; + + // Register touch points count + gestureEvent.pointCount = 1; + // Register touch points position, only one point registered + gestureEvent.position[0] = (Vector2){ (float)x, (float)y }; + // Gesture data is sent to gestures system for processing ProcessGestureEvent(gestureEvent); #endif @@ -1934,7 +1957,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) // Register touch points count gestureEvent.pointCount = AMotionEvent_getPointerCount(event); - // Register touch points id DESKTOP + // Register touch points id gestureEvent.pointerId[0] = AMotionEvent_getPointerId(event, 0); gestureEvent.pointerId[1] = AMotionEvent_getPointerId(event, 1); @@ -2496,7 +2519,7 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent // Register touch points count gestureEvent.pointCount = touchEvent->numTouches; - // Register touch points id WEB + // Register touch points id gestureEvent.pointerId[0] = touchEvent->touches[0].identifier; gestureEvent.pointerId[1] = touchEvent->touches[1].identifier; diff --git a/src/gestures.c b/src/gestures.c index ea744555..59f2c5b7 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -46,7 +46,11 @@ // Defines and Macros //---------------------------------------------------------------------------------- #define FORCE_TO_SWIPE 20 -#define TAP_TIMEOUT 300 +#define FORCE_TO_DRAG 20 +#define FORCE_TO_PINCH 5 +#define TAP_TIMEOUT 300 // Time in milliseconds +#define PINCH_TIMEOUT 300 // Time in milliseconds +#define DOUBLETAP_RANGE 30 //#define MAX_TOUCH_POINTS 4 //---------------------------------------------------------------------------------- @@ -61,10 +65,6 @@ typedef enum { //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -static GestureType gestureType = TYPE_MOTIONLESS; -static double eventTime = 0; -//static int32_t touchId; // Not used... - // Tap gesture variables static Vector2 initialTapPosition = { 0, 0 }; @@ -78,6 +78,21 @@ static Vector2 endDragPosition = { 0, 0 }; static Vector2 lastDragPosition = { 0, 0 }; static Vector2 dragVector = { 0, 0 }; +// Albert&Ian +static Vector2 touchDownPosition = { 0, 0 }; +static Vector2 touchDownPosition2 = { 0, 0 }; +static Vector2 touchUpPosition = { 0, 0 }; +static Vector2 moveDownPosition = { 0, 0 }; +static Vector2 moveDownPosition2 = { 0, 0 }; + +static int numTap = 0; +static int numHold = 0; +static int numPinch = 0; +static int pointCount = 0; +static int touchId = -1; + +static double eventTime = 0; + static float magnitude = 0; // Distance traveled dragging static float angle = 0; // Angle direction of the drag static float intensity = 0; // How fast we did the drag (pixels per frame) @@ -95,7 +110,7 @@ static int previousGesture = GESTURE_NONE; static int currentGesture = GESTURE_NONE; // Enabled gestures flags, all gestures enabled by default -static unsigned int enabledGestures = 0b0000011111111111; +static unsigned int enabledGestures = 0b0000001111111111; //---------------------------------------------------------------------------------- // Module specific Functions Declaration @@ -105,6 +120,7 @@ static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, flo static float VectorDistance(Vector2 v1, Vector2 v2); static float VectorDotProduct(Vector2 v1, Vector2 v2); static double GetCurrentTime(); +static float Vector2Distance(); //---------------------------------------------------------------------------------- // Module Functions Definition @@ -119,173 +135,160 @@ void ProcessGestureEvent(GestureEvent event) previousGesture = currentGesture; - switch (gestureType) - { - case TYPE_MOTIONLESS: // Detect TAP, DOUBLE_TAP and HOLD events + pointCount = event.pointCount; + + // Albert&Ian + if (pointCount < 2) + { + touchId = event.pointerId[0]; + if (event.touchAction == TOUCH_DOWN) { - if (event.touchAction == TOUCH_DOWN) + numTap++; // Tap counter + + // Detect GESTURE_DOUBLE_TAP + if ((currentGesture == GESTURE_NONE) && (numTap >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (GetMagnitude(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE)) { - if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]); - else - { - // Set the press position - initialTapPosition = event.position[0]; - - // If too much time have passed, we reset the double tap - if (GetCurrentTime() - eventTime > TAP_TIMEOUT) untap = false; - - // If we are in time, we detect the double tap - if (untap) doubleTapping = true; - - // Update our event time - eventTime = GetCurrentTime(); - - // Set hold - if (doubleTapping) currentGesture = GESTURE_DOUBLETAP; - else currentGesture = GESTURE_TAP; - } + currentGesture = GESTURE_DOUBLETAP; + numTap = 0; } - else if (event.touchAction == TOUCH_UP) + else // Detect GESTURE_TAP { - currentGesture = GESTURE_NONE; - - // Detect that we are tapping instead of holding - if (GetCurrentTime() - eventTime < TAP_TIMEOUT) - { - if (doubleTapping) untap = false; - else untap = true; - } - - // Tap finished - doubleTapping = false; - - // Update our event time - eventTime = GetCurrentTime(); + numTap = 1; + currentGesture = GESTURE_TAP; } - // Begin dragging - else if (event.touchAction == TOUCH_MOVE) + + touchDownPosition = event.position[0]; + + touchUpPosition = touchDownPosition; + eventTime = GetCurrentTime(); + } + else if (event.touchAction == TOUCH_UP) + { + if (currentGesture = GESTURE_DRAG) { - if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]); - else - { - // Set the drag starting position - initialDragPosition = initialTapPosition; - endDragPosition = initialDragPosition; - - // Initialize drag - draggingTimeCounter = 0; - gestureType = TYPE_DRAG; - currentGesture = GESTURE_NONE; - } + touchUpPosition = event.position[0]; } - } break; - case TYPE_DRAG: // Detect DRAG and SWIPE events - { - // end of the drag - if (event.touchAction == TOUCH_UP) + + // Calculate for swipe + magnitude = GetMagnitude(touchDownPosition, touchUpPosition); + intensity = magnitude / (float)draggingTimeCounter; + + // Detect GESTURE_SWIPE + if ((intensity > FORCE_TO_SWIPE) && (touchId == 0)) + { + angle = CalculateAngle(touchDownPosition, touchUpPosition, magnitude); + if ((angle < 30) || (angle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right + else if ((angle > 30) && (angle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up + else if ((angle > 120) && (angle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left + else if ((angle > 210) && (angle < 300)) currentGesture = GESTURE_SWIPE_DOWN; // Down + else currentGesture = GESTURE_NONE; + } + else { - // Return Swipe if we have enough sensitivity - if (intensity > FORCE_TO_SWIPE) - { - if (angle < 30 || angle > 330) currentGesture = GESTURE_SWIPE_RIGHT; // Right - else if (angle > 60 && angle < 120) currentGesture = GESTURE_SWIPE_UP; // Up - else if (angle > 150 && angle < 210) currentGesture = GESTURE_SWIPE_LEFT; // Left - else if (angle > 240 && angle < 300) currentGesture = GESTURE_SWIPE_DOWN; // Down - } - magnitude = 0; angle = 0; intensity = 0; - gestureType = TYPE_MOTIONLESS; + currentGesture = GESTURE_NONE; } - // Update while we are dragging - else if (event.touchAction == TOUCH_MOVE) + + draggingTimeCounter = 0; + } + else if (event.touchAction == TOUCH_MOVE) + { + if (GetMagnitude(moveDownPosition, event.position[0]) > 5) eventTime = GetCurrentTime(); + moveDownPosition = event.position[0]; + + if (currentGesture == GESTURE_HOLD) { - if (event.pointCount > 1) InitPinchGesture(event.position[0], event.position[1]); - else - { - lastDragPosition = endDragPosition; - endDragPosition = event.position[0]; - - //endDragPosition.x = AMotionEvent_getX(event, 0); - //endDragPosition.y = AMotionEvent_getY(event, 0); - - // Calculate attributes - dragVector = (Vector2){ endDragPosition.x - lastDragPosition.x, endDragPosition.y - lastDragPosition.y }; - magnitude = sqrt(pow(endDragPosition.x - initialDragPosition.x, 2) + pow(endDragPosition.y - initialDragPosition.y, 2)); - angle = CalculateAngle(initialDragPosition, endDragPosition, magnitude); - intensity = magnitude / (float)draggingTimeCounter; - - // Check if drag movement is less than minimum to keep it as hold state or switch to drag state - if(magnitude > FORCE_TO_SWIPE) - { - currentGesture = GESTURE_DRAG; - draggingTimeCounter++; - } - else currentGesture = GESTURE_HOLD; - } + if (numHold == 1) touchDownPosition = event.position[0]; + + numHold = 2; + + magnitude = GetMagnitude(touchDownPosition, moveDownPosition); + + // Detect GESTURE_DRAG + if (magnitude >= FORCE_TO_DRAG) currentGesture = GESTURE_DRAG; } - } break; - case TYPE_DUAL_INPUT: + + draggingTimeCounter++; + } + } + else + { + // two fingers + + if (event.touchAction == TOUCH_DOWN) + { + touchDownPosition = event.position[0]; + touchDownPosition2 = event.position[1]; + + currentGesture = GESTURE_HOLD; + } + else if (event.touchAction == TOUCH_MOVE) { - if (event.touchAction == TOUCH_UP) + magnitude = GetMagnitude(moveDownPosition, moveDownPosition2); + + touchDownPosition = moveDownPosition; + touchDownPosition2 = moveDownPosition2; + + moveDownPosition = event.position[0]; + moveDownPosition2 = event.position[1]; + + if ( (GetMagnitude(touchDownPosition, moveDownPosition) > FORCE_TO_PINCH) || (GetMagnitude(touchDownPosition2, moveDownPosition2) > FORCE_TO_PINCH)) { - if (event.pointCount == 1) - { - // Set the drag starting position - initialTapPosition = event.position[0]; - } - gestureType = TYPE_MOTIONLESS; + if ((GetMagnitude(moveDownPosition, moveDownPosition2) - magnitude) < 0) currentGesture = GESTURE_PINCH_IN; + else currentGesture = GESTURE_PINCH_OUT; } - else if (event.touchAction == TOUCH_MOVE) + else { - // Adapt the ending position of the inputs - firstEndPinchPosition = event.position[0]; - secondEndPinchPosition = event.position[1]; - - // If there is no more than two inputs - if (event.pointCount == 2) - { - // Calculate distances - float initialDistance = VectorDistance(firstInitialPinchPosition, secondInitialPinchPosition); - float endDistance = VectorDistance(firstEndPinchPosition, secondEndPinchPosition); - - // Calculate Vectors - Vector2 firstTouchVector = { firstEndPinchPosition.x - firstInitialPinchPosition.x, firstEndPinchPosition.y - firstInitialPinchPosition.y }; - Vector2 secondTouchVector = { secondEndPinchPosition.x - secondInitialPinchPosition.x, secondEndPinchPosition.y - secondInitialPinchPosition.y }; - - // Detect the pinch gesture - if (VectorDotProduct(firstTouchVector, secondTouchVector) < -0.5) pinchDelta = initialDistance - endDistance; - else pinchDelta = 0; - - // Pinch gesture resolution - if (pinchDelta != 0) - { - if (pinchDelta > 0) currentGesture = GESTURE_PINCH_IN; - else currentGesture = GESTURE_PINCH_OUT; - } - } - else - { - // Set the drag starting position - initialTapPosition = event.position[0]; - - gestureType = TYPE_MOTIONLESS; - } - - // Readapt the initial position of the inputs - firstInitialPinchPosition = firstEndPinchPosition; - secondInitialPinchPosition = secondEndPinchPosition; + currentGesture = GESTURE_HOLD; } - } break; + } + else if (event.touchAction == TOUCH_UP) + { + currentGesture = GESTURE_NONE; + } + } +} + +// Update gestures detected (must be called every frame) +void UpdateGestures(void) +{ + // NOTE: Gestures are processed through system callbacks on touch events + + // Detect GESTURE_HOLD + if (((currentGesture == GESTURE_TAP) || (currentGesture == GESTURE_DOUBLETAP)) && pointCount < 2) currentGesture = GESTURE_HOLD; + if ((GetCurrentTime() - eventTime) > TAP_TIMEOUT && (currentGesture == GESTURE_DRAG) && pointCount < 2) + { + currentGesture = GESTURE_HOLD; + numHold = 1; } + + // Detect GESTURE_NONE + if ((currentGesture == GESTURE_SWIPE_RIGHT) || (currentGesture == GESTURE_SWIPE_UP) || (currentGesture == GESTURE_SWIPE_LEFT) || (currentGesture == GESTURE_SWIPE_DOWN)) + { + currentGesture = GESTURE_NONE; + } +} + +// Calculate distance between two vectors +float Vector2Distance(Vector2 v1, Vector3 v2) +{ + float result; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + + result = sqrt(dx*dx + dy*dy); + + return result; } // Check if a gesture have been detected bool IsGestureDetected(void) { - if (currentGesture != GESTURE_NONE) return true; + if ((enabledGestures & currentGesture) != GESTURE_NONE) return true; else return false; } @@ -298,7 +301,7 @@ int GetGestureType(void) void SetGesturesEnabled(unsigned int gestureFlags) { - enabledGestures = enabledGestures | gestureFlags; + enabledGestures = gestureFlags; } // Get drag intensity (pixels per frame) @@ -440,6 +443,7 @@ static float VectorDotProduct(Vector2 v1, Vector2 v2) return result; } +// Time measure returned are milliseconds static double GetCurrentTime() { double time = 0; diff --git a/src/raylib.h b/src/raylib.h index 6c1a8999..a22c3f83 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -435,17 +435,17 @@ typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode; // Gestures type // NOTE: It could be used as flags to enable only some gestures typedef enum { - GESTURE_NONE = 1, - GESTURE_TAP = 2, - GESTURE_DOUBLETAP = 4, - GESTURE_HOLD = 8, - GESTURE_DRAG = 16, - GESTURE_SWIPE_RIGHT = 32, - GESTURE_SWIPE_LEFT = 64, - GESTURE_SWIPE_UP = 128, - GESTURE_SWIPE_DOWN = 256, - GESTURE_PINCH_IN = 512, - GESTURE_PINCH_OUT = 1024 + GESTURE_NONE = 0, + GESTURE_TAP = 1, + GESTURE_DOUBLETAP = 2, + GESTURE_HOLD = 4, + GESTURE_DRAG = 8, + GESTURE_SWIPE_RIGHT = 16, + GESTURE_SWIPE_LEFT = 32, + GESTURE_SWIPE_UP = 64, + GESTURE_SWIPE_DOWN = 128, + GESTURE_PINCH_IN = 256, + GESTURE_PINCH_OUT = 512 } Gestures; typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction; @@ -781,7 +781,6 @@ bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadi bool CheckCollisionRayBox(Ray ray, Vector3 minBBox, Vector3 maxBBox); // Detect collision between ray and box Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Detect collision of player radius with cubicmap // NOTE: Return the normal vector of the impacted surface - //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 -- cgit v1.2.3 From df5c64d0beee06df8c87a43e5341b6b98f82839f Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 2 Feb 2016 18:41:01 +0100 Subject: Functions parameters reorganize: Axis and Angle sin(), cos() functions cached and replaced by float c99 versions sinf(), cos() --- src/models.c | 12 ++++++------ src/raylib.h | 4 ++-- src/raymath.h | 47 +++++++++++++++++++++++++---------------------- src/rlgl.c | 8 ++++---- src/rlgl.h | 2 +- 5 files changed, 38 insertions(+), 35 deletions(-) (limited to 'src/raylib.h') diff --git a/src/models.c b/src/models.c index 2d78963e..91cb5813 100644 --- a/src/models.c +++ b/src/models.c @@ -1149,14 +1149,14 @@ void DrawModel(Model model, Vector3 position, float scale, Color tint) Vector3 vScale = { scale, scale, scale }; Vector3 rotationAxis = { 0.0f, 0.0f, 0.0f }; - DrawModelEx(model, position, 0.0f, rotationAxis, vScale, tint); + DrawModelEx(model, position, rotationAxis, 0.0f, vScale, tint); } // Draw a model with extended parameters -void DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint) +void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint) { // NOTE: Rotation must be provided in degrees, it's converted to radians inside rlglDrawModel() - rlglDrawModel(model, position, rotationAngle, rotationAxis, scale, tint, false); + rlglDrawModel(model, position, rotationAxis, rotationAngle, scale, tint, false); } // Draw a model wires (with texture if set) @@ -1165,14 +1165,14 @@ void DrawModelWires(Model model, Vector3 position, float scale, Color color) Vector3 vScale = { scale, scale, scale }; Vector3 rotationAxis = { 0.0f, 0.0f, 0.0f }; - rlglDrawModel(model, position, 0.0f, rotationAxis, vScale, color, true); + rlglDrawModel(model, position, rotationAxis, 0.0f, vScale, color, true); } // Draw a model wires (with texture if set) with extended parameters -void DrawModelWiresEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint) +void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint) { // NOTE: Rotation must be provided in degrees, it's converted to radians inside rlglDrawModel() - rlglDrawModel(model, position, rotationAngle, rotationAxis, scale, tint, true); + rlglDrawModel(model, position, rotationAxis, rotationAngle, scale, tint, true); } // Draw a billboard diff --git a/src/raylib.h b/src/raylib.h index a22c3f83..c306518d 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -764,9 +764,9 @@ void UnloadModel(Model model); void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) -void DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint); // Draw a model with extended parameters +void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires (with texture if set) -void DrawModelWiresEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters +void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters void DrawBoundingBox(BoundingBox box); // Draw bounding box (wires) void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture diff --git a/src/raymath.h b/src/raymath.h index 46fab356..35cee39f 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -141,7 +141,7 @@ RMDEF Matrix MatrixIdentity(void); // Returns identit RMDEF Matrix MatrixAdd(Matrix left, Matrix right); // Add two matrices RMDEF Matrix MatrixSubstract(Matrix left, Matrix right); // Substract two matrices (left - right) RMDEF Matrix MatrixTranslate(float x, float y, float z); // Returns translation matrix -RMDEF Matrix MatrixRotate(float angle, Vector3 axis); // Returns rotation matrix for an angle around an specified axis (angle in radians) +RMDEF Matrix MatrixRotate(Vector3 axis, float angle); // Returns rotation matrix for an angle around an specified axis (angle in radians) RMDEF Matrix MatrixRotateX(float angle); // Returns x-rotation matrix (angle in radians) RMDEF Matrix MatrixRotateY(float angle); // Returns y-rotation matrix (angle in radians) RMDEF Matrix MatrixRotateZ(float angle); // Returns z-rotation matrix (angle in radians) @@ -162,8 +162,8 @@ RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2); // Calcula RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float slerp); // Calculates spherical linear interpolation between two quaternions RMDEF Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a quaternion for a given rotation matrix RMDEF Matrix QuaternionToMatrix(Quaternion q); // Returns a matrix for a given quaternion -RMDEF Quaternion QuaternionFromAxisAngle(float angle, Vector3 axis); // Returns rotation quaternion for an angle and axis -RMDEF void QuaternionToAxisAngle(Quaternion q, float *outAngle, Vector3 *outAxis); // Returns the rotation angle and axis for a given quaternion +RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle); // Returns rotation quaternion for an angle and axis +RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle); // Returns the rotation angle and axis for a given quaternion RMDEF void QuaternionTransform(Quaternion *q, Matrix mat); // Transform a quaternion given a transformation matrix #ifdef __cplusplus @@ -587,7 +587,7 @@ RMDEF Matrix MatrixTranslate(float x, float y, float z) // Create rotation matrix from axis and angle // NOTE: Angle should be provided in radians -RMDEF Matrix MatrixRotate(float angle, Vector3 axis) +RMDEF Matrix MatrixRotate(Vector3 axis, float angle) { Matrix result; @@ -605,9 +605,9 @@ RMDEF Matrix MatrixRotate(float angle, Vector3 axis) z *= length; } - float s = sinf(angle); - float c = cosf(angle); - float t = 1.0f - c; + float sinres = sinf(angle); + float cosres = cosf(angle); + float t = 1.0f - cosres; // Cache some matrix values (speed optimization) float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3; @@ -615,9 +615,9 @@ RMDEF Matrix MatrixRotate(float angle, Vector3 axis) float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11; // Construct the elements of the rotation matrix - float b00 = x*x*t + c, b01 = y*x*t + z*s, b02 = z*x*t - y*s; - float b10 = x*y*t - z*s, b11 = y*y*t + c, b12 = z*y*t + x*s; - float b20 = x*z*t + y*s, b21 = y*z*t - x*s, b22 = z*z*t + c; + float b00 = x*x*t + cosres, b01 = y*x*t + z*sinres, b02 = z*x*t - y*sinres; + float b10 = x*y*t - z*sinres, b11 = y*y*t + cosres, b12 = z*y*t + x*sinres; + float b20 = x*z*t + y*sinres, b21 = y*z*t - x*sinres, b22 = z*z*t + cosres; // Perform rotation-specific matrix multiplication result.m0 = a00*b00 + a10*b01 + a20*b02; @@ -688,8 +688,8 @@ RMDEF Matrix MatrixRotateX(float angle) { Matrix result = MatrixIdentity(); - float cosres = (float)cos(angle); - float sinres = (float)sin(angle); + float cosres = cosf(angle); + float sinres = sinf(angle); result.m5 = cosres; result.m6 = -sinres; @@ -720,8 +720,8 @@ RMDEF Matrix MatrixRotateZ(float angle) { Matrix result = MatrixIdentity(); - float cosres = (float)cos(angle); - float sinres = (float)sin(angle); + float cosres = cosf(angle); + float sinres = sinf(angle); result.m0 = cosres; result.m1 = -sinres; @@ -946,8 +946,8 @@ RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount) } else { - float ratioA = sin((1 - amount)*halfTheta)/sinHalfTheta; - float ratioB = sin(amount*halfTheta)/sinHalfTheta; + float ratioA = sinf((1 - amount)*halfTheta)/sinHalfTheta; + float ratioB = sinf(amount*halfTheta)/sinHalfTheta; result.x = (q1.x*ratioA + q2.x*ratioB); result.y = (q1.y*ratioA + q2.y*ratioB); @@ -1060,7 +1060,7 @@ RMDEF Matrix QuaternionToMatrix(Quaternion q) // Returns rotation quaternion for an angle and axis // NOTE: angle must be provided in radians -RMDEF Quaternion QuaternionFromAxisAngle(float angle, Vector3 axis) +RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle) { Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -1069,11 +1069,14 @@ RMDEF Quaternion QuaternionFromAxisAngle(float angle, Vector3 axis) angle *= 0.5f; VectorNormalize(&axis); + + float sinres = sinf(angle); + float cosres = cosf(angle); - result.x = axis.x*(float)sin(angle); - result.y = axis.y*(float)sin(angle); - result.z = axis.z*(float)sin(angle); - result.w = (float)cos(angle); + result.x = axis.x*sinres; + result.y = axis.y*sinres; + result.z = axis.z*sinres; + result.w = cosres; QuaternionNormalize(&result); @@ -1081,7 +1084,7 @@ RMDEF Quaternion QuaternionFromAxisAngle(float angle, Vector3 axis) } // Returns the rotation angle and axis for a given quaternion -RMDEF void QuaternionToAxisAngle(Quaternion q, float *outAngle, Vector3 *outAxis) +RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle) { if (fabs(q.w) > 1.0f) QuaternionNormalize(&q); diff --git a/src/rlgl.c b/src/rlgl.c index 49300054..48e6ac1b 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -411,7 +411,7 @@ void rlRotatef(float angleDeg, float x, float y, float z) Vector3 axis = (Vector3){ x, y, z }; VectorNormalize(&axis); - matRotation = MatrixRotate(angleDeg*DEG2RAD, axis); + matRotation = MatrixRotate(axis, angleDeg*DEG2RAD); MatrixTranspose(&matRotation); @@ -1406,13 +1406,13 @@ void rlglDrawPostpro(void) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) glBindFramebuffer(GL_FRAMEBUFFER, 0); - rlglDrawModel(postproQuad, (Vector3){0,0,0}, 0.0f, (Vector3){0,0,0}, (Vector3){1.0f, 1.0f, 1.0f}, (Color){ 255, 255, 255, 255 }, false); + rlglDrawModel(postproQuad, (Vector3){0,0,0}, (Vector3){0,0,0}, 0.0f, (Vector3){1.0f, 1.0f, 1.0f}, (Color){ 255, 255, 255, 255 }, false); #endif } // Draw a 3d model // NOTE: Model transform can come within model struct -void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires) +void rlglDrawModel(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color color, bool wires) { #if defined (GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) // NOTE: glPolygonMode() not available on OpenGL ES @@ -1461,7 +1461,7 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r // Calculate transformation matrix from function parameters // Get transform matrix (rotation -> scale -> translation) - Matrix matRotation = MatrixRotate(rotationAngle*DEG2RAD, rotationAxis); + Matrix matRotation = MatrixRotate(rotationAxis, rotationAngle*DEG2RAD); Matrix matScale = MatrixScale(scale.x, scale.y, scale.z); Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z); Matrix matTransform = MatrixMultiply(MatrixMultiply(matRotation, matScale), matTranslation); diff --git a/src/rlgl.h b/src/rlgl.h index 64581db8..9e0aaaaa 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -262,7 +262,7 @@ void rlglInitPostpro(void); // Initialize postprocessing sys void rlglDrawPostpro(void); // Draw with postprocessing shader Model rlglLoadModel(Mesh mesh); // Upload vertex data into GPU and provided VAO/VBO ids -void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires); +void rlglDrawModel(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color color, bool wires); Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates -- cgit v1.2.3 From 646f1c3f716dd817ff717d35480a744a8be46ead Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 3 Feb 2016 17:45:28 +0100 Subject: Some formating tweaks --- src/camera.c | 114 +++++++++++++++++++++++++++++------------------------------ src/camera.h | 4 +-- src/core.c | 15 ++++---- src/raylib.h | 4 +-- src/rlgl.c | 2 +- 5 files changed, 70 insertions(+), 69 deletions(-) (limited to 'src/raylib.h') diff --git a/src/camera.c b/src/camera.c index 1e7ac2ff..6539da5f 100644 --- a/src/camera.c +++ b/src/camera.c @@ -36,44 +36,44 @@ // Defines and Macros //---------------------------------------------------------------------------------- // CAMERA_GENERIC -#define CAMERA_SCROLL_SENSITIVITY 1.5 +#define CAMERA_SCROLL_SENSITIVITY 1.5f // FREE_CAMERA -#define FREE_CAMERA_MOUSE_SENSITIVITY 0.01 -#define FREE_CAMERA_DISTANCE_MIN_CLAMP 0.3 -#define FREE_CAMERA_DISTANCE_MAX_CLAMP 120 -#define FREE_CAMERA_MIN_CLAMP 85 -#define FREE_CAMERA_MAX_CLAMP -85 -#define FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY 0.05 -#define FREE_CAMERA_PANNING_DIVIDER 5.1 +#define FREE_CAMERA_MOUSE_SENSITIVITY 0.01f +#define FREE_CAMERA_DISTANCE_MIN_CLAMP 0.3f +#define FREE_CAMERA_DISTANCE_MAX_CLAMP 120.0f +#define FREE_CAMERA_MIN_CLAMP 85.0f +#define FREE_CAMERA_MAX_CLAMP -85.0f +#define FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY 0.05f +#define FREE_CAMERA_PANNING_DIVIDER 5.1f // ORBITAL_CAMERA -#define ORBITAL_CAMERA_SPEED 0.01 +#define ORBITAL_CAMERA_SPEED 0.01f // FIRST_PERSON -//#define FIRST_PERSON_MOUSE_SENSITIVITY 0.003 -#define FIRST_PERSON_FOCUS_DISTANCE 25 -#define FIRST_PERSON_MIN_CLAMP 85 -#define FIRST_PERSON_MAX_CLAMP -85 +//#define FIRST_PERSON_MOUSE_SENSITIVITY 0.003f +#define FIRST_PERSON_FOCUS_DISTANCE 25.0f +#define FIRST_PERSON_MIN_CLAMP 85.0f +#define FIRST_PERSON_MAX_CLAMP -85.0f -#define FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 5.0 -#define FIRST_PERSON_STEP_DIVIDER 30.0 -#define FIRST_PERSON_WAVING_DIVIDER 200.0 +#define FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 5.0f +#define FIRST_PERSON_STEP_DIVIDER 30.0f +#define FIRST_PERSON_WAVING_DIVIDER 200.0f -#define FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION 0.85 +#define FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION 0.85f // THIRD_PERSON -//#define THIRD_PERSON_MOUSE_SENSITIVITY 0.003 -#define THIRD_PERSON_DISTANCE_CLAMP 1.2 -#define THIRD_PERSON_MIN_CLAMP 5 -#define THIRD_PERSON_MAX_CLAMP -85 -#define THIRD_PERSON_OFFSET (Vector3){ 0.4, 0, 0 } +//#define THIRD_PERSON_MOUSE_SENSITIVITY 0.003f +#define THIRD_PERSON_DISTANCE_CLAMP 1.2f +#define THIRD_PERSON_MIN_CLAMP 5.0f +#define THIRD_PERSON_MAX_CLAMP -85.0f +#define THIRD_PERSON_OFFSET (Vector3){ 0.4f, 0.0f, 0.0f } // PLAYER (used by camera) -#define PLAYER_WIDTH 0.4 -#define PLAYER_HEIGHT 0.9 -#define PLAYER_DEPTH 0.4 -#define PLAYER_MOVEMENT_DIVIDER 20.0 +#define PLAYER_WIDTH 0.4f +#define PLAYER_HEIGHT 0.9f +#define PLAYER_DEPTH 0.4f +#define PLAYER_MOVEMENT_DIVIDER 20.0f //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -84,11 +84,11 @@ typedef enum { MOVE_FRONT = 0, MOVE_LEFT, MOVE_BACK, MOVE_RIGHT, MOVE_UP, MOVE_D //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -static Camera internalCamera = {{2, 0, 2}, {0, 0, 0}, {0, 1, 0}}; -static Vector2 cameraAngle = { 0, 0 }; +static Camera internalCamera = {{ 2.0f, 0.0f, 2.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }}; +static Vector2 cameraAngle = { 0.0f, 0.0f }; static float cameraTargetDistance = 5.0f; -static Vector2 cameraMousePosition = { 0, 0 }; -static Vector2 cameraMouseVariation = { 0, 0 }; +static Vector2 cameraMousePosition = { 0.0f, 0.0f }; +static Vector2 cameraMouseVariation = { 0.0f, 0.0f }; static float mouseSensitivity = 0.003f; static int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' }; static int cameraMoveCounter = 0; @@ -107,7 +107,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition); #if defined(CAMERA_STANDALONE) // NOTE: Camera controls depend on some raylib input functions // TODO: Set your own input functions (used in ProcessCamera()) -static Vector2 GetMousePosition() { return (Vector2){ 0, 0}; } +static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; } static void SetMousePosition(Vector2 pos) {} static int IsMouseButtonDown(int button) { return 0;} static int GetMouseWheelMove() { return 0; } @@ -129,33 +129,33 @@ void SetCameraMode(int mode) if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_FREE)) { cameraMode = CAMERA_THIRD_PERSON; - cameraTargetDistance = 5; - cameraAngle.y = -40 * DEG2RAD; + cameraTargetDistance = 5.0f; + cameraAngle.y = -40*DEG2RAD; ProcessCamera(&internalCamera, &internalCamera.position); } else if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_ORBITAL)) { cameraMode = CAMERA_THIRD_PERSON; - cameraTargetDistance = 5; - cameraAngle.y = -40 * DEG2RAD; + cameraTargetDistance = 5.0f; + cameraAngle.y = -40*DEG2RAD; ProcessCamera(&internalCamera, &internalCamera.position); } else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_FREE)) { - cameraTargetDistance = 10; - cameraAngle.x = 45 * DEG2RAD; - cameraAngle.y = -40 * DEG2RAD; - internalCamera.target = (Vector3){ 0, 0, 0 }; + cameraTargetDistance = 10.0f; + cameraAngle.x = 45*DEG2RAD; + cameraAngle.y = -40*DEG2RAD; + internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; ProcessCamera(&internalCamera, &internalCamera.position); ShowCursor(); } else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_ORBITAL)) { - cameraTargetDistance = 10; - cameraAngle.x = 225 * DEG2RAD; - cameraAngle.y = -40 * DEG2RAD; - internalCamera.target = (Vector3){ 0, 0, 0}; + cameraTargetDistance = 10.0f; + cameraAngle.x = 225*DEG2RAD; + cameraAngle.y = -40*DEG2RAD; + internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; ProcessCamera(&internalCamera, &internalCamera.position); } @@ -165,7 +165,7 @@ void SetCameraMode(int mode) // Update camera (player position is ignored) void UpdateCamera(Camera *camera) { - Vector3 position = { 0, 0, 0 }; + Vector3 position = { 0.0f, 0.0f, 0.0f }; // Process internal camera and player position (if required) if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, &position); @@ -244,7 +244,7 @@ void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, // Set camera mouse sensitivity (1st person and 3rd person cameras) void SetCameraMouseSensitivity(float sensitivity) { - mouseSensitivity = (sensitivity/10000.0); + mouseSensitivity = (sensitivity/10000.0f); } //---------------------------------------------------------------------------------- @@ -376,12 +376,12 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) // Focus to center // TODO: Move this function out of the module? - if (IsKeyDown('Z')) camera->target = (Vector3){ 0, 0, 0 }; + if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera position update camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; @@ -398,12 +398,12 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP; // Focus to center - if (IsKeyDown('Z')) camera->target = (Vector3){ 0, 0, 0 }; + if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera position update camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; @@ -412,7 +412,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) case CAMERA_FIRST_PERSON: case CAMERA_THIRD_PERSON: { - int isMoving = 0; + bool isMoving = false; // Keyboard inputs if (IsKeyDown(cameraMoveControl[MOVE_FRONT])) @@ -422,7 +422,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) if (!cameraUseGravity) camera->position.y += sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; - isMoving = 1; + isMoving = true; } else if (IsKeyDown(cameraMoveControl[MOVE_BACK])) { @@ -431,7 +431,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) if (!cameraUseGravity) camera->position.y -= sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; - isMoving = 1; + isMoving = true; } if (IsKeyDown(cameraMoveControl[MOVE_LEFT])) @@ -439,23 +439,23 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) playerPosition->x -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; playerPosition->z += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - isMoving = 1; + isMoving = true; } else if (IsKeyDown(cameraMoveControl[MOVE_RIGHT])) { playerPosition->x += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; playerPosition->z -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - isMoving = 1; + isMoving = true; } if (IsKeyDown(cameraMoveControl[MOVE_UP])) { - if (!cameraUseGravity) playerPosition->y += 1/PLAYER_MOVEMENT_DIVIDER; + if (!cameraUseGravity) playerPosition->y += 1.0f/PLAYER_MOVEMENT_DIVIDER; } else if (IsKeyDown(cameraMoveControl[MOVE_DOWN])) { - if (!cameraUseGravity) playerPosition->y -= 1/PLAYER_MOVEMENT_DIVIDER; + if (!cameraUseGravity) playerPosition->y -= 1.0f/PLAYER_MOVEMENT_DIVIDER; } if (cameraMode == CAMERA_THIRD_PERSON) @@ -482,7 +482,7 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) // Camera position update camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; diff --git a/src/camera.h b/src/camera.h index ed85320a..9ad09c6f 100644 --- a/src/camera.h +++ b/src/camera.h @@ -28,8 +28,8 @@ #define PI 3.14159265358979323846 #endif -#define DEG2RAD (PI / 180.0f) -#define RAD2DEG (180.0f / PI) +#define DEG2RAD (PI/180.0f) +#define RAD2DEG (180.0f/PI) //---------------------------------------------------------------------------------- // Defines and Macros diff --git a/src/core.c b/src/core.c index 1c9e16ae..c872d43e 100644 --- a/src/core.c +++ b/src/core.c @@ -116,6 +116,7 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- +#define STORAGE_FILENAME "storage.data" //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -591,7 +592,7 @@ void Begin3dMode(Camera camera) // Setup perspective projection float aspect = (float)screenWidth/(float)screenHeight; - double top = 0.1f*tan(45.0f*PI/360.0f); + double top = 0.1*tan(45.0*PI/360.0); double right = top*aspect; // NOTE: zNear and zFar values are important when computing depth buffer values @@ -630,7 +631,7 @@ void SetTargetFPS(int fps) // Returns current FPS float GetFPS(void) { - return (float)(1/frameTime); + return (float)(1.0/frameTime); } // Returns time in seconds for one frame @@ -791,10 +792,10 @@ void StorageSaveValue(int position, int value) FILE *storageFile = NULL; // Try open existing file to append data - storageFile = fopen("storage.data", "rb+"); + storageFile = fopen(STORAGE_FILENAME, "rb+"); // If file doesn't exist, create a new storage data file - if (!storageFile) storageFile = fopen("storage.data", "wb"); + if (!storageFile) storageFile = fopen(STORAGE_FILENAME, "wb"); if (!storageFile) TraceLog(WARNING, "Storage data file could not be created"); else @@ -822,7 +823,7 @@ int StorageLoadValue(int position) int value = 0; // Try open existing file to append data - FILE *storageFile = fopen("storage.data", "rb"); + FILE *storageFile = fopen(STORAGE_FILENAME, "rb"); if (!storageFile) TraceLog(WARNING, "Storage data file could not be found"); else @@ -889,8 +890,8 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera) MatrixInvert(&matProjView); // Calculate far and near points - Quaternion near = { deviceCoords.x, deviceCoords.y, 0, 1}; - Quaternion far = { deviceCoords.x, deviceCoords.y, 1, 1}; + Quaternion near = { deviceCoords.x, deviceCoords.y, 0.0f, 1.0f}; + Quaternion far = { deviceCoords.x, deviceCoords.y, 1.0f, 1.0f}; // Multiply points by unproject matrix QuaternionTransform(&near, matProjView); diff --git a/src/raylib.h b/src/raylib.h index c306518d..3d8100b3 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -81,8 +81,8 @@ #define PI 3.14159265358979323846 #endif -#define DEG2RAD (PI / 180.0f) -#define RAD2DEG (180.0f / PI) +#define DEG2RAD (PI/180.0f) +#define RAD2DEG (180.0f/PI) // raylib Config Flags #define FLAG_FULLSCREEN_MODE 1 diff --git a/src/rlgl.c b/src/rlgl.c index 48e6ac1b..6810cb4b 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1406,7 +1406,7 @@ void rlglDrawPostpro(void) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) glBindFramebuffer(GL_FRAMEBUFFER, 0); - rlglDrawModel(postproQuad, (Vector3){0,0,0}, (Vector3){0,0,0}, 0.0f, (Vector3){1.0f, 1.0f, 1.0f}, (Color){ 255, 255, 255, 255 }, false); + rlglDrawModel(postproQuad, (Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, 0.0f, (Vector3){1.0f, 1.0f, 1.0f}, (Color){ 255, 255, 255, 255 }, false); #endif } -- 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/raylib.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 84a6724b33efd9ddea9782c3df88855cff2d9d3a Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 10 Feb 2016 11:24:02 +0100 Subject: Fixed a bug --- src/raylib.h | 2 +- src_android/jni/Android.mk | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'src/raylib.h') diff --git a/src/raylib.h b/src/raylib.h index 55a68ad1..a5dd6ad2 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -602,7 +602,7 @@ bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad b 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) +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 diff --git a/src_android/jni/Android.mk b/src_android/jni/Android.mk index f9c20e66..20073760 100644 --- a/src_android/jni/Android.mk +++ b/src_android/jni/Android.mk @@ -39,7 +39,6 @@ LOCAL_MODULE := raylib LOCAL_SRC_FILES :=\ ../../src/core.c \ ../../src/rlgl.c \ - ../../src/raymath.c \ ../../src/textures.c \ ../../src/text.c \ ../../src/shapes.c \ -- cgit v1.2.3 From 685273675bc9247e215c213939c017e506296a70 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Thu, 11 Feb 2016 15:51:04 +0100 Subject: Improved LoadHeightmap() --- examples/models_heightmap.c | 16 ++++++----- examples/models_heightmap.png | Bin 123602 -> 96976 bytes src/models.c | 60 +++++++++++++++++++----------------------- src/raylib.h | 2 +- 4 files changed, 37 insertions(+), 41 deletions(-) (limited to 'src/raylib.h') diff --git a/examples/models_heightmap.c b/examples/models_heightmap.c index ac578c61..f1da3301 100644 --- a/examples/models_heightmap.c +++ b/examples/models_heightmap.c @@ -21,13 +21,13 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing"); // Define our custom camera to look into our 3d world - Camera camera = {{ 24.0f, 18.0f, 24.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }}; + Camera camera = {{ 18.0f, 16.0f, 18.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }}; - Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM) - Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM) - Model map = LoadHeightmap(image, 32); // Load heightmap model - SetModelTexture(&map, texture); // Bind texture to model - Vector3 mapPosition = { -16.0f, 0.0f, -16.0f }; // Set model position (depends on model scaling!) + Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM) + Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM) + Model map = LoadHeightmap(image, (Vector3){ 16, 8, 16 }); // Load heightmap model with defined size + SetModelTexture(&map, texture); // Bind texture to model + Vector3 mapPosition = { -8.0f, 0.0f, -8.0f }; // Set model position (depends on model scaling!) UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM @@ -54,7 +54,9 @@ int main() Begin3dMode(camera); // NOTE: Model is scaled to 1/4 of its original size (128x128 units) - DrawModel(map, mapPosition, 1/4.0f, RED); + DrawModel(map, mapPosition, 1.0f, RED); + + DrawGrid(20, 1.0f); End3dMode(); diff --git a/examples/models_heightmap.png b/examples/models_heightmap.png index 9ed04586..6dcf01f0 100644 Binary files a/examples/models_heightmap.png and b/examples/models_heightmap.png differ diff --git a/src/models.c b/src/models.c index 91cb5813..94e61d84 100644 --- a/src/models.c +++ b/src/models.c @@ -55,7 +55,6 @@ extern unsigned int whiteTexture; //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static float GetHeightValue(Color pixel); static Mesh LoadOBJ(const char *fileName); //---------------------------------------------------------------------------------- @@ -608,17 +607,19 @@ Model LoadModelEx(Mesh data) } // Load a heightmap image as a 3d model -Model LoadHeightmap(Image heightmap, float maxHeight) +// NOTE: model map size is defined in generic units +Model LoadHeightmap(Image heightmap, Vector3 size) { + #define GRAY_VALUE(c) ((c.r+c.g+c.b)/3) + Mesh mesh; int mapX = heightmap.width; int mapZ = heightmap.height; - Color *heightmapPixels = GetImageData(heightmap); + Color *pixels = GetImageData(heightmap); // NOTE: One vertex per pixel - // TODO: Consider resolution when generating model data? int numTriangles = (mapX-1)*(mapZ-1)*2; // One quad every four pixels mesh.vertexCount = numTriangles*3; @@ -634,7 +635,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight) int trisCounter = 0; - float scaleFactor = maxHeight/255; // TODO: Review scaleFactor calculation + Vector3 scaleFactor = { size.x/mapX, size.y/255.0f, size.z/mapZ }; for(int z = 0; z < mapZ-1; z++) { @@ -644,17 +645,17 @@ Model LoadHeightmap(Image heightmap, float maxHeight) //---------------------------------------------------------- // one triangle - 3 vertex - mesh.vertices[vCounter] = x; - mesh.vertices[vCounter + 1] = GetHeightValue(heightmapPixels[x + z*mapX])*scaleFactor; - mesh.vertices[vCounter + 2] = z; + mesh.vertices[vCounter] = (float)x*scaleFactor.x; + mesh.vertices[vCounter + 1] = (float)GRAY_VALUE(pixels[x + z*mapX])*scaleFactor.y; + mesh.vertices[vCounter + 2] = (float)z*scaleFactor.z; - mesh.vertices[vCounter + 3] = x; - mesh.vertices[vCounter + 4] = GetHeightValue(heightmapPixels[x + (z+1)*mapX])*scaleFactor; - mesh.vertices[vCounter + 5] = z+1; + mesh.vertices[vCounter + 3] = (float)x*scaleFactor.x; + mesh.vertices[vCounter + 4] = (float)GRAY_VALUE(pixels[x + (z + 1)*mapX])*scaleFactor.y; + mesh.vertices[vCounter + 5] = (float)(z + 1)*scaleFactor.z; - mesh.vertices[vCounter + 6] = x+1; - mesh.vertices[vCounter + 7] = GetHeightValue(heightmapPixels[(x+1) + z*mapX])*scaleFactor; - mesh.vertices[vCounter + 8] = z; + mesh.vertices[vCounter + 6] = (float)(x + 1)*scaleFactor.x; + mesh.vertices[vCounter + 7] = (float)GRAY_VALUE(pixels[(x + 1) + z*mapX])*scaleFactor.y; + mesh.vertices[vCounter + 8] = (float)z*scaleFactor.z; // another triangle - 3 vertex mesh.vertices[vCounter + 9] = mesh.vertices[vCounter + 6]; @@ -665,21 +666,21 @@ Model LoadHeightmap(Image heightmap, float maxHeight) mesh.vertices[vCounter + 13] = mesh.vertices[vCounter + 4]; mesh.vertices[vCounter + 14] = mesh.vertices[vCounter + 5]; - mesh.vertices[vCounter + 15] = x+1; - mesh.vertices[vCounter + 16] = GetHeightValue(heightmapPixels[(x+1) + (z+1)*mapX])*scaleFactor; - mesh.vertices[vCounter + 17] = z+1; + mesh.vertices[vCounter + 15] = (float)(x + 1)*scaleFactor.x; + mesh.vertices[vCounter + 16] = (float)GRAY_VALUE(pixels[(x + 1) + (z + 1)*mapX])*scaleFactor.y; + mesh.vertices[vCounter + 17] = (float)(z + 1)*scaleFactor.z; vCounter += 18; // 6 vertex, 18 floats // Fill texcoords array with data //-------------------------------------------------------------- - mesh.texcoords[tcCounter] = (float)x / (mapX-1); - mesh.texcoords[tcCounter + 1] = (float)z / (mapZ-1); + mesh.texcoords[tcCounter] = (float)x/(mapX - 1); + mesh.texcoords[tcCounter + 1] = (float)z/(mapZ - 1); - mesh.texcoords[tcCounter + 2] = (float)x / (mapX-1); - mesh.texcoords[tcCounter + 3] = (float)(z+1) / (mapZ-1); + mesh.texcoords[tcCounter + 2] = (float)x/(mapX - 1); + mesh.texcoords[tcCounter + 3] = (float)(z + 1)/(mapZ - 1); - mesh.texcoords[tcCounter + 4] = (float)(x+1) / (mapX-1); - mesh.texcoords[tcCounter + 5] = (float)z / (mapZ-1); + mesh.texcoords[tcCounter + 4] = (float)(x + 1)/(mapX - 1); + mesh.texcoords[tcCounter + 5] = (float)z/(mapZ - 1); mesh.texcoords[tcCounter + 6] = mesh.texcoords[tcCounter + 4]; mesh.texcoords[tcCounter + 7] = mesh.texcoords[tcCounter + 5]; @@ -687,13 +688,12 @@ Model LoadHeightmap(Image heightmap, float maxHeight) mesh.texcoords[tcCounter + 8] = mesh.texcoords[tcCounter + 2]; mesh.texcoords[tcCounter + 9] = mesh.texcoords[tcCounter + 3]; - mesh.texcoords[tcCounter + 10] = (float)(x+1) / (mapX-1); - mesh.texcoords[tcCounter + 11] = (float)(z+1) / (mapZ-1); + mesh.texcoords[tcCounter + 10] = (float)(x + 1)/(mapX - 1); + mesh.texcoords[tcCounter + 11] = (float)(z + 1)/(mapZ - 1); tcCounter += 12; // 6 texcoords, 12 floats // Fill normals array with data //-------------------------------------------------------------- - // NOTE: Current Model implementation doe not use normals! for (int i = 0; i < 18; i += 3) { mesh.normals[nCounter + i] = 0.0f; @@ -709,7 +709,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight) } } - free(heightmapPixels); + free(pixels); // Fill color data // NOTE: Not used any more... just one plain color defined at DrawModel() @@ -1688,12 +1688,6 @@ Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *p // Module specific Functions Definition //---------------------------------------------------------------------------------- -// Get current vertex y altitude (proportional to pixel colors in grayscale) -static float GetHeightValue(Color pixel) -{ - return (((float)pixel.r + (float)pixel.g + (float)pixel.b)/3); -} - // Load OBJ mesh data static Mesh LoadOBJ(const char *fileName) { diff --git a/src/raylib.h b/src/raylib.h index a5dd6ad2..f9241533 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -759,7 +759,7 @@ void DrawGizmo(Vector3 position); Model LoadModel(const char *fileName); // Load a 3d model (.OBJ) Model LoadModelEx(Mesh data); // Load a 3d model (from vertex data) //Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource) -Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model +Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) void UnloadModel(Model model); // Unload 3d model from memory void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model -- cgit v1.2.3 From cbbe9485294032d680579809976f7035785d3694 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Fri, 12 Feb 2016 19:02:23 +0100 Subject: Some code tweaks --- examples/shaders_basic_lighting.c | 12 ++++++------ src/core.c | 5 ++++- src/raylib.h | 14 ++++++++------ 3 files changed, 18 insertions(+), 13 deletions(-) (limited to 'src/raylib.h') diff --git a/examples/shaders_basic_lighting.c b/examples/shaders_basic_lighting.c index 649eab74..84bd1af4 100644 --- a/examples/shaders_basic_lighting.c +++ b/examples/shaders_basic_lighting.c @@ -77,9 +77,9 @@ int main() light.specIntensity = 1.0f; // Material initialization - matBlinn.diffuse = WHITE; - matBlinn.ambient = (Color){ 50, 50, 50, 255 }; - matBlinn.specular = WHITE; + matBlinn.colDiffuse = WHITE; + matBlinn.colAmbient = (Color){ 50, 50, 50, 255 }; + matBlinn.colSpecular = WHITE; matBlinn.glossiness = 50.0f; // Setup camera @@ -129,8 +129,8 @@ int main() SetShaderValue(shader, lSpecIntensityLoc, &light.specIntensity, 1); // Send material values to shader - SetShaderValue(shader, mAmbientLoc, ColorToFloat(matBlinn.ambient), 3); - SetShaderValue(shader, mSpecularLoc, ColorToFloat(matBlinn.specular), 3); + SetShaderValue(shader, mAmbientLoc, ColorToFloat(matBlinn.colAmbient), 3); + SetShaderValue(shader, mSpecularLoc, ColorToFloat(matBlinn.colSpecular), 3); SetShaderValue(shader, mGlossLoc, &matBlinn.glossiness, 1); // Send camera and light transform values to shader @@ -146,7 +146,7 @@ int main() Begin3dMode(camera); - DrawModel(model, position, 4.0f, matBlinn.diffuse); + DrawModel(model, position, 4.0f, matBlinn.colDiffuse); DrawSphere(light.position, 0.5f, GOLD); DrawGrid(20, 1.0f); diff --git a/src/core.c b/src/core.c index 413006e4..cff90ba9 100644 --- a/src/core.c +++ b/src/core.c @@ -118,7 +118,6 @@ // Defines and Macros //---------------------------------------------------------------------------------- #define STORAGE_FILENAME "storage.data" -#define MAX_TOUCH_POINTS 2 //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -324,6 +323,10 @@ void InitWindow(int width, int height, const char *title) emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenInputCallback); emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenInputCallback); emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenInputCallback); + + // TODO: Add gamepad support (not provided by GLFW3 on emscripten) + //emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenInputCallback); + //emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenInputCallback); #endif mousePosition.x = (float)screenWidth/2.0f; diff --git a/src/raylib.h b/src/raylib.h index f9241533..c2067a0e 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -166,6 +166,9 @@ #define MOUSE_MIDDLE_BUTTON 2 #endif +// Touch points registered +#define MAX_TOUCH_POINTS 2 + // Gamepad Number #define GAMEPAD_PLAYER1 0 #define GAMEPAD_PLAYER2 1 @@ -348,9 +351,6 @@ typedef struct Shader { // Uniforms int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader) - - int modelLoc; // Model transformation matrix uniform location point (vertex shader) - int viewLoc; // View transformation matrix uniform location point (vertex shader) int tintColorLoc; // Color uniform location point (fragment shader) int mapDiffuseLoc; // Diffuse map texture uniform location point (fragment shader) @@ -448,15 +448,16 @@ typedef enum { GESTURE_PINCH_OUT = 512 } Gestures; +// Touch action (fingers or mouse) typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction; // Gesture events -// NOTE: MAX_TOUCH_POINTS fixed to 4 +// NOTE: MAX_TOUCH_POINTS fixed to 2 typedef struct { int touchAction; int pointCount; - int pointerId[4]; - Vector2 position[4]; + int pointerId[MAX_TOUCH_POINTS]; + Vector2 position[MAX_TOUCH_POINTS]; } GestureEvent; // Camera system modes @@ -798,6 +799,7 @@ bool IsPosproShaderEnabled(void); // Check if int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float) void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int) +void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4) void SetShaderMapDiffuse(Shader *shader, Texture2D texture); // Default diffuse shader map texture assignment void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture); // Normal map texture shader assignment void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture); // Specular map texture shader assignment -- cgit v1.2.3 From ed1906440560d5b6b6e2cb1c1927e53b28e302db Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 13 Feb 2016 17:09:53 +0100 Subject: Reviewed physics module A deeper revision required, not clear enough for the user Key: Create a PhysicObjects pool --- examples/physics_basic_rigidbody.c | 44 +++++++-------------------- examples/physics_rigidbody_force.c | 33 ++++++++------------- src/physac.c | 61 ++++++++++++++++++++++---------------- src/physac.h | 11 ++----- src/raylib.h | 13 ++------ 5 files changed, 64 insertions(+), 98 deletions(-) (limited to 'src/raylib.h') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index b82fe638..6c354eb7 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -2,20 +2,10 @@ * * raylib [physac] physics example - Basic rigidbody * -* Welcome to raylib! -* -* To test examples, just press F6 and execute raylib_compile_execute script -* Note that compiled executable is placed in the same folder as .c file -* -* You can find all basic examples on C:\raylib\raylib\examples folder or -* raylib official webpage: www.raylib.com -* -* Enjoy using raylib. :) -* -* This example has been created using raylib 1.3 (www.raylib.com) +* This example has been created using raylib 1.4 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -33,13 +23,7 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [physics] example - basic rigidbody"); - InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) - - // Physics initialization - Physics worldPhysics = { true, false, (Vector2){ 0, -9.81f } }; - - // Set internal physics settings - SetPhysics(worldPhysics); + InitPhysics(3); // Initialize physics system with maximum physic objects // Object initialization Transform player = (Transform){(Vector2){(screenWidth - OBJECT_SIZE) / 2, (screenHeight - OBJECT_SIZE) / 2}, 0.0f, (Vector2){OBJECT_SIZE, OBJECT_SIZE}}; @@ -55,6 +39,8 @@ int main() float moveSpeed = 6.0f; float jumpForce = 5.0f; + bool physicsDebug = false; + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -91,14 +77,7 @@ int main() } // Check debug mode toggle button input - if(IsKeyPressed(KEY_P)) - { - // Update program physics value - worldPhysics.debug = !worldPhysics.debug; - - // Update internal physics value - SetPhysics(worldPhysics); - } + if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug; //---------------------------------------------------------------------------------- // Draw @@ -112,7 +91,7 @@ int main() DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY); // Check if debug mode is enabled - if (worldPhysics.debug) + if (physicsDebug) { // Draw every internal physics stored collider if it is active for (int i = 0; i < 2; i++) @@ -122,14 +101,11 @@ int main() DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN); } } - } else { - // Draw player + // Draw player and floor DrawRectangleRec((Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, GRAY); - - // Draw floor DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK); } @@ -138,7 +114,9 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- + UnloadPhysics(); // Unload physic objects + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/physics_rigidbody_force.c b/examples/physics_rigidbody_force.c index 3ac560c5..74a88a97 100644 --- a/examples/physics_rigidbody_force.c +++ b/examples/physics_rigidbody_force.c @@ -2,10 +2,10 @@ * * raylib [physac] physics example - Rigidbody forces * -* This example has been created using raylib 1.3 (www.raylib.com) +* This example has been created using raylib 1.4 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (@raysan5) +* Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -26,15 +26,9 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [physics] example - rigidbodies forces"); - InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) + InitPhysics(MAX_OBJECTS + 1); // Initialize physics system with maximum physic objects - // Physics initialization - Physics worldPhysics = {true, false, (Vector2){0, -9.81f}}; - - // Set internal physics settings - SetPhysics(worldPhysics); - - // Objects initialization + // Physic Objects initialization Transform objects[MAX_OBJECTS]; for (int i = 0; i < MAX_OBJECTS; i++) @@ -49,6 +43,8 @@ int main() Transform floor = (Transform){(Vector2){0, screenHeight * 0.8f}, 0.0f, (Vector2){screenWidth, screenHeight * 0.2f}}; AddCollider(MAX_OBJECTS, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0}); + bool physicsDebug = false; + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -72,14 +68,7 @@ int main() } // Check debug mode toggle button input - if (IsKeyPressed(KEY_P)) - { - // Update program physics value - worldPhysics.debug = !worldPhysics.debug; - - // Update internal physics value - SetPhysics(worldPhysics); - } + if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug; //---------------------------------------------------------------------------------- // Draw @@ -89,10 +78,10 @@ int main() ClearBackground(RAYWHITE); // Check if debug mode is enabled - if (worldPhysics.debug) + if (physicsDebug) { // Draw every internal physics stored collider if it is active (floor included) - for (int i = 0; i < MAX_OBJECTS + 1; i++) + for (int i = 0; i < MAX_OBJECTS; i++) { if (GetCollider(i).enabled) { @@ -136,7 +125,9 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- + UnloadPhysics(); // Unload physic objects + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/src/physac.c b/src/physac.c index 891f0123..4c50dd41 100644 --- a/src/physac.c +++ b/src/physac.c @@ -30,13 +30,12 @@ #endif #include -#include +#include // Required for: malloc(), free() //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define MAX_ELEMENTS 1024 // Stored rigidbodies and colliders array length -#define DECIMAL_FIX 0.26f // Decimal margin for collision checks (avoid rigidbodies shake) +#define DECIMAL_FIX 0.26f // Decimal margin for collision checks (avoid rigidbodies shake) //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -46,10 +45,13 @@ //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -static Physics physics; -static Collider colliders[MAX_ELEMENTS]; -static Rigidbody rigidbodies[MAX_ELEMENTS]; -static bool collisionChecker = false; +static Collider *colliders; // Colliders array, dynamically allocated at runtime +static Rigidbody *rigidbodies; // Rigitbody array, dynamically allocated at runtime +static bool collisionChecker; + +static int maxElements; // Max physic elements to compute +static bool enabled; // Physics enabled? (true by default) +static Vector2 gravity; // Gravity value used for physic calculations //---------------------------------------------------------------------------------- // Module specific Functions Declarations @@ -61,30 +63,39 @@ static void Vector2Normalize(Vector2 *vector); //---------------------------------------------------------------------------------- // Module Functions Definitions //---------------------------------------------------------------------------------- -void InitPhysics(void) -{ - for (int i = 0; i < MAX_ELEMENTS; i++) +void InitPhysics(int maxPhysicElements) +{ + maxElements = maxPhysicElements; + + colliders = (Collider *)malloc(maxElements*sizeof(Collider)); + rigidbodies = (Rigidbody *)malloc(maxElements*sizeof(Rigidbody)); + + for (int i = 0; i < maxElements; i++) { + colliders[i].enabled = false; + colliders[i].bounds = (Rectangle){ 0, 0, 0, 0 }; + colliders[i].radius = 0; + rigidbodies[i].enabled = false; rigidbodies[i].mass = 0.0f; - rigidbodies[i].velocity = (Vector2){0, 0}; - rigidbodies[i].acceleration = (Vector2){0, 0}; + rigidbodies[i].velocity = (Vector2){ 0.0f, 0.0f }; + rigidbodies[i].acceleration = (Vector2){ 0.0f, 0.0f }; rigidbodies[i].isGrounded = false; rigidbodies[i].isContact = false; rigidbodies[i].friction = 0.0f; - - colliders[i].enabled = false; - colliders[i].bounds = (Rectangle){0, 0, 0, 0}; - colliders[i].radius = 0; } + + collisionChecker = false; + enabled = true; + + // NOTE: To get better results, gravity needs to be 1:10 from original parameter + gravity = (Vector2){ 0.0f, -9.81f/10.0f }; // By default, standard gravity } -void SetPhysics(Physics settings) +void UnloadPhysics() { - physics = settings; - - // To get good results, gravity needs to be 1:10 from original parameter - physics.gravity = (Vector2){physics.gravity.x / 10, physics.gravity.y / 10}; + free(colliders); + free(rigidbodies); } void AddCollider(int index, Collider collider) @@ -159,8 +170,8 @@ void ApplyPhysics(int index, Vector2 *position) } // Apply gravity - rigidbodies[index].velocity.y += physics.gravity.y; - rigidbodies[index].velocity.x += physics.gravity.x; + rigidbodies[index].velocity.y += gravity.y; + rigidbodies[index].velocity.x += gravity.x; // Apply acceleration rigidbodies[index].velocity.y += rigidbodies[index].acceleration.y; @@ -177,7 +188,7 @@ void ApplyPhysics(int index, Vector2 *position) // Check collision with other colliders collisionChecker = false; rigidbodies[index].isContact = false; - for (int j = 0; j < MAX_ELEMENTS; j++) + for (int j = 0; j < maxElements; j++) { if (index != j) { @@ -269,7 +280,7 @@ void AddRigidbodyForce(int index, Vector2 force) void AddForceAtPosition(Vector2 position, float intensity, float radius) { - for(int i = 0; i < MAX_ELEMENTS; i++) + for(int i = 0; i < maxElements; i++) { if(rigidbodies[i].enabled) { diff --git a/src/physac.h b/src/physac.h index 12209987..9e1b0b88 100644 --- a/src/physac.h +++ b/src/physac.h @@ -35,13 +35,6 @@ // Collider types typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType; -// Physics struct -typedef struct Physics { - bool enabled; - bool debug; // Should be used by programmer for testing purposes - Vector2 gravity; -} Physics; - // Transform struct typedef struct Transform { Vector2 position; @@ -77,8 +70,8 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- // Module Functions Declarations //---------------------------------------------------------------------------------- -void InitPhysics(void); // Initialize all internal physics values -void SetPhysics(Physics settings); // Set physics settings values using Physics data type to overwrite internal physics settings +void InitPhysics(int maxPhysicElements); // Initialize all internal physics values +void UnloadPhysics(); // Unload physic elements arrays void AddRigidbody(int index, Rigidbody rigidbody); // Initialize a new rigidbody with parameters to internal index slot void AddCollider(int index, Collider collider); // Initialize a new Collider with parameters to internal index slot diff --git a/src/raylib.h b/src/raylib.h index c2067a0e..43819b14 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -466,13 +466,6 @@ typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERS // Collider types typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType; -// Physics struct -typedef struct Physics { - bool enabled; - bool debug; // Should be used by programmer for testing purposes - Vector2 gravity; -} Physics; - // Transform struct typedef struct Transform { Vector2 position; @@ -808,10 +801,10 @@ void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textur void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied) //---------------------------------------------------------------------------------- -// Physics System Functions (engine-module: physics) +// Physics System Functions (engine-module: physac) //---------------------------------------------------------------------------------- -void InitPhysics(void); // Initialize all internal physics values -void SetPhysics(Physics settings); // Set physics settings values using Physics data type to overwrite internal physics settings +void InitPhysics(int maxPhysicElements); // Initialize all internal physics values +void UnloadPhysics(); // Unload physic elements arrays void AddRigidbody(int index, Rigidbody rigidbody); // Initialize a new rigidbody with parameters to internal index slot void AddCollider(int index, Collider collider); // Initialize a new Collider with parameters to internal index slot -- cgit v1.2.3 From 0018522031b8b06c447d49273bf288ec5e7a8a63 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 13 Feb 2016 19:14:22 +0100 Subject: Updated show-logo and start reviewing RPI inputs --- examples/shapes_logo_raylib_anim.c | 30 ++++++------------------------ src/core.c | 32 ++++++++++---------------------- src/raylib.h | 2 +- 3 files changed, 17 insertions(+), 47 deletions(-) (limited to 'src/raylib.h') diff --git a/examples/shapes_logo_raylib_anim.c b/examples/shapes_logo_raylib_anim.c index b1bdc3a8..c6d3796e 100644 --- a/examples/shapes_logo_raylib_anim.c +++ b/examples/shapes_logo_raylib_anim.c @@ -2,7 +2,7 @@ * * raylib [shapes] example - raylib logo animation * -* This example has been created using raylib 1.1 (www.raylib.com) +* This example has been created using raylib 1.4 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * * Copyright (c) 2014 Ramon Santamaria (@raysan5) @@ -32,8 +32,6 @@ int main() int bottomSideRecWidth = 16; int rightSideRecHeight = 16; - char raylib[8] = " \0"; // raylib text array, max 8 letters - int state = 0; // Tracking animation states (State Machine) float alpha = 1.0f; // Useful for fading @@ -79,24 +77,13 @@ int main() framesCounter = 0; } - switch (lettersCount) - { - case 1: raylib[0] = 'r'; break; - case 2: raylib[1] = 'a'; break; - case 3: raylib[2] = 'y'; break; - case 4: raylib[3] = 'l'; break; - case 5: raylib[4] = 'i'; break; - case 6: raylib[5] = 'b'; break; - default: break; - } - if (lettersCount >= 10) // When all letters have appeared, just fade out everything { - alpha -= 0.02; + alpha -= 0.02f; - if (alpha <= 0) + if (alpha <= 0.0f) { - alpha = 0; + alpha = 0.0f; state = 4; } } @@ -114,12 +101,7 @@ int main() bottomSideRecWidth = 16; rightSideRecHeight = 16; - for (int i = 0; i < 7; i++) raylib[i] = ' '; - - raylib[7] = '\0'; // Last character is end-of-line - - alpha = 1.0; - + alpha = 1.0f; state = 0; // Return to State 0 } } @@ -158,7 +140,7 @@ int main() DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha)); - DrawText(raylib, screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha)); + DrawText(SubText("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha)); } else if (state == 4) { diff --git a/src/core.c b/src/core.c index 7ecedee0..0c85ab26 100644 --- a/src/core.c +++ b/src/core.c @@ -151,7 +151,7 @@ pthread_t mouseThreadId; // Mouse reading thread id static int defaultKeyboardMode; // Used to store default keyboard mode static struct termios defaultKeyboardSettings; // Used to staore default keyboard settings -static int keyboardMode = 0; // Keyboard mode: 1 (KEYCODES), 2 (ASCII) +static int keyboardMode = 0; // Keyboard mode: 1 - KEYCODES, 2 - ASCII // This array maps Unix keycodes to ASCII equivalent and to GLFW3 equivalent for special function keys (>256) const short UnixKeycodeToASCII[128] = { 256, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 259, 9, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 91, 93, 257, 341, 65, 83, 68, @@ -1128,7 +1128,7 @@ bool IsCursorHidden() { return cursorHidden; } -#endif +#endif //defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) // TODO: Enable gamepad usage on Rapsberry Pi // NOTE: emscripten not implemented @@ -2077,7 +2077,7 @@ static bool GetMouseButtonStatus(int button) // TODO: Check for virtual keyboard return false; #elif defined(PLATFORM_RPI) - // NOTE: mouse buttons array is filled on PollInputEvents() + // NOTE: Mouse buttons states are filled in PollInputEvents() return currentMouseState[button]; #endif } @@ -2099,8 +2099,7 @@ static void PollInputEvents(void) mousePosition.x = (float)mouseX; mousePosition.y = (float)mouseY; - // Keyboard polling - // Automatically managed by GLFW3 through callback + // Keyboard input polling (automatically managed by GLFW3 through callback) lastKeyPressed = -1; // Register previous keys states @@ -2157,7 +2156,7 @@ static void PollInputEvents(void) int key = keysBuffer[i]; - if (keyboardMode == 2) // scancodes + if (keyboardMode == 2) // ASCII chars (K_XLATE mode) { // NOTE: If (key == 0x1b), depending on next key, it could be a special keymap code! // Up -> 1b 5b 41 / Left -> 1b 5b 44 / Right -> 1b 5b 43 / Down -> 1b 5b 42 @@ -2215,8 +2214,7 @@ static void PollInputEvents(void) if (key == 0x01) windowShouldClose = true; } - - // Same fucnionality as GLFW3 KeyCallback() + // Same functionality as GLFW3 KeyCallback() /* if (asciiKey == exitKey) windowShouldClose = true; else if (key == GLFW_KEY_F12 && action == GLFW_PRESS) @@ -2356,7 +2354,7 @@ static void InitKeyboard(void) // Set new keyboard settings (change occurs immediately) tcsetattr(STDIN_FILENO, TCSANOW, &keyboardNewSettings); - // NOTE: Reading directly from stdin will give chars already key-mapped by kernel to ASCII or UNICODE, we change that! + // NOTE: Reading directly from stdin will give chars already key-mapped by kernel to ASCII or UNICODE, we change that! -> WHY??? // Save old keyboard mode to restore it at the end if (ioctl(STDIN_FILENO, KDGKBMODE, &defaultKeyboardMode) < 0) @@ -2374,6 +2372,8 @@ static void InitKeyboard(void) // - ASCII chars (K_XLATE) // - UNICODE chars (K_UNICODE) ioctl(STDIN_FILENO, KDSKBMODE, K_MEDIUMRAW); + + //http://lct.sourceforge.net/lct/x60.html keyboardMode = 1; // keycodes } @@ -2587,7 +2587,6 @@ static void LogoAnimation(void) int bottomSideRecWidth = 16; int rightSideRecHeight = 16; - char raylib[8] = " "; // raylib text array, max 8 letters int state = 0; // Tracking animation states (State Machine) float alpha = 1.0f; // Useful for fading @@ -2629,17 +2628,6 @@ static void LogoAnimation(void) framesCounter = 0; } - switch (lettersCount) - { - case 1: raylib[0] = 'r'; break; - case 2: raylib[1] = 'a'; break; - case 3: raylib[2] = 'y'; break; - case 4: raylib[3] = 'l'; break; - case 5: raylib[4] = 'i'; break; - case 6: raylib[5] = 'b'; break; - default: break; - } - if (lettersCount >= 10) // When all letters have appeared, just fade out everything { alpha -= 0.02f; @@ -2686,7 +2674,7 @@ static void LogoAnimation(void) DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha)); - DrawText(raylib, screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha)); + DrawText(SubText("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha)); } EndDrawing(); diff --git a/src/raylib.h b/src/raylib.h index 43819b14..f5a3cc31 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -118,7 +118,7 @@ #define KEY_RIGHT_CONTROL 345 #define KEY_RIGHT_ALT 346 -// Keyboard Alhpa Numeric Keys +// Keyboard Alpha Numeric Keys #define KEY_ZERO 48 #define KEY_ONE 49 #define KEY_TWO 50 -- 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/raylib.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 From 8aab52aeda47ce283d1446be27a7e2e20f027434 Mon Sep 17 00:00:00 2001 From: Ray San Date: Thu, 18 Feb 2016 14:05:48 +0100 Subject: Redesigned RPI input system -IN PROGRESS- --- examples/core_input_mouse.c | 14 +- examples/makefile | 10 +- src/core.c | 421 +++++++++++++++++++++++++++----------------- src/makefile | 8 +- src/raylib.h | 2 - 5 files changed, 279 insertions(+), 176 deletions(-) (limited to 'src/raylib.h') diff --git a/examples/core_input_mouse.c b/examples/core_input_mouse.c index 358b5fd6..24d2dfcd 100644 --- a/examples/core_input_mouse.c +++ b/examples/core_input_mouse.c @@ -21,6 +21,7 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [core] example - mouse input"); Vector2 ballPosition = { -100.0f, -100.0f }; + Color ballColor = DARKBLUE; SetTargetFPS(60); //--------------------------------------------------------------------------------------- @@ -30,10 +31,11 @@ int main() { // Update //---------------------------------------------------------------------------------- - if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) - { - ballPosition = GetMousePosition(); - } + ballPosition = GetMousePosition(); + + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) ballColor = MAROON; + else if (IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) ballColor = LIME; + else if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) ballColor = DARKBLUE; //---------------------------------------------------------------------------------- // Draw @@ -42,9 +44,9 @@ int main() ClearBackground(RAYWHITE); - DrawCircleV(ballPosition, 40, GOLD); + DrawCircleV(ballPosition, 40, ballColor); - DrawText("mouse click to draw the ball", 10, 10, 20, DARKGRAY); + DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/makefile b/examples/makefile index 62428155..2a9e88ba 100644 --- a/examples/makefile +++ b/examples/makefile @@ -227,10 +227,10 @@ core_mouse_wheel: core_mouse_wheel.c # compile [core] example - gamepad input core_input_gamepad: core_input_gamepad.c -ifeq ($(PLATFORM),PLATFORM_DESKTOP) +ifeq ($(PLATFORM), $(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_RPI)) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) else - @echo core_input_gamepad: Only supported on desktop platform + @echo core_input_gamepad: Example not supported on PLATFORM_ANDROID or PLATFORM_WEB endif # compile [core] example - generate random values @@ -246,15 +246,15 @@ core_drop_files: core_drop_files.c ifeq ($(PLATFORM),PLATFORM_DESKTOP) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) else - @echo core_drop_files: Only supported on desktop platform + @echo core_drop_files: Example not supported on PLATFORM_ANDROID or PLATFORM_WEB or PLATFORM_RPI endif # compile [core] example - storage values core_storage_values: core_storage_values.c -ifeq ($(PLATFORM),PLATFORM_DESKTOP) +ifeq ($(PLATFORM), $(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_RPI)) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) else - @echo core_storage_values: Only supported on desktop platform + @echo core_storage_values: Example not supported on PLATFORM_ANDROID or PLATFORM_WEB endif # compile [core] example - gestures detection diff --git a/src/core.c b/src/core.c index 7b981097..c7d93355 100644 --- a/src/core.c +++ b/src/core.c @@ -102,11 +102,16 @@ #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions #include "EGL/eglext.h" // Khronos EGL library - Extensions #include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library + + // Old device inputs system + #define DEFAULT_KEYBOARD_DEV STDIN_FILENO // Standard input + #define DEFAULT_MOUSE_DEV "/dev/input/mouse0" + #define DEFAULT_GAMEPAD_DEV "/dev/input/js0" - #define DEFAULT_KEYBOARD_DEV "/dev/input/event0" // Not used, keyboard inputs are read raw from stdin - #define DEFAULT_MOUSE_DEV "/dev/input/event1" - //#define DEFAULT_MOUSE_DEV "/dev/input/mouse0" - #define DEFAULT_GAMEPAD_DEV "/dev/input/js0" + // New device input events (evdev) (must be detected) + //#define DEFAULT_KEYBOARD_DEV "/dev/input/eventN" + //#define DEFAULT_MOUSE_DEV "/dev/input/eventN" + //#define DEFAULT_GAMEPAD_DEV "/dev/input/eventN" #endif #if defined(PLATFORM_WEB) @@ -142,16 +147,11 @@ static int currentButtonState[128] = { 1 }; // Required to check if button p #elif defined(PLATFORM_RPI) static EGL_DISPMANX_WINDOW_T nativeWindow; // Native window (graphic device) -// Input variables (mouse/keyboard) -static int mouseStream = -1; // Mouse device file descriptor -static bool mouseReady = false; // Flag to know if mouse is ready -pthread_t mouseThreadId; // Mouse reading thread id - +// Keyboard input variables // NOTE: For keyboard we will use the standard input (but reconfigured...) +static struct termios defaultKeyboardSettings; // Used to store default keyboard settings static int defaultKeyboardMode; // Used to store default keyboard mode -static struct termios defaultKeyboardSettings; // Used to staore default keyboard settings - -static int keyboardMode = 0; // Keyboard mode: 1 - KEYCODES, 2 - ASCII +static int keyboardMode = 0; // Register Keyboard mode: 1 - KEYCODES, 2 - ASCII // This array maps Unix keycodes to ASCII equivalent and to GLFW3 equivalent for special function keys (>256) const short UnixKeycodeToASCII[128] = { 256, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 259, 9, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 91, 93, 257, 341, 65, 83, 68, @@ -159,7 +159,15 @@ const short UnixKeycodeToASCII[128] = { 256, 49, 50, 51, 52, 53, 54, 55, 56, 57, 297, 298, 299, -1, -1, -1, -1, -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 257, 345, 47, -1, 346, -1, -1, 265, -1, 263, 262, -1, 264, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; +// Mouse input variables +static int mouseStream = -1; // Mouse device file descriptor +static bool mouseReady = false; // Flag to know if mouse is ready +pthread_t mouseThreadId; // Mouse reading thread id + +// Gamepad input variables static int gamepadStream = -1; // Gamepad device file descriptor +static bool gamepadReady = false; // Flag to know if gamepad is ready +pthread_t gamepadThreadId; // Gamepad reading thread id #endif #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) @@ -244,11 +252,13 @@ static void LogoAnimation(void); // Plays raylib logo app static void SetupFramebufferSize(int displayWidth, int displayHeight); #if defined(PLATFORM_RPI) -static void InitMouse(void); // Mouse initialization (including mouse thread) -static void *MouseThread(void *arg); // Mouse reading thread static void InitKeyboard(void); // Init raw keyboard system (standard input reading) +static void ProcessKeyboard(void); // Process keyboard events static void RestoreKeyboard(void); // Restore keyboard system +static void InitMouse(void); // Mouse initialization (including mouse thread) +static void *MouseThread(void *arg); // Mouse reading thread static void InitGamepad(void); // Init raw gamepad input +static void *GamepadThread(void *arg); // Mouse reading thread #endif #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) @@ -1128,18 +1138,21 @@ bool IsCursorHidden() { return cursorHidden; } -#endif //defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) -// TODO: Enable gamepad usage on Rapsberry Pi -// NOTE: emscripten not implemented -#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) +// NOTE: Gamepad support not implemented in emscripten GLFW3 (PLATFORM_WEB) + // Detect if a gamepad is available bool IsGamepadAvailable(int gamepad) { - int result = glfwJoystickPresent(gamepad); + bool result = false; + +#if defined(PLATFORM_RPI) + if (gamepadReady && (gamepad == 0)) result = true; +#else + if (glfwJoystickPresent(gamepad) == 1) result = true; +#endif - if (result == 1) return true; - else return false; + return result; } // Return axis movement vector for a gamepad @@ -1148,10 +1161,14 @@ Vector2 GetGamepadMovement(int gamepad) Vector2 vec = { 0, 0 }; const float *axes; - int axisCount; - + int axisCount = 0; + +#if defined(PLATFORM_RPI) + // TODO: Get gamepad axis information +#else axes = glfwGetJoystickAxes(gamepad, &axisCount); - +#endif + if (axisCount >= 2) { vec.x = axes[0]; // Left joystick X @@ -1184,16 +1201,20 @@ bool IsGamepadButtonPressed(int gamepad, int button) // Detect if a gamepad button is being pressed bool IsGamepadButtonDown(int gamepad, int button) { + bool result = false; const unsigned char *buttons; int buttonsCount; - + +#if defined(PLATFORM_RPI) + // TODO: Get gamepad buttons information +#else buttons = glfwGetJoystickButtons(gamepad, &buttonsCount); - if ((buttons != NULL) && (buttons[button] == GLFW_PRESS)) - { - return true; - } - else return false; + if ((buttons != NULL) && (buttons[button] == GLFW_PRESS)) result = true; + else result = false; +#endif + + return result; } // Detect if a gamepad button has NOT been pressed once @@ -1216,19 +1237,23 @@ bool IsGamepadButtonReleased(int gamepad, int button) // Detect if a mouse button is NOT being pressed bool IsGamepadButtonUp(int gamepad, int button) { + bool result = false; const unsigned char *buttons; int buttonsCount; +#if defined(PLATFORM_RPI) + // TODO: Get gamepad buttons information +#else buttons = glfwGetJoystickButtons(gamepad, &buttonsCount); - if ((buttons != NULL) && (buttons[button] == GLFW_RELEASE)) - { - return true; - } - else return false; -} + if ((buttons != NULL) && (buttons[button] == GLFW_RELEASE)) result = true; + else result = false; #endif + return result; +} +#endif //defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) + // Returns touch position X int GetTouchX(void) { @@ -2157,7 +2182,68 @@ static void PollInputEvents(void) // NOTE: Keyboard reading could be done using input_event(s) reading or just read from stdin, // we use method 2 (stdin) but maybe in a future we should change to method 1... + ProcessKeyboard(); + + // NOTE: Gamepad (Joystick) input events polling is done asynchonously in another pthread - GamepadThread() + +#endif +} +#if defined(PLATFORM_RPI) +// Initialize Keyboard system (using standard input) +static void InitKeyboard(void) +{ + // NOTE: We read directly from Standard Input (stdin) - STDIN_FILENO file descriptor + + // Make stdin non-blocking (not enough, need to configure to non-canonical mode) + int flags = fcntl(STDIN_FILENO, F_GETFL, 0); // F_GETFL: Get the file access mode and the file status flags + fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK); // F_SETFL: Set the file status flags to the value specified + + // Save terminal keyboard settings and reconfigure terminal with new settings + struct termios keyboardNewSettings; + tcgetattr(STDIN_FILENO, &defaultKeyboardSettings); // Get current keyboard settings + keyboardNewSettings = defaultKeyboardSettings; + + // New terminal settings for keyboard: turn off buffering (non-canonical mode), echo and key processing + // NOTE: ISIG controls if ^C and ^Z generate break signals or not + keyboardNewSettings.c_lflag &= ~(ICANON | ECHO | ISIG); + //keyboardNewSettings.c_iflag &= ~(ISTRIP | INLCR | ICRNL | IGNCR | IXON | IXOFF); + keyboardNewSettings.c_cc[VMIN] = 1; + keyboardNewSettings.c_cc[VTIME] = 0; + + // Set new keyboard settings (change occurs immediately) + tcsetattr(STDIN_FILENO, TCSANOW, &keyboardNewSettings); + + // NOTE: Reading directly from stdin will give chars already key-mapped by kernel to ASCII or UNICODE, we change that! -> WHY??? + + // Save old keyboard mode to restore it at the end + if (ioctl(STDIN_FILENO, KDGKBMODE, &defaultKeyboardMode) < 0) + { + // NOTE: It could mean we are using a remote keyboard through ssh! + TraceLog(WARNING, "Could not change keyboard mode (SSH keyboard?)"); + + keyboardMode = 2; // ASCII + } + else + { + // We reconfigure keyboard mode to get: + // - scancodes (K_RAW) + // - keycodes (K_MEDIUMRAW) + // - ASCII chars (K_XLATE) + // - UNICODE chars (K_UNICODE) + ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE); + + //http://lct.sourceforge.net/lct/x60.html + + keyboardMode = 2; // keycodes + } + + // Register keyboard restore when program finishes + atexit(RestoreKeyboard); +} + +static void ProcessKeyboard(void) +{ // Keyboard input polling (fill keys[256] array with status) int numKeysBuffer = 0; // Keys available on buffer char keysBuffer[32]; // Max keys to be read at a time @@ -2242,45 +2328,18 @@ static void PollInputEvents(void) } */ } +} - // TODO: Gamepad support (use events, easy!) -/* - struct js_event gamepadEvent; - - read(gamepadStream, &gamepadEvent, sizeof(struct js_event)); - - if (gamepadEvent.type == JS_EVENT_BUTTON) - { - switch (gamepadEvent.number) - { - case 0: // 1st Axis X - case 1: // 1st Axis Y - case 2: // 2st Axis X - case 3: // 2st Axis Y - case 4: - { - if (gamepadEvent.value == 1) // Button pressed, 0 release - - } break; - // Buttons is similar, variable for every joystick - } - } - else if (gamepadEvent.type == JS_EVENT_AXIS) - { - switch (gamepadEvent.number) - { - case 0: // 1st Axis X - case 1: // 1st Axis Y - case 2: // 2st Axis X - case 3: // 2st Axis Y - // Buttons is similar, variable for every joystick - } - } -*/ -#endif +// Restore default keyboard input +static void RestoreKeyboard(void) +{ + // Reset to default keyboard settings + tcsetattr(STDIN_FILENO, TCSANOW, &defaultKeyboardSettings); + + // Reconfigure keyboard to default mode + ioctl(STDIN_FILENO, KDSKBMODE, defaultKeyboardMode); } -#if defined(PLATFORM_RPI) // Mouse initialization (including mouse thread) static void InitMouse(void) { @@ -2305,118 +2364,156 @@ static void InitMouse(void) // if too much time passes between reads, queue gets full and new events override older ones... static void *MouseThread(void *arg) { - struct input_event mouseEvent; + const unsigned char XSIGN = 1<<4, YSIGN = 1<<5; + + typedef struct { + char buttons; + char dx, dy; + } MouseEvent; + + MouseEvent mouse; + + int mouseRelX = 0; + int mouseRelY = 0; while(1) { - // NOTE: read() will return -1 if the events queue is empty - read(mouseStream, &mouseEvent, sizeof(struct input_event)); - - // Check event types - if (mouseEvent.type == EV_REL) // Relative motion event + if (read(mouseStream, &mouse, sizeof(MouseEvent)) == (int)sizeof(MouseEvent)) { - if (mouseEvent.code == REL_X) - { - mousePosition.x += (float)mouseEvent.value; - - // Screen limits X check - if (mousePosition.x < 0) mousePosition.x = 0; - if (mousePosition.x > screenWidth) mousePosition.x = screenWidth; - } - - if (mouseEvent.code == REL_Y) - { - mousePosition.y += (float)mouseEvent.value; - - // Screen limits Y check - if (mousePosition.y < 0) mousePosition.y = 0; - if (mousePosition.y > screenHeight) mousePosition.y = screenHeight; - } + if ((mouse.buttons & 0x08) == 0) break; // This bit should always be set + + // Check Left button pressed + if ((mouse.buttons & 0x01) > 0) currentMouseState[0] = 1; + else currentMouseState[0] = 0; - if (mouseEvent.code == REL_WHEEL) - { - // mouseEvent.value give 1 or -1 (direction) - } - } - else if (mouseEvent.type == EV_KEY) // Mouse button event - { - if (mouseEvent.code == BTN_LEFT) currentMouseState[0] = mouseEvent.value; - if (mouseEvent.code == BTN_RIGHT) currentMouseState[1] = mouseEvent.value; - if (mouseEvent.code == BTN_MIDDLE) currentMouseState[2] = mouseEvent.value; - } + // Check Right button pressed + if ((mouse.buttons & 0x02) > 0) currentMouseState[1] = 1; + else currentMouseState[1] = 0; + + // Check Middle button pressed + if ((mouse.buttons & 0x04) > 0) currentMouseState[2] = 1; + else currentMouseState[2] = 0; + + mouseRelX = (int)mouse.dx; + mouseRelY = (int)mouse.dy; + + if ((mouse.buttons & XSIGN) > 0) mouseRelX = -1*(255 - mouseRelX); + if ((mouse.buttons & YSIGN) > 0) mouseRelY = -1*(255 - mouseRelY); + + mousePosition.x += (float)mouseRelX; + mousePosition.y -= (float)mouseRelY; + + if (mousePosition.x < 0) mousePosition.x = 0; + if (mousePosition.y < 0) mousePosition.y = 0; + + if (mousePosition.x > screenWidth) mousePosition.x = screenWidth; + if (mousePosition.y > screenHeight) mousePosition.y = screenHeight; + } + //else read(mouseStream, &mouse, 1); // Try to sync up again } return NULL; } -// Initialize Keyboard system (using standard input) -static void InitKeyboard(void) +// Init gamepad system +static void InitGamepad(void) { - // NOTE: We read directly from Standard Input (stdin) - STDIN_FILENO file descriptor - - // Make stdin non-blocking (not enough, need to configure to non-canonical mode) - int flags = fcntl(STDIN_FILENO, F_GETFL, 0); // F_GETFL: Get the file access mode and the file status flags - fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK); // F_SETFL: Set the file status flags to the value specified - - // Save terminal keyboard settings and reconfigure terminal with new settings - struct termios keyboardNewSettings; - tcgetattr(STDIN_FILENO, &defaultKeyboardSettings); // Get current keyboard settings - keyboardNewSettings = defaultKeyboardSettings; - - // New terminal settings for keyboard: turn off buffering (non-canonical mode), echo and key processing - // NOTE: ISIG controls if ^C and ^Z generate break signals or not - keyboardNewSettings.c_lflag &= ~(ICANON | ECHO | ISIG); - //keyboardNewSettings.c_iflag &= ~(ISTRIP | INLCR | ICRNL | IGNCR | IXON | IXOFF); - keyboardNewSettings.c_cc[VMIN] = 1; - keyboardNewSettings.c_cc[VTIME] = 0; - - // Set new keyboard settings (change occurs immediately) - tcsetattr(STDIN_FILENO, TCSANOW, &keyboardNewSettings); - - // NOTE: Reading directly from stdin will give chars already key-mapped by kernel to ASCII or UNICODE, we change that! -> WHY??? - - // Save old keyboard mode to restore it at the end - if (ioctl(STDIN_FILENO, KDGKBMODE, &defaultKeyboardMode) < 0) + if ((gamepadStream = open(DEFAULT_GAMEPAD_DEV, O_RDONLY|O_NONBLOCK)) < 0) { - // NOTE: It could mean we are using a remote keyboard through ssh! - TraceLog(WARNING, "Could not change keyboard mode (SSH keyboard?)"); - - keyboardMode = 2; // ASCII + TraceLog(WARNING, "Gamepad device could not be opened, no gamepad available"); } else { - // We reconfigure keyboard mode to get: - // - scancodes (K_RAW) - // - keycodes (K_MEDIUMRAW) - // - ASCII chars (K_XLATE) - // - UNICODE chars (K_UNICODE) - ioctl(STDIN_FILENO, KDSKBMODE, K_MEDIUMRAW); - - //http://lct.sourceforge.net/lct/x60.html + gamepadReady = true; - keyboardMode = 1; // keycodes - } + int error = pthread_create(&gamepadThreadId, NULL, &GamepadThread, NULL); - // Register keyboard restore when program finishes - atexit(RestoreKeyboard); + if (error != 0) TraceLog(WARNING, "Error creating gamepad input event thread"); + else TraceLog(INFO, "Gamepad device initialized successfully"); + } } -// Restore default keyboard input -static void RestoreKeyboard(void) +// Process Gamepad (/dev/input/js0) +static void *GamepadThread(void *arg) { - // Reset to default keyboard settings - tcsetattr(STDIN_FILENO, TCSANOW, &defaultKeyboardSettings); + #define JS_EVENT_BUTTON 0x01 // Button pressed/released + #define JS_EVENT_AXIS 0x02 // Joystick axis moved + #define JS_EVENT_INIT 0x80 // Initial state of device + + struct js_event { + unsigned int time; // event timestamp in milliseconds + short value; // event value + unsigned char type; // event type + unsigned char number; // event axis/button number + }; + + // These values are sensible on Logitech Dual Action Rumble and Xbox360 controller + const int joystickAxisX = 0; + const int joystickAxisY = 1; + + // Read gamepad event + struct js_event gamepadEvent; + int bytes; - // Reconfigure keyboard to default mode - ioctl(STDIN_FILENO, KDSKBMODE, defaultKeyboardMode); -} + int buttons[11]; + int stickX; + int stickY; + + while (1) + { + if (read(gamepadStream, &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event)) + { + gamepadEvent.type &= ~JS_EVENT_INIT; // Ignore synthetic events + + // Process gamepad events by type + if (gamepadEvent.type == JS_EVENT_BUTTON) + { + if (gamepadEvent.number < 11) + { + switch (gamepadEvent.value) + { + case 0: + case 1: buttons[gamepadEvent.number] = gamepadEvent.value; break; + default: break; + } + } + /* + switch (gamepadEvent.number) + { + case 0: // 1st Axis X + case 1: // 1st Axis Y + case 2: // 2st Axis X + case 3: // 2st Axis Y + case 4: + { + if (gamepadEvent.value == 1) // Button pressed, 0 release + { + + } -// Init gamepad system -static void InitGamepad(void) -{ - // TODO: Add Gamepad support - if ((gamepadStream = open(DEFAULT_GAMEPAD_DEV, O_RDONLY|O_NONBLOCK)) < 0) TraceLog(WARNING, "Gamepad device could not be opened, no gamepad available"); - else TraceLog(INFO, "Gamepad device initialized successfully"); + } break; + // Buttons is similar, variable for every joystick + } + */ + } + else if (gamepadEvent.type == JS_EVENT_AXIS) + { + if (gamepadEvent.number == joystickAxisX) stickX = gamepadEvent.value; + if (gamepadEvent.number == joystickAxisY) stickY = gamepadEvent.value; + /* + switch (gamepadEvent.number) + { + case 0: // 1st Axis X + case 1: // 1st Axis Y + case 2: // 2st Axis X + case 3: // 2st Axis Y + // Buttons is similar, variable for every joystick + } + */ + } + } + else read(gamepadStream, &gamepadEvent, 1); // Try to sync up again + } } #endif diff --git a/src/makefile b/src/makefile index 4f65c440..2d73e646 100644 --- a/src/makefile +++ b/src/makefile @@ -91,7 +91,13 @@ else endif # define all object files required -OBJS = core.o rlgl.o glad.o shapes.o text.o textures.o models.o audio.o utils.o camera.o gestures.o stb_vorbis.o +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + OBJS = core.o rlgl.o glad.o shapes.o text.o textures.o models.o audio.o utils.o camera.o gestures.o stb_vorbis.o +else + #GLAD only required on desktop platform + OBJS = core.o rlgl.o shapes.o text.o textures.o models.o audio.o stb_vorbis.o utils.o camera.o gestures.o +endif + # typing 'make' will invoke the first target entry in the file, # in this case, the 'default' target entry is raylib diff --git a/src/raylib.h b/src/raylib.h index def56ee2..0dc8c6df 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -583,9 +583,7 @@ void HideCursor(void); // Hides cursor void EnableCursor(void); // Enables cursor void DisableCursor(void); // Disables cursor bool IsCursorHidden(void); // Returns true if cursor is not visible -#endif -#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available Vector2 GetGamepadMovement(int gamepad); // Return axis movement vector for a gamepad bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once -- cgit v1.2.3 From 98c60838fed28958519144840a21f012995d6799 Mon Sep 17 00:00:00 2001 From: Ray San Date: Fri, 19 Feb 2016 19:57:25 +0100 Subject: Reviewed RPI inputs --- src/core.c | 206 ++++++++++++++++++++++++++++------------------------------- src/raylib.h | 2 + 2 files changed, 98 insertions(+), 110 deletions(-) (limited to 'src/raylib.h') diff --git a/src/core.c b/src/core.c index 3bd36d08..dbcfa6bc 100644 --- a/src/core.c +++ b/src/core.c @@ -125,7 +125,7 @@ //#define DEFAULT_MOUSE_DEV "/dev/input/eventN" //#define DEFAULT_GAMEPAD_DEV "/dev/input/eventN" - #define MOUSE_SENSITIVITY 1.0f + #define MOUSE_SENSITIVITY 0.8f #define MAX_GAMEPAD_BUTTONS 11 #endif @@ -156,13 +156,6 @@ static EGL_DISPMANX_WINDOW_T nativeWindow; // Native window (graphic device // NOTE: For keyboard we will use the standard input (but reconfigured...) static struct termios defaultKeyboardSettings; // Used to store default keyboard settings static int defaultKeyboardMode; // Used to store default keyboard mode -static int keyboardMode = 0; // Register Keyboard mode: 1 - KEYCODES, 2 - ASCII - -// This array maps Unix keycodes to ASCII equivalent and to GLFW3 equivalent for special function keys (>256) -const short UnixKeycodeToASCII[128] = { 256, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 259, 9, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 91, 93, 257, 341, 65, 83, 68, - 70, 71, 72, 74, 75, 76, 59, 39, 96, 340, 92, 90, 88, 67, 86, 66, 78, 77, 44, 46, 47, 344, -1, 342, 32, -1, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, -1, -1, -1, -1, -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 257, 345, 47, -1, - 346, -1, -1, 265, -1, 263, 262, -1, 264, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; // Mouse input variables static int mouseStream = -1; // Mouse device file descriptor @@ -227,7 +220,9 @@ static int exitKey = KEY_ESCAPE; // Default exit key (ESC) static int lastKeyPressed = -1; // Register last key pressed static bool cursorHidden; // Track if cursor is hidden +#endif +#if defined(PLATFORM_DESKTOP) static char **dropFilesPath; // Store dropped files paths as strings static int dropFilesCount = 0; // Count stored strings #endif @@ -781,7 +776,7 @@ void ShowLogo(void) showLogo = true; } -#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) +#if defined(PLATFORM_DESKTOP) // Check if a file have been dropped into window bool IsFileDropped(void) { @@ -1212,14 +1207,15 @@ bool IsGamepadButtonPressed(int gamepad, int button) bool IsGamepadButtonDown(int gamepad, int button) { bool result = false; - const unsigned char *buttons; - int buttonsCount; #if defined(PLATFORM_RPI) // Get gamepad buttons information if ((gamepad == 0) && (gamepadButtons[button] == 1)) result = true; else result = false; #else + const unsigned char *buttons; + int buttonsCount; + buttons = glfwGetJoystickButtons(gamepad, &buttonsCount); if ((buttons != NULL) && (buttons[button] == GLFW_PRESS)) result = true; @@ -1250,14 +1246,15 @@ bool IsGamepadButtonReleased(int gamepad, int button) bool IsGamepadButtonUp(int gamepad, int button) { bool result = false; - const unsigned char *buttons; - int buttonsCount; #if defined(PLATFORM_RPI) // Get gamepad buttons information if ((gamepad == 0) && (gamepadButtons[button] == 0)) result = true; else result = false; #else + const unsigned char *buttons; + int buttonsCount; + buttons = glfwGetJoystickButtons(gamepad, &buttonsCount); if ((buttons != NULL) && (buttons[button] == GLFW_RELEASE)) result = true; @@ -2235,8 +2232,6 @@ static void InitKeyboard(void) { // NOTE: It could mean we are using a remote keyboard through ssh! TraceLog(WARNING, "Could not change keyboard mode (SSH keyboard?)"); - - keyboardMode = 2; // ASCII } else { @@ -2246,102 +2241,108 @@ static void InitKeyboard(void) // - ASCII chars (K_XLATE) // - UNICODE chars (K_UNICODE) ioctl(STDIN_FILENO, KDSKBMODE, K_XLATE); - - //http://lct.sourceforge.net/lct/x60.html - - keyboardMode = 2; // keycodes } // Register keyboard restore when program finishes atexit(RestoreKeyboard); } +// Process keyboard inputs +// TODO: Most probably input reading and processing should be in a separate thread static void ProcessKeyboard(void) { + #define MAX_KEYBUFFER_SIZE 32 // Max size in bytes to read + // Keyboard input polling (fill keys[256] array with status) - int numKeysBuffer = 0; // Keys available on buffer - char keysBuffer[32]; // Max keys to be read at a time + int bufferByteCount = 0; // Bytes available on the buffer + char keysBuffer[MAX_KEYBUFFER_SIZE]; // Max keys to be read at a time // Reset pressed keys array for (int i = 0; i < 512; i++) currentKeyState[i] = 0; // Read availables keycodes from stdin - numKeysBuffer = read(STDIN_FILENO, keysBuffer, 32); // POSIX system call + bufferByteCount = read(STDIN_FILENO, keysBuffer, MAX_KEYBUFFER_SIZE); // POSIX system call - // Fill array with pressed keys - for (int i = 0; i < numKeysBuffer; i++) + // Fill all read bytes (looking for keys) + for (int i = 0; i < bufferByteCount; i++) { - //TraceLog(INFO, "Bytes on keysBuffer: %i", numKeysBuffer); - - int key = keysBuffer[i]; + TraceLog(DEBUG, "Bytes on keysBuffer: %i", bufferByteCount); + + //printf("Key(s) bytes: "); + //for (int i = 0; i < bufferByteCount; i++) printf("0x%02x ", keysBuffer[i]); + //printf("\n"); - if (keyboardMode == 2) // ASCII chars (K_XLATE mode) + // NOTE: If (key == 0x1b), depending on next key, it could be a special keymap code! + // Up -> 1b 5b 41 / Left -> 1b 5b 44 / Right -> 1b 5b 43 / Down -> 1b 5b 42 + if (keysBuffer[i] == 0x1b) { - // NOTE: If (key == 0x1b), depending on next key, it could be a special keymap code! - // Up -> 1b 5b 41 / Left -> 1b 5b 44 / Right -> 1b 5b 43 / Down -> 1b 5b 42 - if (key == 0x1b) + // Detect ESC to stop program + if (bufferByteCount == 1) currentKeyState[256] = 1; // raylib key: KEY_ESCAPE + else { - if (keysBuffer[i+1] == 0x5b) // Special function key + if (keysBuffer[i + 1] == 0x5b) // Special function key { - switch (keysBuffer[i+2]) + if ((keysBuffer[i + 2] == 0x5b) || (keysBuffer[i + 2] == 0x31) || (keysBuffer[i + 2] == 0x32)) { - case 0x41: currentKeyState[265] = 1; break; - case 0x42: currentKeyState[264] = 1; break; - case 0x43: currentKeyState[262] = 1; break; - case 0x44: currentKeyState[263] = 1; break; - default: break; + // Process special function keys (F1 - F12) + switch (keysBuffer[i + 3]) + { + case 0x41: currentKeyState[290] = 1; break; // raylib KEY_F1 + case 0x42: currentKeyState[291] = 1; break; // raylib KEY_F2 + case 0x43: currentKeyState[292] = 1; break; // raylib KEY_F3 + case 0x44: currentKeyState[293] = 1; break; // raylib KEY_F4 + case 0x45: currentKeyState[294] = 1; break; // raylib KEY_F5 + case 0x37: currentKeyState[295] = 1; break; // raylib KEY_F6 + case 0x38: currentKeyState[296] = 1; break; // raylib KEY_F7 + case 0x39: currentKeyState[297] = 1; break; // raylib KEY_F8 + case 0x30: currentKeyState[298] = 1; break; // raylib KEY_F9 + case 0x31: currentKeyState[299] = 1; break; // raylib KEY_F10 + case 0x33: currentKeyState[300] = 1; break; // raylib KEY_F11 + case 0x34: currentKeyState[301] = 1; break; // raylib KEY_F12 + default: break; + } + + if (keysBuffer[i + 2] == 0x5b) i += 4; + else if ((keysBuffer[i + 2] == 0x31) || (keysBuffer[i + 2] == 0x32)) i += 5; } + else + { + switch (keysBuffer[i + 2]) + { + case 0x41: currentKeyState[265] = 1; break; // raylib KEY_UP + case 0x42: currentKeyState[264] = 1; break; // raylib KEY_DOWN + case 0x43: currentKeyState[262] = 1; break; // raylib KEY_RIGHT + case 0x44: currentKeyState[263] = 1; break; // raylib KEY_LEFT + default: break; + } - i += 2; // Jump to next key - - // NOTE: Other special function keys (F1, F2...) are not contempled for this keyboardMode... - // ...or they are just not directly keymapped (CTRL, ALT, SHIFT) + i += 3; // Jump to next key + } + + // NOTE: Some keys are not directly keymapped (CTRL, ALT, SHIFT) } } - else if (key == 0x0a) currentKeyState[257] = 1; // raylib KEY_ENTER (don't mix with KEY_*) - else if (key == 0x7f) currentKeyState[259] = 1; - else - { - TraceLog(DEBUG, "Pressed key (ASCII): 0x%02x", key); - - currentKeyState[key] = 1; - } - - // Detect ESC to stop program - if ((key == 0x1b) && (numKeysBuffer == 1)) windowShouldClose = true; } - else if (keyboardMode == 1) // keycodes (K_MEDIUMRAW mode) + else if (keysBuffer[i] == 0x0a) currentKeyState[257] = 1; // raylib KEY_ENTER (don't mix with KEY_*) + else if (keysBuffer[i] == 0x7f) currentKeyState[259] = 1; // raylib KEY_BACKSPACE + else { - TraceLog(DEBUG, "Pressed key (keycode): 0x%02x", key); - - // NOTE: Each key is 7-bits (high bit in the byte is 0 for down, 1 for up) + TraceLog(DEBUG, "Pressed key (ASCII): 0x%02x", keysBuffer[i]); - // TODO: Review (or rewrite) this code... not clear... replace by events! - - int asciiKey = -1; - - // Convert keycode to some recognized key (ASCII or GLFW3 equivalent) - if (key < 128) asciiKey = (int)UnixKeycodeToASCII[key]; - - // Record equivalent key state - if ((asciiKey >= 0) && (asciiKey < 512)) currentKeyState[asciiKey] = 1; - - // In case of letter, we also activate lower case version - if ((asciiKey >= 65) && (asciiKey <=90)) currentKeyState[asciiKey + 32] = 1; - - // Detect KEY_ESC to stop program - if (key == 0x01) windowShouldClose = true; - } - - // Same functionality as GLFW3 KeyCallback() - /* - if (asciiKey == exitKey) windowShouldClose = true; - else if (key == GLFW_KEY_F12 && action == GLFW_PRESS) - { - TakeScreenshot(); + // Translate lowercase a-z letters to A-Z + if ((keysBuffer[i] >= 97) && (keysBuffer[i] <= 122)) + { + currentKeyState[(int)keysBuffer[i] - 32] = 1; + } + else currentKeyState[(int)keysBuffer[i]] = 1; } - */ } + + // Check exit key (same functionality as GLFW3 KeyCallback()) + if (currentKeyState[exitKey] == 1) windowShouldClose = true; + + // Check screen capture key + if (currentKeyState[301] == 1) TakeScreenshot(); // raylib key: KEY_F12 (GLFW_KEY_F12) } // Restore default keyboard input @@ -2414,10 +2415,12 @@ static void *MouseThread(void *arg) if ((mouse.buttons & XSIGN) > 0) mouseRelX = -1*(255 - mouseRelX); if ((mouse.buttons & YSIGN) > 0) mouseRelY = -1*(255 - mouseRelY); - // TODO: Mouse movement should not depend on screenWidth and screenHeight, normalize! - - mousePosition.x += (float)mouseRelX/MOUSE_SENSITIVITY; - mousePosition.y -= (float)mouseRelY/MOUSE_SENSITIVITY; + // NOTE: Mouse movement is normalized to not be screen resolution dependant + // We suppose 2*255 (max relative movement) is equivalent to screenWidth (max pixels width) + // Result after normalization is multiplied by MOUSE_SENSITIVITY factor + + mousePosition.x += (float)mouseRelX*((float)screenWidth/(2*255))*MOUSE_SENSITIVITY; + mousePosition.y -= (float)mouseRelY*((float)screenHeight/(2*255))*MOUSE_SENSITIVITY; if (mousePosition.x < 0) mousePosition.x = 0; if (mousePosition.y < 0) mousePosition.y = 0; @@ -2479,36 +2482,18 @@ static void *GamepadThread(void *arg) // Process gamepad events by type if (gamepadEvent.type == JS_EVENT_BUTTON) { + TraceLog(DEBUG, "Gamepad button: %i, value: %i", gamepadEvent.number, gamepadEvent.value); + if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS) { - switch (gamepadEvent.value) - { - case 0: - case 1: gamepadButtons[gamepadEvent.number] = (int)gamepadEvent.value; break; - default: break; - } + // 1 - button pressed, 0 - button released + gamepadButtons[gamepadEvent.number] = (int)gamepadEvent.value; } - /* - switch (gamepadEvent.number) - { - case 0: // 1st Axis X - case 1: // 1st Axis Y - case 2: // 2st Axis X - case 3: // 2st Axis Y - case 4: - { - if (gamepadEvent.value == 1) // Button pressed, 0 release - { - - } - - } break; - // Buttons is similar, variable for every joystick - } - */ } else if (gamepadEvent.type == JS_EVENT_AXIS) { + TraceLog(DEBUG, "Gamepad axis: %i, value: %i", gamepadEvent.number, gamepadEvent.value); + if (gamepadEvent.number == joystickAxisX) gamepadAxisX = (int)gamepadEvent.value; if (gamepadEvent.number == joystickAxisY) gamepadAxisY = (int)gamepadEvent.value; /* @@ -2518,12 +2503,13 @@ static void *GamepadThread(void *arg) case 1: // 1st Axis Y case 2: // 2st Axis X case 3: // 2st Axis Y - // Buttons is similar, variable for every joystick } */ } } } + + return NULL; } #endif diff --git a/src/raylib.h b/src/raylib.h index 0dc8c6df..c4d4392d 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -111,6 +111,8 @@ #define KEY_F8 297 #define KEY_F9 298 #define KEY_F10 299 +#define KEY_F11 300 +#define KEY_F12 301 #define KEY_LEFT_SHIFT 340 #define KEY_LEFT_CONTROL 341 #define KEY_LEFT_ALT 342 -- cgit v1.2.3 From 2cc05e5e9243645aad810fee86465d4e84c81816 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 21 Feb 2016 16:19:31 +0100 Subject: Corrected typo --- src/raylib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/raylib.h') diff --git a/src/raylib.h b/src/raylib.h index c4d4392d..c598ec30 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -697,7 +697,7 @@ void ImageFlipVertical(Image *image); void ImageFlipHorizontal(Image *image); // Flip image horizontally void ImageColorTint(Image *image, Color color); // Modify image color: tint void ImageColorInvert(Image *image); // Modify image color: invert -void ImageColorGrayscale(Image *image); // Modify bimage color: grayscale +void ImageColorGrayscale(Image *image); // Modify image color: grayscale void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100) void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255) void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture -- cgit v1.2.3