Ver código fonte

Reviewed physics module

A deeper revision required, not clear enough for the user
Key: Create a PhysicObjects pool
pull/83/head
raysan5 9 anos atrás
pai
commit
ed19064405
5 arquivos alterados com 64 adições e 98 exclusões
  1. +11
    -33
      examples/physics_basic_rigidbody.c
  2. +12
    -21
      examples/physics_rigidbody_force.c
  3. +36
    -25
      src/physac.c
  4. +2
    -9
      src/physac.h
  5. +3
    -10
      src/raylib.h

+ 11
- 33
examples/physics_basic_rigidbody.c Ver arquivo

@ -2,20 +2,10 @@
* *
* raylib [physac] physics example - Basic rigidbody * 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) * 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"); 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 // Object initialization
Transform player = (Transform){(Vector2){(screenWidth - OBJECT_SIZE) / 2, (screenHeight - OBJECT_SIZE) / 2}, 0.0f, (Vector2){OBJECT_SIZE, OBJECT_SIZE}}; 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 moveSpeed = 6.0f;
float jumpForce = 5.0f; float jumpForce = 5.0f;
bool physicsDebug = false;
SetTargetFPS(60); SetTargetFPS(60);
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -91,14 +77,7 @@ int main()
} }
// Check debug mode toggle button input // 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 // 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); 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 // Check if debug mode is enabled
if (worldPhysics.debug)
if (physicsDebug)
{ {
// Draw every internal physics stored collider if it is active // Draw every internal physics stored collider if it is active
for (int i = 0; i < 2; i++) 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); DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN);
} }
} }
} }
else else
{ {
// Draw player
// Draw player and floor
DrawRectangleRec((Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, GRAY); 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); DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK);
} }
@ -138,7 +114,9 @@ int main()
} }
// De-Initialization // De-Initialization
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
UnloadPhysics(); // Unload physic objects
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------

+ 12
- 21
examples/physics_rigidbody_force.c Ver arquivo

@ -2,10 +2,10 @@
* *
* raylib [physac] physics example - Rigidbody forces * 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) * 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"); InitWindow(screenWidth, screenHeight, "raylib [physics] example - rigidbodies forces");
InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024)
InitPhysics(n">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]; Transform objects[MAX_OBJECTS];
for (int i = 0; i < MAX_OBJECTS; i++) 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}}; 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}); 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); SetTargetFPS(60);
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -72,14 +68,7 @@ int main()
} }
// Check debug mode toggle button input // 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 // Draw
@ -89,10 +78,10 @@ int main()
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
// Check if debug mode is enabled // Check if debug mode is enabled
if (worldPhysics.debug)
if (physicsDebug)
{ {
// Draw every internal physics stored collider if it is active (floor included) // 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) if (GetCollider(i).enabled)
{ {
@ -136,7 +125,9 @@ int main()
} }
// De-Initialization // De-Initialization
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
UnloadPhysics(); // Unload physic objects
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------

+ 36
- 25
src/physac.c Ver arquivo

@ -30,13 +30,12 @@
#endif #endif
#include <math.h> #include <math.h>
#include <stdio.h>
#include <stdlib.h> // Required for: malloc(), free()
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // 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 // Types and Structures Definition
@ -46,10 +45,13 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // 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 // Module specific Functions Declarations
@ -61,30 +63,39 @@ static void Vector2Normalize(Vector2 *vector);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definitions // 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].enabled = false;
rigidbodies[i].mass = 0.0f; 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].isGrounded = false;
rigidbodies[i].isContact = false; rigidbodies[i].isContact = false;
rigidbodies[i].friction = 0.0f; 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) void AddCollider(int index, Collider collider)
@ -159,8 +170,8 @@ void ApplyPhysics(int index, Vector2 *position)
} }
// Apply gravity // 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 // Apply acceleration
rigidbodies[index].velocity.y += rigidbodies[index].acceleration.y; rigidbodies[index].velocity.y += rigidbodies[index].acceleration.y;
@ -177,7 +188,7 @@ void ApplyPhysics(int index, Vector2 *position)
// Check collision with other colliders // Check collision with other colliders
collisionChecker = false; collisionChecker = false;
rigidbodies[index].isContact = false; rigidbodies[index].isContact = false;
for (int j = 0; j < MAX_ELEMENTS; j++)
for (int j = 0; j < maxElements; j++)
{ {
if (index != j) if (index != j)
{ {
@ -269,7 +280,7 @@ void AddRigidbodyForce(int index, Vector2 force)
void AddForceAtPosition(Vector2 position, float intensity, float radius) 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) if(rigidbodies[i].enabled)
{ {

+ 2
- 9
src/physac.h Ver arquivo

@ -35,13 +35,6 @@
// Collider types // Collider types
typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } 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
Vector2 gravity;
} Physics;
// Transform struct // Transform struct
typedef struct Transform { typedef struct Transform {
Vector2 position; Vector2 position;
@ -77,8 +70,8 @@ extern "C" { // Prevents name mangling of functions
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Declarations // 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 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 AddCollider(int index, Collider collider); // Initialize a new Collider with parameters to internal index slot

+ 3
- 10
src/raylib.h Ver arquivo

@ -466,13 +466,6 @@ typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERS
// Collider types // Collider types
typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } 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
Vector2 gravity;
} Physics;
// Transform struct // Transform struct
typedef struct Transform { typedef struct Transform {
Vector2 position; 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) 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 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 AddCollider(int index, Collider collider); // Initialize a new Collider with parameters to internal index slot

Carregando…
Cancelar
Salvar