From 8c8e5bb7c86e4de6036ce2f8f9b00c2587268de4 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 30 Dec 2015 13:43:53 +0100 Subject: Update and rename physics.c to physac.c --- src/physac.c | 272 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 src/physac.c (limited to 'src/physac.c') diff --git a/src/physac.c b/src/physac.c new file mode 100644 index 00000000..11e1766e --- /dev/null +++ b/src/physac.c @@ -0,0 +1,272 @@ +/********************************************************************************************** +* +* raylib physics engine module - Basic functions to apply physics to 2D objects +* +* Copyright (c) 2015 Victor Fisac and Ramon Santamaria +* +* 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. +* +**********************************************************************************************/ + +//#define PHYSAC_STANDALONE // NOTE: To use the physics module as standalone lib, just uncomment this line + +#if defined(PHYSAC_STANDALONE) + #include "physac.h" +#else + #include "raylib.h" +#endif + +#include +#include + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#define MAX_ELEMENTS 1024 // Stored rigidbodies and colliders array length +#define DECIMAL_FIX 0.01f // Decimal margin for collision checks (avoid rigidbodies shake) + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// ... + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +static Physics physics; +static Collider colliders[MAX_ELEMENTS]; +static Rigidbody rigidbodies[MAX_ELEMENTS]; +static bool collisionChecker = false; + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- +void InitPhysics() +{ + for (int i = 0; i < MAX_ELEMENTS; i++) + { + rigidbodies[i].enabled = false; + rigidbodies[i].mass = 0.0f; + rigidbodies[i].velocity = (Vector2){0, 0}; + rigidbodies[i].acceleration = (Vector2){0, 0}; + rigidbodies[i].isGrounded = false; + rigidbodies[i].isContact = false; + rigidbodies[i].friction = 0.0f; + + colliders[i].enabled = false; + colliders[i].bounds = (Rectangle){0, 0, 0, 0}; + colliders[i].radius = 0; + } +} + +void SetPhysics(Physics settings) +{ + 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}; +} + +void AddCollider(int index, Collider collider) +{ + colliders[index] = collider; +} + +void AddRigidbody(int index, Rigidbody rigidbody) +{ + rigidbodies[index] = rigidbody; +} + +void ApplyPhysics(int index, Vector2 *position) +{ + if (rigidbodies[index].enabled) + { + // Apply gravity + rigidbodies[index].velocity.y += rigidbodies[index].acceleration.y; + rigidbodies[index].velocity.x += rigidbodies[index].acceleration.x; + + rigidbodies[index].velocity.y += physics.gravity.y; + rigidbodies[index].velocity.x += physics.gravity.x; + + // Apply friction to velocity + if (rigidbodies[index].isGrounded) + { + if (rigidbodies[index].velocity.x > DECIMAL_FIX) + { + rigidbodies[index].velocity.x -= rigidbodies[index].friction; + } + else if (rigidbodies[index].velocity.x < -DECIMAL_FIX) + { + rigidbodies[index].velocity.x += rigidbodies[index].friction; + } + else + { + rigidbodies[index].velocity.x = 0; + } + } + + if (rigidbodies[index].velocity.y > DECIMAL_FIX) + { + rigidbodies[index].velocity.y -= rigidbodies[index].friction; + } + else if (rigidbodies[index].velocity.y < -DECIMAL_FIX) + { + rigidbodies[index].velocity.y += rigidbodies[index].friction; + } + else + { + 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; + } + } + + 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; + } + + // Update position vector + position->x += rigidbodies[index].velocity.x; + position->y -= rigidbodies[index].velocity.y; + + // Update collider bounds + colliders[index].bounds.x = position->x; + colliders[index].bounds.y = position->y; + + // Check collision with other colliders + collisionChecker = false; + rigidbodies[index].isContact = false; + for (int j = 0; j < MAX_ELEMENTS; j++) + { + if (index != j) + { + if (colliders[index].enabled && colliders[j].enabled) + { + if (colliders[index].type == RectangleCollider) + { + if (colliders[j].type == RectangleCollider) + { + if (CheckCollisionRecs(colliders[index].bounds, colliders[j].bounds)) + { + collisionChecker = true; + + if ((colliders[index].bounds.y + colliders[index].bounds.height <= colliders[j].bounds.y) == false) + { + rigidbodies[index].isContact = true; + } + } + } + else + { + if (CheckCollisionCircleRec((Vector2){colliders[j].bounds.x, colliders[j].bounds.y}, colliders[j].radius, colliders[index].bounds)) + { + collisionChecker = true; + } + } + } + else + { + if (colliders[j].type == RectangleCollider) + { + if (CheckCollisionCircleRec((Vector2){colliders[index].bounds.x, colliders[index].bounds.y}, colliders[index].radius, colliders[j].bounds)) + { + collisionChecker = true; + } + } + else + { + if (CheckCollisionCircles((Vector2){colliders[j].bounds.x, colliders[j].bounds.y}, colliders[j].radius, (Vector2){colliders[index].bounds.x, colliders[index].bounds.y}, colliders[index].radius)) + { + collisionChecker = true; + } + } + } + } + } + } + + // Update grounded rigidbody state + rigidbodies[index].isGrounded = collisionChecker; + + // Set grounded state if needed (fix overlap and set y velocity) + if (collisionChecker && rigidbodies[index].velocity.y != 0) + { + position->y += rigidbodies[index].velocity.y; + rigidbodies[index].velocity.y = -rigidbodies[index].velocity.y * rigidbodies[index].bounciness; + } + + if (rigidbodies[index].isContact) + { + position->x -= rigidbodies[index].velocity.x; + rigidbodies[index].velocity.x = rigidbodies[index].velocity.x; + } + } +} + +void SetRigidbodyEnabled(int index, bool state) +{ + rigidbodies[index].enabled = state; +} + +void SetRigidbodyVelocity(int index, Vector2 velocity) +{ + rigidbodies[index].velocity.x = velocity.x; + rigidbodies[index].velocity.y = velocity.y; +} + +void AddRigidbodyForce(int index, Vector2 force) +{ + rigidbodies[index].acceleration.x = force.x * rigidbodies[index].mass; + rigidbodies[index].acceleration.y = force.y * rigidbodies[index].mass; +} + +void SetColliderEnabled(int index, bool state) +{ + colliders[index].enabled = state; +} + +Collider GetCollider(int index) +{ + return colliders[index]; +} + +Rigidbody GetRigidbody(int index) +{ + return rigidbodies[index]; +} -- cgit v1.2.3 From a299bc289b36a40efcf9d02597d5122546458021 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Sun, 3 Jan 2016 17:53:29 +0100 Subject: Improved and added functions to physac engine module - Improved physics calculations. - Added AddForceAtPosition function (added to all enabled rigidbodies). - Updated raylib header. --- src/physac.c | 150 +++++++++++++++++++++++++++++++++++++++++++---------------- src/physac.h | 28 +++++------ src/raylib.h | 24 +++++----- 3 files changed, 138 insertions(+), 64 deletions(-) (limited to 'src/physac.c') diff --git a/src/physac.c b/src/physac.c index 11e1766e..73ce7adc 100644 --- a/src/physac.c +++ b/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 * @@ -36,7 +36,7 @@ // Defines and Macros //---------------------------------------------------------------------------------- #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 @@ -52,7 +52,14 @@ static Rigidbody rigidbodies[MAX_ELEMENTS]; 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() { @@ -94,12 +101,32 @@ void ApplyPhysics(int index, Vector2 *position) { 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 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; } - else if (rigidbodies[index].velocity.y < -DECIMAL_FIX) + else if (rigidbodies[index].velocity.y < -DECIMAL_FIX / 2) { rigidbodies[index].velocity.y += rigidbodies[index].friction; } @@ -131,35 +158,13 @@ void ApplyPhysics(int index, Vector2 *position) 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 position->x += rigidbodies[index].velocity.x; @@ -250,10 +255,49 @@ void SetRigidbodyVelocity(int index, Vector2 velocity) 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) { - 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) @@ -270,3 +314,29 @@ Rigidbody GetRigidbody(int 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}; +} diff --git a/src/physac.h b/src/physac.h index aec57d6f..7dbfe1fe 100644 --- a/src/physac.h +++ b/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 * @@ -74,23 +74,25 @@ extern "C" { // Prevents name mangling of functions #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 } diff --git a/src/raylib.h b/src/raylib.h index 864a240a..99a6979c 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -793,21 +793,23 @@ void SetMaterialNormalDepth(Material *material, float depth); // Set n //---------------------------------------------------------------------------------- // 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) -- cgit v1.2.3 From fe0cf8f9a9d6cafa40a1baf8b3cdace0268ccb82 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Tue, 5 Jan 2016 13:58:20 +0100 Subject: Added some comments and fixed spaces --- src/core.c | 1 + src/physac.c | 2 +- src/physac.h | 2 +- src/raylib.h | 4 ++-- templates/android_project/jni/include/raylib.h | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/physac.c') diff --git a/src/core.c b/src/core.c index 40691403..1d05edc6 100644 --- a/src/core.c +++ b/src/core.c @@ -1111,6 +1111,7 @@ Vector2 GetTouchPosition(void) return position; } +// Detect if a button has been pressed once bool IsButtonPressed(int button) { bool pressed = false; diff --git a/src/physac.c b/src/physac.c index 73ce7adc..6e3b6e61 100644 --- a/src/physac.c +++ b/src/physac.c @@ -61,7 +61,7 @@ static Vector2 Vector2Normalize(Vector2 vector); //---------------------------------------------------------------------------------- // Module Functions Definitions //---------------------------------------------------------------------------------- -void InitPhysics() +void InitPhysics(void) { for (int i = 0; i < MAX_ELEMENTS; i++) { diff --git a/src/physac.h b/src/physac.h index 7dbfe1fe..558673ef 100644 --- a/src/physac.h +++ b/src/physac.h @@ -76,7 +76,7 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- // Module Functions Declarations //---------------------------------------------------------------------------------- -void InitPhysics(); // Initialize all internal physics values +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 AddRigidbody(int index, Rigidbody rigidbody); // Initialize a new rigidbody with parameters to internal index slot diff --git a/src/raylib.h b/src/raylib.h index 641eac4b..72211b59 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -589,7 +589,7 @@ int GetTouchY(void); // Returns touch positio Vector2 GetTouchPosition(void); // Returns touch position XY (relative to screen size) bool IsButtonPressed(int button); // Detect if an android physic button has been pressed bool IsButtonDown(int button); // Detect if an android physic button is being pressed -bool IsButtonReleased(int button); // Detect if an android physic button has been released +bool IsButtonReleased(int button); // Detect if an android physic button has been released //------------------------------------------------------------------------------------ // Gestures and Touch Handling Functions (Module: gestures) @@ -805,7 +805,7 @@ void SetMaterialNormalDepth(Material *material, float depth); // Set n //---------------------------------------------------------------------------------- // Physics System Functions (engine-module: physics) //---------------------------------------------------------------------------------- -void InitPhysics(); // Initialize all internal physics values +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 AddRigidbody(int index, Rigidbody rigidbody); // Initialize a new rigidbody with parameters to internal index slot diff --git a/templates/android_project/jni/include/raylib.h b/templates/android_project/jni/include/raylib.h index 641eac4b..72211b59 100644 --- a/templates/android_project/jni/include/raylib.h +++ b/templates/android_project/jni/include/raylib.h @@ -589,7 +589,7 @@ int GetTouchY(void); // Returns touch positio Vector2 GetTouchPosition(void); // Returns touch position XY (relative to screen size) bool IsButtonPressed(int button); // Detect if an android physic button has been pressed bool IsButtonDown(int button); // Detect if an android physic button is being pressed -bool IsButtonReleased(int button); // Detect if an android physic button has been released +bool IsButtonReleased(int button); // Detect if an android physic button has been released //------------------------------------------------------------------------------------ // Gestures and Touch Handling Functions (Module: gestures) @@ -805,7 +805,7 @@ void SetMaterialNormalDepth(Material *material, float depth); // Set n //---------------------------------------------------------------------------------- // Physics System Functions (engine-module: physics) //---------------------------------------------------------------------------------- -void InitPhysics(); // Initialize all internal physics values +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 AddRigidbody(int index, Rigidbody rigidbody); // Initialize a new rigidbody with parameters to internal index slot -- cgit v1.2.3 From c5663ca015e550ab8e2a43c10fa72db0aab7cac8 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 20 Jan 2016 19:09:48 +0100 Subject: Some formatting tweaks --- examples/physics_basic_rigidbody.c | 24 +++++++++++++----------- examples/physics_rigidbody_force.c | 37 ++++++++++++++++++++----------------- src/physac.c | 6 +++--- src/physac.h | 3 ++- src/raylib.h | 8 ++++---- 5 files changed, 42 insertions(+), 36 deletions(-) (limited to 'src/physac.c') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 17d6564f..b82fe638 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -32,28 +32,30 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physics] example - basic rigidbody"); - SetTargetFPS(60); // Enable v-sync + InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) // Physics initialization - Physics worldPhysics = {true, false, (Vector2){0, -9.81f}}; + Physics worldPhysics = { true, false, (Vector2){ 0, -9.81f } }; // Set internal physics settings SetPhysics(worldPhysics); // Object initialization Transform player = (Transform){(Vector2){(screenWidth - OBJECT_SIZE) / 2, (screenHeight - OBJECT_SIZE) / 2}, 0.0f, (Vector2){OBJECT_SIZE, OBJECT_SIZE}}; - AddCollider(PLAYER_INDEX, (Collider){true, RectangleCollider, (Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, 0}); + AddCollider(PLAYER_INDEX, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, 0}); AddRigidbody(PLAYER_INDEX, (Rigidbody){true, 1.0f, (Vector2){0, 0}, (Vector2){0, 0}, false, false, true, 0.5f, 1.0f}); // Floor initialization // NOTE: floor doesn't need a rigidbody because it's a static physic object, just a collider to collide with other dynamic colliders (with rigidbody) Transform floor = (Transform){(Vector2){0, screenHeight * 0.8f}, 0.0f, (Vector2){screenWidth, screenHeight * 0.2f}}; - AddCollider(PLAYER_INDEX + 1, (Collider){true, RectangleCollider, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0}); + AddCollider(PLAYER_INDEX + 1, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0}); // Object properties initialization float moveSpeed = 6.0f; - float jumpForce = 4.5f; + float jumpForce = 5.0f; + + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -67,7 +69,7 @@ int main() ApplyPhysics(PLAYER_INDEX, &player.position); // Check jump button input - if(IsKeyDown(KEY_SPACE) && GetRigidbody(PLAYER_INDEX).isGrounded) + if (IsKeyDown(KEY_SPACE) && GetRigidbody(PLAYER_INDEX).isGrounded) { // Reset object Y velocity to avoid double jumping cases but keep the same X velocity that it already has SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){GetRigidbody(PLAYER_INDEX).velocity.x, 0}); @@ -77,12 +79,12 @@ int main() } // Check movement buttons input - if(IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) + if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) { // Set rigidbody velocity in X based on moveSpeed value and apply the same Y velocity that it already has SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){moveSpeed, GetRigidbody(PLAYER_INDEX).velocity.y}); } - else if(IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) + else if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) { // Set rigidbody velocity in X based on moveSpeed negative value and apply the same Y velocity that it already has SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){-moveSpeed, GetRigidbody(PLAYER_INDEX).velocity.y}); @@ -110,12 +112,12 @@ int main() DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY); // Check if debug mode is enabled - if(worldPhysics.debug) + if (worldPhysics.debug) { // Draw every internal physics stored collider if it is active - for(int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { - if(GetCollider(i).enabled) + if (GetCollider(i).enabled) { DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN); } diff --git a/examples/physics_rigidbody_force.c b/examples/physics_rigidbody_force.c index 726e7c67..3ac560c5 100644 --- a/examples/physics_rigidbody_force.c +++ b/examples/physics_rigidbody_force.c @@ -11,11 +11,11 @@ #include "raylib.h" -#define MAX_OBJECTS 5 -#define OBJECTS_OFFSET 150 +#define MAX_OBJECTS 5 +#define OBJECTS_OFFSET 150 -#define FORCE_INTENSITY 250.0f // Customize by user -#define FORCE_RADIUS 100 // Customize by user +#define FORCE_INTENSITY 250.0f // Customize by user +#define FORCE_RADIUS 100 // Customize by user int main() { @@ -25,7 +25,7 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physics] example - rigidbodies forces"); - SetTargetFPS(60); // Enable v-sync + InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) // Physics initialization @@ -36,17 +36,20 @@ int main() // Objects initialization Transform objects[MAX_OBJECTS]; - for(int i = 0; i < MAX_OBJECTS; i++) + + for (int i = 0; i < MAX_OBJECTS; i++) { objects[i] = (Transform){(Vector2){75 + OBJECTS_OFFSET * i, (screenHeight - 50) / 2}, 0.0f, (Vector2){50, 50}}; - AddCollider(i, (Collider){true, RectangleCollider, (Rectangle){objects[i].position.x, objects[i].position.y, objects[i].scale.x, objects[i].scale.y}, 0}); + AddCollider(i, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){objects[i].position.x, objects[i].position.y, objects[i].scale.x, objects[i].scale.y}, 0}); AddRigidbody(i, (Rigidbody){true, 1.0f, (Vector2){0, 0}, (Vector2){0, 0}, false, false, true, 0.5f, 0.5f}); } // Floor initialization // NOTE: floor doesn't need a rigidbody because it's a static physic object, just a collider to collide with other dynamic colliders (with rigidbody) Transform floor = (Transform){(Vector2){0, screenHeight * 0.8f}, 0.0f, (Vector2){screenWidth, screenHeight * 0.2f}}; - AddCollider(MAX_OBJECTS, (Collider){true, RectangleCollider, (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}); + + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -57,19 +60,19 @@ int main() // Update object physics // NOTE: all physics detections and reactions are calculated in ApplyPhysics() function (You will live happier :D) - for(int i = 0; i < MAX_OBJECTS; i++) + for (int i = 0; i < MAX_OBJECTS; i++) { ApplyPhysics(i, &objects[i].position); } // Check foce button input - if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { AddForceAtPosition(GetMousePosition(), FORCE_INTENSITY, FORCE_RADIUS); } // Check debug mode toggle button input - if(IsKeyPressed(KEY_P)) + if (IsKeyPressed(KEY_P)) { // Update program physics value worldPhysics.debug = !worldPhysics.debug; @@ -86,21 +89,21 @@ int main() ClearBackground(RAYWHITE); // Check if debug mode is enabled - if(worldPhysics.debug) + if (worldPhysics.debug) { // 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 + 1; i++) { - if(GetCollider(i).enabled) + if (GetCollider(i).enabled) { // Draw collider bounds DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN); // Check if current collider is not floor - if(i < MAX_OBJECTS) + if (i < MAX_OBJECTS) { // Draw lines between mouse position and objects if they are in force range - if(CheckCollisionPointCircle(GetMousePosition(), (Vector2){GetCollider(i).bounds.x + GetCollider(i).bounds.width / 2, GetCollider(i).bounds.y + GetCollider(i).bounds.height / 2}, FORCE_RADIUS)) + if (CheckCollisionPointCircle(GetMousePosition(), (Vector2){GetCollider(i).bounds.x + GetCollider(i).bounds.width / 2, GetCollider(i).bounds.y + GetCollider(i).bounds.height / 2}, FORCE_RADIUS)) { DrawLineV(GetMousePosition(), (Vector2){GetCollider(i).bounds.x + GetCollider(i).bounds.width / 2, GetCollider(i).bounds.y + GetCollider(i).bounds.height / 2}, RED); } @@ -114,7 +117,7 @@ int main() else { // Draw objects - for(int i = 0; i < MAX_OBJECTS; i++) + for (int i = 0; i < MAX_OBJECTS; i++) { DrawRectangleRec((Rectangle){objects[i].position.x, objects[i].position.y, objects[i].scale.x, objects[i].scale.y}, GRAY); } diff --git a/src/physac.c b/src/physac.c index 6e3b6e61..6dfdbb49 100644 --- a/src/physac.c +++ b/src/physac.c @@ -183,9 +183,9 @@ void ApplyPhysics(int index, Vector2 *position) { if (colliders[index].enabled && colliders[j].enabled) { - if (colliders[index].type == RectangleCollider) + if (colliders[index].type == COLLIDER_RECTANGLE) { - if (colliders[j].type == RectangleCollider) + if (colliders[j].type == COLLIDER_RECTANGLE) { if (CheckCollisionRecs(colliders[index].bounds, colliders[j].bounds)) { @@ -207,7 +207,7 @@ void ApplyPhysics(int index, Vector2 *position) } else { - if (colliders[j].type == RectangleCollider) + if (colliders[j].type == COLLIDER_RECTANGLE) { if (CheckCollisionCircleRec((Vector2){colliders[index].bounds.x, colliders[index].bounds.y}, colliders[index].radius, colliders[j].bounds)) { diff --git a/src/physac.h b/src/physac.h index 558673ef..a1501ee3 100644 --- a/src/physac.h +++ b/src/physac.h @@ -32,7 +32,8 @@ //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -typedef enum { RectangleCollider, CircleCollider } ColliderType; +// Collider types +typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType; // Physics struct typedef struct Physics { diff --git a/src/raylib.h b/src/raylib.h index 0a768fe4..5798d907 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -463,12 +463,12 @@ typedef struct { typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; // Collider types -typedef enum { RectangleCollider, CircleCollider } 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 + bool debug; // Should be used by programmer for testing purposes Vector2 gravity; } Physics; @@ -496,8 +496,8 @@ typedef struct Rigidbody { typedef struct Collider { bool enabled; ColliderType type; - Rectangle bounds; // Just used for RectangleCollider type - int radius; // Just used for CircleCollider type + Rectangle bounds; // Used for COLLIDER_RECTANGLE and COLLIDER_CAPSULE + int radius; // Used for COLLIDER_CIRCLE and COLLIDER_CAPSULE } Collider; #ifdef __cplusplus -- cgit v1.2.3 From cf6c6fefd76135df0247339c9adc2712da6c2691 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 20 Jan 2016 19:23:58 +0100 Subject: Review some function names for consistency with raymath --- src/physac.c | 26 +++++++++++++++----------- src/physac.h | 4 ++-- 2 files changed, 17 insertions(+), 13 deletions(-) (limited to 'src/physac.c') diff --git a/src/physac.c b/src/physac.c index 6dfdbb49..891f0123 100644 --- a/src/physac.c +++ b/src/physac.c @@ -55,8 +55,8 @@ static bool collisionChecker = false; // Module specific Functions Declarations //---------------------------------------------------------------------------------- static float Vector2Length(Vector2 vector); -static float Vector2LengthPoints(Vector2 a, Vector2 b); -static Vector2 Vector2Normalize(Vector2 vector); +static float Vector2Distance(Vector2 a, Vector2 b); +static void Vector2Normalize(Vector2 *vector); //---------------------------------------------------------------------------------- // Module Functions Definitions @@ -277,7 +277,7 @@ void AddForceAtPosition(Vector2 position, float intensity, float radius) Vector2 pos = {colliders[i].bounds.x, colliders[i].bounds.y}; // Get distance between rigidbody position and target position - float distance = Vector2LengthPoints(position, pos); + float distance = Vector2Distance(position, pos); if(distance <= radius) { @@ -285,7 +285,7 @@ void AddForceAtPosition(Vector2 position, float intensity, float radius) Vector2 force = {colliders[i].bounds.x - position.x, colliders[i].bounds.y - position.y}; // Normalize the direction vector - force = Vector2Normalize(force); + Vector2Normalize(&force); // Invert y value force.y *= -1; @@ -323,20 +323,24 @@ static float Vector2Length(Vector2 vector) return sqrt((vector.x * vector.x) + (vector.y * vector.y)); } -static float Vector2LengthPoints(Vector2 a, Vector2 b) +static float Vector2Distance(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) +static void Vector2Normalize(Vector2 *vector) { - float length = Vector2Length(vector); + float length = Vector2Length(*vector); - if(length != 0) + if (length != 0.0f) { - return (Vector2){vector.x / length, vector.y / length}; + vector->x /= length; + vector->y /= length; + } + else + { + vector->x = 0.0f; + vector->y = 0.0f; } - - return (Vector2){0, 0}; } diff --git a/src/physac.h b/src/physac.h index a1501ee3..12209987 100644 --- a/src/physac.h +++ b/src/physac.h @@ -66,8 +66,8 @@ typedef struct Rigidbody { typedef struct Collider { bool enabled; ColliderType type; - Rectangle bounds; // Just used for RectangleCollider type - int radius; // Just used for CircleCollider type + Rectangle bounds; // Used for COLLIDER_RECTANGLE and COLLIDER_CAPSULE + int radius; // Used for COLLIDER_CIRCLE and COLLIDER_CAPSULE } Collider; #ifdef __cplusplus -- cgit v1.2.3 From ed1906440560d5b6b6e2cb1c1927e53b28e302db Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 13 Feb 2016 17:09:53 +0100 Subject: Reviewed physics module A deeper revision required, not clear enough for the user Key: Create a PhysicObjects pool --- examples/physics_basic_rigidbody.c | 44 +++++++-------------------- examples/physics_rigidbody_force.c | 33 ++++++++------------- src/physac.c | 61 ++++++++++++++++++++++---------------- src/physac.h | 11 ++----- src/raylib.h | 13 ++------ 5 files changed, 64 insertions(+), 98 deletions(-) (limited to 'src/physac.c') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index b82fe638..6c354eb7 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -2,20 +2,10 @@ * * raylib [physac] physics example - Basic rigidbody * -* Welcome to raylib! -* -* To test examples, just press F6 and execute raylib_compile_execute script -* Note that compiled executable is placed in the same folder as .c file -* -* You can find all basic examples on C:\raylib\raylib\examples folder or -* raylib official webpage: www.raylib.com -* -* Enjoy using raylib. :) -* -* This example has been created using raylib 1.3 (www.raylib.com) +* This example has been created using raylib 1.4 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -33,13 +23,7 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [physics] example - basic rigidbody"); - InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) - - // Physics initialization - Physics worldPhysics = { true, false, (Vector2){ 0, -9.81f } }; - - // Set internal physics settings - SetPhysics(worldPhysics); + InitPhysics(3); // Initialize physics system with maximum physic objects // Object initialization Transform player = (Transform){(Vector2){(screenWidth - OBJECT_SIZE) / 2, (screenHeight - OBJECT_SIZE) / 2}, 0.0f, (Vector2){OBJECT_SIZE, OBJECT_SIZE}}; @@ -55,6 +39,8 @@ int main() float moveSpeed = 6.0f; float jumpForce = 5.0f; + bool physicsDebug = false; + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -91,14 +77,7 @@ int main() } // Check debug mode toggle button input - if(IsKeyPressed(KEY_P)) - { - // Update program physics value - worldPhysics.debug = !worldPhysics.debug; - - // Update internal physics value - SetPhysics(worldPhysics); - } + if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug; //---------------------------------------------------------------------------------- // Draw @@ -112,7 +91,7 @@ int main() DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY); // Check if debug mode is enabled - if (worldPhysics.debug) + if (physicsDebug) { // Draw every internal physics stored collider if it is active for (int i = 0; i < 2; i++) @@ -122,14 +101,11 @@ int main() DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN); } } - } else { - // Draw player + // Draw player and floor DrawRectangleRec((Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, GRAY); - - // Draw floor DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK); } @@ -138,7 +114,9 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- + UnloadPhysics(); // Unload physic objects + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/physics_rigidbody_force.c b/examples/physics_rigidbody_force.c index 3ac560c5..74a88a97 100644 --- a/examples/physics_rigidbody_force.c +++ b/examples/physics_rigidbody_force.c @@ -2,10 +2,10 @@ * * raylib [physac] physics example - Rigidbody forces * -* This example has been created using raylib 1.3 (www.raylib.com) +* This example has been created using raylib 1.4 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (@raysan5) +* Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -26,15 +26,9 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [physics] example - rigidbodies forces"); - InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) + InitPhysics(MAX_OBJECTS + 1); // Initialize physics system with maximum physic objects - // Physics initialization - Physics worldPhysics = {true, false, (Vector2){0, -9.81f}}; - - // Set internal physics settings - SetPhysics(worldPhysics); - - // Objects initialization + // Physic Objects initialization Transform objects[MAX_OBJECTS]; for (int i = 0; i < MAX_OBJECTS; i++) @@ -49,6 +43,8 @@ int main() Transform floor = (Transform){(Vector2){0, screenHeight * 0.8f}, 0.0f, (Vector2){screenWidth, screenHeight * 0.2f}}; AddCollider(MAX_OBJECTS, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0}); + bool physicsDebug = false; + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -72,14 +68,7 @@ int main() } // Check debug mode toggle button input - if (IsKeyPressed(KEY_P)) - { - // Update program physics value - worldPhysics.debug = !worldPhysics.debug; - - // Update internal physics value - SetPhysics(worldPhysics); - } + if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug; //---------------------------------------------------------------------------------- // Draw @@ -89,10 +78,10 @@ int main() ClearBackground(RAYWHITE); // Check if debug mode is enabled - if (worldPhysics.debug) + if (physicsDebug) { // Draw every internal physics stored collider if it is active (floor included) - for (int i = 0; i < MAX_OBJECTS + 1; i++) + for (int i = 0; i < MAX_OBJECTS; i++) { if (GetCollider(i).enabled) { @@ -136,7 +125,9 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- + UnloadPhysics(); // Unload physic objects + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/src/physac.c b/src/physac.c index 891f0123..4c50dd41 100644 --- a/src/physac.c +++ b/src/physac.c @@ -30,13 +30,12 @@ #endif #include -#include +#include // Required for: malloc(), free() //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define MAX_ELEMENTS 1024 // Stored rigidbodies and colliders array length -#define DECIMAL_FIX 0.26f // Decimal margin for collision checks (avoid rigidbodies shake) +#define DECIMAL_FIX 0.26f // Decimal margin for collision checks (avoid rigidbodies shake) //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -46,10 +45,13 @@ //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -static Physics physics; -static Collider colliders[MAX_ELEMENTS]; -static Rigidbody rigidbodies[MAX_ELEMENTS]; -static bool collisionChecker = false; +static Collider *colliders; // Colliders array, dynamically allocated at runtime +static Rigidbody *rigidbodies; // Rigitbody array, dynamically allocated at runtime +static bool collisionChecker; + +static int maxElements; // Max physic elements to compute +static bool enabled; // Physics enabled? (true by default) +static Vector2 gravity; // Gravity value used for physic calculations //---------------------------------------------------------------------------------- // Module specific Functions Declarations @@ -61,30 +63,39 @@ static void Vector2Normalize(Vector2 *vector); //---------------------------------------------------------------------------------- // Module Functions Definitions //---------------------------------------------------------------------------------- -void InitPhysics(void) -{ - for (int i = 0; i < MAX_ELEMENTS; i++) +void InitPhysics(int maxPhysicElements) +{ + maxElements = maxPhysicElements; + + colliders = (Collider *)malloc(maxElements*sizeof(Collider)); + rigidbodies = (Rigidbody *)malloc(maxElements*sizeof(Rigidbody)); + + for (int i = 0; i < maxElements; i++) { + colliders[i].enabled = false; + colliders[i].bounds = (Rectangle){ 0, 0, 0, 0 }; + colliders[i].radius = 0; + rigidbodies[i].enabled = false; rigidbodies[i].mass = 0.0f; - rigidbodies[i].velocity = (Vector2){0, 0}; - rigidbodies[i].acceleration = (Vector2){0, 0}; + rigidbodies[i].velocity = (Vector2){ 0.0f, 0.0f }; + rigidbodies[i].acceleration = (Vector2){ 0.0f, 0.0f }; rigidbodies[i].isGrounded = false; rigidbodies[i].isContact = false; rigidbodies[i].friction = 0.0f; - - colliders[i].enabled = false; - colliders[i].bounds = (Rectangle){0, 0, 0, 0}; - colliders[i].radius = 0; } + + collisionChecker = false; + enabled = true; + + // NOTE: To get better results, gravity needs to be 1:10 from original parameter + gravity = (Vector2){ 0.0f, -9.81f/10.0f }; // By default, standard gravity } -void SetPhysics(Physics settings) +void UnloadPhysics() { - physics = settings; - - // To get good results, gravity needs to be 1:10 from original parameter - physics.gravity = (Vector2){physics.gravity.x / 10, physics.gravity.y / 10}; + free(colliders); + free(rigidbodies); } void AddCollider(int index, Collider collider) @@ -159,8 +170,8 @@ void ApplyPhysics(int index, Vector2 *position) } // Apply gravity - rigidbodies[index].velocity.y += physics.gravity.y; - rigidbodies[index].velocity.x += physics.gravity.x; + rigidbodies[index].velocity.y += gravity.y; + rigidbodies[index].velocity.x += gravity.x; // Apply acceleration rigidbodies[index].velocity.y += rigidbodies[index].acceleration.y; @@ -177,7 +188,7 @@ void ApplyPhysics(int index, Vector2 *position) // Check collision with other colliders collisionChecker = false; rigidbodies[index].isContact = false; - for (int j = 0; j < MAX_ELEMENTS; j++) + for (int j = 0; j < maxElements; j++) { if (index != j) { @@ -269,7 +280,7 @@ void AddRigidbodyForce(int index, Vector2 force) void AddForceAtPosition(Vector2 position, float intensity, float radius) { - for(int i = 0; i < MAX_ELEMENTS; i++) + for(int i = 0; i < maxElements; i++) { if(rigidbodies[i].enabled) { diff --git a/src/physac.h b/src/physac.h index 12209987..9e1b0b88 100644 --- a/src/physac.h +++ b/src/physac.h @@ -35,13 +35,6 @@ // Collider types typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType; -// Physics struct -typedef struct Physics { - bool enabled; - bool debug; // Should be used by programmer for testing purposes - Vector2 gravity; -} Physics; - // Transform struct typedef struct Transform { Vector2 position; @@ -77,8 +70,8 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- // Module Functions Declarations //---------------------------------------------------------------------------------- -void InitPhysics(void); // Initialize all internal physics values -void SetPhysics(Physics settings); // Set physics settings values using Physics data type to overwrite internal physics settings +void InitPhysics(int maxPhysicElements); // Initialize all internal physics values +void UnloadPhysics(); // Unload physic elements arrays void AddRigidbody(int index, Rigidbody rigidbody); // Initialize a new rigidbody with parameters to internal index slot void AddCollider(int index, Collider collider); // Initialize a new Collider with parameters to internal index slot diff --git a/src/raylib.h b/src/raylib.h index c2067a0e..43819b14 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -466,13 +466,6 @@ typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERS // Collider types typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType; -// Physics struct -typedef struct Physics { - bool enabled; - bool debug; // Should be used by programmer for testing purposes - Vector2 gravity; -} Physics; - // Transform struct typedef struct Transform { Vector2 position; @@ -808,10 +801,10 @@ void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textur void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied) //---------------------------------------------------------------------------------- -// Physics System Functions (engine-module: physics) +// Physics System Functions (engine-module: physac) //---------------------------------------------------------------------------------- -void InitPhysics(void); // Initialize all internal physics values -void SetPhysics(Physics settings); // Set physics settings values using Physics data type to overwrite internal physics settings +void InitPhysics(int maxPhysicElements); // Initialize all internal physics values +void UnloadPhysics(); // Unload physic elements arrays void AddRigidbody(int index, Rigidbody rigidbody); // Initialize a new rigidbody with parameters to internal index slot void AddCollider(int index, Collider collider); // Initialize a new Collider with parameters to internal index slot -- cgit v1.2.3