Browse Source

Improved and added functions to physac engine module

- Improved physics calculations.
- Added AddForceAtPosition function (added to all enabled rigidbodies).
- Updated raylib header.
victorfisac 9 years ago
parent
commit
a299bc289b
3 changed files with 138 additions and 64 deletions
  1. 110 40
      src/physac.c
  2. 15 13
      src/physac.h
  3. 13 11
      src/raylib.h

+ 110 - 40
src/physac.c

@@ -1,6 +1,6 @@
 /**********************************************************************************************
 /**********************************************************************************************
 *
 *
-*   raylib physics engine module - Basic functions to apply physics to 2D objects
+*   [physac] raylib physics engine module - Basic functions to apply physics to 2D objects
 *
 *
 *   Copyright (c) 2015 Victor Fisac and Ramon Santamaria
 *   Copyright (c) 2015 Victor Fisac and Ramon Santamaria
 *
 *
@@ -36,7 +36,7 @@
 // Defines and Macros
 // Defines and Macros
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 #define MAX_ELEMENTS 1024       // Stored rigidbodies and colliders array length
 #define MAX_ELEMENTS 1024       // Stored rigidbodies and colliders array length
-#define DECIMAL_FIX 0.01f       // 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
@@ -52,7 +52,14 @@ static Rigidbody rigidbodies[MAX_ELEMENTS];
 static bool collisionChecker = false;
 static bool collisionChecker = false;
 
 
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-// Module Functions Definition
+// Module specific Functions Declarations
+//----------------------------------------------------------------------------------
+static float Vector2Length(Vector2 vector);
+static float Vector2LengthPoints(Vector2 a, Vector2 b);
+static Vector2 Vector2Normalize(Vector2 vector);
+
+//----------------------------------------------------------------------------------
+// Module Functions Definitions
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 void InitPhysics()
 void InitPhysics()
 {    
 {    
@@ -94,12 +101,32 @@ void ApplyPhysics(int index, Vector2 *position)
 {
 {
     if (rigidbodies[index].enabled)
     if (rigidbodies[index].enabled)
     {
     {
-        // Apply gravity
-        rigidbodies[index].velocity.y += rigidbodies[index].acceleration.y;
-        rigidbodies[index].velocity.x += rigidbodies[index].acceleration.x;
+        // Apply friction to acceleration
+        if (rigidbodies[index].acceleration.x > DECIMAL_FIX)
+        {
+            rigidbodies[index].acceleration.x -= rigidbodies[index].friction;
+        }
+        else if (rigidbodies[index].acceleration.x < -DECIMAL_FIX)
+        {
+            rigidbodies[index].acceleration.x += rigidbodies[index].friction;
+        }
+        else
+        {
+            rigidbodies[index].acceleration.x = 0;
+        }
         
         
-        rigidbodies[index].velocity.y += physics.gravity.y;
-        rigidbodies[index].velocity.x += physics.gravity.x;
+        if (rigidbodies[index].acceleration.y > DECIMAL_FIX / 2)
+        {
+            rigidbodies[index].acceleration.y -= rigidbodies[index].friction;
+        }
+        else if (rigidbodies[index].acceleration.y < -DECIMAL_FIX / 2)
+        {
+            rigidbodies[index].acceleration.y += rigidbodies[index].friction;
+        }
+        else
+        {
+            rigidbodies[index].acceleration.y = 0;
+        }
         
         
         // Apply friction to velocity
         // Apply friction to velocity
         if (rigidbodies[index].isGrounded)
         if (rigidbodies[index].isGrounded)
@@ -118,11 +145,11 @@ void ApplyPhysics(int index, Vector2 *position)
             }
             }
         }
         }
         
         
-        if (rigidbodies[index].velocity.y > DECIMAL_FIX)
+        if (rigidbodies[index].velocity.y > DECIMAL_FIX / 2)
         {
         {
             rigidbodies[index].velocity.y -= rigidbodies[index].friction;
             rigidbodies[index].velocity.y -= rigidbodies[index].friction;
         }
         }
-        else if (rigidbodies[index].velocity.y < -DECIMAL_FIX)
+        else if (rigidbodies[index].velocity.y < -DECIMAL_FIX / 2)
         {
         {
             rigidbodies[index].velocity.y += rigidbodies[index].friction;
             rigidbodies[index].velocity.y += rigidbodies[index].friction;
         }
         }
@@ -131,35 +158,13 @@ void ApplyPhysics(int index, Vector2 *position)
             rigidbodies[index].velocity.y = 0;
             rigidbodies[index].velocity.y = 0;
         }
         }
         
         
-        // Apply friction to acceleration
-        if (rigidbodies[index].isGrounded)
-        {
-            if (rigidbodies[index].acceleration.x > DECIMAL_FIX)
-            {
-                rigidbodies[index].acceleration.x -= rigidbodies[index].friction;
-            }
-            else if (rigidbodies[index].acceleration.x < -DECIMAL_FIX)
-            {
-                rigidbodies[index].acceleration.x += rigidbodies[index].friction;
-            }
-            else
-            {
-                rigidbodies[index].acceleration.x = 0;
-            }
-        }
+        // Apply gravity
+        rigidbodies[index].velocity.y += physics.gravity.y;
+        rigidbodies[index].velocity.x += physics.gravity.x;
         
         
-        if (rigidbodies[index].acceleration.y > DECIMAL_FIX)
-        {
-            rigidbodies[index].acceleration.y -= rigidbodies[index].friction;
-        }
-        else if (rigidbodies[index].acceleration.y < -DECIMAL_FIX)
-        {
-            rigidbodies[index].acceleration.y += rigidbodies[index].friction;
-        }
-        else
-        {
-            rigidbodies[index].acceleration.y = 0;
-        }
+        // Apply acceleration
+        rigidbodies[index].velocity.y += rigidbodies[index].acceleration.y;
+        rigidbodies[index].velocity.x += rigidbodies[index].acceleration.x;
         
         
         // Update position vector
         // Update position vector
         position->x += rigidbodies[index].velocity.x;        
         position->x += rigidbodies[index].velocity.x;        
@@ -250,10 +255,49 @@ void SetRigidbodyVelocity(int index, Vector2 velocity)
     rigidbodies[index].velocity.y = velocity.y;
     rigidbodies[index].velocity.y = velocity.y;
 }
 }
 
 
+void SetRigidbodyAcceleration(int index, Vector2 acceleration)
+{
+    rigidbodies[index].acceleration.x = acceleration.x;
+    rigidbodies[index].acceleration.y = acceleration.y;
+}
+
 void AddRigidbodyForce(int index, Vector2 force)
 void AddRigidbodyForce(int index, Vector2 force)
 {
 {
-    rigidbodies[index].acceleration.x = force.x * rigidbodies[index].mass;
-    rigidbodies[index].acceleration.y = force.y * rigidbodies[index].mass;
+    rigidbodies[index].acceleration.x = force.x / rigidbodies[index].mass;
+    rigidbodies[index].acceleration.y = force.y / rigidbodies[index].mass;
+}
+
+void AddForceAtPosition(Vector2 position, float intensity, float radius)
+{
+    for(int i = 0; i < MAX_ELEMENTS; i++)
+    {
+        if(rigidbodies[i].enabled)
+        {
+            // Get position from its collider
+            Vector2 pos = {colliders[i].bounds.x, colliders[i].bounds.y};
+            
+            // Get distance between rigidbody position and target position
+            float distance = Vector2LengthPoints(position, pos);
+            
+            if(distance <= radius)
+            {
+                // Calculate force based on direction
+                Vector2 force = {colliders[i].bounds.x - position.x, colliders[i].bounds.y - position.y};
+                
+                // Normalize the direction vector
+                force = Vector2Normalize(force);
+                
+                // Invert y value
+                force.y *= -1;
+                
+                // Apply intensity and distance
+                force = (Vector2){force.x * intensity / distance, force.y * intensity / distance};
+                
+                // Add calculated force to the rigidbodies
+                AddRigidbodyForce(i, force);
+            }
+        }
+    }
 }
 }
 
 
 void SetColliderEnabled(int index, bool state)
 void SetColliderEnabled(int index, bool state)
@@ -270,3 +314,29 @@ Rigidbody GetRigidbody(int index)
 {
 {
     return rigidbodies[index];
     return rigidbodies[index];
 }
 }
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Definitions
+//----------------------------------------------------------------------------------
+static float Vector2Length(Vector2 vector)
+{
+    return sqrt((vector.x * vector.x) + (vector.y * vector.y));
+}
+
+static float Vector2LengthPoints(Vector2 a, Vector2 b)
+{
+    Vector2 vector = {b.x - a.x, b.y - a.y};
+    return sqrt((vector.x * vector.x) + (vector.y * vector.y));
+}
+
+static Vector2 Vector2Normalize(Vector2 vector)
+{
+    float length = Vector2Length(vector);
+    
+    if(length != 0)
+    {
+        return (Vector2){vector.x / length, vector.y / length};
+    }
+    
+    return (Vector2){0, 0};
+}

+ 15 - 13
src/physac.h

@@ -1,6 +1,6 @@
 /**********************************************************************************************
 /**********************************************************************************************
 *
 *
-*   raylib physics engine module - Basic functions to apply physics to 2D objects
+*   [physac] raylib physics engine module - Basic functions to apply physics to 2D objects
 *
 *
 *   Copyright (c) 2015 Victor Fisac and Ramon Santamaria
 *   Copyright (c) 2015 Victor Fisac and Ramon Santamaria
 *
 *
@@ -74,23 +74,25 @@ extern "C" {            // Prevents name mangling of functions
 #endif
 #endif
 
 
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-// Module Functions Declaration
+// Module Functions Declarations
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-void InitPhysics();                                                     // Initialize all internal physics values
-void SetPhysics(Physics settings);                                      // Set physics settings values using Physics data type to overwrite internal physics settings
+void InitPhysics();                                                         // Initialize all internal physics values
+void SetPhysics(Physics settings);                                          // Set physics settings values using Physics data type to overwrite internal physics settings
 
 
-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 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 ApplyPhysics(int index, Vector2 *position);                        // Apply physics to internal rigidbody, physics calculations are applied to position pointer parameter
-void SetRigidbodyEnabled(int index, bool state);                        // Set enabled state to a defined rigidbody
-void SetRigidbodyVelocity(int index, Vector2 velocity);                 // Set velocity of rigidbody (without considering of mass value)
-void AddRigidbodyForce(int index, Vector2 force);                       // Set rigidbody force (considering mass value)
+void ApplyPhysics(int index, Vector2 *position);                            // Apply physics to internal rigidbody, physics calculations are applied to position pointer parameter
+void SetRigidbodyEnabled(int index, bool state);                            // Set enabled state to a defined rigidbody
+void SetRigidbodyVelocity(int index, Vector2 velocity);                     // Set velocity of rigidbody (without considering of mass value)
+void SetRigidbodyAcceleration(int index, Vector2 acceleration);             // Set acceleration of rigidbody (without considering of mass value)
+void AddRigidbodyForce(int index, Vector2 force);                           // Set rigidbody force (considering mass value)
+void AddForceAtPosition(Vector2 position, float intensity, float radius);   // Add a force to all enabled rigidbodies at a position
 
 
-void SetColliderEnabled(int index, bool state);                         // Set enabled state to a defined collider
+void SetColliderEnabled(int index, bool state);                             // Set enabled state to a defined collider
 
 
-Rigidbody GetRigidbody(int index);                                      // Returns the internal rigidbody data defined by index parameter
-Collider GetCollider(int index);                                        // Returns the internal collider data defined by index parameter
+Rigidbody GetRigidbody(int index);                                          // Returns the internal rigidbody data defined by index parameter
+Collider GetCollider(int index);                                            // Returns the internal collider data defined by index parameter
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 13 - 11
src/raylib.h

@@ -793,21 +793,23 @@ void SetMaterialNormalDepth(Material *material, float depth);           // Set n
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Physics System Functions (engine-module: physics)
 // Physics System Functions (engine-module: physics)
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-void InitPhysics();                                                     // Initialize all internal physics values
-void SetPhysics(Physics settings);                                      // Set physics settings values using Physics data type to overwrite internal physics settings
+void InitPhysics();                                                         // Initialize all internal physics values
+void SetPhysics(Physics settings);                                          // Set physics settings values using Physics data type to overwrite internal physics settings
 
 
-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 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 ApplyPhysics(int index, Vector2 *position);                        // Apply physics to internal rigidbody, physics calculations are applied to position pointer parameter
-void SetRigidbodyEnabled(int index, bool state);                        // Set enabled state to a defined rigidbody
-void SetRigidbodyVelocity(int index, Vector2 velocity);                 // Set velocity of rigidbody (without considering of mass value)
-void AddRigidbodyForce(int index, Vector2 force);                       // Set rigidbody force (considering mass value)
+void ApplyPhysics(int index, Vector2 *position);                            // Apply physics to internal rigidbody, physics calculations are applied to position pointer parameter
+void SetRigidbodyEnabled(int index, bool state);                            // Set enabled state to a defined rigidbody
+void SetRigidbodyVelocity(int index, Vector2 velocity);                     // Set velocity of rigidbody (without considering of mass value)
+void SetRigidbodyAcceleration(int index, Vector2 acceleration);             // Set acceleration of rigidbody (without considering of mass value)
+void AddRigidbodyForce(int index, Vector2 force);                           // Set rigidbody force (considering mass value)
+void AddForceAtPosition(Vector2 position, float intensity, float radius);   // Add a force to all enabled rigidbodies at a position
 
 
-void SetColliderEnabled(int index, bool state);                         // Set enabled state to a defined collider
+void SetColliderEnabled(int index, bool state);                             // Set enabled state to a defined collider
 
 
-Rigidbody GetRigidbody(int index);                                      // Returns the internal rigidbody data defined by index parameter
-Collider GetCollider(int index);                                        // Returns the internal collider data defined by index parameter
+Rigidbody GetRigidbody(int index);                                          // Returns the internal rigidbody data defined by index parameter
+Collider GetCollider(int index);                                            // Returns the internal collider data defined by index parameter
 
 
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 // Audio Loading and Playing Functions (Module: audio)
 // Audio Loading and Playing Functions (Module: audio)