Browse Source

Reviewed physics module

A deeper revision required, not clear enough for the user
Key: Create a PhysicObjects pool
raysan5 9 years ago
parent
commit
ed19064405
5 changed files with 64 additions and 98 deletions
  1. 11 33
      examples/physics_basic_rigidbody.c
  2. 12 21
      examples/physics_rigidbody_force.c
  3. 36 25
      src/physac.c
  4. 2 9
      src/physac.h
  5. 3 10
      src/raylib.h

+ 11 - 33
examples/physics_basic_rigidbody.c

@@ -2,20 +2,10 @@
 *
 *
 *   raylib [physac] physics example - Basic rigidbody
 *   raylib [physac] physics example - Basic rigidbody
 *
 *
-*   Welcome to raylib!
-*
-*   To test examples, just press F6 and execute raylib_compile_execute script
-*   Note that compiled executable is placed in the same folder as .c file
-*
-*   You can find all basic examples on C:\raylib\raylib\examples folder or
-*   raylib official webpage: www.raylib.com
-*
-*   Enjoy using raylib. :)
-*
-*   This example has been created using raylib 1.3 (www.raylib.com)
+*   This example has been created using raylib 1.4 (www.raylib.com)
 *   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
 *   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
 *
 *
-*   Copyright (c) 2015 Ramon Santamaria (@raysan5)
+*   Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5)
 *
 *
 ********************************************************************************************/
 ********************************************************************************************/
 
 
@@ -33,13 +23,7 @@ int main()
     
     
     InitWindow(screenWidth, screenHeight, "raylib [physics] example - basic rigidbody");
     InitWindow(screenWidth, screenHeight, "raylib [physics] example - basic rigidbody");
 
 
-    InitPhysics();      // Initialize internal physics values   (max rigidbodies/colliders available: 1024)
-    
-    // Physics initialization
-    Physics worldPhysics = { true, false, (Vector2){ 0, -9.81f } };
-    
-    // Set internal physics settings
-    SetPhysics(worldPhysics);
+    InitPhysics(3);      // Initialize physics system with maximum physic objects
     
     
     // Object initialization
     // Object initialization
     Transform player = (Transform){(Vector2){(screenWidth - OBJECT_SIZE) / 2, (screenHeight - OBJECT_SIZE) / 2}, 0.0f, (Vector2){OBJECT_SIZE, OBJECT_SIZE}};
     Transform player = (Transform){(Vector2){(screenWidth - OBJECT_SIZE) / 2, (screenHeight - OBJECT_SIZE) / 2}, 0.0f, (Vector2){OBJECT_SIZE, OBJECT_SIZE}};
@@ -55,6 +39,8 @@ int main()
     float moveSpeed = 6.0f;
     float moveSpeed = 6.0f;
     float jumpForce = 5.0f;
     float jumpForce = 5.0f;
     
     
+    bool physicsDebug = false;
+    
     SetTargetFPS(60);
     SetTargetFPS(60);
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
 
 
@@ -91,14 +77,7 @@ int main()
         }
         }
         
         
         // Check debug mode toggle button input
         // Check debug mode toggle button input
-        if(IsKeyPressed(KEY_P))
-        {
-            // Update program physics value
-            worldPhysics.debug = !worldPhysics.debug;
-            
-            // Update internal physics value
-            SetPhysics(worldPhysics);
-        }
+        if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug;
         //----------------------------------------------------------------------------------
         //----------------------------------------------------------------------------------
 
 
         // Draw
         // Draw
@@ -112,7 +91,7 @@ int main()
             DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY);
             DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY);
             
             
             // Check if debug mode is enabled
             // Check if debug mode is enabled
-            if (worldPhysics.debug)
+            if (physicsDebug)
             {
             {
                 // Draw every internal physics stored collider if it is active
                 // Draw every internal physics stored collider if it is active
                 for (int i = 0; i < 2; i++)
                 for (int i = 0; i < 2; i++)
@@ -122,14 +101,11 @@ int main()
                         DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN);
                         DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN);
                     }
                     }
                 }
                 }
-                
             }
             }
             else
             else
             {
             {
-                // Draw player
+                // Draw player and floor
                 DrawRectangleRec((Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, GRAY);
                 DrawRectangleRec((Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, GRAY);
-                
-                // Draw floor
                 DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK);
                 DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK);
             }
             }
 
 
@@ -138,7 +114,9 @@ int main()
     }
     }
 
 
     // De-Initialization
     // De-Initialization
-    //--------------------------------------------------------------------------------------   
+    //--------------------------------------------------------------------------------------
+    UnloadPhysics();      // Unload physic objects
+    
     CloseWindow();        // Close window and OpenGL context
     CloseWindow();        // Close window and OpenGL context
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
 
 

+ 12 - 21
examples/physics_rigidbody_force.c

@@ -2,10 +2,10 @@
 *
 *
 *   raylib [physac] physics example - Rigidbody forces
 *   raylib [physac] physics example - Rigidbody forces
 *
 *
-*   This example has been created using raylib 1.3 (www.raylib.com)
+*   This example has been created using raylib 1.4 (www.raylib.com)
 *   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
 *   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
 *
 *
-*   Copyright (c) 2014 Ramon Santamaria (@raysan5)
+*   Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5)
 *
 *
 ********************************************************************************************/
 ********************************************************************************************/
 
 
@@ -26,15 +26,9 @@ int main()
     
     
     InitWindow(screenWidth, screenHeight, "raylib [physics] example - rigidbodies forces");
     InitWindow(screenWidth, screenHeight, "raylib [physics] example - rigidbodies forces");
 
 
-    InitPhysics();      // Initialize internal physics values   (max rigidbodies/colliders available: 1024)
+    InitPhysics(MAX_OBJECTS + 1);      // Initialize physics system with maximum physic objects
     
     
-    // Physics initialization
-    Physics worldPhysics = {true, false, (Vector2){0, -9.81f}};
-    
-    // Set internal physics settings
-    SetPhysics(worldPhysics);
-    
-    // Objects initialization
+    // Physic Objects initialization
     Transform objects[MAX_OBJECTS];
     Transform objects[MAX_OBJECTS];
     
     
     for (int i = 0; i < MAX_OBJECTS; i++)
     for (int i = 0; i < MAX_OBJECTS; i++)
@@ -49,6 +43,8 @@ int main()
     Transform floor = (Transform){(Vector2){0, screenHeight * 0.8f}, 0.0f, (Vector2){screenWidth, screenHeight * 0.2f}};
     Transform floor = (Transform){(Vector2){0, screenHeight * 0.8f}, 0.0f, (Vector2){screenWidth, screenHeight * 0.2f}};
     AddCollider(MAX_OBJECTS, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0});
     AddCollider(MAX_OBJECTS, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0});
 
 
+    bool physicsDebug = false;
+    
     SetTargetFPS(60);
     SetTargetFPS(60);
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
 
 
@@ -72,14 +68,7 @@ int main()
         }
         }
         
         
         // Check debug mode toggle button input
         // Check debug mode toggle button input
-        if (IsKeyPressed(KEY_P))
-        {
-            // Update program physics value
-            worldPhysics.debug = !worldPhysics.debug;
-            
-            // Update internal physics value
-            SetPhysics(worldPhysics);
-        }
+        if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug;
         //----------------------------------------------------------------------------------
         //----------------------------------------------------------------------------------
 
 
         // Draw
         // Draw
@@ -89,10 +78,10 @@ int main()
             ClearBackground(RAYWHITE);
             ClearBackground(RAYWHITE);
             
             
             // Check if debug mode is enabled
             // Check if debug mode is enabled
-            if (worldPhysics.debug)
+            if (physicsDebug)
             {
             {
                 // Draw every internal physics stored collider if it is active (floor included)
                 // Draw every internal physics stored collider if it is active (floor included)
-                for (int i = 0; i < MAX_OBJECTS + 1; i++)
+                for (int i = 0; i < MAX_OBJECTS; i++)
                 {
                 {
                     if (GetCollider(i).enabled)
                     if (GetCollider(i).enabled)
                     {
                     {
@@ -136,7 +125,9 @@ int main()
     }
     }
 
 
     // De-Initialization
     // De-Initialization
-    //--------------------------------------------------------------------------------------   
+    //--------------------------------------------------------------------------------------
+    UnloadPhysics();      // Unload physic objects
+    
     CloseWindow();        // Close window and OpenGL context
     CloseWindow();        // Close window and OpenGL context
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
 
 

+ 36 - 25
src/physac.c

@@ -30,13 +30,12 @@
 #endif
 #endif
 
 
 #include <math.h>
 #include <math.h>
-#include <stdio.h>
+#include <stdlib.h>             // Required for: malloc(), free()
 
 
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Defines and Macros
 // Defines and Macros
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-#define MAX_ELEMENTS 1024       // Stored rigidbodies and colliders array length
-#define DECIMAL_FIX 0.26f       // Decimal margin for collision checks (avoid rigidbodies shake)
+#define DECIMAL_FIX     0.26f       // Decimal margin for collision checks (avoid rigidbodies shake)
 
 
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Types and Structures Definition
 // Types and Structures Definition
@@ -46,10 +45,13 @@
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Global Variables Definition
 // Global Variables Definition
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-static Physics physics;
-static Collider colliders[MAX_ELEMENTS];
-static Rigidbody rigidbodies[MAX_ELEMENTS];
-static bool collisionChecker = false;
+static Collider *colliders;         // Colliders array, dynamically allocated at runtime
+static Rigidbody *rigidbodies;      // Rigitbody array, dynamically allocated at runtime
+static bool collisionChecker;
+
+static int maxElements;             // Max physic elements to compute
+static bool enabled;                // Physics enabled? (true by default)
+static Vector2 gravity;             // Gravity value used for physic calculations
 
 
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Module specific Functions Declarations
 // Module specific Functions Declarations
@@ -61,30 +63,39 @@ static void Vector2Normalize(Vector2 *vector);
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Module Functions Definitions
 // Module Functions Definitions
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-void InitPhysics(void)
-{    
-    for (int i = 0; i < MAX_ELEMENTS; i++)
+void InitPhysics(int maxPhysicElements)
+{
+    maxElements = maxPhysicElements;
+    
+    colliders = (Collider *)malloc(maxElements*sizeof(Collider));
+    rigidbodies = (Rigidbody *)malloc(maxElements*sizeof(Rigidbody));
+    
+    for (int i = 0; i < maxElements; i++)
     {
     {
+        colliders[i].enabled = false;
+        colliders[i].bounds = (Rectangle){ 0, 0, 0, 0 };
+        colliders[i].radius = 0;
+        
         rigidbodies[i].enabled = false;
         rigidbodies[i].enabled = false;
         rigidbodies[i].mass = 0.0f;
         rigidbodies[i].mass = 0.0f;
-        rigidbodies[i].velocity = (Vector2){0, 0};
-        rigidbodies[i].acceleration = (Vector2){0, 0};
+        rigidbodies[i].velocity = (Vector2){ 0.0f, 0.0f };
+        rigidbodies[i].acceleration = (Vector2){ 0.0f, 0.0f };
         rigidbodies[i].isGrounded = false;
         rigidbodies[i].isGrounded = false;
         rigidbodies[i].isContact = false;
         rigidbodies[i].isContact = false;
         rigidbodies[i].friction = 0.0f;
         rigidbodies[i].friction = 0.0f;
-        
-        colliders[i].enabled = false;
-        colliders[i].bounds = (Rectangle){0, 0, 0, 0};
-        colliders[i].radius = 0;
     }
     }
+    
+    collisionChecker = false;
+    enabled = true;
+    
+    // NOTE: To get better results, gravity needs to be 1:10 from original parameter
+    gravity = (Vector2){ 0.0f, -9.81f/10.0f };     // By default, standard gravity
 }
 }
 
 
-void SetPhysics(Physics settings)
+void UnloadPhysics()
 {
 {
-    physics = settings;
-    
-    // To get good results, gravity needs to be 1:10 from original parameter
-    physics.gravity = (Vector2){physics.gravity.x / 10, physics.gravity.y / 10};
+    free(colliders);
+    free(rigidbodies);
 }
 }
 
 
 void AddCollider(int index, Collider collider)
 void AddCollider(int index, Collider collider)
@@ -159,8 +170,8 @@ void ApplyPhysics(int index, Vector2 *position)
         }
         }
         
         
         // Apply gravity
         // Apply gravity
-        rigidbodies[index].velocity.y += physics.gravity.y;
-        rigidbodies[index].velocity.x += physics.gravity.x;
+        rigidbodies[index].velocity.y += gravity.y;
+        rigidbodies[index].velocity.x += gravity.x;
         
         
         // Apply acceleration
         // Apply acceleration
         rigidbodies[index].velocity.y += rigidbodies[index].acceleration.y;
         rigidbodies[index].velocity.y += rigidbodies[index].acceleration.y;
@@ -177,7 +188,7 @@ void ApplyPhysics(int index, Vector2 *position)
         // Check collision with other colliders
         // Check collision with other colliders
         collisionChecker = false;
         collisionChecker = false;
         rigidbodies[index].isContact = false;
         rigidbodies[index].isContact = false;
-        for (int j = 0; j < MAX_ELEMENTS; j++)
+        for (int j = 0; j < maxElements; j++)
         {
         {
             if (index != j)
             if (index != j)
             {
             {
@@ -269,7 +280,7 @@ void AddRigidbodyForce(int index, Vector2 force)
 
 
 void AddForceAtPosition(Vector2 position, float intensity, float radius)
 void AddForceAtPosition(Vector2 position, float intensity, float radius)
 {
 {
-    for(int i = 0; i < MAX_ELEMENTS; i++)
+    for(int i = 0; i < maxElements; i++)
     {
     {
         if(rigidbodies[i].enabled)
         if(rigidbodies[i].enabled)
         {
         {

+ 2 - 9
src/physac.h

@@ -35,13 +35,6 @@
 // Collider types
 // Collider types
 typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType;
 typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType;
 
 
-// Physics struct
-typedef struct Physics {
-    bool enabled;
-    bool debug;     // Should be used by programmer for testing purposes
-    Vector2 gravity;
-} Physics;
-
 // Transform struct
 // Transform struct
 typedef struct Transform {
 typedef struct Transform {
     Vector2 position;
     Vector2 position;
@@ -77,8 +70,8 @@ extern "C" {            // Prevents name mangling of functions
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Module Functions Declarations
 // Module Functions Declarations
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-void InitPhysics(void);                                                     // Initialize all internal physics values
-void SetPhysics(Physics settings);                                          // Set physics settings values using Physics data type to overwrite internal physics settings
+void InitPhysics(int maxPhysicElements);                                    // Initialize all internal physics values
+void UnloadPhysics();                                                       // Unload physic elements arrays
 
 
 void AddRigidbody(int index, Rigidbody rigidbody);                          // Initialize a new rigidbody with parameters to internal index slot
 void AddRigidbody(int index, Rigidbody rigidbody);                          // Initialize a new rigidbody with parameters to internal index slot
 void AddCollider(int index, Collider collider);                             // Initialize a new Collider with parameters to internal index slot
 void AddCollider(int index, Collider collider);                             // Initialize a new Collider with parameters to internal index slot

+ 3 - 10
src/raylib.h

@@ -466,13 +466,6 @@ typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERS
 // Collider types
 // Collider types
 typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType;
 typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType;
 
 
-// Physics struct
-typedef struct Physics {
-    bool enabled;
-    bool debug;             // Should be used by programmer for testing purposes
-    Vector2 gravity;
-} Physics;
-
 // Transform struct
 // Transform struct
 typedef struct Transform {
 typedef struct Transform {
     Vector2 position;
     Vector2 position;
@@ -808,10 +801,10 @@ void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textur
 void SetBlendMode(int mode);                                        // Set blending mode (alpha, additive, multiplied)
 void SetBlendMode(int mode);                                        // Set blending mode (alpha, additive, multiplied)
 
 
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-// Physics System Functions (engine-module: physics)
+// Physics System Functions (engine-module: physac)
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-void InitPhysics(void);                                                     // Initialize all internal physics values
-void SetPhysics(Physics settings);                                          // Set physics settings values using Physics data type to overwrite internal physics settings
+void InitPhysics(int maxPhysicElements);                                    // Initialize all internal physics values
+void UnloadPhysics();                                                       // Unload physic elements arrays
 
 
 void AddRigidbody(int index, Rigidbody rigidbody);                          // Initialize a new rigidbody with parameters to internal index slot
 void AddRigidbody(int index, Rigidbody rigidbody);                          // Initialize a new rigidbody with parameters to internal index slot
 void AddCollider(int index, Collider collider);                             // Initialize a new Collider with parameters to internal index slot
 void AddCollider(int index, Collider collider);                             // Initialize a new Collider with parameters to internal index slot