2D physics header-only library for videogames developed in C using raylib library.

Overview

Physac

Physac is a small 2D physics engine written in pure C. The engine uses a fixed time-step thread loop to simluate physics. A physics step contains the following phases: get collision information, apply dynamics, collision solving and position correction. It uses a very simple struct for physic bodies with a position vector to be used in any 3D rendering API.

The header file includes some tweakable define values to fit the results that the user wants with a minimal bad results. Most of those values are commented with a little explanation about their uses.

Note: The example code uses raylib programming library to create the program window and rendering framework.

Installation

Physac requires raylib. To get it, follow the next steps:

* Go to [raylib](https://www.github.com/raysan5/raylib) and clone the repository.
* Ensure to pull the last changes of 'master' branch.
* Use code inside examples header comments to compile and execute.

Physac API

The PhysicsBody struct contains all dynamics information and collision shape. The user should use the following structure components:

typedef struct *PhysicsBody {
    unsigned int id;
    bool enabled;                   // Enabled dynamics state (collisions are calculated anyway)
    Vector2 position;               // Physics body shape pivot
    Vector2 velocity;               // Current linear velocity applied to position
    Vector2 force;                  // Current linear force (reset to 0 every step)
    float angularVelocity;          // Current angular velocity applied to orient
    float torque;                   // Current angular force (reset to 0 every step)
    float orient;                   // Rotation in radians
    float staticFriction;           // Friction when the body has not movement (0 to 1)
    float dynamicFriction;          // Friction when the body has movement (0 to 1)
    float restitution;              // Restitution coefficient of the body (0 to 1)
    bool useGravity;                // Apply gravity force to dynamics
    bool isGrounded;                // Physics grounded on other body state
    bool freezeOrient;              // Physics rotation constraint
    PhysicsShape shape;             // Physics body shape information (type, radius, vertices, normals)
} *PhysicsBody;

The header contains a few customizable define values. I set the values that gived me the best results.

#define     PHYSAC_MAX_BODIES               64
#define     PHYSAC_MAX_MANIFOLDS            4096
#define     PHYSAC_MAX_VERTICES             24
#define     PHYSAC_CIRCLE_VERTICES          24

#define     PHYSAC_COLLISION_ITERATIONS     100
#define     PHYSAC_PENETRATION_ALLOWANCE    0.05f
#define     PHYSAC_PENETRATION_CORRECTION   0.4f

Physac contains defines for memory management functions (malloc, free) to bring the user the opportunity to implement its own memory functions:

#define     PHYSAC_MALLOC(size)             malloc(size)
#define     PHYSAC_FREE(ptr)                free(ptr)

The Physac API functions availables for the user are the following:

// Initializes physics values, pointers and creates physics loop thread
void InitPhysics(void);

// Returns true if physics thread is currently enabled
bool IsPhysicsEnabled(void);

// Sets physics global gravity force
void SetPhysicsGravity(float x, float y);

// Creates a new circle physics body with generic parameters
PhysicsBody CreatePhysicsBodyCircle(Vector2 pos, float radius, float density);

// Creates a new rectangle physics body with generic parameters
PhysicsBody CreatePhysicsBodyRectangle(Vector2 pos, float width, float height, float density);

// Creates a new polygon physics body with generic parameters
PhysicsBody CreatePhysicsBodyPolygon(Vector2 pos, float radius, int sides, float density);

// Adds a force to a physics body
void PhysicsAddForce(PhysicsBody body, Vector2 force);

// Adds a angular force to a physics body
void PhysicsAddTorque(PhysicsBody body, float amount);

// Shatters a polygon shape physics body to little physics bodies with explosion force
void PhysicsShatter(PhysicsBody body, Vector2 position, float force);

// Returns the current amount of created physics bodies
int GetPhysicsBodiesCount(void);

// Returns a physics body of the bodies pool at a specific index
PhysicsBody GetPhysicsBody(int index);

// Returns the physics body shape type (PHYSICS_CIRCLE or PHYSICS_POLYGON)
int GetPhysicsShapeType(int index);

// Returns the amount of vertices of a physics body shape
int GetPhysicsShapeVerticesCount(int index);

// Returns transformed position of a body shape (body position + vertex transformed position)
Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex);

// Sets physics body shape transform based on radians parameter
void SetPhysicsBodyRotation(PhysicsBody body, float radians);

// Unitializes and destroy a physics body
void DestroyPhysicsBody(PhysicsBody body);

// Unitializes physics pointers and closes physics loop thread
void ClosePhysics(void);

Note: InitPhysics() needs to be called at program start and ClosePhysics() before the program ends. Closing and initializing Physac during the program flow doesn't affect or produces any error (useful as a 'reset' to destroy any created body by user in runtime).

Dependencies

Physac uses the following C libraries for memory management, math operations and some debug features:

  • stdlib.h - Memory allocation [malloc(), free(), srand(), rand()].
  • stdio.h - Message logging (only if PHYSAC_DEBUG is defined) [printf()].
  • math.h - Math operations functions [cos(), sin(), fabs(), sqrtf()].

It is independent to any graphics engine and prepared to use any graphics API and use the vertices information (look at examples Drawing logic) to draw lines or shapes in screen. For example, this vertices information can be use in OpenGL API glVertex2f().

By the way, I use raylib to create the examples. This videogames programming library is used to handle inputs, window management and graphics drawing (using OpenGL API).

Issues
  • Add examples pack

    Add examples pack

    Physac needs a interesting pack of examples to show all features and results of the library. I have this pack as reference to adapt them to Physac: https://phaser.io/examples/v2/category/box2d

    Current examples are a simple demo of creating random physics bodies and a shatter feature example...

    enhancement 
    opened by victorfisac 3
  • Unresolved external symbol for QueryPerformanceCounter in Visual Studio 2019

    Unresolved external symbol for QueryPerformanceCounter in Visual Studio 2019

    In VStudio 2019, QueryPerformanceCounter and QueryPerformanceFrequency needs theses headers to work: #include <Windows.h> #include <profileapi.h> it's described here in the requirements section: https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancefrequency

    but if I include windows.h raylib and physac don't compile, because of function names conflict.

    opened by RafaelOliveira 2
  • Physac functions conflict with Visual Studio WINAPI function names

    Physac functions conflict with Visual Studio WINAPI function names

    OK, This issue/problem is weirdest issue i had...

    Doing game template with C99 for Visual Studio 2019, I added physac.h with being standalone via defining PHYSAC_STANDALONE, But when building solution i get type conflict errors

    Screenshot (369)

    The problem with both functions GetCurrentTime and GetTimeCount, Anyway... When i went to their definition, I found that both names used by Windows API functions via WinBase.h, As you see in the image below

    Screenshot (370)

    So yes, Windows API functions use these names, To solve this i renamed GetCurrentTime to CurrentTime and renamed GetTimeCount to TimeCount everywhere in physac.h

    Do you have idea to solve this by checking for Windows platform or Windows API, Tell me...

    opened by Rabios 2
  • No shared libs (dlls, dylib, so) built for Physac

    No shared libs (dlls, dylib, so) built for Physac

    Hi victor! It is weird if i asked for shared library files for Physac,Cause i'm trying to bind it to LuaJIT

    Is it okay if you offered built shared library files (dll, dylib, so) for Physac? Sorry if i'm annoying you

    And thanks for reading ^^

    opened by Rabios 2
  • Where is PhysicsBody defined?

    Where is PhysicsBody defined?

    You have this line:

    typedef struct PhysicsBodyData *PhysicsBody;
    

    But where is PhysicsBody defined?
    I am trying to do a rust port, should i just create a struct PhysicsBody or struct PhysicsBodyData?

    opened by theamazingwaffle 2
  • Physac naming and icon

    Physac naming and icon

    Hi @victorfisac, just noticed Physac icon only includes 16x16, 32x32 and 48x48 versions, directly scaled from the 256x256 .png version provided and physac_icon object does not include .rc properties correctly (just check generated .exe files to see that).

    Do you mind if I review icon design following the proposed line but more aligned with raylib iconography?

    opened by raysan5 2
  • Enable BSD function definitions and C99 POSIX compliance

    Enable BSD function definitions and C99 POSIX compliance

    This is just hypothetical. I think calls to <sys/time.h> require BSD function definitions. The old way was to define _BSD_SOURCE but it is included in the new way, _DEFAULT_SOURCE which also adds some POSIX stuff for c99.

    You might look at raylib/src/external/dr_flac.h:682. where _BSD_SOURCE is defined. They should update, btw. One could do -D_DEFAULT_SOURCE -D_BSD_SOURCE to catch old systems too .My problem was not having either defined in raylib. Here is my reference.

    Again, just something to look at. You might want to do it for portability outside of raylib where it has already been merged. Have a great day!

    opened by RDR8 2
  • Knowing whether collisions have happened

    Knowing whether collisions have happened

    (I found the closed issue from 2017, but this query is a little different)

    I'm just using Physac by itself, with SDL 2. So far I have things that move and collide quite nicely.

    While I understand collisions are internal to the engine, is there a strategy to know whether two things have collided? For example suppose I have a rocket moving across the screen and it hits a target, how can I tell the collision has happened so I can make some game logic run?

    opened by ncot-tech 1
  • Typo in physac.h

    Typo in physac.h

    At around like 255, I believe there is a typo and instead of:

    int __stdcall QueryPerformanceCounter(unsigned long long int* lpPerformanceCount);
    int __stdcall QueryPerformanceFrequency(unsigned long long int* lpFrequency);
    

    there should be:

    #if defined(__cplusplus)
    extern "C" {                                    // Prevents name mangling of functions
    #endif
    int __stdcall QueryPerformanceCounter(unsigned long long int* lpPerformanceCount);
    int __stdcall QueryPerformanceFrequency(unsigned long long int* lpFrequency);
    #if defined(__cplusplus)
    }
    #endif
    
    opened by iN1PE 1
  • No physics calculations in example programs

    No physics calculations in example programs

    The examples in examples/ run, but no physics calulcations are applied. Tried current master branch on FreeBSD 12.1, with raylib 3.0.0 from ports:

    # pkg install devel/raylib
    

    Building and running (with raymath.h in src/):

    $ gcc -I/usr/local/include/ -L/usr/local/lib/ -I../src/ -o demo physics_demo.c -lm -lpthread -lraylib
    $ ./demo
    INFO: Initializing raylib 3.0
    INFO: DISPLAY: Device initialized successfully
    INFO:     > Display size: 1920 x 1080
    INFO:     > Render size:  800 x 450
    INFO:     > Screen size:  800 x 450
    INFO:     > Viewport offsets: 0, 0
    INFO: GLAD: OpenGL extensions loaded successfully
    INFO: GL: OpenGL 3.3 Core profile supported
    INFO: GL: OpenGL device information:
    INFO:     > Vendor:   Intel Open Source Technology Center
    INFO:     > Renderer: Mesa DRI Intel(R) HD Graphics 620 (Kaby Lake GT2) 
    INFO:     > Version:  4.5 (Core Profile) Mesa 19.0.8
    INFO:     > GLSL:     4.50
    INFO: GL: Supported extensions count: 204
    INFO: GL: DXT compressed textures supported
    INFO: GL: ETC2/EAC compressed textures supported
    INFO: GL: Anisotropic textures filtering supported (max: 16X)
    INFO: TEXTURE: [ID 1] Texture created successfully (1x1 - 1 mipmaps)
    INFO: TEXTURE: [ID 1] Default texture loaded successfully
    INFO: SHADER: [ID 1] Compiled successfully
    INFO: SHADER: [ID 2] Compiled successfully
    INFO: SHADER: [ID 3] Program loaded successfully
    INFO: SHADER: [ID 3] Default shader loaded successfully
    INFO: RLGL: Internal vertex buffers initialized successfully in RAM (CPU)
    INFO: RLGL: Internal vertex buffers uploaded successfully to VRAM (GPU)
    INFO: RLGL: Default state initialized successfully
    INFO: TEXTURE: [ID 2] Texture created successfully (128x128 - 1 mipmaps)
    INFO: FONT: Default font loaded successfully
    [PHYSAC] physics module initialized successfully
    [PHYSAC] physics thread created successfully
    [PHYSAC] created polygon physics body id 0
    [PHYSAC] created polygon physics body id 1
    INFO: TIMER: Target time per frame: 16.667 milliseconds
    [PHYSAC] created polygon physics body id 2
    [PHYSAC] created polygon physics body id 3
    [PHYSAC] created polygon physics body id 4
    [PHYSAC] destroyed physics body id 4
    [PHYSAC] destroyed physics body id 3
    [PHYSAC] destroyed physics body id 2
    [PHYSAC] destroyed physics body id 1
    [PHYSAC] destroyed physics body id 0
    [PHYSAC] physics module closed successfully
    INFO: TEXTURE: [ID 2] Unloaded texture data from VRAM (GPU)
    INFO: TEXTURE: [ID 1] Unloaded default texture data from VRAM (GPU)
    INFO: Window closed successfully
    

    The bodies are created on mouse click events, but they do not seem to move.

    opened by interkosmos 1
  • C99 compilation fails

    C99 compilation fails

    Output

    c99  -Wall -Wextra -Werror -O2  -pedantic -o main -lraylib -lglfw -lGL -lopenal -lm -lpthread -ldl main.c  
    In file included from main.c:5:  
    /usr/include/physac.h: In function ‘InitTimer’:  
    /usr/include/physac.h:1905:21: error: storage size of ‘now’ isn’t known  
     1905 |     struct timespec now;  
          |                     ^~~  
    /usr/include/physac.h:1906:23: error: ‘CLOCK_MONOTONIC’ undeclared (first use in this function)  
     1906 |     if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) frequency = 1000000000;  
          |                       ^~~~~~~~~~~~~~~  
    /usr/include/physac.h:1906:23: note: each undeclared identifier is reported only once for  each function it appears in  
    /usr/include/physac.h: In function ‘GetTimeCount’:  
    /usr/include/physac.h:1929:21: error: storage size of ‘now’ isn’t known  
     1929 |     struct timespec now;  
          |                     ^~~  
    /usr/include/physac.h:1930:19: error: ‘CLOCK_MONOTONIC’ undeclared (first use in this function)  
     1930 |     clock_gettime(CLOCK_MONOTONIC, &now);  
          |                   ^~~~~~~~~~~~~~~  
    make: *** [Makefile:7: main] Error 1
    
    opened by theamazingwaffle 1
  • Heap use after free in examples

    Heap use after free in examples

    Related issues: https://github.com/raysan5/raylib/issues/485 and https://github.com/raysan5/raylib/issues/486

    As stated by another user by mail, those issues seem related to:

    ...when you call reset the code is still running in the thread... so while it iterating over the items, suddenly they are removed and of course you will get floating point errors and access violations. Also destroying and item while iterating over the list, will cause these problems too.

    ...basically in a thread environment, you have to project critical sections with semaphores.... I basically flatten the PhysicsLoop into a routine called PhysicsThread... and then have my own loop that calls PhysicsThread and I wrap this in critical sections (pseudocode:

    procedure physics_loop
    begin
        repeat 
            lock.enter;
            PhysicsThread;
            lock.leave
        until done = true;
    end;
    
    bug help 
    opened by raysan5 0
Releases(1.1)
Owner
Víctor Fisac
I am experienced in Creative Media, 3D Animation and game design focused in video games development and software programming for tools and middleware.
Víctor Fisac
Mod - MASTERS of DATA, a course about videogames data processing and optimization

MASTERS of DATA Welcome to MASTERS of DATA. A course oriented to Technical Designers, Technical Artists and any game developer that wants to understan

Ray 32 Apr 5, 2022
A pong clone written in C++ using Raylib

How To Play Objective: first player to reach 10 points is the winner! PLAYER 1: W: up S: down PLAYER 2: ARROW UP or I: up ARROW DOWN or S: down Requir

Victor Sarkisov 1 Dec 15, 2021
Projeto da disciplina de Introdução a Programação no qual consiste em criar um jogo em C utilizando a biblioteca raylib.

DebugProject Projeto da disciplina de Introdução a Programação no qual consiste em criar um jogo em C utilizando a biblioteca raylib. Link da bibliote

SarahLMelo 5 Jun 30, 2022
A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types and values using Ptrace during program execution.

print-function-args-debugger A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types an

*finixbit 15 Jun 17, 2022
Open source C++ physics engine library in 3D

ReactPhysics3D ReactPhysics3D is an open source C++ physics engine library that can be used in 3D simulations and games. www.reactphysics3d.com ?? Fea

Daniel Chappuis 1k Jun 30, 2022
Real-time oriented physics engine and library that's currently best suited for 2D games.

PlayRho A way to play with physical behaviors like the conservation of momentum. PlayRho is a real-time oriented physics engine and library that's cur

Louis Langholtz 85 Jun 25, 2022
Integrate the ZENO node system into Blender for creating robust physics animations!

ZenoBlend Integrate the ZENO node system into Blender for creating robust physics animations! End-user Installation Goto Release page, and click Asset

Zenus Technology 31 Jun 10, 2022
Basic physics simulation of a chain

Basic Chain Simulation Compile using for example $ g++ ChainElement.cpp ChainLink.cpp Chain.cpp Simulation.cpp main.cpp -std=c++11 -o run -O3 The outp

Steffen Richters-Finger 115 May 30, 2022
This repository consists an implementation of the Algorithms encountered in Computer Science, Physics and Mathematics.

All the Algorithms you'll ever need xD This repository contains all the algorithms we have encountered in the fields of Computer Science, Mathematics

ACM VIT 7 Jan 2, 2022
Improved version of real-time physics engine that couples FEM-based deformables and rigid body dynamics

Enhanced version of coupled FEM and constrained rigid body simulation Description This little playground aimed to test our Conjugate Gradients based M

Andrey Voroshilov 25 Apr 11, 2022
Servo library with stm developed by the Liek Software Team. We are working on new versions.

Liek-Servo-Library Liek Servo Library is a library that makes it easy for you to drive servo motors with STM32F10x series cards. The library is still

null 14 Jan 13, 2022
🎮 Plants vs. Zombies multiplayer battle, developed via reverse engineering, inline hook and dynamic-link library injection. Two online players defend and attack as the plant side and zombie side respectively.

Plants vs. Zombies Online Battle This project has two original repositories: https://github.com/czs108/Plants-vs.-Zombies-Online-Battle https://github

Liugw 71 Oct 14, 2021
DISLIN is a high-level plotting library developed by Helmut Michels at the Max Planck Institute.

Harbour bindings for DISLIN, is a high level library of subroutines and functions that display data graphically.

Rafał Jopek 2 Dec 10, 2021
Digital control and signal processing library for DSPs developed in C

digital-control Overview Thisis a simple C library containing very useful digital control and signal processing functionalities destinated for DSP's a

CLECIO JUNG 2 Jun 8, 2022
Libnaomi - Toolchain and system library enabling hobby/homebrew software to be developed for the Sega Naomi platform.

Naomi Toolchain & Libraries A minimal Naomi homebrew environment, very loosely based off of KallistiOS toolchain work but bare metal and implemented f

Jennifer Taylor 17 Jun 19, 2022
A header-only library for C++(0x) that allows automagic pretty-printing of any container.

cxx-prettyprint =============== A pretty printing library for C++ containers. Synopsis: Simply by including this header-only library in your sourc

Louis Delacroix 526 Jun 9, 2022
Cross-platform C++11 header-only library for memory mapped file IO

mio An easy to use header-only cross-platform C++11 memory mapping library with an MIT license. mio has been created with the goal to be easily includ

null 1.3k Jun 24, 2022
A C++ header-only library for creating, displaying, iterating and manipulating dates

The ASAP date/time library for beautiful C++ code ASAP is a small, header-only date-time library for C++11 and beyond. It is heavily inspired by my gr

Leonardo Guilherme de Freitas 53 Jun 21, 2022
A Minimal, Header only Modern c++ library for terminal goodies 💄✨

rang Colors for your Terminal. Windows Demo Example usage #include "rang.hpp" using namespace std; using namespace rang; int main() { cout << "P

Abhinav Gauniyal 1.2k Jun 27, 2022