|
|
@ -1,6 +1,6 @@ |
|
|
|
/********************************************************************************************** |
|
|
|
* |
|
|
|
* raylib physics engine module - Basic functions to apply physics to 2D objects |
|
|
|
* p">[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}; |
|
|
|
} |