aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay <raysan5@gmail.com>2016-01-04 12:40:54 +0100
committerRay <raysan5@gmail.com>2016-01-04 12:40:54 +0100
commit546c727520d8116132e57fd5e007dd7d873ba9a1 (patch)
tree9626741431535dbfdb518d35f553c8184392a23c
parent3a739c38c591687d0e298a85f1e7bfe4666076bd (diff)
parent1656d17b22b362e54710b7164638464e02bd7e5a (diff)
downloadraylib-546c727520d8116132e57fd5e007dd7d873ba9a1.tar.gz
raylib-546c727520d8116132e57fd5e007dd7d873ba9a1.zip
Merge pull request #69 from victorfisac/develop
Improved lighting and physac engine modules and added new example
-rw-r--r--examples/lighting_blinn_phong.c4
-rw-r--r--examples/physics_basic_rigidbody.c2
-rw-r--r--examples/physics_rigidbody_force.c141
-rw-r--r--examples/physics_rigidbody_force.pngbin0 -> 18510 bytes
-rw-r--r--src/lighting.c2
-rw-r--r--src/lighting.h2
-rw-r--r--src/physac.c150
-rw-r--r--src/physac.h28
-rw-r--r--src/raylib.h24
9 files changed, 284 insertions, 69 deletions
diff --git a/examples/lighting_blinn_phong.c b/examples/lighting_blinn_phong.c
index 48949b03..d4ff548a 100644
--- a/examples/lighting_blinn_phong.c
+++ b/examples/lighting_blinn_phong.c
@@ -31,7 +31,7 @@ int main()
// Model initialization
Vector3 position = { 0.0, 0.0, 0.0 };
Model model = LoadModel("resources/model/dwarf.obj");
- // Shader shader = LoadShader("resources/shaders/phong.vs", "resources/shaders/phong.fs");
+ Shader shader = LoadShader("resources/shaders/phong.vs", "resources/shaders/phong.fs");
SetModelShader(&model, shader);
// Shader locations initialization
@@ -154,7 +154,7 @@ int main()
Begin3dMode(camera);
- DrawModel(model, position, 0.1f, (Color){255 * blinnMaterial.diffuseColor[0], 255 * blinnMaterial.diffuseColor[1], 255 * blinnMaterial.diffuseColor[2], 255});
+ DrawModel(model, position, 4.0f, (Color){255 * blinnMaterial.diffuseColor[0], 255 * blinnMaterial.diffuseColor[1], 255 * blinnMaterial.diffuseColor[2], 255});
DrawSphere((Vector3){directionalLight.position[0], directionalLight.position[1], directionalLight.position[2]}, 1, YELLOW);
diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c
index 2f3fffbc..17d6564f 100644
--- a/examples/physics_basic_rigidbody.c
+++ b/examples/physics_basic_rigidbody.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [physics] example - Basic rigidbody
+* raylib [physac] physics example - Basic rigidbody
*
* Welcome to raylib!
*
diff --git a/examples/physics_rigidbody_force.c b/examples/physics_rigidbody_force.c
new file mode 100644
index 00000000..726e7c67
--- /dev/null
+++ b/examples/physics_rigidbody_force.c
@@ -0,0 +1,141 @@
+/*******************************************************************************************
+*
+* raylib [physac] physics example - Rigidbody forces
+*
+* This example has been created using raylib 1.3 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Copyright (c) 2014 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#define MAX_OBJECTS 5
+#define OBJECTS_OFFSET 150
+
+#define FORCE_INTENSITY 250.0f // Customize by user
+#define FORCE_RADIUS 100 // Customize by user
+
+int main()
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ int screenWidth = 800;
+ 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
+ Physics worldPhysics = {true, false, (Vector2){0, -9.81f}};
+
+ // Set internal physics settings
+ SetPhysics(worldPhysics);
+
+ // Objects initialization
+ Transform objects[MAX_OBJECTS];
+ 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});
+ 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});
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+
+ // 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++)
+ {
+ ApplyPhysics(i, &objects[i].position);
+ }
+
+ // Check foce button input
+ if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
+ {
+ AddForceAtPosition(GetMousePosition(), FORCE_INTENSITY, FORCE_RADIUS);
+ }
+
+ // Check debug mode toggle button input
+ if(IsKeyPressed(KEY_P))
+ {
+ // Update program physics value
+ worldPhysics.debug = !worldPhysics.debug;
+
+ // Update internal physics value
+ SetPhysics(worldPhysics);
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ // Check if debug mode is enabled
+ if(worldPhysics.debug)
+ {
+ // Draw every internal physics stored collider if it is active (floor included)
+ for(int i = 0; i < MAX_OBJECTS + 1; i++)
+ {
+ 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)
+ {
+ // 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))
+ {
+ DrawLineV(GetMousePosition(), (Vector2){GetCollider(i).bounds.x + GetCollider(i).bounds.width / 2, GetCollider(i).bounds.y + GetCollider(i).bounds.height / 2}, RED);
+ }
+ }
+ }
+ }
+
+ // Draw radius circle
+ DrawCircleLines(GetMousePosition().x, GetMousePosition().y, FORCE_RADIUS, RED);
+ }
+ else
+ {
+ // Draw objects
+ 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);
+ }
+
+ // Draw floor
+ DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK);
+ }
+
+
+ // Draw help messages
+ DrawText("Use LEFT MOUSE BUTTON to create a force in mouse position", (screenWidth - MeasureText("Use LEFT MOUSE BUTTON to create a force in mouse position", 20)) / 2, screenHeight * 0.20f, 20, LIGHTGRAY);
+ DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
diff --git a/examples/physics_rigidbody_force.png b/examples/physics_rigidbody_force.png
new file mode 100644
index 00000000..48afa91b
--- /dev/null
+++ b/examples/physics_rigidbody_force.png
Binary files differ
diff --git a/src/lighting.c b/src/lighting.c
index 5cf2a2ec..9014dcd4 100644
--- a/src/lighting.c
+++ b/src/lighting.c
@@ -121,4 +121,4 @@ void SetMaterialGlossiness(Material *material, float glossiness)
void SetMaterialNormalDepth(Material *material, float depth)
{
material->normalDepth[0] = depth;
-} \ No newline at end of file
+}
diff --git a/src/lighting.h b/src/lighting.h
index a35113c3..e1fc4e50 100644
--- a/src/lighting.h
+++ b/src/lighting.h
@@ -84,4 +84,4 @@ void SetMaterialNormalDepth(Material *material, float depth); // Set n
}
#endif
-#endif // LIGHTING_H \ No newline at end of file
+#endif // LIGHTING_H
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)