浏览代码

Improved and added functions to physac engine module

- Improved physics calculations.
- Added AddForceAtPosition function (added to all enabled rigidbodies).
- Updated raylib header.
pull/69/head
victorfisac 9 年前
父节点
当前提交
a299bc289b
共有 3 个文件被更改,包括 138 次插入64 次删除
  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
* 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};
}

+ 15
- 13
src/physac.h 查看文件

@ -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
*
@ -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
}

+ 13
- 11
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)

正在加载...
取消
保存