Browse Source

WARNING: Removed `physac` from raylib sources/examples

`physac` is available on its own repo
Ray 3 years ago
parent
commit
8da566d6e7

+ 1 - 10
examples/Makefile

@@ -494,20 +494,12 @@ AUDIO = \
     audio/audio_sound_loading \
     audio/audio_multichannel_sound
 
-PHYSICS = \
-    physics/physics_demo \
-    physics/physics_friction \
-    physics/physics_movement \
-    physics/physics_restitution \
-    physics/physics_shatter
-
-
 CURRENT_MAKEFILE = $(lastword $(MAKEFILE_LIST))
 
 # Define processes to execute
 #------------------------------------------------------------------------------------------------
 # Default target entry
-all: $(CORE) $(SHAPES) $(TEXT) $(TEXTURES) $(MODELS) $(SHADERS) $(AUDIO) $(PHYSICS)
+all: $(CORE) $(SHAPES) $(TEXT) $(TEXTURES) $(MODELS) $(SHADERS) $(AUDIO)
 
 core: $(CORE)
 shapes: $(SHAPES)
@@ -516,7 +508,6 @@ text: $(TEXT)
 models: $(MODELS)
 shaders: $(SHADERS)
 audio: $(AUDIO)
-physics: $(PHYSICS)
 
 # Generic compilation pattern
 # NOTE: Examples must be ready for Android compilation!

+ 2 - 29
examples/Makefile.Web

@@ -238,7 +238,7 @@ ifeq ($(PLATFORM),PLATFORM_DRM)
 endif
 
 # Define include paths for required headers
-# NOTE: Some external/extras libraries could be required (stb, physac, easings...)
+# NOTE: Some external/extras libraries could be required (stb, easings...)
 INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external -I$(RAYLIB_PATH)/src/extras
 
 # Define additional directories containing required header files
@@ -324,8 +324,6 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
         # Libraries for Windows desktop compilation
         # NOTE: WinMM library required to set high-res timer resolution
         LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm
-        # Required for physac examples
-        LDLIBS += -static -lpthread
     endif
     ifeq ($(PLATFORM_OS),LINUX)
         # Libraries for Debian GNU/Linux desktop compiling
@@ -508,17 +506,10 @@ AUDIO = \
     audio/audio_sound_loading \
     audio/audio_multichannel_sound
 
-PHYSICS = \
-    physics/physics_demo \
-    physics/physics_friction \
-    physics/physics_movement \
-    physics/physics_restitution \
-    physics/physics_shatter
-
 CURRENT_MAKEFILE = $(lastword $(MAKEFILE_LIST))
 
 # Default target entry
-all: $(CORE) $(SHAPES) $(TEXT) $(TEXTURES) $(MODELS) $(SHADERS) $(AUDIO) $(PHYSICS)
+all: $(CORE) $(SHAPES) $(TEXT) $(TEXTURES) $(MODELS) $(SHADERS) $(AUDIO)
 
 core: $(CORE)
 shapes: $(SHAPES)
@@ -527,7 +518,6 @@ text: $(TEXT)
 models: $(MODELS)
 shaders: $(SHADERS)
 audio: $(AUDIO)
-physics: $(PHYSICS)
 
 # Compile CORE examples
 core/core_basic_window: core/core_basic_window.c
@@ -1007,23 +997,6 @@ audio/audio_multichannel_sound: audio/audio_multichannel_sound.c
     --preload-file audio/resources/sound.wav@resources/sound.wav \
     --preload-file audio/resources/target.ogg@resources/target.ogg
 
-# Compile PHYSICS examples
-physics/physics_demo: physics/physics_demo.c
-	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -DPHYSAC_AVOID_TIMMING_SYSTEM
-
-physics/physics_friction: physics/physics_friction.c
-	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -DPHYSAC_AVOID_TIMMING_SYSTEM
-
-physics/physics_movement: physics/physics_movement.c
-	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -DPHYSAC_AVOID_TIMMING_SYSTEM
-
-physics/physics_restitution: physics/physics_restitution.c
-	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -DPHYSAC_AVOID_TIMMING_SYSTEM
-
-physics/physics_shatter: physics/physics_shatter.c
-	$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -DPHYSAC_AVOID_TIMMING_SYSTEM
-
-
 # Clean everything
 clean:
 ifeq ($(PLATFORM),PLATFORM_DESKTOP)

+ 0 - 12
examples/README.md

@@ -176,18 +176,6 @@ Examples using raylib audio functionality, including sound/music loading and pla
 | 105 | [audio_sound_loading](audio/audio_sound_loading.c)           | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="200">           | ray                                          |        |
 | 106 | [audio_multichannel_sound](audio/audio_multichannel_sound.c) | <img src="audio/audio_multichannel_sound.png" alt="audio_multichannel_sound" width="200"> | [Chris Camacho](https://github.com/codifies) | ⭐️     |
 
-### category: physics
-
-Examples showing physics functionality with raylib. This functionality is provided by [physac](https://github.com/victorfisac/Physac) library, included with raylib [sources](../src/physac.h). Note this library is not linked with raylib by default, it should be manually included in user code.
-
-| ## | example  | image  | developer  | new |
-|----|----------|--------|:----------:|:---:|
-| 107 | [physics_demo](physics/physics_demo.c)               | <img src="physics/physics_demo.png" alt="physics_demo" width="200">               | [Victor Fisac](https://github.com/victorfisac) |        |
-| 108 | [physics_friction](physics/physics_friction.c)       | <img src="physics/physics_friction.png" alt="physics_friction" width="200">       | [Victor Fisac](https://github.com/victorfisac) |        |
-| 109 | [physics_movement](physics/physics_movement.c)       | <img src="physics/physics_movement.png" alt="physics_movement" width="200">       | [Victor Fisac](https://github.com/victorfisac) |        |
-| 110 | [physics_restitution](physics/physics_restitution.c) | <img src="physics/physics_restitution.png" alt="physics_restitution" width="200"> | [Victor Fisac](https://github.com/victorfisac) |        |
-| 111 | [physics_shatter](physics/physics_shatter.c)         | <img src="physics/physics_shatter.png" alt="physics_shatter" width="200">         | [Victor Fisac](https://github.com/victorfisac) |        |
-
 ### category: others
 
 Examples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries.

+ 0 - 128
examples/physics/physics_demo.c

@@ -1,128 +0,0 @@
-/*******************************************************************************************
-*
-*   raylib [physac] example - physics demo
-*
-*   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)
-*
-*   This example uses physac 1.1 (https://github.com/raysan5/raylib/blob/master/src/physac.h)
-*
-*   Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
-*
-********************************************************************************************/
-
-#include "raylib.h"
-
-#define PHYSAC_IMPLEMENTATION
-#include "extras/physac.h"
-
-int main(void)
-{
-    // Initialization
-    //--------------------------------------------------------------------------------------
-    const int screenWidth = 800;
-    const int screenHeight = 450;
-
-    SetConfigFlags(FLAG_MSAA_4X_HINT);
-    InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics demo");
-
-    // Physac logo drawing position
-    int logoX = screenWidth - MeasureText("Physac", 30) - 10;
-    int logoY = 15;
-
-    // Initialize physics and default physics bodies
-    InitPhysics();
-
-    // Create floor rectangle physics body
-    PhysicsBody floor = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2.0f, (float)screenHeight }, 500, 100, 10);
-    floor->enabled = false;         // Disable body state to convert it to static (no dynamics, but collisions)
-
-    // Create obstacle circle physics body
-    PhysicsBody circle = CreatePhysicsBodyCircle((Vector2){ screenWidth/2.0f, screenHeight/2.0f }, 45, 10);
-    circle->enabled = false;        // Disable body state to convert it to static (no dynamics, but collisions)
-
-    SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
-    //--------------------------------------------------------------------------------------
-
-    // Main game loop
-    while (!WindowShouldClose())    // Detect window close button or ESC key
-    {
-        // Update
-        //----------------------------------------------------------------------------------
-        UpdatePhysics();            // Update physics system
-
-        if (IsKeyPressed(KEY_R))    // Reset physics system
-        {
-            ResetPhysics();
-
-            floor = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2.0f, (float)screenHeight }, 500, 100, 10);
-            floor->enabled = false;
-
-            circle = CreatePhysicsBodyCircle((Vector2){ screenWidth/2.0f, screenHeight/2.0f }, 45, 10);
-            circle->enabled = false;
-        }
-
-        // Physics body creation inputs
-        if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) CreatePhysicsBodyPolygon(GetMousePosition(), (float)GetRandomValue(20, 80), GetRandomValue(3, 8), 10);
-        else if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) CreatePhysicsBodyCircle(GetMousePosition(), (float)GetRandomValue(10, 45), 10);
-
-        // Destroy falling physics bodies
-        int bodiesCount = GetPhysicsBodiesCount();
-        for (int i = bodiesCount - 1; i >= 0; i--)
-        {
-            PhysicsBody body = GetPhysicsBody(i);
-            if (body != NULL && (body->position.y > screenHeight*2)) DestroyPhysicsBody(body);
-        }
-        //----------------------------------------------------------------------------------
-
-        // Draw
-        //----------------------------------------------------------------------------------
-        BeginDrawing();
-
-            ClearBackground(BLACK);
-
-            DrawFPS(screenWidth - 90, screenHeight - 30);
-
-            // Draw created physics bodies
-            bodiesCount = GetPhysicsBodiesCount();
-            for (int i = 0; i < bodiesCount; i++)
-            {
-                PhysicsBody body = GetPhysicsBody(i);
-
-                if (body != NULL)
-                {
-                    int vertexCount = GetPhysicsShapeVerticesCount(i);
-                    for (int j = 0; j < vertexCount; j++)
-                    {
-                        // Get physics bodies shape vertices to draw lines
-                        // Note: GetPhysicsShapeVertex() already calculates rotation transformations
-                        Vector2 vertexA = GetPhysicsShapeVertex(body, j);
-
-                        int jj = (((j + 1) < vertexCount) ? (j + 1) : 0);   // Get next vertex or first to close the shape
-                        Vector2 vertexB = GetPhysicsShapeVertex(body, jj);
-
-                        DrawLineV(vertexA, vertexB, GREEN);     // Draw a line between two vertex positions
-                    }
-                }
-            }
-
-            DrawText("Left mouse button to create a polygon", 10, 10, 10, WHITE);
-            DrawText("Right mouse button to create a circle", 10, 25, 10, WHITE);
-            DrawText("Press 'R' to reset example", 10, 40, 10, WHITE);
-
-            DrawText("Physac", logoX, logoY, 30, WHITE);
-            DrawText("Powered by", logoX + 50, logoY - 7, 10, WHITE);
-
-        EndDrawing();
-        //----------------------------------------------------------------------------------
-    }
-
-    // De-Initialization
-    //--------------------------------------------------------------------------------------
-    ClosePhysics();       // Unitialize physics
-
-    CloseWindow();        // Close window and OpenGL context
-    //--------------------------------------------------------------------------------------
-
-    return 0;
-}

BIN
examples/physics/physics_demo.png


+ 0 - 142
examples/physics/physics_friction.c

@@ -1,142 +0,0 @@
-/*******************************************************************************************
-*
-*   raylib [physac] example - physics friction
-*
-*   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)
-*
-*   This example uses physac 1.1 (https://github.com/raysan5/raylib/blob/master/src/physac.h)
-*
-*   Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
-*
-********************************************************************************************/
-
-#include "raylib.h"
-
-#define PHYSAC_IMPLEMENTATION
-#include "extras/physac.h"
-
-int main(void)
-{
-    // Initialization
-    //--------------------------------------------------------------------------------------
-    const int screenWidth = 800;
-    const int screenHeight = 450;
-
-    SetConfigFlags(FLAG_MSAA_4X_HINT);
-    InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics friction");
-
-    // Physac logo drawing position
-    int logoX = screenWidth - MeasureText("Physac", 30) - 10;
-    int logoY = 15;
-
-    // Initialize physics and default physics bodies
-    InitPhysics();
-
-    // Create floor rectangle physics body
-    PhysicsBody floor = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2.0f, (float)screenHeight }, (float)screenWidth, 100, 10);
-    floor->enabled = false; // Disable body state to convert it to static (no dynamics, but collisions)
-    PhysicsBody wall = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2.0f, screenHeight*0.8f }, 10, 80, 10);
-    wall->enabled = false; // Disable body state to convert it to static (no dynamics, but collisions)
-
-    // Create left ramp physics body
-    PhysicsBody rectLeft = CreatePhysicsBodyRectangle((Vector2){ 25, (float)screenHeight - 5 }, 250, 250, 10);
-    rectLeft->enabled = false; // Disable body state to convert it to static (no dynamics, but collisions)
-    SetPhysicsBodyRotation(rectLeft, 30*DEG2RAD);
-
-    // Create right ramp  physics body
-    PhysicsBody rectRight = CreatePhysicsBodyRectangle((Vector2){ (float)screenWidth - 25, (float)screenHeight - 5 }, 250, 250, 10);
-    rectRight->enabled = false; // Disable body state to convert it to static (no dynamics, but collisions)
-    SetPhysicsBodyRotation(rectRight, 330*DEG2RAD);
-
-    // Create dynamic physics bodies
-    PhysicsBody bodyA = CreatePhysicsBodyRectangle((Vector2){ 35, screenHeight*0.6f }, 40, 40, 10);
-    bodyA->staticFriction = 0.1f;
-    bodyA->dynamicFriction = 0.1f;
-    SetPhysicsBodyRotation(bodyA, 30*DEG2RAD);
-
-    PhysicsBody bodyB = CreatePhysicsBodyRectangle((Vector2){ (float)screenWidth - 35, (float)screenHeight*0.6f }, 40, 40, 10);
-    bodyB->staticFriction = 1.0f;
-    bodyB->dynamicFriction = 1.0f;
-    SetPhysicsBodyRotation(bodyB, 330*DEG2RAD);
-
-    SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
-    //--------------------------------------------------------------------------------------
-
-    // Main game loop
-    while (!WindowShouldClose())    // Detect window close button or ESC key
-    {
-        // Update
-        //----------------------------------------------------------------------------------
-        UpdatePhysics();            // Update physics system
-
-        if (IsKeyPressed(KEY_R))    // Reset physics system
-        {
-            // Reset dynamic physics bodies position, velocity and rotation
-            bodyA->position = (Vector2){ 35, screenHeight*0.6f };
-            bodyA->velocity = (Vector2){ 0, 0 };
-            bodyA->angularVelocity = 0;
-            SetPhysicsBodyRotation(bodyA, 30*DEG2RAD);
-
-            bodyB->position = (Vector2){ (float)screenWidth - 35, screenHeight * 0.6f };
-            bodyB->velocity = (Vector2){ 0, 0 };
-            bodyB->angularVelocity = 0;
-            SetPhysicsBodyRotation(bodyB, 330*DEG2RAD);
-        }
-        //----------------------------------------------------------------------------------
-
-        // Draw
-        //----------------------------------------------------------------------------------
-        BeginDrawing();
-
-            ClearBackground(BLACK);
-
-            DrawFPS(screenWidth - 90, screenHeight - 30);
-
-            // Draw created physics bodies
-            int bodiesCount = GetPhysicsBodiesCount();
-            for (int i = 0; i < bodiesCount; i++)
-            {
-                PhysicsBody body = GetPhysicsBody(i);
-
-                if (body != NULL)
-                {
-                    int vertexCount = GetPhysicsShapeVerticesCount(i);
-                    for (int j = 0; j < vertexCount; j++)
-                    {
-                        // Get physics bodies shape vertices to draw lines
-                        // Note: GetPhysicsShapeVertex() already calculates rotation transformations
-                        Vector2 vertexA = GetPhysicsShapeVertex(body, j);
-
-                        int jj = (((j + 1) < vertexCount) ? (j + 1) : 0);   // Get next vertex or first to close the shape
-                        Vector2 vertexB = GetPhysicsShapeVertex(body, jj);
-
-                        DrawLineV(vertexA, vertexB, GREEN);     // Draw a line between two vertex positions
-                    }
-                }
-            }
-
-            DrawRectangle(0, screenHeight - 49, screenWidth, 49, BLACK);
-
-            DrawText("Friction amount", (screenWidth - MeasureText("Friction amount", 30))/2.0f, 75, 30, WHITE);
-            DrawText("0.1", (int)bodyA->position.x - MeasureText("0.1", 20)/2, (int)bodyA->position.y - 7, 20, WHITE);
-            DrawText("1", (int)bodyB->position.x - MeasureText("1", 20)/2, (int)bodyB->position.y - 7, 20, WHITE);
-
-            DrawText("Press 'R' to reset example", 10, 10, 10, WHITE);
-
-            DrawText("Physac", logoX, logoY, 30, WHITE);
-            DrawText("Powered by", logoX + 50, logoY - 7, 10, WHITE);
-
-        EndDrawing();
-        //----------------------------------------------------------------------------------
-    }
-
-    // De-Initialization
-    //--------------------------------------------------------------------------------------
-    ClosePhysics();       // Unitialize physics
-
-    CloseWindow();        // Close window and OpenGL context
-    //--------------------------------------------------------------------------------------
-
-    return 0;
-}

BIN
examples/physics/physics_friction.png


+ 0 - 128
examples/physics/physics_movement.c

@@ -1,128 +0,0 @@
-/*******************************************************************************************
-*
-*   raylib [physac] example - physics movement
-*
-*   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)
-*
-*   This example uses physac 1.1 (https://github.com/raysan5/raylib/blob/master/src/physac.h)
-*
-*   Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
-*
-********************************************************************************************/
-
-#include "raylib.h"
-
-#define PHYSAC_IMPLEMENTATION
-#include "extras/physac.h"
-
-#define VELOCITY    0.5f
-
-int main(void)
-{
-    // Initialization
-    //--------------------------------------------------------------------------------------
-    const int screenWidth = 800;
-    const int screenHeight = 450;
-
-    SetConfigFlags(FLAG_MSAA_4X_HINT);
-    InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics movement");
-
-    // Physac logo drawing position
-    int logoX = screenWidth - MeasureText("Physac", 30) - 10;
-    int logoY = 15;
-
-    // Initialize physics and default physics bodies
-    InitPhysics();
-
-    // Create floor and walls rectangle physics body
-    PhysicsBody floor = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2.0f, (float)screenHeight }, (float)screenWidth, 100, 10);
-    PhysicsBody platformLeft = CreatePhysicsBodyRectangle((Vector2){ screenWidth*0.25f, screenHeight*0.6f }, screenWidth*0.25f, 10, 10);
-    PhysicsBody platformRight = CreatePhysicsBodyRectangle((Vector2){ screenWidth*0.75f, screenHeight*0.6f }, screenWidth*0.25f, 10, 10);
-    PhysicsBody wallLeft = CreatePhysicsBodyRectangle((Vector2){ -5, screenHeight/2.0f }, 10, (float)screenHeight, 10);
-    PhysicsBody wallRight = CreatePhysicsBodyRectangle((Vector2){ (float)screenWidth + 5, screenHeight/2.0f }, 10, (float)screenHeight, 10);
-
-    // Disable dynamics to floor and walls physics bodies
-    floor->enabled = false;
-    platformLeft->enabled = false;
-    platformRight->enabled = false;
-    wallLeft->enabled = false;
-    wallRight->enabled = false;
-
-    // Create movement physics body
-    PhysicsBody body = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2.0f, screenHeight/2.0f }, 50, 50, 1);
-    body->freezeOrient = true;      // Constrain body rotation to avoid little collision torque amounts
-
-    SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
-    //--------------------------------------------------------------------------------------
-
-    // Main game loop
-    while (!WindowShouldClose())    // Detect window close button or ESC key
-    {
-        // Update
-        //----------------------------------------------------------------------------------
-        UpdatePhysics();              // Update physics system
-
-        if (IsKeyPressed(KEY_R))      // Reset physics input
-        {
-            // Reset movement physics body position, velocity and rotation
-            body->position = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
-            body->velocity = (Vector2){ 0, 0 };
-            SetPhysicsBodyRotation(body, 0);
-        }
-
-        // Horizontal movement input
-        if (IsKeyDown(KEY_RIGHT)) body->velocity.x = VELOCITY;
-        else if (IsKeyDown(KEY_LEFT)) body->velocity.x = -VELOCITY;
-
-        // Vertical movement input checking if player physics body is grounded
-        if (IsKeyDown(KEY_UP) && body->isGrounded) body->velocity.y = -VELOCITY*4;
-        //----------------------------------------------------------------------------------
-
-        // Draw
-        //----------------------------------------------------------------------------------
-        BeginDrawing();
-
-            ClearBackground(BLACK);
-
-            DrawFPS(screenWidth - 90, screenHeight - 30);
-
-            // Draw created physics bodies
-            int bodiesCount = GetPhysicsBodiesCount();
-            for (int i = 0; i < bodiesCount; i++)
-            {
-                PhysicsBody body = GetPhysicsBody(i);
-
-                int vertexCount = GetPhysicsShapeVerticesCount(i);
-                for (int j = 0; j < vertexCount; j++)
-                {
-                    // Get physics bodies shape vertices to draw lines
-                    // Note: GetPhysicsShapeVertex() already calculates rotation transformations
-                    Vector2 vertexA = GetPhysicsShapeVertex(body, j);
-
-                    int jj = (((j + 1) < vertexCount) ? (j + 1) : 0);   // Get next vertex or first to close the shape
-                    Vector2 vertexB = GetPhysicsShapeVertex(body, jj);
-
-                    DrawLineV(vertexA, vertexB, GREEN);     // Draw a line between two vertex positions
-                }
-            }
-
-            DrawText("Use 'ARROWS' to move player", 10, 10, 10, WHITE);
-            DrawText("Press 'R' to reset example", 10, 30, 10, WHITE);
-
-            DrawText("Physac", logoX, logoY, 30, WHITE);
-            DrawText("Powered by", logoX + 50, logoY - 7, 10, WHITE);
-
-        EndDrawing();
-        //----------------------------------------------------------------------------------
-    }
-
-    // De-Initialization
-    //--------------------------------------------------------------------------------------
-    ClosePhysics();       // Unitialize physics
-
-    CloseWindow();        // Close window and OpenGL context
-    //--------------------------------------------------------------------------------------
-
-    return 0;
-}

BIN
examples/physics/physics_movement.png


+ 0 - 129
examples/physics/physics_restitution.c

@@ -1,129 +0,0 @@
-/*******************************************************************************************
-*
-*   raylib [physac] example - physics restitution
-*
-*   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)
-*
-*   This example uses physac 1.1 (https://github.com/raysan5/raylib/blob/master/src/physac.h)
-*
-*   Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
-*
-********************************************************************************************/
-
-#include "raylib.h"
-
-#define PHYSAC_IMPLEMENTATION
-#include "extras/physac.h"
-
-int main(void)
-{
-    // Initialization
-    //--------------------------------------------------------------------------------------
-    const int screenWidth = 800;
-    const int screenHeight = 450;
-
-    SetConfigFlags(FLAG_MSAA_4X_HINT);
-    InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics restitution");
-
-    // Physac logo drawing position
-    int logoX = screenWidth - MeasureText("Physac", 30) - 10;
-    int logoY = 15;
-
-    // Initialize physics and default physics bodies
-    InitPhysics();
-
-    // Create floor rectangle physics body
-    PhysicsBody floor = CreatePhysicsBodyRectangle((Vector2){ screenWidth/2.0f, (float)screenHeight }, (float)screenWidth, 100, 10);
-    floor->enabled = false; // Disable body state to convert it to static (no dynamics, but collisions)
-    floor->restitution = 1;
-
-    // Create circles physics body
-    PhysicsBody circleA = CreatePhysicsBodyCircle((Vector2){ screenWidth*0.25f, screenHeight/2.0f }, 30, 10);
-    circleA->restitution = 0;
-    PhysicsBody circleB = CreatePhysicsBodyCircle((Vector2){ screenWidth*0.5f, screenHeight/2.0f }, 30, 10);
-    circleB->restitution = 0.5f;
-    PhysicsBody circleC = CreatePhysicsBodyCircle((Vector2){ screenWidth*0.75f, screenHeight/2.0f }, 30, 10);
-    circleC->restitution = 1;
-
-    // Restitution demo needs a very tiny physics time step for a proper simulation
-    SetPhysicsTimeStep(1.0/60.0/100*1000);
-
-    SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
-    //--------------------------------------------------------------------------------------
-
-    // Main game loop
-    while (!WindowShouldClose())    // Detect window close button or ESC key
-    {
-        // Update
-        //----------------------------------------------------------------------------------
-        UpdatePhysics();            // Update physics system
-
-        if (IsKeyPressed(KEY_R))    // Reset physics input
-        {
-            // Reset circles physics bodies position and velocity
-            circleA->position = (Vector2){ screenWidth*0.25f, screenHeight/2.0f };
-            circleA->velocity = (Vector2){ 0, 0 };
-            circleB->position = (Vector2){ screenWidth*0.5f, screenHeight/2.0f };
-            circleB->velocity = (Vector2){ 0, 0 };
-            circleC->position = (Vector2){ screenWidth*0.75f, screenHeight/2.0f };
-            circleC->velocity = (Vector2){ 0, 0 };
-        }
-        //----------------------------------------------------------------------------------
-
-        // Draw
-        //----------------------------------------------------------------------------------
-        BeginDrawing();
-
-            ClearBackground(BLACK);
-
-            DrawFPS(screenWidth - 90, screenHeight - 30);
-
-            // Draw created physics bodies
-            int bodiesCount = GetPhysicsBodiesCount();
-            for (int i = 0; i < bodiesCount; i++)
-            {
-                PhysicsBody body = GetPhysicsBody(i);
-
-                int vertexCount = GetPhysicsShapeVerticesCount(i);
-                for (int j = 0; j < vertexCount; j++)
-                {
-                    // Get physics bodies shape vertices to draw lines
-                    // Note: GetPhysicsShapeVertex() already calculates rotation transformations
-                    Vector2 vertexA = GetPhysicsShapeVertex(body, j);
-
-                    int jj = (((j + 1) < vertexCount) ? (j + 1) : 0);   // Get next vertex or first to close the shape
-                    Vector2 vertexB = GetPhysicsShapeVertex(body, jj);
-
-                    DrawLineV(vertexA, vertexB, GREEN);     // Draw a line between two vertex positions
-                }
-            }
-
-            DrawText("Restitution amount", (screenWidth - MeasureText("Restitution amount", 30))/2, 75, 30, WHITE);
-            DrawText("0", (int)circleA->position.x - MeasureText("0", 20)/2, circleA->position.y - 7, 20, WHITE);
-            DrawText("0.5", (int)circleB->position.x - MeasureText("0.5", 20)/2, circleB->position.y - 7, 20, WHITE);
-            DrawText("1", (int)circleC->position.x - MeasureText("1", 20)/2, circleC->position.y - 7, 20, WHITE);
-
-            DrawText("Press 'R' to reset example", 10, 10, 10, WHITE);
-
-            DrawText("Physac", logoX, logoY, 30, WHITE);
-            DrawText("Powered by", logoX + 50, logoY - 7, 10, WHITE);
-
-        EndDrawing();
-        //----------------------------------------------------------------------------------
-    }
-
-    // De-Initialization
-    //--------------------------------------------------------------------------------------
-    DestroyPhysicsBody(circleA);
-    DestroyPhysicsBody(circleB);
-    DestroyPhysicsBody(circleC);
-    DestroyPhysicsBody(floor);
-
-    ClosePhysics();       // Unitialize physics
-
-    CloseWindow();        // Close window and OpenGL context
-    //--------------------------------------------------------------------------------------
-
-    return 0;
-}

BIN
examples/physics/physics_restitution.png


+ 0 - 111
examples/physics/physics_shatter.c

@@ -1,111 +0,0 @@
-/*******************************************************************************************
-*
-*   raylib [physac] example - physics shatter
-*
-*   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)
-*
-*   This example uses physac 1.1 (https://github.com/raysan5/raylib/blob/master/src/physac.h)
-*
-*   Copyright (c) 2016-2021 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
-*
-********************************************************************************************/
-
-#include "raylib.h"
-
-#define PHYSAC_IMPLEMENTATION
-#include "extras/physac.h"
-
-int main(void)
-{
-    // Initialization
-    //--------------------------------------------------------------------------------------
-    const int screenWidth = 800;
-    const int screenHeight = 450;
-
-    SetConfigFlags(FLAG_MSAA_4X_HINT);
-    InitWindow(screenWidth, screenHeight, "raylib [physac] example - physics shatter");
-
-    // Physac logo drawing position
-    int logoX = screenWidth - MeasureText("Physac", 30) - 10;
-    int logoY = 15;
-
-    // Initialize physics and default physics bodies
-    InitPhysics();
-    SetPhysicsGravity(0, 0);
-
-    // Create random polygon physics body to shatter
-    CreatePhysicsBodyPolygon((Vector2){ screenWidth/2.0f, screenHeight/2.0f }, (float)GetRandomValue(80, 200), GetRandomValue(3, 8), 10);
-
-    SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
-    //--------------------------------------------------------------------------------------
-
-    // Main game loop
-    while (!WindowShouldClose())    // Detect window close button or ESC key
-    {
-        //----------------------------------------------------------------------------------
-        UpdatePhysics();            // Update physics system
-
-        if (IsKeyPressed(KEY_R))    // Reset physics input
-        {
-            ResetPhysics();
-
-            CreatePhysicsBodyPolygon((Vector2){ screenWidth/2.0f, screenHeight/2.0f }, (float)GetRandomValue(80, 200), GetRandomValue(3, 8), 10);
-        }
-
-        if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))    // Physics shatter input
-        {
-            int count = GetPhysicsBodiesCount();
-            for (int i = count - 1; i >= 0; i--)
-            {
-                PhysicsBody currentBody = GetPhysicsBody(i);
-
-                if (currentBody != NULL) PhysicsShatter(currentBody, GetMousePosition(), 10/currentBody->inverseMass);
-            }
-        }
-        //----------------------------------------------------------------------------------
-
-        // Draw
-        //----------------------------------------------------------------------------------
-        BeginDrawing();
-
-            ClearBackground(BLACK);
-
-            // Draw created physics bodies
-            int bodiesCount = GetPhysicsBodiesCount();
-            for (int i = 0; i < bodiesCount; i++)
-            {
-                PhysicsBody currentBody = GetPhysicsBody(i);
-
-                int vertexCount = GetPhysicsShapeVerticesCount(i);
-                for (int j = 0; j < vertexCount; j++)
-                {
-                    // Get physics bodies shape vertices to draw lines
-                    // Note: GetPhysicsShapeVertex() already calculates rotation transformations
-                    Vector2 vertexA = GetPhysicsShapeVertex(currentBody, j);
-
-                    int jj = (((j + 1) < vertexCount) ? (j + 1) : 0);   // Get next vertex or first to close the shape
-                    Vector2 vertexB = GetPhysicsShapeVertex(currentBody, jj);
-
-                    DrawLineV(vertexA, vertexB, GREEN);     // Draw a line between two vertex positions
-                }
-            }
-
-            DrawText("Left mouse button in polygon area to shatter body\nPress 'R' to reset example", 10, 10, 10, WHITE);
-
-            DrawText("Physac", logoX, logoY, 30, WHITE);
-            DrawText("Powered by", logoX + 50, logoY - 7, 10, WHITE);
-
-        EndDrawing();
-        //----------------------------------------------------------------------------------
-    }
-
-    // De-Initialization
-    //--------------------------------------------------------------------------------------
-    ClosePhysics();       // Unitialize physics
-
-    CloseWindow();        // Close window and OpenGL context
-    //--------------------------------------------------------------------------------------
-
-    return 0;
-}

BIN
examples/physics/physics_shatter.png


+ 0 - 1987
src/extras/physac.h

@@ -1,1987 +0,0 @@
-/**********************************************************************************************
-*
-*   Physac v1.1 - 2D Physics library for videogames
-*
-*   DESCRIPTION:
-*
-*   Physac is a small 2D physics engine written in pure C. The engine uses a fixed time-step thread loop
-*   to simulate physics. A physics step contains the following phases: get collision information,
-*   apply dynamics, collision solving and position correction. It uses a very simple struct for physic
-*   bodies with a position vector to be used in any 3D rendering API.
-*
-*   CONFIGURATION:
-*
-*   #define PHYSAC_IMPLEMENTATION
-*       Generates the implementation of the library into the included file.
-*       If not defined, the library is in header only mode and can be included in other headers
-*       or source files without problems. But only ONE file should hold the implementation.
-*
-*   #define PHYSAC_DEBUG
-*       Show debug traces log messages about physic bodies creation/destruction, physic system errors,
-*       some calculations results and NULL reference exceptions.
-*
-*   #define PHYSAC_AVOID_TIMMING_SYSTEM
-*       Disables internal timming system, used by UpdatePhysics() to launch timmed physic steps,
-*       it allows just running UpdatePhysics() automatically on a separate thread at a desired time step.
-*       In case physics steps update needs to be controlled by user with a custom timming mechanism,
-*       just define this flag and the internal timming mechanism will be avoided, in that case,
-*       timming libraries are neither required by the module.
-*
-*   #define PHYSAC_MALLOC()
-*   #define PHYSAC_CALLOC()
-*   #define PHYSAC_FREE()
-*       You can define your own malloc/free implementation replacing stdlib.h malloc()/free() functions.
-*       Otherwise it will include stdlib.h and use the C standard library malloc()/free() function.
-*
-*   COMPILATION:
-*
-*   Use the following code to compile with GCC:
-*       gcc -o $(NAME_PART).exe $(FILE_NAME) -s -static -lraylib -lopengl32 -lgdi32 -lwinmm -std=c99
-*
-*   VERSIONS HISTORY:
-*       1.1 (20-Jan-2021) @raysan5: Library general revision 
-*               Removed threading system (up to the user)
-*               Support MSVC C++ compilation using CLITERAL()
-*               Review DEBUG mechanism for TRACELOG() and all TRACELOG() messages
-*               Review internal variables/functions naming for consistency
-*               Allow option to avoid internal timming system, to allow app manage the steps
-*       1.0 (12-Jun-2017) First release of the library
-*
-*
-*   LICENSE: zlib/libpng
-*
-*   Copyright (c) 2016-2022 Victor Fisac (@victorfisac) and Ramon Santamaria (@raysan5)
-*
-*   This software is provided "as-is", without any express or implied warranty. In no event
-*   will the authors be held liable for any damages arising from the use of this software.
-*
-*   Permission is granted to anyone to use this software for any purpose, including commercial
-*   applications, and to alter it and redistribute it freely, subject to the following restrictions:
-*
-*     1. The origin of this software must not be misrepresented; you must not claim that you
-*     wrote the original software. If you use this software in a product, an acknowledgment
-*     in the product documentation would be appreciated but is not required.
-*
-*     2. Altered source versions must be plainly marked as such, and must not be misrepresented
-*     as being the original software.
-*
-*     3. This notice may not be removed or altered from any source distribution.
-*
-**********************************************************************************************/
-
-#if !defined(PHYSAC_H)
-#define PHYSAC_H
-
-// Function specifiers in case library is build/used as a shared library (Windows)
-// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
-#if defined(_WIN32)
-    #if defined(BUILD_LIBTYPE_SHARED)
-        #define PHYSACDEF __declspec(dllexport)     // We are building the library as a Win32 shared library (.dll)
-    #elif defined(USE_LIBTYPE_SHARED)
-        #define PHYSACDEF __declspec(dllimport)     // We are using the library as a Win32 shared library (.dll)
-    #endif
-#endif
-
-#ifndef PHYSACDEF
-    #define PHYSACDEF       // We are building or using physac as a static library
-#endif
-
-// Allow custom memory allocators
-#ifndef PHYSAC_MALLOC
-    #define PHYSAC_MALLOC(size)         malloc(size)
-#endif
-#ifndef PHYSAC_CALLOC
-    #define PHYSAC_CALLOC(size, n)      calloc(size, n)
-#endif
-#ifndef PHYSAC_FREE
-    #define PHYSAC_FREE(ptr)            free(ptr)
-#endif
-
-//----------------------------------------------------------------------------------
-// Defines and Macros
-//----------------------------------------------------------------------------------
-#define PHYSAC_MAX_BODIES               64          // Maximum number of physic bodies supported
-#define PHYSAC_MAX_MANIFOLDS            4096        // Maximum number of physic bodies interactions (64x64)
-#define PHYSAC_MAX_VERTICES             24          // Maximum number of vertex for polygons shapes
-#define PHYSAC_DEFAULT_CIRCLE_VERTICES  24          // Default number of vertices for circle shapes
-
-#define PHYSAC_COLLISION_ITERATIONS     100
-#define PHYSAC_PENETRATION_ALLOWANCE    0.05f
-#define PHYSAC_PENETRATION_CORRECTION   0.4f
-
-#define PHYSAC_PI                       3.14159265358979323846f
-#define PHYSAC_DEG2RAD                  (PHYSAC_PI/180.0f)
-
-//----------------------------------------------------------------------------------
-// Data Types Structure Definition
-//----------------------------------------------------------------------------------
-#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
-    #include <stdbool.h>
-#endif
-
-typedef enum PhysicsShapeType { PHYSICS_CIRCLE = 0, PHYSICS_POLYGON } PhysicsShapeType;
-
-// Previously defined to be used in PhysicsShape struct as circular dependencies
-typedef struct PhysicsBodyData *PhysicsBody;
-
-#if !defined(RL_VECTOR2_TYPE)
-// Vector2 type
-typedef struct Vector2 {
-    float x;
-    float y;
-} Vector2;
-#endif
-
-// Matrix2x2 type (used for polygon shape rotation matrix)
-typedef struct Matrix2x2 {
-    float m00;
-    float m01;
-    float m10;
-    float m11;
-} Matrix2x2;
-
-typedef struct PhysicsVertexData {
-    unsigned int vertexCount;                   // Vertex count (positions and normals)
-    Vector2 positions[PHYSAC_MAX_VERTICES];     // Vertex positions vectors
-    Vector2 normals[PHYSAC_MAX_VERTICES];       // Vertex normals vectors
-} PhysicsVertexData;
-
-typedef struct PhysicsShape {
-    PhysicsShapeType type;                      // Shape type (circle or polygon)
-    PhysicsBody body;                           // Shape physics body data pointer
-    PhysicsVertexData vertexData;               // Shape vertices data (used for polygon shapes)
-    float radius;                               // Shape radius (used for circle shapes)
-    Matrix2x2 transform;                        // Vertices transform matrix 2x2
-} PhysicsShape;
-
-typedef struct PhysicsBodyData {
-    unsigned int id;                            // Unique identifier
-    bool enabled;                               // Enabled dynamics state (collisions are calculated anyway)
-    Vector2 position;                           // Physics body shape pivot
-    Vector2 velocity;                           // Current linear velocity applied to position
-    Vector2 force;                              // Current linear force (reset to 0 every step)
-    float angularVelocity;                      // Current angular velocity applied to orient
-    float torque;                               // Current angular force (reset to 0 every step)
-    float orient;                               // Rotation in radians
-    float inertia;                              // Moment of inertia
-    float inverseInertia;                       // Inverse value of inertia
-    float mass;                                 // Physics body mass
-    float inverseMass;                          // Inverse value of mass
-    float staticFriction;                       // Friction when the body has not movement (0 to 1)
-    float dynamicFriction;                      // Friction when the body has movement (0 to 1)
-    float restitution;                          // Restitution coefficient of the body (0 to 1)
-    bool useGravity;                            // Apply gravity force to dynamics
-    bool isGrounded;                            // Physics grounded on other body state
-    bool freezeOrient;                          // Physics rotation constraint
-    PhysicsShape shape;                         // Physics body shape information (type, radius, vertices, transform)
-} PhysicsBodyData;
-
-typedef struct PhysicsManifoldData {
-    unsigned int id;                            // Unique identifier
-    PhysicsBody bodyA;                          // Manifold first physics body reference
-    PhysicsBody bodyB;                          // Manifold second physics body reference
-    float penetration;                          // Depth of penetration from collision
-    Vector2 normal;                             // Normal direction vector from 'a' to 'b'
-    Vector2 contacts[2];                        // Points of contact during collision
-    unsigned int contactsCount;                 // Current collision number of contacts
-    float restitution;                          // Mixed restitution during collision
-    float dynamicFriction;                      // Mixed dynamic friction during collision
-    float staticFriction;                       // Mixed static friction during collision
-} PhysicsManifoldData, *PhysicsManifold;
-
-//----------------------------------------------------------------------------------
-// Module Functions Declaration
-//----------------------------------------------------------------------------------
-
-#if defined(__cplusplus)
-extern "C" {            // Prevents name mangling of functions
-#endif
-// Physics system management
-PHYSACDEF void InitPhysics(void);                                                                           // Initializes physics system
-PHYSACDEF void UpdatePhysics(void);                                                                         // Update physics system
-PHYSACDEF void ResetPhysics(void);                                                                          // Reset physics system (global variables)
-PHYSACDEF void ClosePhysics(void);                                                                          // Close physics system and unload used memory
-PHYSACDEF void SetPhysicsTimeStep(double delta);                                                            // Sets physics fixed time step in milliseconds. 1.666666 by default
-PHYSACDEF void SetPhysicsGravity(float x, float y);                                                         // Sets physics global gravity force
-
-// Physic body creation/destroy
-PHYSACDEF PhysicsBody CreatePhysicsBodyCircle(Vector2 pos, float radius, float density);                    // Creates a new circle physics body with generic parameters
-PHYSACDEF PhysicsBody CreatePhysicsBodyRectangle(Vector2 pos, float width, float height, float density);    // Creates a new rectangle physics body with generic parameters
-PHYSACDEF PhysicsBody CreatePhysicsBodyPolygon(Vector2 pos, float radius, int sides, float density);        // Creates a new polygon physics body with generic parameters
-PHYSACDEF void DestroyPhysicsBody(PhysicsBody body);                                                        // Destroy a physics body
-
-// Physic body forces
-PHYSACDEF void PhysicsAddForce(PhysicsBody body, Vector2 force);                                            // Adds a force to a physics body
-PHYSACDEF void PhysicsAddTorque(PhysicsBody body, float amount);                                            // Adds an angular force to a physics body
-PHYSACDEF void PhysicsShatter(PhysicsBody body, Vector2 position, float force);                             // Shatters a polygon shape physics body to little physics bodies with explosion force
-PHYSACDEF void SetPhysicsBodyRotation(PhysicsBody body, float radians);                                     // Sets physics body shape transform based on radians parameter
-
-// Query physics info
-PHYSACDEF PhysicsBody GetPhysicsBody(int index);                                                            // Returns a physics body of the bodies pool at a specific index
-PHYSACDEF int GetPhysicsBodiesCount(void);                                                                  // Returns the current amount of created physics bodies
-PHYSACDEF int GetPhysicsShapeType(int index);                                                               // Returns the physics body shape type (PHYSICS_CIRCLE or PHYSICS_POLYGON)
-PHYSACDEF int GetPhysicsShapeVerticesCount(int index);                                                      // Returns the amount of vertices of a physics body shape
-PHYSACDEF Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex);                                      // Returns transformed position of a body shape (body position + vertex transformed position)
-#if defined(__cplusplus)
-}
-#endif
-
-#endif // PHYSAC_H
-
-/***********************************************************************************
-*
-*   PHYSAC IMPLEMENTATION
-*
-************************************************************************************/
-
-#if defined(PHYSAC_IMPLEMENTATION)
-
-// Support TRACELOG macros
-#if defined(PHYSAC_DEBUG)
-    #include <stdio.h>              // Required for: printf()
-    #define TRACELOG(...) printf(__VA_ARGS__)
-#else
-    #define TRACELOG(...) (void)0;
-#endif
-
-#include <stdlib.h>                 // Required for: malloc(), calloc(), free()
-#include <math.h>                   // Required for: cosf(), sinf(), fabs(), sqrtf()
-
-#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
-    // Time management functionality
-    #include <time.h>               // Required for: time(), clock_gettime()
-    #if defined(_WIN32)
-        #if defined(__cplusplus)
-        extern "C" {        // Prevents name mangling of functions
-        #endif
-        // Functions required to query time on Windows
-        int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
-        int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
-        #if defined(__cplusplus)
-        }
-        #endif
-    #endif
-    #if defined(__linux__) || defined(__FreeBSD__)
-        #if _POSIX_C_SOURCE < 199309L
-            #undef _POSIX_C_SOURCE
-            #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
-        #endif
-        #include <sys/time.h>           // Required for: timespec
-    #endif
-    #if defined(__APPLE__)              // macOS also defines __MACH__
-        #include <mach/mach_time.h>     // Required for: mach_absolute_time()
-    #endif
-#endif
-
-// NOTE: MSVC C++ compiler does not support compound literals (C99 feature)
-// Plain structures in C++ (without constructors) can be initialized from { } initializers.
-#if defined(__cplusplus)
-    #define CLITERAL(type)      type
-#else
-    #define CLITERAL(type)      (type)
-#endif
-
-//----------------------------------------------------------------------------------
-// Defines and Macros
-//----------------------------------------------------------------------------------
-#define PHYSAC_MIN(a,b)         (((a)<(b))?(a):(b))
-#define PHYSAC_MAX(a,b)         (((a)>(b))?(a):(b))
-#define PHYSAC_FLT_MAX          3.402823466e+38f
-#define PHYSAC_EPSILON          0.000001f
-#define PHYSAC_K                1.0f/3.0f
-#define PHYSAC_VECTOR_ZERO      CLITERAL(Vector2){ 0.0f, 0.0f }
-
-//----------------------------------------------------------------------------------
-// Global Variables Definition
-//----------------------------------------------------------------------------------
-static double deltaTime = 1.0/60.0/10.0 * 1000;             // Delta time in milliseconds used for physics steps
-
-#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
-// Time measure variables
-static double baseClockTicks = 0.0;                         // Offset clock ticks for MONOTONIC clock
-static unsigned long long int frequency = 0;                // Hi-res clock frequency
-static double startTime = 0.0;                              // Start time in milliseconds
-static double currentTime = 0.0;                            // Current time in milliseconds
-#endif
-
-// Physics system configuration
-static PhysicsBody bodies[PHYSAC_MAX_BODIES];               // Physics bodies pointers array
-static unsigned int physicsBodiesCount = 0;                 // Physics world current bodies counter
-static PhysicsManifold contacts[PHYSAC_MAX_MANIFOLDS];      // Physics bodies pointers array
-static unsigned int physicsManifoldsCount = 0;              // Physics world current manifolds counter
-
-static Vector2 gravityForce = { 0.0f, 9.81f };              // Physics world gravity force
-
-// Utilities variables
-static unsigned int usedMemory = 0;                         // Total allocated dynamic memory
-
-//----------------------------------------------------------------------------------
-// Module Internal Functions Declaration
-//----------------------------------------------------------------------------------
-#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
-// Timming measure functions
-static void InitTimerHiRes(void);                                                                           // Initializes hi-resolution MONOTONIC timer
-static unsigned long long int GetClockTicks(void);                                                          // Get hi-res MONOTONIC time measure in mseconds
-static double GetCurrentTime(void);                                                                         // Get current time measure in milliseconds
-#endif
-
-static void UpdatePhysicsStep(void);                                                                        // Update physics step (dynamics, collisions and position corrections)
-
-static int FindAvailableBodyIndex();                                                                        // Finds a valid index for a new physics body initialization
-static int FindAvailableManifoldIndex();                                                                    // Finds a valid index for a new manifold initialization
-static PhysicsVertexData CreateDefaultPolygon(float radius, int sides);                                     // Creates a random polygon shape with max vertex distance from polygon pivot
-static PhysicsVertexData CreateRectanglePolygon(Vector2 pos, Vector2 size);                                 // Creates a rectangle polygon shape based on a min and max positions
-
-static void InitializePhysicsManifolds(PhysicsManifold manifold);                                           // Initializes physics manifolds to solve collisions
-static PhysicsManifold CreatePhysicsManifold(PhysicsBody a, PhysicsBody b);                                 // Creates a new physics manifold to solve collision
-static void DestroyPhysicsManifold(PhysicsManifold manifold);                                               // Unitializes and destroys a physics manifold
-
-static void SolvePhysicsManifold(PhysicsManifold manifold);                                                 // Solves a created physics manifold between two physics bodies
-static void SolveCircleToCircle(PhysicsManifold manifold);                                                  // Solves collision between two circle shape physics bodies
-static void SolveCircleToPolygon(PhysicsManifold manifold);                                                 // Solves collision between a circle to a polygon shape physics bodies
-static void SolvePolygonToCircle(PhysicsManifold manifold);                                                 // Solves collision between a polygon to a circle shape physics bodies
-static void SolvePolygonToPolygon(PhysicsManifold manifold);                                                // Solves collision between two polygons shape physics bodies
-static void IntegratePhysicsForces(PhysicsBody body);                                                       // Integrates physics forces into velocity
-static void IntegratePhysicsVelocity(PhysicsBody body);                                                     // Integrates physics velocity into position and forces
-static void IntegratePhysicsImpulses(PhysicsManifold manifold);                                             // Integrates physics collisions impulses to solve collisions
-static void CorrectPhysicsPositions(PhysicsManifold manifold);                                              // Corrects physics bodies positions based on manifolds collision information
-static void FindIncidentFace(Vector2 *v0, Vector2 *v1, PhysicsShape ref, PhysicsShape inc, int index);      // Finds two polygon shapes incident face
-static float FindAxisLeastPenetration(int *faceIndex, PhysicsShape shapeA, PhysicsShape shapeB);            // Finds polygon shapes axis least penetration
-
-// Math required functions
-static Vector2 MathVector2Product(Vector2 vector, float value);                                             // Returns the product of a vector and a value
-static float MathVector2CrossProduct(Vector2 v1, Vector2 v2);                                               // Returns the cross product of two vectors
-static float MathVector2SqrLen(Vector2 vector);                                                             // Returns the len square root of a vector
-static float MathVector2DotProduct(Vector2 v1, Vector2 v2);                                                 // Returns the dot product of two vectors
-static inline float MathVector2SqrDistance(Vector2 v1, Vector2 v2);                                         // Returns the square root of distance between two vectors
-static void MathVector2Normalize(Vector2 *vector);                                                          // Returns the normalized values of a vector
-static Vector2 MathVector2Add(Vector2 v1, Vector2 v2);                                                      // Returns the sum of two given vectors
-static Vector2 MathVector2Subtract(Vector2 v1, Vector2 v2);                                                 // Returns the subtract of two given vectors
-static Matrix2x2 MathMatFromRadians(float radians);                                                         // Returns a matrix 2x2 from a given radians value
-static inline Matrix2x2 MathMatTranspose(Matrix2x2 matrix);                                                 // Returns the transpose of a given matrix 2x2
-static inline Vector2 MathMatVector2Product(Matrix2x2 matrix, Vector2 vector);                              // Returns product between matrix 2x2 and vector
-static int MathVector2Clip(Vector2 normal, Vector2 *faceA, Vector2 *faceB, float clip);                     // Returns clipping value based on a normal and two faces
-static Vector2 MathTriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3);                                  // Returns the barycenter of a triangle given by 3 points
-
-//----------------------------------------------------------------------------------
-// Module Functions Definition
-//----------------------------------------------------------------------------------
-
-// Initializes physics values, pointers and creates physics loop thread
-void InitPhysics(void)
-{
-#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
-    // Initialize high resolution timer
-    InitTimerHiRes();
-#endif
-
-    TRACELOG("[PHYSAC] Physics module initialized successfully\n");
-}
-
-// Sets physics global gravity force
-void SetPhysicsGravity(float x, float y)
-{
-    gravityForce.x = x;
-    gravityForce.y = y;
-}
-
-// Creates a new circle physics body with generic parameters
-PhysicsBody CreatePhysicsBodyCircle(Vector2 pos, float radius, float density)
-{
-    PhysicsBody body = CreatePhysicsBodyPolygon(pos, radius, PHYSAC_DEFAULT_CIRCLE_VERTICES, density);
-    return body;
-}
-
-// Creates a new rectangle physics body with generic parameters
-PhysicsBody CreatePhysicsBodyRectangle(Vector2 pos, float width, float height, float density)
-{
-    // NOTE: Make sure body data is initialized to 0
-    PhysicsBody body = (PhysicsBody)PHYSAC_CALLOC(sizeof(PhysicsBodyData), 1);
-    usedMemory += sizeof(PhysicsBodyData);
-
-    int id = FindAvailableBodyIndex();
-    if (id != -1)
-    {
-        // Initialize new body with generic values
-        body->id = id;
-        body->enabled = true;
-        body->position = pos;
-        body->shape.type = PHYSICS_POLYGON;
-        body->shape.body = body;
-        body->shape.transform = MathMatFromRadians(0.0f);
-        body->shape.vertexData = CreateRectanglePolygon(pos, CLITERAL(Vector2){ width, height });
-
-        // Calculate centroid and moment of inertia
-        Vector2 center = { 0.0f, 0.0f };
-        float area = 0.0f;
-        float inertia = 0.0f;
-
-        for (unsigned int i = 0; i < body->shape.vertexData.vertexCount; i++)
-        {
-            // Triangle vertices, third vertex implied as (0, 0)
-            Vector2 p1 = body->shape.vertexData.positions[i];
-            unsigned int nextIndex = (((i + 1) < body->shape.vertexData.vertexCount) ? (i + 1) : 0);
-            Vector2 p2 = body->shape.vertexData.positions[nextIndex];
-
-            float D = MathVector2CrossProduct(p1, p2);
-            float triangleArea = D/2;
-
-            area += triangleArea;
-
-            // Use area to weight the centroid average, not just vertex position
-            center.x += triangleArea*PHYSAC_K*(p1.x + p2.x);
-            center.y += triangleArea*PHYSAC_K*(p1.y + p2.y);
-
-            float intx2 = p1.x*p1.x + p2.x*p1.x + p2.x*p2.x;
-            float inty2 = p1.y*p1.y + p2.y*p1.y + p2.y*p2.y;
-            inertia += (0.25f*PHYSAC_K*D)*(intx2 + inty2);
-        }
-
-        center.x *= 1.0f/area;
-        center.y *= 1.0f/area;
-
-        // Translate vertices to centroid (make the centroid (0, 0) for the polygon in model space)
-        // Note: this is not really necessary
-        for (unsigned int i = 0; i < body->shape.vertexData.vertexCount; i++)
-        {
-            body->shape.vertexData.positions[i].x -= center.x;
-            body->shape.vertexData.positions[i].y -= center.y;
-        }
-
-        body->mass = density*area;
-        body->inverseMass = ((body->mass != 0.0f) ? 1.0f/body->mass : 0.0f);
-        body->inertia = density*inertia;
-        body->inverseInertia = ((body->inertia != 0.0f) ? 1.0f/body->inertia : 0.0f);
-        body->staticFriction = 0.4f;
-        body->dynamicFriction = 0.2f;
-        body->restitution = 0.0f;
-        body->useGravity = true;
-        body->isGrounded = false;
-        body->freezeOrient = false;
-
-        // Add new body to bodies pointers array and update bodies count
-        bodies[physicsBodiesCount] = body;
-        physicsBodiesCount++;
-
-        TRACELOG("[PHYSAC] Physic body created successfully (id: %i)\n", body->id);
-    }
-    else TRACELOG("[PHYSAC] Physic body could not be created, PHYSAC_MAX_BODIES reached\n");
-
-    return body;
-}
-
-// Creates a new polygon physics body with generic parameters
-PhysicsBody CreatePhysicsBodyPolygon(Vector2 pos, float radius, int sides, float density)
-{
-    PhysicsBody body = (PhysicsBody)PHYSAC_MALLOC(sizeof(PhysicsBodyData));
-    usedMemory += sizeof(PhysicsBodyData);
-
-    int id = FindAvailableBodyIndex();
-    if (id != -1)
-    {
-        // Initialize new body with generic values
-        body->id = id;
-        body->enabled = true;
-        body->position = pos;
-        body->velocity = PHYSAC_VECTOR_ZERO;
-        body->force = PHYSAC_VECTOR_ZERO;
-        body->angularVelocity = 0.0f;
-        body->torque = 0.0f;
-        body->orient = 0.0f;
-        body->shape.type = PHYSICS_POLYGON;
-        body->shape.body = body;
-        body->shape.transform = MathMatFromRadians(0.0f);
-        body->shape.vertexData = CreateDefaultPolygon(radius, sides);
-
-        // Calculate centroid and moment of inertia
-        Vector2 center = { 0.0f, 0.0f };
-        float area = 0.0f;
-        float inertia = 0.0f;
-
-        for (unsigned int i = 0; i < body->shape.vertexData.vertexCount; i++)
-        {
-            // Triangle vertices, third vertex implied as (0, 0)
-            Vector2 position1 = body->shape.vertexData.positions[i];
-            unsigned int nextIndex = (((i + 1) < body->shape.vertexData.vertexCount) ? (i + 1) : 0);
-            Vector2 position2 = body->shape.vertexData.positions[nextIndex];
-
-            float cross = MathVector2CrossProduct(position1, position2);
-            float triangleArea = cross/2;
-
-            area += triangleArea;
-
-            // Use area to weight the centroid average, not just vertex position
-            center.x += triangleArea*PHYSAC_K*(position1.x + position2.x);
-            center.y += triangleArea*PHYSAC_K*(position1.y + position2.y);
-
-            float intx2 = position1.x*position1.x + position2.x*position1.x + position2.x*position2.x;
-            float inty2 = position1.y*position1.y + position2.y*position1.y + position2.y*position2.y;
-            inertia += (0.25f*PHYSAC_K*cross)*(intx2 + inty2);
-        }
-
-        center.x *= 1.0f/area;
-        center.y *= 1.0f/area;
-
-        // Translate vertices to centroid (make the centroid (0, 0) for the polygon in model space)
-        // Note: this is not really necessary
-        for (unsigned int i = 0; i < body->shape.vertexData.vertexCount; i++)
-        {
-            body->shape.vertexData.positions[i].x -= center.x;
-            body->shape.vertexData.positions[i].y -= center.y;
-        }
-
-        body->mass = density*area;
-        body->inverseMass = ((body->mass != 0.0f) ? 1.0f/body->mass : 0.0f);
-        body->inertia = density*inertia;
-        body->inverseInertia = ((body->inertia != 0.0f) ? 1.0f/body->inertia : 0.0f);
-        body->staticFriction = 0.4f;
-        body->dynamicFriction = 0.2f;
-        body->restitution = 0.0f;
-        body->useGravity = true;
-        body->isGrounded = false;
-        body->freezeOrient = false;
-
-        // Add new body to bodies pointers array and update bodies count
-        bodies[physicsBodiesCount] = body;
-        physicsBodiesCount++;
-
-        TRACELOG("[PHYSAC] Physic body created successfully (id: %i)\n", body->id);
-    }
-    else TRACELOG("[PHYSAC] Physics body could not be created, PHYSAC_MAX_BODIES reached\n");
-
-    return body;
-}
-
-// Adds a force to a physics body
-void PhysicsAddForce(PhysicsBody body, Vector2 force)
-{
-    if (body != NULL) body->force = MathVector2Add(body->force, force);
-}
-
-// Adds an angular force to a physics body
-void PhysicsAddTorque(PhysicsBody body, float amount)
-{
-    if (body != NULL) body->torque += amount;
-}
-
-// Shatters a polygon shape physics body to little physics bodies with explosion force
-void PhysicsShatter(PhysicsBody body, Vector2 position, float force)
-{
-    if (body != NULL)
-    {
-        if (body->shape.type == PHYSICS_POLYGON)
-        {
-            PhysicsVertexData vertexData = body->shape.vertexData;
-            bool collision = false;
-
-            for (unsigned int i = 0; i < vertexData.vertexCount; i++)
-            {
-                Vector2 positionA = body->position;
-                Vector2 positionB = MathMatVector2Product(body->shape.transform, MathVector2Add(body->position, vertexData.positions[i]));
-                unsigned int nextIndex = (((i + 1) < vertexData.vertexCount) ? (i + 1) : 0);
-                Vector2 positionC = MathMatVector2Product(body->shape.transform, MathVector2Add(body->position, vertexData.positions[nextIndex]));
-
-                // Check collision between each triangle
-                float alpha = ((positionB.y - positionC.y)*(position.x - positionC.x) + (positionC.x - positionB.x)*(position.y - positionC.y))/
-                              ((positionB.y - positionC.y)*(positionA.x - positionC.x) + (positionC.x - positionB.x)*(positionA.y - positionC.y));
-
-                float beta = ((positionC.y - positionA.y)*(position.x - positionC.x) + (positionA.x - positionC.x)*(position.y - positionC.y))/
-                             ((positionB.y - positionC.y)*(positionA.x - positionC.x) + (positionC.x - positionB.x)*(positionA.y - positionC.y));
-
-                float gamma = 1.0f - alpha - beta;
-
-                if ((alpha > 0.0f) && (beta > 0.0f) & (gamma > 0.0f))
-                {
-                    collision = true;
-                    break;
-                }
-            }
-
-            if (collision)
-            {
-                int count = vertexData.vertexCount;
-                Vector2 bodyPos = body->position;
-                Vector2 *vertices = (Vector2 *)PHYSAC_MALLOC(sizeof(Vector2)*count);
-                Matrix2x2 trans = body->shape.transform;
-                for (int i = 0; i < count; i++) vertices[i] = vertexData.positions[i];
-
-                // Destroy shattered physics body
-                DestroyPhysicsBody(body);
-
-                for (int i = 0; i < count; i++)
-                {
-                    int nextIndex = (((i + 1) < count) ? (i + 1) : 0);
-                    Vector2 center = MathTriangleBarycenter(vertices[i], vertices[nextIndex], PHYSAC_VECTOR_ZERO);
-                    center = MathVector2Add(bodyPos, center);
-                    Vector2 offset = MathVector2Subtract(center, bodyPos);
-
-                    PhysicsBody body = CreatePhysicsBodyPolygon(center, 10, 3, 10);     // Create polygon physics body with relevant values
-
-                    PhysicsVertexData vertexData = { 0 };
-                    vertexData.vertexCount = 3;
-
-                    vertexData.positions[0] = MathVector2Subtract(vertices[i], offset);
-                    vertexData.positions[1] = MathVector2Subtract(vertices[nextIndex], offset);
-                    vertexData.positions[2] = MathVector2Subtract(position, center);
-
-                    // Separate vertices to avoid unnecessary physics collisions
-                    vertexData.positions[0].x *= 0.95f;
-                    vertexData.positions[0].y *= 0.95f;
-                    vertexData.positions[1].x *= 0.95f;
-                    vertexData.positions[1].y *= 0.95f;
-                    vertexData.positions[2].x *= 0.95f;
-                    vertexData.positions[2].y *= 0.95f;
-
-                    // Calculate polygon faces normals
-                    for (unsigned int j = 0; j < vertexData.vertexCount; j++)
-                    {
-                        unsigned int nextVertex = (((j + 1) < vertexData.vertexCount) ? (j + 1) : 0);
-                        Vector2 face = MathVector2Subtract(vertexData.positions[nextVertex], vertexData.positions[j]);
-
-                        vertexData.normals[j] = CLITERAL(Vector2){ face.y, -face.x };
-                        MathVector2Normalize(&vertexData.normals[j]);
-                    }
-
-                    // Apply computed vertex data to new physics body shape
-                    body->shape.vertexData = vertexData;
-                    body->shape.transform = trans;
-
-                    // Calculate centroid and moment of inertia
-                    center = PHYSAC_VECTOR_ZERO;
-                    float area = 0.0f;
-                    float inertia = 0.0f;
-
-                    for (unsigned int j = 0; j < body->shape.vertexData.vertexCount; j++)
-                    {
-                        // Triangle vertices, third vertex implied as (0, 0)
-                        Vector2 p1 = body->shape.vertexData.positions[j];
-                        unsigned int nextVertex = (((j + 1) < body->shape.vertexData.vertexCount) ? (j + 1) : 0);
-                        Vector2 p2 = body->shape.vertexData.positions[nextVertex];
-
-                        float D = MathVector2CrossProduct(p1, p2);
-                        float triangleArea = D/2;
-
-                        area += triangleArea;
-
-                        // Use area to weight the centroid average, not just vertex position
-                        center.x += triangleArea*PHYSAC_K*(p1.x + p2.x);
-                        center.y += triangleArea*PHYSAC_K*(p1.y + p2.y);
-
-                        float intx2 = p1.x*p1.x + p2.x*p1.x + p2.x*p2.x;
-                        float inty2 = p1.y*p1.y + p2.y*p1.y + p2.y*p2.y;
-                        inertia += (0.25f*PHYSAC_K*D)*(intx2 + inty2);
-                    }
-
-                    center.x *= 1.0f/area;
-                    center.y *= 1.0f/area;
-
-                    body->mass = area;
-                    body->inverseMass = ((body->mass != 0.0f) ? 1.0f/body->mass : 0.0f);
-                    body->inertia = inertia;
-                    body->inverseInertia = ((body->inertia != 0.0f) ? 1.0f/body->inertia : 0.0f);
-
-                    // Calculate explosion force direction
-                    Vector2 pointA = body->position;
-                    Vector2 pointB = MathVector2Subtract(vertexData.positions[1], vertexData.positions[0]);
-                    pointB.x /= 2.0f;
-                    pointB.y /= 2.0f;
-                    Vector2 forceDirection = MathVector2Subtract(MathVector2Add(pointA, MathVector2Add(vertexData.positions[0], pointB)), body->position);
-                    MathVector2Normalize(&forceDirection);
-                    forceDirection.x *= force;
-                    forceDirection.y *= force;
-
-                    // Apply force to new physics body
-                    PhysicsAddForce(body, forceDirection);
-                }
-
-                PHYSAC_FREE(vertices);
-            }
-        }
-    }
-    else TRACELOG("[PHYSAC] WARNING: PhysicsShatter: NULL physic body\n");
-}
-
-// Returns the current amount of created physics bodies
-int GetPhysicsBodiesCount(void)
-{
-    return physicsBodiesCount;
-}
-
-// Returns a physics body of the bodies pool at a specific index
-PhysicsBody GetPhysicsBody(int index)
-{
-    PhysicsBody body = NULL;
-
-    if (index < (int)physicsBodiesCount)
-    {
-        body = bodies[index];
-
-        if (body == NULL) TRACELOG("[PHYSAC] WARNING: GetPhysicsBody: NULL physic body\n");
-    }
-    else TRACELOG("[PHYSAC] WARNING: Physic body index is out of bounds\n");
-
-    return body;
-}
-
-// Returns the physics body shape type (PHYSICS_CIRCLE or PHYSICS_POLYGON)
-int GetPhysicsShapeType(int index)
-{
-    int result = -1;
-
-    if (index < (int)physicsBodiesCount)
-    {
-        PhysicsBody body = bodies[index];
-
-        if (body != NULL) result = body->shape.type;
-        else TRACELOG("[PHYSAC] WARNING: GetPhysicsShapeType: NULL physic body\n");
-    }
-    else TRACELOG("[PHYSAC] WARNING: Physic body index is out of bounds\n");
-
-    return result;
-}
-
-// Returns the amount of vertices of a physics body shape
-int GetPhysicsShapeVerticesCount(int index)
-{
-    int result = 0;
-
-    if (index < (int)physicsBodiesCount)
-    {
-        PhysicsBody body = bodies[index];
-
-        if (body != NULL)
-        {
-            switch (body->shape.type)
-            {
-                case PHYSICS_CIRCLE: result = PHYSAC_DEFAULT_CIRCLE_VERTICES; break;
-                case PHYSICS_POLYGON: result = body->shape.vertexData.vertexCount; break;
-                default: break;
-            }
-        }
-        else TRACELOG("[PHYSAC] WARNING: GetPhysicsShapeVerticesCount: NULL physic body\n");
-    }
-    else TRACELOG("[PHYSAC] WARNING: Physic body index is out of bounds\n");
-
-    return result;
-}
-
-// Returns transformed position of a body shape (body position + vertex transformed position)
-Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex)
-{
-    Vector2 position = { 0.0f, 0.0f };
-
-    if (body != NULL)
-    {
-        switch (body->shape.type)
-        {
-            case PHYSICS_CIRCLE:
-            {
-                position.x = body->position.x + cosf(360.0f/PHYSAC_DEFAULT_CIRCLE_VERTICES*vertex*PHYSAC_DEG2RAD)*body->shape.radius;
-                position.y = body->position.y + sinf(360.0f/PHYSAC_DEFAULT_CIRCLE_VERTICES*vertex*PHYSAC_DEG2RAD)*body->shape.radius;
-            } break;
-            case PHYSICS_POLYGON:
-            {
-                PhysicsVertexData vertexData = body->shape.vertexData;
-                position = MathVector2Add(body->position, MathMatVector2Product(body->shape.transform, vertexData.positions[vertex]));
-            } break;
-            default: break;
-        }
-    }
-    else TRACELOG("[PHYSAC] WARNING: GetPhysicsShapeVertex: NULL physic body\n");
-
-    return position;
-}
-
-// Sets physics body shape transform based on radians parameter
-void SetPhysicsBodyRotation(PhysicsBody body, float radians)
-{
-    if (body != NULL)
-    {
-        body->orient = radians;
-
-        if (body->shape.type == PHYSICS_POLYGON) body->shape.transform = MathMatFromRadians(radians);
-    }
-}
-
-// Unitializes and destroys a physics body
-void DestroyPhysicsBody(PhysicsBody body)
-{
-    if (body != NULL)
-    {
-        int id = body->id;
-        int index = -1;
-
-        for (unsigned int i = 0; i < physicsBodiesCount; i++)
-        {
-            if (bodies[i]->id == id)
-            {
-                index = i;
-                break;
-            }
-        }
-
-        if (index == -1)
-        {
-            TRACELOG("[PHYSAC] WARNING: Requested body (id: %i) can not be found\n", id);
-            return;     // Prevent access to index -1
-        }
-
-        // Free body allocated memory
-        PHYSAC_FREE(body);
-        usedMemory -= sizeof(PhysicsBodyData);
-        bodies[index] = NULL;
-
-        // Reorder physics bodies pointers array and its catched index
-        for (unsigned int i = index; i < physicsBodiesCount; i++)
-        {
-            if ((i + 1) < physicsBodiesCount) bodies[i] = bodies[i + 1];
-        }
-
-        // Update physics bodies count
-        physicsBodiesCount--;
-
-        TRACELOG("[PHYSAC] Physic body destroyed successfully (id: %i)\n", id);
-    }
-    else TRACELOG("[PHYSAC] WARNING: DestroyPhysicsBody: NULL physic body\n");
-}
-
-// Destroys created physics bodies and manifolds and resets global values
-void ResetPhysics(void)
-{
-    if (physicsBodiesCount > 0)
-    {
-        // Unitialize physics bodies dynamic memory allocations
-        for (int i = physicsBodiesCount - 1; i >= 0; i--)
-        {
-            PhysicsBody body = bodies[i];
-
-            if (body != NULL)
-            {
-                PHYSAC_FREE(body);
-                bodies[i] = NULL;
-                usedMemory -= sizeof(PhysicsBodyData);
-            }
-        }
-
-        physicsBodiesCount = 0;
-    }
-
-    if (physicsManifoldsCount > 0)
-    {
-        // Unitialize physics manifolds dynamic memory allocations
-        for (int i = physicsManifoldsCount - 1; i >= 0; i--)
-        {
-            PhysicsManifold manifold = contacts[i];
-
-            if (manifold != NULL)
-            {
-                PHYSAC_FREE(manifold);
-                contacts[i] = NULL;
-                usedMemory -= sizeof(PhysicsManifoldData);
-            }
-        }
-
-        physicsManifoldsCount = 0;
-    }
-
-    TRACELOG("[PHYSAC] Physics module reseted successfully\n");
-}
-
-// Unitializes physics pointers and exits physics loop thread
-void ClosePhysics(void)
-{
-    // Unitialize physics manifolds dynamic memory allocations
-    if (physicsManifoldsCount > 0)
-    {
-        for (int i = physicsManifoldsCount - 1; i >= 0; i--) DestroyPhysicsManifold(contacts[i]);
-    }
-    
-    // Unitialize physics bodies dynamic memory allocations
-    if (physicsBodiesCount > 0)
-    {
-        for (int i = physicsBodiesCount - 1; i >= 0; i--) DestroyPhysicsBody(bodies[i]);
-    }
-
-    // Trace log info
-    if ((physicsBodiesCount > 0) || (usedMemory != 0)) 
-    {
-        TRACELOG("[PHYSAC] WARNING: Physics module closed with unallocated bodies (BODIES: %i, MEMORY: %i bytes)\n", physicsBodiesCount, usedMemory);
-    }
-    else if ((physicsManifoldsCount > 0) || (usedMemory != 0)) 
-    {
-        TRACELOG("[PHYSAC] WARNING: Pysics module closed with unallocated manifolds (MANIFOLDS: %i, MEMORY: %i bytes)\n", physicsManifoldsCount, usedMemory);
-    }
-    else TRACELOG("[PHYSAC] Physics module closed successfully\n");
-}
-
-// Update physics system
-// Physics steps are launched at a fixed time step if enabled
-void UpdatePhysics(void)
-{
-#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
-    static double deltaTimeAccumulator = 0.0;
-
-    // Calculate current time (ms)
-    currentTime = GetCurrentTime();
-
-    // Calculate current delta time (ms)
-    const double delta = currentTime - startTime;
-
-    // Store the time elapsed since the last frame began
-    deltaTimeAccumulator += delta;
-
-    // Fixed time stepping loop
-    while (deltaTimeAccumulator >= deltaTime)
-    {
-        UpdatePhysicsStep();
-        deltaTimeAccumulator -= deltaTime;
-    }
-
-    // Record the starting of this frame
-    startTime = currentTime;
-#else
-    UpdatePhysicsStep();
-#endif
-}
-
-void SetPhysicsTimeStep(double delta)
-{
-    deltaTime = delta;
-}
-
-//----------------------------------------------------------------------------------
-// Module Internal Functions Definition
-//----------------------------------------------------------------------------------
-#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
-// Initializes hi-resolution MONOTONIC timer
-static void InitTimerHiRes(void)
-{
-#if defined(_WIN32)
-    QueryPerformanceFrequency((unsigned long long int *) &frequency);
-#endif
-
-#if defined(__EMSCRIPTEN__) || defined(__linux__)
-    struct timespec now;
-    if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) frequency = 1000000000;
-#endif
-
-#if defined(__APPLE__)
-    mach_timebase_info_data_t timebase;
-    mach_timebase_info(&timebase);
-    frequency = (timebase.denom*1e9)/timebase.numer;
-#endif
-
-    baseClockTicks = (double)GetClockTicks();      // Get MONOTONIC clock time offset
-    startTime = GetCurrentTime();                  // Get current time in milliseconds
-}
-
-// Get hi-res MONOTONIC time measure in clock ticks
-static unsigned long long int GetClockTicks(void)
-{
-    unsigned long long int value = 0;
-
-#if defined(_WIN32)
-    QueryPerformanceCounter((unsigned long long int *) &value);
-#endif
-
-#if defined(__linux__)
-    struct timespec now;
-    clock_gettime(CLOCK_MONOTONIC, &now);
-    value = (unsigned long long int)now.tv_sec*(unsigned long long int)1000000000 + (unsigned long long int)now.tv_nsec;
-#endif
-
-#if defined(__APPLE__)
-    value = mach_absolute_time();
-#endif
-
-    return value;
-}
-
-// Get current time in milliseconds
-static double GetCurrentTime(void)
-{
-    return (double)(GetClockTicks() - baseClockTicks)/frequency*1000;
-}
-#endif // !PHYSAC_AVOID_TIMMING_SYSTEM
-
-// Update physics step (dynamics, collisions and position corrections)
-static void UpdatePhysicsStep(void)
-{
-    // Clear previous generated collisions information
-    for (int i = (int)physicsManifoldsCount - 1; i >= 0; i--)
-    {
-        PhysicsManifold manifold = contacts[i];
-        if (manifold != NULL) DestroyPhysicsManifold(manifold);
-    }
-
-    // Reset physics bodies grounded state
-    for (unsigned int i = 0; i < physicsBodiesCount; i++)
-    {
-        PhysicsBody body = bodies[i];
-        body->isGrounded = false;
-    }
- 
-    // Generate new collision information
-    for (unsigned int i = 0; i < physicsBodiesCount; i++)
-    {
-        PhysicsBody bodyA = bodies[i];
-
-        if (bodyA != NULL)
-        {
-            for (unsigned int j = i + 1; j < physicsBodiesCount; j++)
-            {
-                PhysicsBody bodyB = bodies[j];
-
-                if (bodyB != NULL)
-                {
-                    if ((bodyA->inverseMass == 0) && (bodyB->inverseMass == 0)) continue;
-
-                    PhysicsManifold manifold = CreatePhysicsManifold(bodyA, bodyB);
-                    SolvePhysicsManifold(manifold);
-
-                    if (manifold->contactsCount > 0)
-                    {
-                        // Create a new manifold with same information as previously solved manifold and add it to the manifolds pool last slot
-                        PhysicsManifold manifold = CreatePhysicsManifold(bodyA, bodyB);
-                        manifold->penetration = manifold->penetration;
-                        manifold->normal = manifold->normal;
-                        manifold->contacts[0] = manifold->contacts[0];
-                        manifold->contacts[1] = manifold->contacts[1];
-                        manifold->contactsCount = manifold->contactsCount;
-                        manifold->restitution = manifold->restitution;
-                        manifold->dynamicFriction = manifold->dynamicFriction;
-                        manifold->staticFriction = manifold->staticFriction;
-                    }
-                }
-            }
-        }
-    }
-
-    // Integrate forces to physics bodies
-    for (unsigned int i = 0; i < physicsBodiesCount; i++)
-    {
-        PhysicsBody body = bodies[i];
-        if (body != NULL) IntegratePhysicsForces(body);
-    }
-
-    // Initialize physics manifolds to solve collisions
-    for (unsigned int i = 0; i < physicsManifoldsCount; i++)
-    {
-        PhysicsManifold manifold = contacts[i];
-        if (manifold != NULL) InitializePhysicsManifolds(manifold);
-    }
-
-    // Integrate physics collisions impulses to solve collisions
-    for (unsigned int i = 0; i < PHYSAC_COLLISION_ITERATIONS; i++)
-    {
-        for (unsigned int j = 0; j < physicsManifoldsCount; j++)
-        {
-            PhysicsManifold manifold = contacts[i];
-            if (manifold != NULL) IntegratePhysicsImpulses(manifold);
-        }
-    }
-
-    // Integrate velocity to physics bodies
-    for (unsigned int i = 0; i < physicsBodiesCount; i++)
-    {
-        PhysicsBody body = bodies[i];
-        if (body != NULL) IntegratePhysicsVelocity(body);
-    }
-
-    // Correct physics bodies positions based on manifolds collision information
-    for (unsigned int i = 0; i < physicsManifoldsCount; i++)
-    {
-        PhysicsManifold manifold = contacts[i];
-        if (manifold != NULL) CorrectPhysicsPositions(manifold);
-    }
-
-    // Clear physics bodies forces
-    for (unsigned int i = 0; i < physicsBodiesCount; i++)
-    {
-        PhysicsBody body = bodies[i];
-        if (body != NULL)
-        {
-            body->force = PHYSAC_VECTOR_ZERO;
-            body->torque = 0.0f;
-        }
-    }
-}
-
-// Finds a valid index for a new physics body initialization
-static int FindAvailableBodyIndex()
-{
-    int index = -1;
-    for (int i = 0; i < PHYSAC_MAX_BODIES; i++)
-    {
-        int currentId = i;
-
-        // Check if current id already exist in other physics body
-        for (unsigned int k = 0; k < physicsBodiesCount; k++)
-        {
-            if (bodies[k]->id == currentId)
-            {
-                currentId++;
-                break;
-            }
-        }
-
-        // If it is not used, use it as new physics body id
-        if (currentId == (int)i)
-        {
-            index = (int)i;
-            break;
-        }
-    }
-
-    return index;
-}
-
-// Creates a default polygon shape with max vertex distance from polygon pivot
-static PhysicsVertexData CreateDefaultPolygon(float radius, int sides)
-{
-    PhysicsVertexData data = { 0 };
-    data.vertexCount = sides;
-
-    // Calculate polygon vertices positions
-    for (unsigned int i = 0; i < data.vertexCount; i++)
-    {
-        data.positions[i].x = (float)cosf(360.0f/sides*i*PHYSAC_DEG2RAD)*radius;
-        data.positions[i].y = (float)sinf(360.0f/sides*i*PHYSAC_DEG2RAD)*radius;
-    }
-
-    // Calculate polygon faces normals
-    for (int i = 0; i < (int)data.vertexCount; i++)
-    {
-        int nextIndex = (((i + 1) < sides) ? (i + 1) : 0);
-        Vector2 face = MathVector2Subtract(data.positions[nextIndex], data.positions[i]);
-
-        data.normals[i] = CLITERAL(Vector2){ face.y, -face.x };
-        MathVector2Normalize(&data.normals[i]);
-    }
-
-    return data;
-}
-
-// Creates a rectangle polygon shape based on a min and max positions
-static PhysicsVertexData CreateRectanglePolygon(Vector2 pos, Vector2 size)
-{
-    PhysicsVertexData data = { 0 };
-    data.vertexCount = 4;
-
-    // Calculate polygon vertices positions
-    data.positions[0] = CLITERAL(Vector2){ pos.x + size.x/2, pos.y - size.y/2 };
-    data.positions[1] = CLITERAL(Vector2){ pos.x + size.x/2, pos.y + size.y/2 };
-    data.positions[2] = CLITERAL(Vector2){ pos.x - size.x/2, pos.y + size.y/2 };
-    data.positions[3] = CLITERAL(Vector2){ pos.x - size.x/2, pos.y - size.y/2 };
-
-    // Calculate polygon faces normals
-    for (unsigned int i = 0; i < data.vertexCount; i++)
-    {
-        int nextIndex = (((i + 1) < data.vertexCount) ? (i + 1) : 0);
-        Vector2 face = MathVector2Subtract(data.positions[nextIndex], data.positions[i]);
-
-        data.normals[i] = CLITERAL(Vector2){ face.y, -face.x };
-        MathVector2Normalize(&data.normals[i]);
-    }
-
-    return data;
-}
-
-// Finds a valid index for a new manifold initialization
-static int FindAvailableManifoldIndex()
-{
-    int index = -1;
-    for (int i = 0; i < PHYSAC_MAX_MANIFOLDS; i++)
-    {
-        int currentId = i;
-
-        // Check if current id already exist in other physics body
-        for (unsigned int k = 0; k < physicsManifoldsCount; k++)
-        {
-            if (contacts[k]->id == currentId)
-            {
-                currentId++;
-                break;
-            }
-        }
-
-        // If it is not used, use it as new physics body id
-        if (currentId == i)
-        {
-            index = i;
-            break;
-        }
-    }
-
-    return index;
-}
-
-// Creates a new physics manifold to solve collision
-static PhysicsManifold CreatePhysicsManifold(PhysicsBody a, PhysicsBody b)
-{
-    PhysicsManifold manifold = (PhysicsManifold)PHYSAC_MALLOC(sizeof(PhysicsManifoldData));
-    usedMemory += sizeof(PhysicsManifoldData);
-
-    int id = FindAvailableManifoldIndex();
-    if (id != -1)
-    {
-        // Initialize new manifold with generic values
-        manifold->id = id;
-        manifold->bodyA = a;
-        manifold->bodyB = b;
-        manifold->penetration = 0;
-        manifold->normal = PHYSAC_VECTOR_ZERO;
-        manifold->contacts[0] = PHYSAC_VECTOR_ZERO;
-        manifold->contacts[1] = PHYSAC_VECTOR_ZERO;
-        manifold->contactsCount = 0;
-        manifold->restitution = 0.0f;
-        manifold->dynamicFriction = 0.0f;
-        manifold->staticFriction = 0.0f;
-
-        // Add new body to bodies pointers array and update bodies count
-        contacts[physicsManifoldsCount] = manifold;
-        physicsManifoldsCount++;
-    }
-    else TRACELOG("[PHYSAC] Physic manifold could not be created, PHYSAC_MAX_MANIFOLDS reached\n");
-
-    return manifold;
-}
-
-// Unitializes and destroys a physics manifold
-static void DestroyPhysicsManifold(PhysicsManifold manifold)
-{
-    if (manifold != NULL)
-    {
-        int id = manifold->id;
-        int index = -1;
-
-        for (unsigned int i = 0; i < physicsManifoldsCount; i++)
-        {
-            if (contacts[i]->id == id)
-            {
-                index = i;
-                break;
-            }
-        }
-
-        if (index == -1) return;     // Prevent access to index -1
-
-        // Free manifold allocated memory
-        PHYSAC_FREE(manifold);
-        usedMemory -= sizeof(PhysicsManifoldData);
-        contacts[index] = NULL;
-
-        // Reorder physics manifolds pointers array and its catched index
-        for (unsigned int i = index; i < physicsManifoldsCount; i++)
-        {
-            if ((i + 1) < physicsManifoldsCount) contacts[i] = contacts[i + 1];
-        }
-
-        // Update physics manifolds count
-        physicsManifoldsCount--;
-    }
-    else TRACELOG("[PHYSAC] WARNING: DestroyPhysicsManifold: NULL physic manifold\n");
-}
-
-// Solves a created physics manifold between two physics bodies
-static void SolvePhysicsManifold(PhysicsManifold manifold)
-{
-    switch (manifold->bodyA->shape.type)
-    {
-        case PHYSICS_CIRCLE:
-        {
-            switch (manifold->bodyB->shape.type)
-            {
-                case PHYSICS_CIRCLE: SolveCircleToCircle(manifold); break;
-                case PHYSICS_POLYGON: SolveCircleToPolygon(manifold); break;
-                default: break;
-            }
-        } break;
-        case PHYSICS_POLYGON:
-        {
-            switch (manifold->bodyB->shape.type)
-            {
-                case PHYSICS_CIRCLE: SolvePolygonToCircle(manifold); break;
-                case PHYSICS_POLYGON: SolvePolygonToPolygon(manifold); break;
-                default: break;
-            }
-        } break;
-        default: break;
-    }
-
-    // Update physics body grounded state if normal direction is down and grounded state is not set yet in previous manifolds
-    if (!manifold->bodyB->isGrounded) manifold->bodyB->isGrounded = (manifold->normal.y < 0);
-}
-
-// Solves collision between two circle shape physics bodies
-static void SolveCircleToCircle(PhysicsManifold manifold)
-{
-    PhysicsBody bodyA = manifold->bodyA;
-    PhysicsBody bodyB = manifold->bodyB;
-
-    if ((bodyA == NULL) || (bodyB == NULL)) return;
-
-    // Calculate translational vector, which is normal
-    Vector2 normal = MathVector2Subtract(bodyB->position, bodyA->position);
-
-    float distSqr = MathVector2SqrLen(normal);
-    float radius = bodyA->shape.radius + bodyB->shape.radius;
-
-    // Check if circles are not in contact
-    if (distSqr >= radius*radius)
-    {
-        manifold->contactsCount = 0;
-        return;
-    }
-
-    float distance = sqrtf(distSqr);
-    manifold->contactsCount = 1;
-
-    if (distance == 0.0f)
-    {
-        manifold->penetration = bodyA->shape.radius;
-        manifold->normal = CLITERAL(Vector2){ 1.0f, 0.0f };
-        manifold->contacts[0] = bodyA->position;
-    }
-    else
-    {
-        manifold->penetration = radius - distance;
-        manifold->normal = CLITERAL(Vector2){ normal.x/distance, normal.y/distance }; // Faster than using MathVector2Normalize() due to sqrt is already performed
-        manifold->contacts[0] = CLITERAL(Vector2){ manifold->normal.x*bodyA->shape.radius + bodyA->position.x, manifold->normal.y*bodyA->shape.radius + bodyA->position.y };
-    }
-
-    // Update physics body grounded state if normal direction is down
-    if (!bodyA->isGrounded) bodyA->isGrounded = (manifold->normal.y < 0);
-}
-
-// Solves collision between a circle to a polygon shape physics bodies
-static void SolveCircleToPolygon(PhysicsManifold manifold)
-{
-    PhysicsBody bodyA = manifold->bodyA;
-    PhysicsBody bodyB = manifold->bodyB;
-
-    if ((bodyA == NULL) || (bodyB == NULL)) return;
-
-    manifold->contactsCount = 0;
-
-    // Transform circle center to polygon transform space
-    Vector2 center = bodyA->position;
-    center = MathMatVector2Product(MathMatTranspose(bodyB->shape.transform), MathVector2Subtract(center, bodyB->position));
-
-    // Find edge with minimum penetration
-    // It is the same concept as using support points in SolvePolygonToPolygon
-    float separation = -PHYSAC_FLT_MAX;
-    int faceNormal = 0;
-    PhysicsVertexData vertexData = bodyB->shape.vertexData;
-
-    for (unsigned int i = 0; i < vertexData.vertexCount; i++)
-    {
-        float currentSeparation = MathVector2DotProduct(vertexData.normals[i], MathVector2Subtract(center, vertexData.positions[i]));
-
-        if (currentSeparation > bodyA->shape.radius) return;
-
-        if (currentSeparation > separation)
-        {
-            separation = currentSeparation;
-            faceNormal = i;
-        }
-    }
-
-    // Grab face's vertices
-    Vector2 v1 = vertexData.positions[faceNormal];
-    int nextIndex = (((faceNormal + 1) < (int)vertexData.vertexCount) ? (faceNormal + 1) : 0);
-    Vector2 v2 = vertexData.positions[nextIndex];
-
-    // Check to see if center is within polygon
-    if (separation < PHYSAC_EPSILON)
-    {
-        manifold->contactsCount = 1;
-        Vector2 normal = MathMatVector2Product(bodyB->shape.transform, vertexData.normals[faceNormal]);
-        manifold->normal = CLITERAL(Vector2){ -normal.x, -normal.y };
-        manifold->contacts[0] = CLITERAL(Vector2){ manifold->normal.x*bodyA->shape.radius + bodyA->position.x, manifold->normal.y*bodyA->shape.radius + bodyA->position.y };
-        manifold->penetration = bodyA->shape.radius;
-        return;
-    }
-
-    // Determine which voronoi region of the edge center of circle lies within
-    float dot1 = MathVector2DotProduct(MathVector2Subtract(center, v1), MathVector2Subtract(v2, v1));
-    float dot2 = MathVector2DotProduct(MathVector2Subtract(center, v2), MathVector2Subtract(v1, v2));
-    manifold->penetration = bodyA->shape.radius - separation;
-
-    if (dot1 <= 0.0f) // Closest to v1
-    {
-        if (MathVector2SqrDistance(center, v1) > bodyA->shape.radius*bodyA->shape.radius) return;
-
-        manifold->contactsCount = 1;
-        Vector2 normal = MathVector2Subtract(v1, center);
-        normal = MathMatVector2Product(bodyB->shape.transform, normal);
-        MathVector2Normalize(&normal);
-        manifold->normal = normal;
-        v1 = MathMatVector2Product(bodyB->shape.transform, v1);
-        v1 = MathVector2Add(v1, bodyB->position);
-        manifold->contacts[0] = v1;
-    }
-    else if (dot2 <= 0.0f) // Closest to v2
-    {
-        if (MathVector2SqrDistance(center, v2) > bodyA->shape.radius*bodyA->shape.radius) return;
-
-        manifold->contactsCount = 1;
-        Vector2 normal = MathVector2Subtract(v2, center);
-        v2 = MathMatVector2Product(bodyB->shape.transform, v2);
-        v2 = MathVector2Add(v2, bodyB->position);
-        manifold->contacts[0] = v2;
-        normal = MathMatVector2Product(bodyB->shape.transform, normal);
-        MathVector2Normalize(&normal);
-        manifold->normal = normal;
-    }
-    else // Closest to face
-    {
-        Vector2 normal = vertexData.normals[faceNormal];
-
-        if (MathVector2DotProduct(MathVector2Subtract(center, v1), normal) > bodyA->shape.radius) return;
-
-        normal = MathMatVector2Product(bodyB->shape.transform, normal);
-        manifold->normal = CLITERAL(Vector2){ -normal.x, -normal.y };
-        manifold->contacts[0] = CLITERAL(Vector2){ manifold->normal.x*bodyA->shape.radius + bodyA->position.x, manifold->normal.y*bodyA->shape.radius + bodyA->position.y };
-        manifold->contactsCount = 1;
-    }
-}
-
-// Solves collision between a polygon to a circle shape physics bodies
-static void SolvePolygonToCircle(PhysicsManifold manifold)
-{
-    PhysicsBody bodyA = manifold->bodyA;
-    PhysicsBody bodyB = manifold->bodyB;
-
-    if ((bodyA == NULL) || (bodyB == NULL)) return;
-
-    manifold->bodyA = bodyB;
-    manifold->bodyB = bodyA;
-    SolveCircleToPolygon(manifold);
-
-    manifold->normal.x *= -1.0f;
-    manifold->normal.y *= -1.0f;
-}
-
-// Solves collision between two polygons shape physics bodies
-static void SolvePolygonToPolygon(PhysicsManifold manifold)
-{
-    if ((manifold->bodyA == NULL) || (manifold->bodyB == NULL)) return;
-
-    PhysicsShape bodyA = manifold->bodyA->shape;
-    PhysicsShape bodyB = manifold->bodyB->shape;
-    manifold->contactsCount = 0;
-
-    // Check for separating axis with A shape's face planes
-    int faceA = 0;
-    float penetrationA = FindAxisLeastPenetration(&faceA, bodyA, bodyB);
-    if (penetrationA >= 0.0f) return;
-
-    // Check for separating axis with B shape's face planes
-    int faceB = 0;
-    float penetrationB = FindAxisLeastPenetration(&faceB, bodyB, bodyA);
-    if (penetrationB >= 0.0f) return;
-
-    int referenceIndex = 0;
-    bool flip = false;  // Always point from A shape to B shape
-
-    PhysicsShape refPoly; // Reference
-    PhysicsShape incPoly; // Incident
-
-    // Determine which shape contains reference face
-    // Checking bias range for penetration
-    if (penetrationA >= (penetrationB*0.95f + penetrationA*0.01f))
-    {
-        refPoly = bodyA;
-        incPoly = bodyB;
-        referenceIndex = faceA;
-    }
-    else
-    {
-        refPoly = bodyB;
-        incPoly = bodyA;
-        referenceIndex = faceB;
-        flip = true;
-    }
-
-    // World space incident face
-    Vector2 incidentFace[2];
-    FindIncidentFace(&incidentFace[0], &incidentFace[1], refPoly, incPoly, referenceIndex);
-
-    // Setup reference face vertices
-    PhysicsVertexData refData = refPoly.vertexData;
-    Vector2 v1 = refData.positions[referenceIndex];
-    referenceIndex = (((referenceIndex + 1) < (int)refData.vertexCount) ? (referenceIndex + 1) : 0);
-    Vector2 v2 = refData.positions[referenceIndex];
-
-    // Transform vertices to world space
-    v1 = MathMatVector2Product(refPoly.transform, v1);
-    v1 = MathVector2Add(v1, refPoly.body->position);
-    v2 = MathMatVector2Product(refPoly.transform, v2);
-    v2 = MathVector2Add(v2, refPoly.body->position);
-
-    // Calculate reference face side normal in world space
-    Vector2 sidePlaneNormal = MathVector2Subtract(v2, v1);
-    MathVector2Normalize(&sidePlaneNormal);
-
-    // Orthogonalize
-    Vector2 refFaceNormal = { sidePlaneNormal.y, -sidePlaneNormal.x };
-    float refC = MathVector2DotProduct(refFaceNormal, v1);
-    float negSide = MathVector2DotProduct(sidePlaneNormal, v1)*-1;
-    float posSide = MathVector2DotProduct(sidePlaneNormal, v2);
-
-    // MathVector2Clip incident face to reference face side planes (due to floating point error, possible to not have required points
-    if (MathVector2Clip(CLITERAL(Vector2){ -sidePlaneNormal.x, -sidePlaneNormal.y }, &incidentFace[0], &incidentFace[1], negSide) < 2) return;
-    if (MathVector2Clip(sidePlaneNormal, &incidentFace[0], &incidentFace[1], posSide) < 2) return;
-
-    // Flip normal if required
-    manifold->normal = (flip ? CLITERAL(Vector2){ -refFaceNormal.x, -refFaceNormal.y } : refFaceNormal);
-
-    // Keep points behind reference face
-    int currentPoint = 0; // MathVector2Clipped points behind reference face
-    float separation = MathVector2DotProduct(refFaceNormal, incidentFace[0]) - refC;
-    if (separation <= 0.0f)
-    {
-        manifold->contacts[currentPoint] = incidentFace[0];
-        manifold->penetration = -separation;
-        currentPoint++;
-    }
-    else manifold->penetration = 0.0f;
-
-    separation = MathVector2DotProduct(refFaceNormal, incidentFace[1]) - refC;
-
-    if (separation <= 0.0f)
-    {
-        manifold->contacts[currentPoint] = incidentFace[1];
-        manifold->penetration += -separation;
-        currentPoint++;
-
-        // Calculate total penetration average
-        manifold->penetration /= currentPoint;
-    }
-
-    manifold->contactsCount = currentPoint;
-}
-
-// Integrates physics forces into velocity
-static void IntegratePhysicsForces(PhysicsBody body)
-{
-    if ((body == NULL) || (body->inverseMass == 0.0f) || !body->enabled) return;
-
-    body->velocity.x += (float)((body->force.x*body->inverseMass)*(deltaTime/2.0));
-    body->velocity.y += (float)((body->force.y*body->inverseMass)*(deltaTime/2.0));
-
-    if (body->useGravity)
-    {
-        body->velocity.x += (float)(gravityForce.x*(deltaTime/1000/2.0));
-        body->velocity.y += (float)(gravityForce.y*(deltaTime/1000/2.0));
-    }
-
-    if (!body->freezeOrient) body->angularVelocity += (float)(body->torque*body->inverseInertia*(deltaTime/2.0));
-}
-
-// Initializes physics manifolds to solve collisions
-static void InitializePhysicsManifolds(PhysicsManifold manifold)
-{
-    PhysicsBody bodyA = manifold->bodyA;
-    PhysicsBody bodyB = manifold->bodyB;
-
-    if ((bodyA == NULL) || (bodyB == NULL)) return;
-
-    // Calculate average restitution, static and dynamic friction
-    manifold->restitution = sqrtf(bodyA->restitution*bodyB->restitution);
-    manifold->staticFriction = sqrtf(bodyA->staticFriction*bodyB->staticFriction);
-    manifold->dynamicFriction = sqrtf(bodyA->dynamicFriction*bodyB->dynamicFriction);
-
-    for (unsigned int i = 0; i < manifold->contactsCount; i++)
-    {
-        // Caculate radius from center of mass to contact
-        Vector2 radiusA = MathVector2Subtract(manifold->contacts[i], bodyA->position);
-        Vector2 radiusB = MathVector2Subtract(manifold->contacts[i], bodyB->position);
-
-        Vector2 crossA = MathVector2Product(radiusA, bodyA->angularVelocity);
-        Vector2 crossB = MathVector2Product(radiusB, bodyB->angularVelocity);
-
-        Vector2 radiusV = { 0.0f, 0.0f };
-        radiusV.x = bodyB->velocity.x + crossB.x - bodyA->velocity.x - crossA.x;
-        radiusV.y = bodyB->velocity.y + crossB.y - bodyA->velocity.y - crossA.y;
-
-        // Determine if we should perform a resting collision or not;
-        // The idea is if the only thing moving this object is gravity, then the collision should be performed without any restitution
-        if (MathVector2SqrLen(radiusV) < (MathVector2SqrLen(CLITERAL(Vector2){ (float)(gravityForce.x*deltaTime/1000), (float)(gravityForce.y*deltaTime/1000) }) + PHYSAC_EPSILON)) manifold->restitution = 0;
-    }
-}
-
-// Integrates physics collisions impulses to solve collisions
-static void IntegratePhysicsImpulses(PhysicsManifold manifold)
-{
-    PhysicsBody bodyA = manifold->bodyA;
-    PhysicsBody bodyB = manifold->bodyB;
-
-    if ((bodyA == NULL) || (bodyB == NULL)) return;
-
-    // Early out and positional correct if both objects have infinite mass
-    if (fabs(bodyA->inverseMass + bodyB->inverseMass) <= PHYSAC_EPSILON)
-    {
-        bodyA->velocity = PHYSAC_VECTOR_ZERO;
-        bodyB->velocity = PHYSAC_VECTOR_ZERO;
-        return;
-    }
-
-    for (unsigned int i = 0; i < manifold->contactsCount; i++)
-    {
-        // Calculate radius from center of mass to contact
-        Vector2 radiusA = MathVector2Subtract(manifold->contacts[i], bodyA->position);
-        Vector2 radiusB = MathVector2Subtract(manifold->contacts[i], bodyB->position);
-
-        // Calculate relative velocity
-        Vector2 radiusV = { 0.0f, 0.0f };
-        radiusV.x = bodyB->velocity.x + MathVector2Product(radiusB, bodyB->angularVelocity).x - bodyA->velocity.x - MathVector2Product(radiusA, bodyA->angularVelocity).x;
-        radiusV.y = bodyB->velocity.y + MathVector2Product(radiusB, bodyB->angularVelocity).y - bodyA->velocity.y - MathVector2Product(radiusA, bodyA->angularVelocity).y;
-
-        // Relative velocity along the normal
-        float contactVelocity = MathVector2DotProduct(radiusV, manifold->normal);
-
-        // Do not resolve if velocities are separating
-        if (contactVelocity > 0.0f) return;
-
-        float raCrossN = MathVector2CrossProduct(radiusA, manifold->normal);
-        float rbCrossN = MathVector2CrossProduct(radiusB, manifold->normal);
-
-        float inverseMassSum = bodyA->inverseMass + bodyB->inverseMass + (raCrossN*raCrossN)*bodyA->inverseInertia + (rbCrossN*rbCrossN)*bodyB->inverseInertia;
-
-        // Calculate impulse scalar value
-        float impulse = -(1.0f + manifold->restitution)*contactVelocity;
-        impulse /= inverseMassSum;
-        impulse /= (float)manifold->contactsCount;
-
-        // Apply impulse to each physics body
-        Vector2 impulseV = { manifold->normal.x*impulse, manifold->normal.y*impulse };
-
-        if (bodyA->enabled)
-        {
-            bodyA->velocity.x += bodyA->inverseMass*(-impulseV.x);
-            bodyA->velocity.y += bodyA->inverseMass*(-impulseV.y);
-            if (!bodyA->freezeOrient) bodyA->angularVelocity += bodyA->inverseInertia*MathVector2CrossProduct(radiusA, CLITERAL(Vector2){ -impulseV.x, -impulseV.y });
-        }
-
-        if (bodyB->enabled)
-        {
-            bodyB->velocity.x += bodyB->inverseMass*(impulseV.x);
-            bodyB->velocity.y += bodyB->inverseMass*(impulseV.y);
-            if (!bodyB->freezeOrient) bodyB->angularVelocity += bodyB->inverseInertia*MathVector2CrossProduct(radiusB, impulseV);
-        }
-
-        // Apply friction impulse to each physics body
-        radiusV.x = bodyB->velocity.x + MathVector2Product(radiusB, bodyB->angularVelocity).x - bodyA->velocity.x - MathVector2Product(radiusA, bodyA->angularVelocity).x;
-        radiusV.y = bodyB->velocity.y + MathVector2Product(radiusB, bodyB->angularVelocity).y - bodyA->velocity.y - MathVector2Product(radiusA, bodyA->angularVelocity).y;
-
-        Vector2 tangent = { radiusV.x - (manifold->normal.x*MathVector2DotProduct(radiusV, manifold->normal)), radiusV.y - (manifold->normal.y*MathVector2DotProduct(radiusV, manifold->normal)) };
-        MathVector2Normalize(&tangent);
-
-        // Calculate impulse tangent magnitude
-        float impulseTangent = -MathVector2DotProduct(radiusV, tangent);
-        impulseTangent /= inverseMassSum;
-        impulseTangent /= (float)manifold->contactsCount;
-
-        float absImpulseTangent = (float)fabs(impulseTangent);
-
-        // Don't apply tiny friction impulses
-        if (absImpulseTangent <= PHYSAC_EPSILON) return;
-
-        // Apply coulumb's law
-        Vector2 tangentImpulse = { 0.0f, 0.0f };
-        if (absImpulseTangent < impulse*manifold->staticFriction) tangentImpulse = CLITERAL(Vector2){ tangent.x*impulseTangent, tangent.y*impulseTangent };
-        else tangentImpulse = CLITERAL(Vector2){ tangent.x*-impulse*manifold->dynamicFriction, tangent.y*-impulse*manifold->dynamicFriction };
-
-        // Apply friction impulse
-        if (bodyA->enabled)
-        {
-            bodyA->velocity.x += bodyA->inverseMass*(-tangentImpulse.x);
-            bodyA->velocity.y += bodyA->inverseMass*(-tangentImpulse.y);
-
-            if (!bodyA->freezeOrient) bodyA->angularVelocity += bodyA->inverseInertia*MathVector2CrossProduct(radiusA, CLITERAL(Vector2){ -tangentImpulse.x, -tangentImpulse.y });
-        }
-
-        if (bodyB->enabled)
-        {
-            bodyB->velocity.x += bodyB->inverseMass*(tangentImpulse.x);
-            bodyB->velocity.y += bodyB->inverseMass*(tangentImpulse.y);
-
-            if (!bodyB->freezeOrient) bodyB->angularVelocity += bodyB->inverseInertia*MathVector2CrossProduct(radiusB, tangentImpulse);
-        }
-    }
-}
-
-// Integrates physics velocity into position and forces
-static void IntegratePhysicsVelocity(PhysicsBody body)
-{
-    if ((body == NULL) ||!body->enabled) return;
-
-    body->position.x += (float)(body->velocity.x*deltaTime);
-    body->position.y += (float)(body->velocity.y*deltaTime);
-
-    if (!body->freezeOrient) body->orient += (float)(body->angularVelocity*deltaTime);
-    body->shape.transform = MathMatFromRadians(body->orient);
-
-    IntegratePhysicsForces(body);
-}
-
-// Corrects physics bodies positions based on manifolds collision information
-static void CorrectPhysicsPositions(PhysicsManifold manifold)
-{
-    PhysicsBody bodyA = manifold->bodyA;
-    PhysicsBody bodyB = manifold->bodyB;
-
-    if ((bodyA == NULL) || (bodyB == NULL)) return;
-
-    Vector2 correction = { 0.0f, 0.0f };
-    correction.x = (PHYSAC_MAX(manifold->penetration - PHYSAC_PENETRATION_ALLOWANCE, 0.0f)/(bodyA->inverseMass + bodyB->inverseMass))*manifold->normal.x*PHYSAC_PENETRATION_CORRECTION;
-    correction.y = (PHYSAC_MAX(manifold->penetration - PHYSAC_PENETRATION_ALLOWANCE, 0.0f)/(bodyA->inverseMass + bodyB->inverseMass))*manifold->normal.y*PHYSAC_PENETRATION_CORRECTION;
-
-    if (bodyA->enabled)
-    {
-        bodyA->position.x -= correction.x*bodyA->inverseMass;
-        bodyA->position.y -= correction.y*bodyA->inverseMass;
-    }
-
-    if (bodyB->enabled)
-    {
-        bodyB->position.x += correction.x*bodyB->inverseMass;
-        bodyB->position.y += correction.y*bodyB->inverseMass;
-    }
-}
-
-// Returns the extreme point along a direction within a polygon
-static Vector2 GetSupport(PhysicsShape shape, Vector2 dir)
-{
-    float bestProjection = -PHYSAC_FLT_MAX;
-    Vector2 bestVertex = { 0.0f, 0.0f };
-    PhysicsVertexData data = shape.vertexData;
-
-    for (unsigned int i = 0; i < data.vertexCount; i++)
-    {
-        Vector2 vertex = data.positions[i];
-        float projection = MathVector2DotProduct(vertex, dir);
-
-        if (projection > bestProjection)
-        {
-            bestVertex = vertex;
-            bestProjection = projection;
-        }
-    }
-
-    return bestVertex;
-}
-
-// Finds polygon shapes axis least penetration
-static float FindAxisLeastPenetration(int *faceIndex, PhysicsShape shapeA, PhysicsShape shapeB)
-{
-    float bestDistance = -PHYSAC_FLT_MAX;
-    int bestIndex = 0;
-
-    PhysicsVertexData dataA = shapeA.vertexData;
-    //PhysicsVertexData dataB = shapeB.vertexData;
-
-    for (unsigned int i = 0; i < dataA.vertexCount; i++)
-    {
-        // Retrieve a face normal from A shape
-        Vector2 normal = dataA.normals[i];
-        Vector2 transNormal = MathMatVector2Product(shapeA.transform, normal);
-
-        // Transform face normal into B shape's model space
-        Matrix2x2 buT = MathMatTranspose(shapeB.transform);
-        normal = MathMatVector2Product(buT, transNormal);
-
-        // Retrieve support point from B shape along -n
-        Vector2 support = GetSupport(shapeB, CLITERAL(Vector2){ -normal.x, -normal.y });
-
-        // Retrieve vertex on face from A shape, transform into B shape's model space
-        Vector2 vertex = dataA.positions[i];
-        vertex = MathMatVector2Product(shapeA.transform, vertex);
-        vertex = MathVector2Add(vertex, shapeA.body->position);
-        vertex = MathVector2Subtract(vertex, shapeB.body->position);
-        vertex = MathMatVector2Product(buT, vertex);
-
-        // Compute penetration distance in B shape's model space
-        float distance = MathVector2DotProduct(normal, MathVector2Subtract(support, vertex));
-
-        // Store greatest distance
-        if (distance > bestDistance)
-        {
-            bestDistance = distance;
-            bestIndex = i;
-        }
-    }
-
-    *faceIndex = bestIndex;
-    return bestDistance;
-}
-
-// Finds two polygon shapes incident face
-static void FindIncidentFace(Vector2 *v0, Vector2 *v1, PhysicsShape ref, PhysicsShape inc, int index)
-{
-    PhysicsVertexData refData = ref.vertexData;
-    PhysicsVertexData incData = inc.vertexData;
-
-    Vector2 referenceNormal = refData.normals[index];
-
-    // Calculate normal in incident's frame of reference
-    referenceNormal = MathMatVector2Product(ref.transform, referenceNormal); // To world space
-    referenceNormal = MathMatVector2Product(MathMatTranspose(inc.transform), referenceNormal); // To incident's model space
-
-    // Find most anti-normal face on polygon
-    int incidentFace = 0;
-    float minDot = PHYSAC_FLT_MAX;
-
-    for (unsigned int i = 0; i < incData.vertexCount; i++)
-    {
-        float dot = MathVector2DotProduct(referenceNormal, incData.normals[i]);
-
-        if (dot < minDot)
-        {
-            minDot = dot;
-            incidentFace = i;
-        }
-    }
-
-    // Assign face vertices for incident face
-    *v0 = MathMatVector2Product(inc.transform, incData.positions[incidentFace]);
-    *v0 = MathVector2Add(*v0, inc.body->position);
-    incidentFace = (((incidentFace + 1) < (int)incData.vertexCount) ? (incidentFace + 1) : 0);
-    *v1 = MathMatVector2Product(inc.transform, incData.positions[incidentFace]);
-    *v1 = MathVector2Add(*v1, inc.body->position);
-}
-
-// Returns clipping value based on a normal and two faces
-static int MathVector2Clip(Vector2 normal, Vector2 *faceA, Vector2 *faceB, float clip)
-{
-    int sp = 0;
-    Vector2 out[2] = { *faceA, *faceB };
-
-    // Retrieve distances from each endpoint to the line
-    float distanceA = MathVector2DotProduct(normal, *faceA) - clip;
-    float distanceB = MathVector2DotProduct(normal, *faceB) - clip;
-
-    // If negative (behind plane)
-    if (distanceA <= 0.0f) out[sp++] = *faceA;
-    if (distanceB <= 0.0f) out[sp++] = *faceB;
-
-    // If the points are on different sides of the plane
-    if ((distanceA*distanceB) < 0.0f)
-    {
-        // Push intersection point
-        float alpha = distanceA/(distanceA - distanceB);
-        out[sp] = *faceA;
-        Vector2 delta = MathVector2Subtract(*faceB, *faceA);
-        delta.x *= alpha;
-        delta.y *= alpha;
-        out[sp] = MathVector2Add(out[sp], delta);
-        sp++;
-    }
-
-    // Assign the new converted values
-    *faceA = out[0];
-    *faceB = out[1];
-
-    return sp;
-}
-
-// Returns the barycenter of a triangle given by 3 points
-static Vector2 MathTriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3)
-{
-    Vector2 result = { 0.0f, 0.0f };
-
-    result.x = (v1.x + v2.x + v3.x)/3;
-    result.y = (v1.y + v2.y + v3.y)/3;
-
-    return result;
-}
-
-// Returns the cross product of a vector and a value
-static inline Vector2 MathVector2Product(Vector2 vector, float value)
-{
-    Vector2 result = { -value*vector.y, value*vector.x };
-    return result;
-}
-
-// Returns the cross product of two vectors
-static inline float MathVector2CrossProduct(Vector2 v1, Vector2 v2)
-{
-    return (v1.x*v2.y - v1.y*v2.x);
-}
-
-// Returns the len square root of a vector
-static inline float MathVector2SqrLen(Vector2 vector)
-{
-    return (vector.x*vector.x + vector.y*vector.y);
-}
-
-// Returns the dot product of two vectors
-static inline float MathVector2DotProduct(Vector2 v1, Vector2 v2)
-{
-    return (v1.x*v2.x + v1.y*v2.y);
-}
-
-// Returns the square root of distance between two vectors
-static inline float MathVector2SqrDistance(Vector2 v1, Vector2 v2)
-{
-    Vector2 dir = MathVector2Subtract(v1, v2);
-    return MathVector2DotProduct(dir, dir);
-}
-
-// Returns the normalized values of a vector
-static void MathVector2Normalize(Vector2 *vector)
-{
-    float length, ilength;
-
-    Vector2 aux = *vector;
-    length = sqrtf(aux.x*aux.x + aux.y*aux.y);
-
-    if (length == 0) length = 1.0f;
-
-    ilength = 1.0f/length;
-
-    vector->x *= ilength;
-    vector->y *= ilength;
-}
-
-// Returns the sum of two given vectors
-static inline Vector2 MathVector2Add(Vector2 v1, Vector2 v2)
-{
-    Vector2 result = { v1.x + v2.x, v1.y + v2.y };
-    return result;
-}
-
-// Returns the subtract of two given vectors
-static inline Vector2 MathVector2Subtract(Vector2 v1, Vector2 v2)
-{
-    Vector2 result = { v1.x - v2.x, v1.y - v2.y };
-    return result;
-}
-
-// Creates a matrix 2x2 from a given radians value
-static Matrix2x2 MathMatFromRadians(float radians)
-{
-    float cos = cosf(radians);
-    float sin = sinf(radians);
-
-    Matrix2x2 result = { cos, -sin, sin, cos };
-    return result;
-}
-
-// Returns the transpose of a given matrix 2x2
-static inline Matrix2x2 MathMatTranspose(Matrix2x2 matrix)
-{
-    Matrix2x2 result = { matrix.m00, matrix.m10, matrix.m01, matrix.m11 };
-    return result;
-}
-
-// Multiplies a vector by a matrix 2x2
-static inline Vector2 MathMatVector2Product(Matrix2x2 matrix, Vector2 vector)
-{
-    Vector2 result = { matrix.m00*vector.x + matrix.m01*vector.y, matrix.m10*vector.x + matrix.m11*vector.y };
-    return result;
-}
-
-#endif  // PHYSAC_IMPLEMENTATION