Bounce is a 3D physics engine for games.

Overview

Bounce

Welcome! Bounce is a 3D physics engine for games.

Features

Common

  • Efficient data structures with no use of STL
  • Fast memory allocators
  • Built-in math library
  • Tunable settings used across the entire library

Collision

  • Dynamic tree broadphase
  • Static tree "midphase"
  • SAT
  • GJK
  • Spheres, capsules, convex hulls, triangle meshes
  • Optimized pair management

Dynamics

  • Rigid bodies
  • Contact, friction, restitution
  • Sphere, cone, revolute, and more joint types
  • Joint motors, limits
  • Constraint graphs
  • Simulation islands and sleep management
  • Linear time solver
  • Stable shape stacking
  • One-shot contact manifolds
  • Contact clustering, reduction, and persistence
  • Contact callbacks: begin, pre-solve, post-solve
  • Ray-casting, convex-casting, and volume queries

Testbed

  • OpenGL with GLFW and GLAD
  • UI by imgui
  • Mouse picking
  • CMake build system

Documentation

Note: Use the quickstart guide and the Testbed for learning how to use Bounce. Testbed is a collection of visual tests and examples that can support the development of the library. As you would imagine, this application is not part of the library.

License

Bounce is released under the zlib license. Please recognize this software in the product documentation if possible.

Dependencies

Testbed

These are the external dependencies for the Testbed example project. If you don't care about the Testbed you don't need these dependencies.

Building

  • Install CMake
  • Ensure CMake is in the user 'PATH'

Visual Studio

  • You can run 'build.bat' from the command prompt
  • Building results are in the build sub-folder
  • Open bounce.sln

Any system

  • Run 'build.sh' from a bash shell
  • Building results are in the build sub-folder

Contributing

You can ask anything relative to this project using the issue tracker.

Please do not open pull requests with bugfixes or new features that require large changes. Open an issue first for discussion.

Issues
  • Question: How to lower the center of mass?

    Question: How to lower the center of mass?

    Sorry, I know I've asked this question before but I'm still having trouble. I have a working car physics system using bounce, and I'm trying to lower the COM so that the cars are self-righting and don't keep rolling over. I'm currently doing that like this:

        b3MassData data;
        body_->GetMassData(&data);
        data.center = new_com;
        body_->SetMassData(&data);
    

    But this makes everything behave erratically; cars spin everywhere, they get stuck into the ground etc.

    What am I doing wrong?

    opened by Kazade 64
  • Assertion failed: edge1->twin == i + 1 && twin1->twin == i

    Assertion failed: edge1->twin == i + 1 && twin1->twin == i

    Error at at: collision/sat/sat.cpp,129

    Just hello world sample but I separate start and update so data goes outside the scope:

    const scalar timeStep = 1.0f / 60.0f;
        const uint32 velocityIterations = 8;
        const uint32 positionIterations = 2;
    
        sptr<b3World> m_bounceWorld = nullptr;
    
        b3Vec3 gravity = {};
    
        b3BodyDef groundDef = {};
        b3Body* ground = nullptr;
        b3BoxHull groundBox = {};
        b3HullShape groundShape = {};
        b3FixtureDef groundBoxDef = {};
        b3Fixture* groundFixture = nullptr;
    
        b3BodyDef bodyDef = {};
        b3Body* m_body;
        b3BoxHull bodyBox = {};
        b3HullShape bodyShape = {};
        b3FixtureDef bodyBoxDef = {};
        b3Fixture* bodyFixture = nullptr;
    
        void emulateStart()
        {
            m_bounceWorld = make::sptr<b3World>();
            gravity = b3Vec3(0.0f, -9.8f, 0.0f);
            m_bounceWorld->SetGravity(gravity);
    
            // Create a static ground body at the world origin.
            ground = m_bounceWorld->CreateBody(groundDef);
            groundBox = b3BoxHull{10.0f, 1.0f, 10.0f};
            groundShape.m_hull = &groundBox;
            groundBoxDef.shape = &groundShape;
            groundFixture = ground->CreateFixture(groundBoxDef);
    
            // Create a dynamic body.
            bodyDef.type = e_dynamicBody;
            bodyDef.position.Set(0.0f, 10.0f, 0.0f);
            bodyDef.angularVelocity.Set(0.0f, B3_PI, 0.0f);
            m_body = m_bounceWorld->CreateBody(bodyDef);
            bodyBox.SetIdentity();
            bodyShape.m_hull = &bodyBox;
            bodyBoxDef.shape = &bodyShape;
            bodyBoxDef.density = 1.0f;
            bodyFixture = m_body->CreateFixture(bodyBoxDef);
        }
    
        void emulateUpdate(float dt)
        {
            W4_LOG_DEBUG("upd");
            m_bounceWorld->Step(timeStep, velocityIterations, positionIterations);
        }
    
        void main()
        {
            emulateStart();
            for (int i = 0; i < 100; ++i)
            {
                emulateUpdate(1.0f / 60.0f);
            }
        }
    

    Everything works when I have start method with inlined update at the end:

    void emulateStart()
        {
            m_bounceWorld = make::sptr<b3World>();
            gravity = b3Vec3(0.0f, -9.8f, 0.0f);
            m_bounceWorld->SetGravity(gravity);
    
            // Create a static ground body at the world origin.
            ground = m_bounceWorld->CreateBody(groundDef);
            groundBox = b3BoxHull{10.0f, 1.0f, 10.0f};
            groundShape.m_hull = &groundBox;
            groundBoxDef.shape = &groundShape;
            groundFixture = ground->CreateFixture(groundBoxDef);
    
            // Create a dynamic body.
            bodyDef.type = e_dynamicBody;
            bodyDef.position.Set(0.0f, 10.0f, 0.0f);
            bodyDef.angularVelocity.Set(0.0f, B3_PI, 0.0f);
            m_body = m_bounceWorld->CreateBody(bodyDef);
            bodyBox.SetIdentity();
            bodyShape.m_hull = &bodyBox;
            bodyBoxDef.shape = &bodyShape;
            bodyBoxDef.density = 1.0f;
            bodyFixture = m_body->CreateFixture(bodyBoxDef);
    
            for (int i = 0; i < 100; ++i)
            {
                m_bounceWorld->Step(timeStep, velocityIterations, positionIterations);
            }
        }
    

    But I can't use this solution cuz I have separate update method in my engine

    Also it looks like its broken but it works with immediate update just because memory garbage is untouched while callling it. How to locate the root of the problem?

    opened by caxapexac 8
  • Overlap

    Overlap

    Physx overlap https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/GeometryQueries.html#overlaps

    React collide/overlap https://www.reactphysics3d.com/usermanual.html#:~:text=in%20this%20case%3A-,testOverlap(),-This%20group%20of

    What's the analogue here?

    Shapecasting to zero-length ray sounds ineffective. It also doesn't give me extrusion vector

    Shape listener updates only inside world step so I can't manually call body.SetPosition then check if it was overlapped by something (in the same frame)

    Why do I need overlap? I have kinematic character controller thats why it doesn't extrude by itself. Character can stuck inside geometry while playing (doesn't stuck manually by movement logic but it can occur sometimes, e.g. standing under moving elevator). So I need to un-stuck player in every frame before movement logic happens. Extrusion vector can be taken from contact listener but it won't update immediately after I call body.setTransform. Also seemsd like kinematic bodies doesn't make contact points. Is the solution to use dynamic bodies with zero gravity and return ShouldRespond = false for their collisions?

    opened by caxapexac 7
  • Collision matrix implementation

    Collision matrix implementation

    Is there any example of implementing optimized collision masks/matrices based on b3*Filter?

    I think I need public api like

    enum class layer
    {
        Player = 0,
        Obstacle = 1,
        Transparent = 2
        // 3,4.5.... this isn't a bitmask
    }
    
    worldWrapper.setCollision(layer::Player, layer::Obstacle, true); // By default all collisions are disabled
    bodyWrapper.addFixture(definition, scale, layer::Player);
    
    class CustomXxxxxxxFilter : public b3XxxxxxxFilter
            {
            public:
                virtual bool ShouldRayCast(b3Fixture* fixture)
                {
                    // What to do here?
                }
            };
    
    

    I've implemented something like this in the last library I've switched from (https://github.com/DanielChappuis/reactphysics3d) (switched cuz it doesn't have any shapeCast):

    
    // collisionLayer = [0..15]
    typedef unsigned char collisionLayer;
    
    struct collisionMask
    {
    public:
        static const collisionMask all;
    
        unsigned short value = 0;
    
        collisionMask (std::initializer_list<collisionLayer> layers)
        {
            for (int i: layers)
            {
                ASSERT(i >= 0 && i < 16);
                value |= 1 << i;
            }
        }
    
    private:
        collisionMask (unsigned short mask) : value(mask) { }
    };
    
    class worldWrapper {
    // ...
        void setEnabledCollision (collisionLayer layer1, collisionLayer layer2, bool state)
        {
            ASSERT(layer1 >= 0 && layer1 < 16);
            ASSERT(layer2 >= 0 && layer2 < 16);
            unsigned short layer1Value = 1 << layer1;
            unsigned short layer2Value = 1 << layer2;
            unsigned short firstMask = m_collisionMatrix[layer1];
            firstMask ^= firstMask & layer2Value;
            firstMask |= state ? layer2Value : 0;
            m_collisionMatrix[layer1] = firstMask;
            unsigned short secondMask = m_collisionMatrix[layer2];
            secondMask ^= secondMask & layer1Value;
            secondMask |= state ? layer1Value : 0;
            m_collisionMatrix[layer2] = secondMask;
        }
    
        // Layer = [0..15]
        void setColliderLayer (rp::Collider* collider, collisionLayer layer)
        {
            ASSERT(layer >= 0 && layer < 16);
            unsigned short layerValue = 1 << layer;
            collider->setCollisionCategoryBits(layerValue);
            collider->setCollideWithMaskBits(m_collisionMatrix[layer]);
        }
    // ...
    }
    
    

    But that library has setCollisionCategoryBits and setCollideWithMaskBits (and its pretty ugly tbh) so I have to use Fixture::userData here for storing these bits (or storing global std::map<Fixture, layer> inside the worldWrapper)

    Also I think its a bit unflexible so looking for another solution

    opened by caxapexac 5
  • Debug draw shape wrong draw

    Debug draw shape wrong draw

    shape.cpp, line 42

    b3Vec3 p1 = xf * capsule->m_vertex1;
    b3Vec3 p2 = xf * capsule->m_vertex2;
    draw->DrawPoint(p1, scalar(4), color);
    draw->DrawPoint(p2, scalar(4), color);
    draw->DrawSegment(p1, p2, color);
    

    Should be changed to

    b3Vec3 c1 = xf * capsule->m_vertex1;
    b3Vec3 c2 = xf * capsule->m_vertex2;
    draw->DrawCapsule(c1, c2, capsule->m_radius, color);
    

    Also API of draw:

    virtual void DrawSolidCapsule(const b3Quat& rotation, const b3Vec3& p1, const b3Vec3& p2, scalar radius, const b3Color& color, bool depthEnabled = true) = 0;
    

    rotation is found implicitly from p1 and p2 but rotation is passed as argument (DrawCapsule doesn't have this mistake)

    opened by caxapexac 3
  • Minor compilation error

    Minor compilation error "explicit qualification required to use member 'Copy' from dependent base class"

    C++ 17, emscripten

    /common/template/array.h:246:3: error: explicit qualification required to use member 'Copy' from dependent base class
    

    Solved by changing Line 246 from:

    Copy(other);
    

    to

    this->Copy(other);
    

    http://www.cs.technion.ac.il/users/yechiel/CS/FAQs/c++-faq/nondependent-name-lookup-members.html

    opened by caxapexac 3
  • Question: Does b3SphereShape::ComputeAABB need to rotate m_center?

    Question: Does b3SphereShape::ComputeAABB need to rotate m_center?

    I'm using Bounce on a SEGA Dreamcast game, and as you can imagine that's a fairly resource constrained system!

    Everything is working fine, but I'm trying to squeeze out some last bits of performance.

    Interestingly, 3% of my frame-time is going into b3SphereShape::ComputeAABB - specifically it's the subsequent calls to b3Mul, and b3Cross.

    I was wondering if that rotation is necessary there, or is it enough to just add m_center to xf.translation?

    opened by Kazade 2
  • Vec2/3/4 class extra?

    Vec2/3/4 class extra?

    I mean B3_VEC3_CLASS_EXTRA in user_settings.h like in https://github.com/ocornut/imgui/blob/master/imconfig.h#L85 For vec2, vec3, vec4, transform and quaternion implicit convertion in client code

    opened by caxapexac 1
  • Possible bug in quickhull.c line 1696

    Possible bug in quickhull.c line 1696

    My compiler has flagged this:

    warning: self-comparison always evaluates to false [-Wtautological-compare]
     1696 |   } while (edge != edge);
    

    Looks like a bug?

    opened by Kazade 0
  • Fix build on ubuntu GCC-7.5

    Fix build on ubuntu GCC-7.5

    Fixes build on ubuntu 18 with gcc-7.5. Fixes 2 types of errors: 1#

    /home/dee/dev/test/bounce/include/bounce/common/time.h:182:48: error: ‘c0’ was not declared in this scope
             double dt = 1000.0 * double(c.tv_sec - c0.tv_sec) + 1.0e-6 * double(c.tv_nsec - c0.tv_nsec);
    

    2#

    bounce/dynamics/contacts/hull_sphere_contact.cpp:27:60: error: no matching function for call to ‘operator new(sizetype, void*&)’
      return new (mem) b3HullAndSphereContact(fixtureA, fixtureB);
      
    /bounce/dynamics/contacts/triangle_capsule_contact.cpp:27:65: error: no matching function for call to ‘operator new(sizetype, void*&)’
      return new (mem) b3TriangleAndCapsuleContact(fixtureA, fixtureB);
    etc.
    
    opened by Deins 0
Owner
Irlan Robson
Irlan Robson
A multi core friendly rigid body physics and collision detection library suitable for games and VR applications.

Jolt Physics Library A multi core friendly rigid body physics and collision detection library suitable for games and VR applications. A YouTube video

null 1.8k Jun 27, 2022
This repository is about a school project about games with physics, written in C++.

Eight Ball Pool ?? A game about playing physics-based eight ball pool. ?? Table of Contents About Getting Started Usage Built Using About the creators

Valeri Ivanov 17 May 22, 2022
Godot bindings for the Rapier3D physics engine

Godot bindings for the Rapier3D physics library How to use There are two parts: A Godot module which must be compiled with the engine.

David Hoppenbrouwers 23 Jun 20, 2022
SKR_Physics is a lightweight and easy to use 2D physics engine which is written in C++.

SKR_Physics SKR_Physics is a lightweight and easy to use 2D physics engine which is written in C++. Features Rectangle based collision system Very sim

Şükrü 0 Mar 8, 2022
Sequential impulses physics engine made for learning purposes

A 3D physics engine that uses Separating Axis Test for collision detection, the clipping method for generating contact manifold, contact point reducti

Ahmad Saleh 1 Nov 24, 2021
This is a list of different open-source video games and commercial video games open-source remakes.

This is a list of different open-source video games and commercial video games open-source remakes.

Ivan Bobev 79 Jun 27, 2022
Open-source, cross-platform, C++ game engine for creating 2D/3D games.

GamePlay v3.0.0 GamePlay is an open-source, cross-platform, C++ game framework/engine for creating 2D/3D mobile and desktop games. Website Wiki API De

gameplay3d 3.7k Jun 28, 2022
Game engine behind Sea Dogs, Pirates of the Caribbean and Age of Pirates games.

Game engine behind Sea Dogs, Pirates of the Caribbean and Age of Pirates games.

Storm Devs 633 Jun 27, 2022
OGRE is a scene-oriented, flexible 3D engine written in C++ designed to make it easier and more intuitive for developers to produce games and demos utilising 3D hardware.

OGRE (Object-Oriented Graphics Rendering Engine) is a scene-oriented, flexible 3D engine written in C++ designed to make it easier and more intuitive for developers to produce games and demos utilising 3D hardware. The class library abstracts all the details of using the underlying system libraries like Direct3D and OpenGL and provides an interface based on world objects and other intuitive classes.

null 2.8k Jun 29, 2022
Project DELTA - An open-source trainer built on the Void Engine for Toby Fox's games and their spin-offs.

Project DELTA v3 Project DELTA - An open-source, modular mod menu for Toby Fox's games and their spin-offs. Important note to Grossley: Yes, it is out

Archie 7 Apr 20, 2022
Speedrun plugin for Source engine games.

Features Automatic demo recording Accurate session timing Speedrun timer with complex custom rule system Tools for segmented and tool-assisted speedru

Portal 2 Speedrunning 44 Jun 21, 2022
TrenchBroom is a modern cross-platform level editor for Quake-engine based games.

TrenchBroom is a modern cross-platform level editor for Quake-engine based games.

TrenchBroom 1.2k Jul 1, 2022
An Unreal Engine 4 silent aim method, not usable on all games. Tested on Fortnite, Rogue Company, Bloodhunt, and Splitgate.

UE4-Silent-Aim An Unreal Engine 4 silent aim method, not usable on all games. Only tested on Fortnite, Rogue Company, Bloodhunt, and Splitgate. Done t

null 35 Jun 26, 2022
Engine being created for homeworks in UPC Master's Degree in Advanced Programming for AAA Video Games.

Strawhat Engine Strawhat Engine is a game engine under construction that has model loading and camera movement features along with an editor. Reposito

I. Baran Surucu 12 May 18, 2022
This is netvars, interfaces and class ids dump from Valve's Source2 Engine games

About this This is netvars, interfaces and class ids dump from Valve's Source2 Engine games: Artifact Classic Artifact Foundry Dota 2 Dota Underlords

Dmitry 9 May 24, 2022
Unreal Engine 4 plugin for Yodo1 MAS (Managed Ad Services) integration. Used for ad monetization of games.

Unofficial Yodo MAS SDK for Unreal Engine 4 Disclaimer: this plugin is in no way associated with Yodo1, this is just a wrapper on top of their officia

Nineva Studios 3 Apr 9, 2022
C++ library for multi-physics simulation

Project Chrono represents a community effort aimed at producing a physics-based modelling and simulation infrastructure based on a platform-independent, open-source design.

null 1.4k Jun 23, 2022
A game with basic physics and platforming.

Physgun A simple game with basic physics and platforming. Planned features Work in progress: Physics engine. Swept AABB collision algorithm. Elastic a

Bad Games Studio 24 Dec 17, 2021
Source code for Game Physics Cookbook

Game Physics Cookbook Website Facebook Twitter This book is a comprehensive guide to the linear algebra and collision detection games commonly use, bu

Gabor Szauer 612 Jun 27, 2022