Forums
Setting Up Bullet - Printable Version

+- Forums (http://www.scratchpadgames.net/forums)
+-- Forum: Main Forums (http://www.scratchpadgames.net/forums/forumdisplay.php?fid=1)
+--- Forum: Assets, Tools, Libraries and other useful things (http://www.scratchpadgames.net/forums/forumdisplay.php?fid=21)
+--- Thread: Setting Up Bullet (/showthread.php?tid=24)



Setting Up Bullet - Brian Beuken - 02-26-2018

Code:
#include <bullet/btBulletDynamicsCommon.h>
class PhysicsObj
{
public:
    PhysicsObj(btCollisionShape* Shape,  // to create a new object it needs shape
        float mass,                        // and mass data
        const btVector3 &Position, // these have defaults(0,0,0), but best to be replaced
        const btQuaternion &Rotation );  // here be dragons...but glm and bt, can handle it
    
    ~PhysicsObj();

// best to allow our Object to set and return use things in accessors    
    inline btCollisionShape* GetShape(){return m_Shape;}
    inline void    SetShape(btCollisionShape* S) {m_Shape = S; }
    
    inline btRigidBody* GetRigidBody(){return m_Body;    }
    inline void SetRighidBody(btRigidBody* RB)    { m_Body = RB; }

    inline btMotionState* GetMotionState() {return m_Status;}


// couple of useful utility functions to simplify the rotate and position of our physics objects
// these act on the Rigid body and therefore will reposition/orient an object while it is
// in the physics world, useful for restarting or teleporting.
    inline void SetOrientation(btQuaternion Rotation)
    {
        // could just m_body->setXXX but there's a slim chance you might add multiple rigid bodies to an object
        // and you would make GetRigidBody return the active one, so this is a safer method to allow for later expansion
        GetRigidBody()->setWorldTransform(btTransform(Rotation, m_Body->getWorldTransform().getOrigin()));
    }

    inline void SetPosition(btVector3 Position)
    {
        GetRigidBody()->setWorldTransform(btTransform(m_Body->getOrientation(), Position));
    
    }

    

// This gets the Motionstate transform, which is useful variables made available after the step
// as these are generated by the step system, they should be used as read only, as writing to them
// has no effect and sending them back to the motionstate is not useful,
    void GetTransform(btScalar* transform)  
    {
        if (m_Status)
            m_Status->GetWorldTransform(transform); //this is the important part
    }

    


protected:
    
    btRigidBody* m_Body;
    btCollisionShape* m_Shape;
    GameValues* m_Status; // the general position, orientation and scale of our object to return back
    
};
For me Bullet Physics is the best overall physics engine available for an SBC, its not by any means the best system, it just works well and is light enough not to overload a small machine. On most cases on a single core, I can control 100-150 rigid bodies quite well with it, and that's usually enough. With some care and planning more is possible.

It is possible to build the source code for Bullet, but really thats just too much effort... best to install it on your target with
sudo apt-get  install libbullet-dev

Bullet itself makes use of 4 main sub libraries

BulletCollision, BulletSoftBody, BulletDynamics, LinearMath 

These need to be included in your VisualGDB/Studio library list and of course you need to include your library directory for the header files /usr/include/bullet

Once done its all pretty much self contained and then its up to you to make the physics world.

Bullet works by creating a physics based world, populated with objects which represent your objects and providing a set of base classes which you can attach to your own objects and keep track of their position, and orientation so that you can render them. And in doing so it provides physical property concepts of velocity, mass, orientation, shape and other real world properties you can expect a 300metre long spacecraft to have, as well as a 5’2” overweight but surprisingly athletic plumber. Once these representative physical objects are set up, Bullet then updates their motion and forces acting on or against them and keeps track of all the positional and orientation information in its own class members, allowing you to use them in your own position and rendering systems.


In the simplest terms, Bullet has all these objects in this unseen physics world, and then works out what happens to them when they all get thrown up into the air bouncing off each other and then landing and bouncing on the ground. Rotational effects, friction, material properties, momentum retention and absorption as well as many other things are taken care of for us.

In order for this magic to work, we must allow Bullet to create and maintain this world which will mainly contain mathematical concepts of our terrain and of any moving or static objects we deem important enough to be part that dynamic world. The objects are added to the world, given some physical properties, and a suitable “solver” function is then called which then does the work to move them around. With a few optimisations added to the mix for efficiency and speed, such as a choice of method for a broad phase collision to reduce unwanted tests.

We can have quite some variety of basic object shapes which are based on our previous ideas of Primitive collision types, and of course every object can have it’s own physical properties and different solvers can be used for different kinds of motion and interaction.

By using Bullets methods to implement motion, we effectively can let it take care of all the movement, collision, response and reactions we should expect our objects to have.  That lets us focus more on logic and decision making. Bullet will create events we can detect and objects we can test, when something important happens, like a collision, allowing us to make the right kind of sound, or destruction of a relevant object, and then Bullet can be asked to continue to work on the motion of the interacting objects according to standard rules of how we think the universe should work.

We should bear in mind though it’s not exact, physics in the real universe works on a quantum level, everything checked and tested at all times. Computers work on a sequential, one at time, at a given point in time, level. But it does work quite effectively, at the cost of quite a lot of processing!

Bullet needs a few things set up before it can work...

       btBroadphaseInterface* BroadPhase;

       btDefaultCollisionConfiguration* CollisionConfiguration;

       btCollisionDispatcher* Dispatcher;

       btSequentialImpulseConstraintSolver* ConstraintSolver;
       btDiscreteDynamicsWorld* DynamicPhysicsWorld;

each in turn need to be initialised

// create the main physics systems

       BroadPhase = new btDbvtBroadphase();
       CollisionConfiguration = new btDefaultCollisionConfiguration();
       Dispatcher = new btCollisionDispatcher(CollisionConfiguration);
       ConstraintSolver = new btSequentialImpulseConstraintSolver;
       DynamicPhysicsWorld = new btDiscreteDynamicsWorld(Dispatcher, BroadPhase, ConstraintSolver, CollisionConfiguration);
// set a "normal" gravity level
       DynamicPhysicsWorld->setGravity(btVector3(0, -9.81f, 0));

Once done, we will now have a physics world that simply needs to be updated in steps, 
DynamicPhysicsWorld->stepSimulation(1 / 60.0f);

but we still have to populate the physics world, and that requires us to create our rigid bodies from a list of possible types
In my book I create a class called a PhysicsObj, which any render object can have an instance of, the header is in the code snippet above. The rest of the code can be downloaded from my site.

Once you have a PhysicObj created, you can focus on moving that object around, or allowing it to be moved around by the physics simulation. Then its a (fairly) simple step to acquire orientation and position data that will allow you to render your object and if you choose, its physics boundings.

You will find a good example of setting up Bullet in the V2MD2ModelDemo example code.


RE: Setting Up Bullet - Brian Beuken - 03-01-2018

BTW, there are not too many books on how to use Bullet Physics, but Chris Dickinsons' Learning Game Physics with Bullet Physics and OpenGL, (Packt Publishing 2013) gives a really excellent intro to most of the concepts needed and how to apply them. Its a small and easy to digest book, which provides good online examples of what Bullet does for you.

Once this is understood it is a lot easier to grasp what is being discussed on the https://pybullet.org/wordpress/ site


RE: Setting Up Bullet - Brian Beuken - 10-12-2022

If anyone needs to know how to create a physics object that connects to your game objects this might help


PhysicsObj* Game::CreatePhysicsObj(btCollisionShape* pShape,
const float &mass,
const btVector3 &aPosition,
const btQuaternion &aRotation,
int mask) // mask defaults to 1
{
// create a new game object
PhysicsObj* pPhysicsObject = new PhysicsObj(pShape, mass, aPosition, aRotation);
float currentm = pShape->getMargin();

pShape->setMargin(0.09f); // I make it a tiny bit smaller

if (DynamicPhysicsWorld)
{
DynamicPhysicsWorld->addRigidBody(pPhysicsObject->GetRigidBody(), 1, 1); // group 1, mask 1;
// the group and mask are accessable using these functions but don't need them till you do collision responses
// pPhysicsObject->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterGroup;
// pPhysicsObject->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterMask;

} else {
printf("Attempting to add to a Dynamic world that does not exist\n"); }
ListOfPObjects.push_back(pPhysicsObject); // need this to clear the world at times does physics not have this?0

return pPhysicsObject; // return to place in the objects data or in another list
}


RE: Setting Up Bullet - Brian Beuken - 10-12-2022

Also a nice outline of how to work with it here

https://www.gamedesigning.org/engines/bullet/