From 4c43a407888d516b38191b5df76e373dae6ec58e Mon Sep 17 00:00:00 2001 From: victorfisac Date: Sat, 11 Jun 2016 19:11:30 +0200 Subject: Update physac examples with fixed timestep method --- examples/physics_basic_rigidbody.c | 32 ++++++++++++++++++++++++++++++-- examples/physics_forces.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 8870c55b..24570426 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -13,10 +13,13 @@ #define PHYSAC_IMPLEMENTATION #include "physac.h" +#include #define MOVE_VELOCITY 5 #define JUMP_VELOCITY 30 +void* PhysicsThread(void *arg); + int main() { // Initialization @@ -53,6 +56,10 @@ int main() // Create pplatform physic object PhysicBody platform = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight*0.7f }, 0.0f, (Vector2){ screenWidth*0.25f, 20 }); + // Create physics thread + pthread_t tid; + pthread_create(&tid, NULL, &PhysicsThread, NULL); + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -61,10 +68,9 @@ int main() { // Update //---------------------------------------------------------------------------------- - UpdatePhysics(); // Update all created physic objects // Check rectangle movement inputs - if (IsKeyDown('W') && rectangle->rigidbody.isGrounded) rectangle->rigidbody.velocity.y = JUMP_VELOCITY; + if (IsKeyPressed('W')) rectangle->rigidbody.velocity.y = JUMP_VELOCITY; if (IsKeyDown('A')) rectangle->rigidbody.velocity.x = -MOVE_VELOCITY; else if (IsKeyDown('D')) rectangle->rigidbody.velocity.x = MOVE_VELOCITY; @@ -117,10 +123,32 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- + pthread_cancel(tid); // Destroy physics thread + ClosePhysics(); // Unitialize physics (including all loaded objects) CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; +} + +void* PhysicsThread(void *arg) +{ + // Initialize time variables + double currentTime = GetTime(); + double previousTime = currentTime; + + // Physics update loop + while (!WindowShouldClose()) + { + currentTime = GetTime(); + double deltaTime = (double)(currentTime - previousTime); + previousTime = currentTime; + + // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) + UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); + } + + return NULL; } \ No newline at end of file diff --git a/examples/physics_forces.c b/examples/physics_forces.c index 3e90a21d..397c2331 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -13,12 +13,15 @@ #define PHYSAC_IMPLEMENTATION #include "physac.h" +#include #define FORCE_AMOUNT 5.0f #define FORCE_RADIUS 150 #define LINE_LENGTH 75 #define TRIANGLE_LENGTH 12 +void* PhysicsThread(void *arg); + int main() { // Initialization @@ -61,6 +64,10 @@ int main() PhysicBody topWall = CreatePhysicBody((Vector2){ screenWidth/2, -25 }, 0.0f, (Vector2){ screenWidth, 50 }); PhysicBody bottomWall = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight + 25 }, 0.0f, (Vector2){ screenWidth, 50 }); + // Create physics thread + pthread_t tid; + pthread_create(&tid, NULL, &PhysicsThread, NULL); + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -69,7 +76,6 @@ int main() { // Update //---------------------------------------------------------------------------------- - UpdatePhysics(); // Update all created physic objects // Update mouse position value mousePosition = GetMousePosition(); @@ -174,10 +180,32 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- + pthread_cancel(tid); // Destroy physics thread + ClosePhysics(); // Unitialize physics module CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; +} + +void* PhysicsThread(void *arg) +{ + // Initialize time variables + double currentTime = GetTime(); + double previousTime = currentTime; + + // Physics update loop + while (!WindowShouldClose()) + { + currentTime = GetTime(); + double deltaTime = (double)(currentTime - previousTime); + previousTime = currentTime; + + // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) + UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); + } + + return NULL; } \ No newline at end of file -- cgit v1.2.3 From 6a2bbae5216e66e5581d697998efe135ad826c50 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Sun, 12 Jun 2016 22:07:36 +0200 Subject: Updated physics examples with new module changes --- examples/physics_basic_rigidbody.c | 32 +------------------------------- examples/physics_forces.c | 33 +-------------------------------- 2 files changed, 2 insertions(+), 63 deletions(-) (limited to 'examples') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 24570426..811ab982 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -13,12 +13,10 @@ #define PHYSAC_IMPLEMENTATION #include "physac.h" -#include #define MOVE_VELOCITY 5 #define JUMP_VELOCITY 30 -void* PhysicsThread(void *arg); int main() { @@ -28,7 +26,6 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physac] example - basic rigidbody"); - InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module // Debug variables @@ -56,10 +53,6 @@ int main() // Create pplatform physic object PhysicBody platform = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight*0.7f }, 0.0f, (Vector2){ screenWidth*0.25f, 20 }); - // Create physics thread - pthread_t tid; - pthread_create(&tid, NULL, &PhysicsThread, NULL); - SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -122,33 +115,10 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- - pthread_cancel(tid); // Destroy physics thread - + //-------------------------------------------------------------------------------------- ClosePhysics(); // Unitialize physics (including all loaded objects) - CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; -} - -void* PhysicsThread(void *arg) -{ - // Initialize time variables - double currentTime = GetTime(); - double previousTime = currentTime; - - // Physics update loop - while (!WindowShouldClose()) - { - currentTime = GetTime(); - double deltaTime = (double)(currentTime - previousTime); - previousTime = currentTime; - - // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) - UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); - } - - return NULL; } \ No newline at end of file diff --git a/examples/physics_forces.c b/examples/physics_forces.c index 397c2331..28566753 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -13,15 +13,12 @@ #define PHYSAC_IMPLEMENTATION #include "physac.h" -#include #define FORCE_AMOUNT 5.0f #define FORCE_RADIUS 150 #define LINE_LENGTH 75 #define TRIANGLE_LENGTH 12 -void* PhysicsThread(void *arg); - int main() { // Initialization @@ -30,7 +27,6 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physac] example - forces"); - InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module // Global variables @@ -64,10 +60,6 @@ int main() PhysicBody topWall = CreatePhysicBody((Vector2){ screenWidth/2, -25 }, 0.0f, (Vector2){ screenWidth, 50 }); PhysicBody bottomWall = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight + 25 }, 0.0f, (Vector2){ screenWidth, 50 }); - // Create physics thread - pthread_t tid; - pthread_create(&tid, NULL, &PhysicsThread, NULL); - SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -179,33 +171,10 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- - pthread_cancel(tid); // Destroy physics thread - + //-------------------------------------------------------------------------------------- ClosePhysics(); // Unitialize physics module - CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; -} - -void* PhysicsThread(void *arg) -{ - // Initialize time variables - double currentTime = GetTime(); - double previousTime = currentTime; - - // Physics update loop - while (!WindowShouldClose()) - { - currentTime = GetTime(); - double deltaTime = (double)(currentTime - previousTime); - previousTime = currentTime; - - // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) - UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); - } - - return NULL; } \ No newline at end of file -- cgit v1.2.3 From 54537e8f0b57df2f3f15d8e46309672f46e4775a Mon Sep 17 00:00:00 2001 From: victorfisac Date: Tue, 14 Jun 2016 20:23:46 +0200 Subject: Fixed bug in delta time calculation... and added PHYSAC_NO_THREADS define. Improved physac example drawing frames per second in screen. --- examples/physics_basic_rigidbody.c | 2 ++ examples/physics_forces.c | 4 +++- src/physac.h | 26 ++++++++++++++++---------- 3 files changed, 21 insertions(+), 11 deletions(-) (limited to 'examples') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 811ab982..5223f46a 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -110,6 +110,8 @@ int main() // Draw help message DrawText("Use WASD to move rectangle and ARROWS to move square", screenWidth/2 - MeasureText("Use WASD to move rectangle and ARROWS to move square", 20)/2, screenHeight*0.075f, 20, LIGHTGRAY); + DrawFPS(10, 10); + EndDrawing(); //---------------------------------------------------------------------------------- } diff --git a/examples/physics_forces.c b/examples/physics_forces.c index 28566753..87510552 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -164,7 +164,9 @@ int main() // Draw help messages DrawText("Use LEFT MOUSE BUTTON to apply a force", screenWidth/2 - MeasureText("Use LEFT MOUSE BUTTON to apply a force", 20)/2, screenHeight*0.075f, 20, LIGHTGRAY); - DrawText("Use R to reset objects position", screenWidth/2 - MeasureText("Use R to reset objects position", 20)/2, screenHeight*0.875f, 20, GRAY); + DrawText("Use R to reset objects position", screenWidth/2 - MeasureText("Use R to reset objects position", 20)/2, screenHeight*0.875f, 20, GRAY); + + DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/src/physac.h b/src/physac.h index ea8801c3..5ce3970e 100644 --- a/src/physac.h +++ b/src/physac.h @@ -178,8 +178,10 @@ PHYSACDEF Rectangle TransformToRectangle(Transform transform); #include // Required for: cos(), sin(), abs(), fminf() #include // Required for typedef unsigned long long int uint64_t, used by hi-res timer -#include // Required for: pthread_create() -#include "utils.h" // Required for: TraceLog() + +#ifndef PHYSAC_NO_THREADS + #include // Required for: pthread_create() +#endif #if defined(PLATFORM_DESKTOP) // Functions required to query time on Windows @@ -234,9 +236,11 @@ PHYSACDEF void InitPhysics(Vector2 gravity) physicBodiesCount = 0; gravityForce = gravity; - // Create physics thread - pthread_t tid; - pthread_create(&tid, NULL, &PhysicsThread, NULL); + #ifndef PHYSAC_NO_THREADS // NOTE: if defined, user will need to create a thread for PhysicsThread function manually + // Create physics thread + pthread_t tid; + pthread_create(&tid, NULL, &PhysicsThread, NULL); + #endif } // Update physic objects, calculating physic behaviours and collisions detection @@ -768,7 +772,6 @@ static void InitTimer(void) { baseTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; } - else TraceLog(WARNING, "No hi-resolution timer available"); #endif previousTime = GetCurrentTime(); // Get time as double @@ -777,22 +780,25 @@ static void InitTimer(void) // Time measure returned are microseconds static double GetCurrentTime(void) { + double time; + #if defined(PLATFORM_DESKTOP) unsigned long long int clockFrequency, currentTime; QueryPerformanceFrequency(&clockFrequency); QueryPerformanceCounter(¤tTime); - - return (double)(currentTime/clockFrequency); + #endif #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - uint64_t time = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec; + uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec; - return (double)(time - baseTime)*1e-9; + time = (double)(temp - baseTime)*1e-9; #endif + + return time; } // Returns the dot product of two Vector2 -- cgit v1.2.3 From 1a8fbe5cf0b982cf74434f1ba4654fced71a0450 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Tue, 14 Jun 2016 20:31:48 +0200 Subject: Add pthread external library to source... and add instructions in physac examples to run it successful. --- .gitignore | 3 ++- examples/physics_basic_rigidbody.c | 4 ++++ examples/physics_forces.c | 5 +++++ src/external/pthread/pthreadGC2.dll | Bin 0 -> 119888 bytes 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 src/external/pthread/pthreadGC2.dll (limited to 'examples') diff --git a/.gitignore b/.gitignore index b221a37b..cf9cdfe1 100644 --- a/.gitignore +++ b/.gitignore @@ -72,4 +72,5 @@ src/libraylib.bc # external libraries DLLs !src/external/glfw3/lib/win32/glfw3.dll !src/external/openal_soft/lib/win32/OpenAL32.dll -!src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll \ No newline at end of file +!src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll +!src/external/pthread/pthreadGC2.dll \ No newline at end of file diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 5223f46a..b85f7543 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -5,6 +5,10 @@ * This example has been created using raylib 1.5 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * +* +* Compile example using: +* cmd /c IF NOT EXIST pthreadGC2.dll copy C:\raylib\raylib\src\external\pthread\pthreadGC2.dll $(CURRENT_DIRECTORY) /Y +* * Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/physics_forces.c b/examples/physics_forces.c index 87510552..7de85483 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -5,6 +5,11 @@ * This example has been created using raylib 1.5 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * +* NOTE: This example requires raylib module [rlgl] +* +* Compile example using: +* cmd /c IF NOT EXIST pthreadGC2.dll copy C:\raylib\raylib\src\external\pthread\pthreadGC2.dll $(CURRENT_DIRECTORY) /Y +* * Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/src/external/pthread/pthreadGC2.dll b/src/external/pthread/pthreadGC2.dll new file mode 100644 index 00000000..67b9289d Binary files /dev/null and b/src/external/pthread/pthreadGC2.dll differ -- cgit v1.2.3 From 4e84ded7ef3b165081e08a83d95bf54387a413ca Mon Sep 17 00:00:00 2001 From: victorfisac Date: Tue, 14 Jun 2016 20:38:49 +0200 Subject: Fixed spacing and set UpdatePhysics() function as static... and remove static from PhysicsThread(). --- examples/physics_basic_rigidbody.c | 8 +- examples/physics_forces.c | 2 +- src/physac.h | 418 ++++++++++++++++++------------------- 3 files changed, 213 insertions(+), 215 deletions(-) (limited to 'examples') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index b85f7543..084bfb0e 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -21,7 +21,6 @@ #define MOVE_VELOCITY 5 #define JUMP_VELOCITY 30 - int main() { // Initialization @@ -30,7 +29,7 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physac] example - basic rigidbody"); - InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module + // InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module // Debug variables bool isDebug = false; @@ -64,8 +63,7 @@ int main() while (!WindowShouldClose()) // Detect window close button or ESC key { // Update - //---------------------------------------------------------------------------------- - + //---------------------------------------------------------------------------------- // Check rectangle movement inputs if (IsKeyPressed('W')) rectangle->rigidbody.velocity.y = JUMP_VELOCITY; if (IsKeyDown('A')) rectangle->rigidbody.velocity.x = -MOVE_VELOCITY; @@ -121,7 +119,7 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- ClosePhysics(); // Unitialize physics (including all loaded objects) CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/physics_forces.c b/examples/physics_forces.c index 7de85483..efe8e240 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -178,7 +178,7 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- ClosePhysics(); // Unitialize physics module CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/src/physac.h b/src/physac.h index 4f9b736f..b8cc8f15 100644 --- a/src/physac.h +++ b/src/physac.h @@ -146,7 +146,7 @@ typedef struct PhysicBodyData { // Module Functions Declaration //---------------------------------------------------------------------------------- PHYSACDEF void InitPhysics(Vector2 gravity); // Initializes pointers array (just pointers, fixed size) -PHYSACDEF void UpdatePhysics(double deltaTime); // Update physic objects, calculating physic behaviours and collisions detection +PHYSACDEF void* PhysicsThread(void *arg); // Physics calculations thread function PHYSACDEF void ClosePhysics(); // Unitialize all physic objects and empty the objects pool PHYSACDEF PhysicBody CreatePhysicBody(Vector2 position, float rotation, Vector2 scale); // Create a new physic body dinamically, initialize it and add to pool @@ -219,7 +219,7 @@ static Vector2 gravityForce; // Gravity f //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static void* PhysicsThread(void *arg); // Physics calculations thread function +static void UpdatePhysics(double deltaTime); // Update physic objects, calculating physic behaviours and collisions detection static void InitTimer(void); // Initialize hi-resolution timer static double GetCurrentTime(void); // Time measure returned are microseconds static float Vector2DotProduct(Vector2 v1, Vector2 v2); // Returns the dot product of two Vector2 @@ -243,8 +243,214 @@ PHYSACDEF void InitPhysics(Vector2 gravity) #endif } +// Unitialize all physic objects and empty the objects pool +PHYSACDEF void ClosePhysics() +{ + // Exit physics thread loop + physicsThreadEnabled = false; + + // Free all dynamic memory allocations + for (int i = 0; i < physicBodiesCount; i++) PHYSAC_FREE(physicBodies[i]); + + // Reset enabled physic objects count + physicBodiesCount = 0; +} + +// Create a new physic body dinamically, initialize it and add to pool +PHYSACDEF PhysicBody CreatePhysicBody(Vector2 position, float rotation, Vector2 scale) +{ + // Allocate dynamic memory + PhysicBody obj = (PhysicBody)PHYSAC_MALLOC(sizeof(PhysicBodyData)); + + // Initialize physic body values with generic values + obj->id = physicBodiesCount; + obj->enabled = true; + + obj->transform = (Transform){ (Vector2){ position.x - scale.x/2, position.y - scale.y/2 }, rotation, scale }; + + obj->rigidbody.enabled = false; + obj->rigidbody.mass = 1.0f; + obj->rigidbody.acceleration = (Vector2){ 0.0f, 0.0f }; + obj->rigidbody.velocity = (Vector2){ 0.0f, 0.0f }; + obj->rigidbody.applyGravity = false; + obj->rigidbody.isGrounded = false; + obj->rigidbody.friction = 0.0f; + obj->rigidbody.bounciness = 0.0f; + + obj->collider.enabled = true; + obj->collider.type = COLLIDER_RECTANGLE; + obj->collider.bounds = TransformToRectangle(obj->transform); + obj->collider.radius = 0.0f; + + // Add new physic body to the pointers array + physicBodies[physicBodiesCount] = obj; + + // Increase enabled physic bodies count + physicBodiesCount++; + + return obj; +} + +// Destroy a specific physic body and take it out of the list +PHYSACDEF void DestroyPhysicBody(PhysicBody pbody) +{ + // Free dynamic memory allocation + PHYSAC_FREE(physicBodies[pbody->id]); + + // Remove *obj from the pointers array + for (int i = pbody->id; i < physicBodiesCount; i++) + { + // Resort all the following pointers of the array + if ((i + 1) < physicBodiesCount) + { + physicBodies[i] = physicBodies[i + 1]; + physicBodies[i]->id = physicBodies[i + 1]->id; + } + else PHYSAC_FREE(physicBodies[i]); + } + + // Decrease enabled physic bodies count + physicBodiesCount--; +} + +// Apply directional force to a physic body +PHYSACDEF void ApplyForce(PhysicBody pbody, Vector2 force) +{ + if (pbody->rigidbody.enabled) + { + pbody->rigidbody.velocity.x += force.x/pbody->rigidbody.mass; + pbody->rigidbody.velocity.y += force.y/pbody->rigidbody.mass; + } +} + +// Apply radial force to all physic objects in range +PHYSACDEF void ApplyForceAtPosition(Vector2 position, float force, float radius) +{ + for (int i = 0; i < physicBodiesCount; i++) + { + if (physicBodies[i]->rigidbody.enabled) + { + // Calculate direction and distance between force and physic body position + Vector2 distance = (Vector2){ physicBodies[i]->transform.position.x - position.x, physicBodies[i]->transform.position.y - position.y }; + + if (physicBodies[i]->collider.type == COLLIDER_RECTANGLE) + { + distance.x += physicBodies[i]->transform.scale.x/2; + distance.y += physicBodies[i]->transform.scale.y/2; + } + + float distanceLength = Vector2Length(distance); + + // Check if physic body is in force range + if (distanceLength <= radius) + { + // Normalize force direction + distance.x /= distanceLength; + distance.y /= -distanceLength; + + // Calculate final force + Vector2 finalForce = { distance.x*force, distance.y*force }; + + // Apply force to the physic body + ApplyForce(physicBodies[i], finalForce); + } + } + } +} + +// Convert Transform data type to Rectangle (position and scale) +PHYSACDEF Rectangle TransformToRectangle(Transform transform) +{ + return (Rectangle){transform.position.x, transform.position.y, transform.scale.x, transform.scale.y}; +} + +// Physics calculations thread function +PHYSACDEF void* PhysicsThread(void *arg) +{ + // Initialize thread loop state + physicsThreadEnabled = true; + + // Initialize hi-resolution timer + InitTimer(); + + // Physics update loop + while (physicsThreadEnabled) + { + currentTime = GetCurrentTime(); + double deltaTime = (double)(currentTime - previousTime); + previousTime = currentTime; + + // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) + UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); + } + + return NULL; +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- +// Initialize hi-resolution timer +static void InitTimer(void) +{ +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) + struct timespec now; + + if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success + { + baseTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; + } +#endif + + previousTime = GetCurrentTime(); // Get time as double +} + +// Time measure returned are microseconds +static double GetCurrentTime(void) +{ + double time; + +#if defined(PLATFORM_DESKTOP) + unsigned long long int clockFrequency, currentTime; + + QueryPerformanceFrequency(&clockFrequency); + QueryPerformanceCounter(¤tTime); + + time = (double)((double)currentTime/(double)clockFrequency); +#endif + +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec; + + time = (double)(temp - baseTime)*1e-9; +#endif + + return time; +} + +// Returns the dot product of two Vector2 +static float Vector2DotProduct(Vector2 v1, Vector2 v2) +{ + float result; + + result = v1.x*v2.x + v1.y*v2.y; + + return result; +} + +static float Vector2Length(Vector2 v) +{ + float result; + + result = sqrt(v.x*v.x + v.y*v.y); + + return result; +} + // Update physic objects, calculating physic behaviours and collisions detection -PHYSACDEF void UpdatePhysics(double deltaTime) +static void UpdatePhysics(double deltaTime) { for (int i = 0; i < physicBodiesCount; i++) { @@ -615,210 +821,4 @@ PHYSACDEF void UpdatePhysics(double deltaTime) } } -// Unitialize all physic objects and empty the objects pool -PHYSACDEF void ClosePhysics() -{ - // Exit physics thread loop - physicsThreadEnabled = false; - - // Free all dynamic memory allocations - for (int i = 0; i < physicBodiesCount; i++) PHYSAC_FREE(physicBodies[i]); - - // Reset enabled physic objects count - physicBodiesCount = 0; -} - -// Create a new physic body dinamically, initialize it and add to pool -PHYSACDEF PhysicBody CreatePhysicBody(Vector2 position, float rotation, Vector2 scale) -{ - // Allocate dynamic memory - PhysicBody obj = (PhysicBody)PHYSAC_MALLOC(sizeof(PhysicBodyData)); - - // Initialize physic body values with generic values - obj->id = physicBodiesCount; - obj->enabled = true; - - obj->transform = (Transform){ (Vector2){ position.x - scale.x/2, position.y - scale.y/2 }, rotation, scale }; - - obj->rigidbody.enabled = false; - obj->rigidbody.mass = 1.0f; - obj->rigidbody.acceleration = (Vector2){ 0.0f, 0.0f }; - obj->rigidbody.velocity = (Vector2){ 0.0f, 0.0f }; - obj->rigidbody.applyGravity = false; - obj->rigidbody.isGrounded = false; - obj->rigidbody.friction = 0.0f; - obj->rigidbody.bounciness = 0.0f; - - obj->collider.enabled = true; - obj->collider.type = COLLIDER_RECTANGLE; - obj->collider.bounds = TransformToRectangle(obj->transform); - obj->collider.radius = 0.0f; - - // Add new physic body to the pointers array - physicBodies[physicBodiesCount] = obj; - - // Increase enabled physic bodies count - physicBodiesCount++; - - return obj; -} - -// Destroy a specific physic body and take it out of the list -PHYSACDEF void DestroyPhysicBody(PhysicBody pbody) -{ - // Free dynamic memory allocation - PHYSAC_FREE(physicBodies[pbody->id]); - - // Remove *obj from the pointers array - for (int i = pbody->id; i < physicBodiesCount; i++) - { - // Resort all the following pointers of the array - if ((i + 1) < physicBodiesCount) - { - physicBodies[i] = physicBodies[i + 1]; - physicBodies[i]->id = physicBodies[i + 1]->id; - } - else PHYSAC_FREE(physicBodies[i]); - } - - // Decrease enabled physic bodies count - physicBodiesCount--; -} - -// Apply directional force to a physic body -PHYSACDEF void ApplyForce(PhysicBody pbody, Vector2 force) -{ - if (pbody->rigidbody.enabled) - { - pbody->rigidbody.velocity.x += force.x/pbody->rigidbody.mass; - pbody->rigidbody.velocity.y += force.y/pbody->rigidbody.mass; - } -} - -// Apply radial force to all physic objects in range -PHYSACDEF void ApplyForceAtPosition(Vector2 position, float force, float radius) -{ - for (int i = 0; i < physicBodiesCount; i++) - { - if (physicBodies[i]->rigidbody.enabled) - { - // Calculate direction and distance between force and physic body position - Vector2 distance = (Vector2){ physicBodies[i]->transform.position.x - position.x, physicBodies[i]->transform.position.y - position.y }; - - if (physicBodies[i]->collider.type == COLLIDER_RECTANGLE) - { - distance.x += physicBodies[i]->transform.scale.x/2; - distance.y += physicBodies[i]->transform.scale.y/2; - } - - float distanceLength = Vector2Length(distance); - - // Check if physic body is in force range - if (distanceLength <= radius) - { - // Normalize force direction - distance.x /= distanceLength; - distance.y /= -distanceLength; - - // Calculate final force - Vector2 finalForce = { distance.x*force, distance.y*force }; - - // Apply force to the physic body - ApplyForce(physicBodies[i], finalForce); - } - } - } -} - -// Convert Transform data type to Rectangle (position and scale) -PHYSACDEF Rectangle TransformToRectangle(Transform transform) -{ - return (Rectangle){transform.position.x, transform.position.y, transform.scale.x, transform.scale.y}; -} - -//---------------------------------------------------------------------------------- -// Module specific Functions Definition -//---------------------------------------------------------------------------------- -// Physics calculations thread function -static void* PhysicsThread(void *arg) -{ - // Initialize thread loop state - physicsThreadEnabled = true; - - // Initialize hi-resolution timer - InitTimer(); - - // Physics update loop - while (physicsThreadEnabled) - { - currentTime = GetCurrentTime(); - double deltaTime = (double)(currentTime - previousTime); - previousTime = currentTime; - - // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) - UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); - } - - return NULL; -} - -// Initialize hi-resolution timer -static void InitTimer(void) -{ -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) - struct timespec now; - - if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success - { - baseTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; - } -#endif - - previousTime = GetCurrentTime(); // Get time as double -} - -// Time measure returned are microseconds -static double GetCurrentTime(void) -{ - double time; - -#if defined(PLATFORM_DESKTOP) - unsigned long long int clockFrequency, currentTime; - - QueryPerformanceFrequency(&clockFrequency); - QueryPerformanceCounter(¤tTime); - - time = (double)((double)currentTime/(double)clockFrequency); -#endif - -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec; - - time = (double)(temp - baseTime)*1e-9; -#endif - - return time; -} - -// Returns the dot product of two Vector2 -static float Vector2DotProduct(Vector2 v1, Vector2 v2) -{ - float result; - - result = v1.x*v2.x + v1.y*v2.y; - - return result; -} - -static float Vector2Length(Vector2 v) -{ - float result; - - result = sqrt(v.x*v.x + v.y*v.y); - - return result; -} - #endif // PHYSAC_IMPLEMENTATION \ No newline at end of file -- cgit v1.2.3 From 1879a8129e786e859cc2984e294ef9c22663f923 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Tue, 14 Jun 2016 20:40:12 +0200 Subject: Fixed little bug in physac example --- examples/physics_basic_rigidbody.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 084bfb0e..75720c97 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -29,7 +29,7 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physac] example - basic rigidbody"); - // InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module + InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module // Debug variables bool isDebug = false; -- cgit v1.2.3