Simple ball falling down on plane using bullet

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.

Simple ball falling down on plane using bullet

Postby Lil Margin » Fri May 14, 2010 9:39 pm

While i was reading this article and was listining to the Beatles I challenged myself to make a simple ball falling down on a plane using bullet... and guess what... i made it!


I made this today, its only one file(main.cpp) and it doesn't use classes(so its more understandable for the novice)

Code: Select all
#include <irrlicht.h>
#include <btBulletDynamicsCommon.h>
#include <iostream>

using namespace irr;


using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

void QuaternionToEuler(const btQuaternion &TQuat, btVector3 &TEuler)
{
    btScalar W = TQuat.getW();
    btScalar X = TQuat.getX();
    btScalar Y = TQuat.getY();
    btScalar Z = TQuat.getZ();
    float WSquared = W * W;
    float XSquared = X * X;
    float YSquared = Y * Y;
    float ZSquared = Z * Z;

    TEuler.setX(atan2f(2.0f * (Y * Z + X * W), -XSquared - YSquared + ZSquared + WSquared));
    TEuler.setY(asinf(-2.0f * (X * Z - Y * W)));
    TEuler.setZ(atan2f(2.0f * (X * Y + Z * W), XSquared - YSquared - ZSquared + WSquared));
    TEuler *= core::RADTODEG;
}

int main(int argc, char** argv)
{
    //Creating the irrlicht device
    IrrlichtDevice *device =createDevice(EDT_OPENGL, dimension2d<u32>(640, 480), 16, false, false, false, 0);

    //setting pointers to the device!
    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* guienv = device->getGUIEnvironment();

    //creating the 3d ball
    ISceneNode *irrball = smgr->addSphereSceneNode();
    irrball->setMaterialTexture( 0, driver->getTexture("../../media/wall.jpg") );
    irrball->setMaterialFlag(EMF_LIGHTING,false);

    //creating the camera
    ICameraSceneNode *irrcam = smgr->addCameraSceneNode();
    irrcam->setPosition(vector3df(0,0,-70));

    //creating the broadphase
    btBroadphaseInterface* broadphase = new btDbvtBroadphase();

    //creating the physics properties configuration
    btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
    btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);

    //creating the solvers
    btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;

    //Making the dynamic world
    btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);

    //setting the gravity
    dynamicsWorld->setGravity(btVector3(0,-10,0));


    //Its time to create the shapes for our collision
    //Creating the ground( a simple plane )
    btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);

    //Creating the ball shape
    btCollisionShape* fallShape = new btSphereShape(1);

    //its time to create the ground object
    btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-1,0)));

    //making the ground rigidody
    btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0));
    btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);

    //adding the ground to the physics world
    dynamicsWorld->addRigidBody(groundRigidBody);

    //its time to create the ball object!!!
    btDefaultMotionState* fallMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,50,0)));

    //adding and calculating the ball sphere mas
    btScalar mass = 1;
    btVector3 fallInertia(0,0,0);
    fallShape->calculateLocalInertia(mass,fallInertia);

    //constructing the rigidody(adding info,etc)
    btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass,fallMotionState,fallShape,fallInertia);

    //Creating the ball rigidbody
    btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);

    //And offcourse add it to the world
    dynamicsWorld->addRigidBody(fallRigidBody);

    btTransform trans;
    btVector3 rot;

    while (device->run())
    {
        //getting the world positions(x,y,z)
        fallRigidBody->getMotionState()->getWorldTransform(trans);

        //converting the bullet rotation axes so we can use it with our irrlicht node
        QuaternionToEuler(trans.getRotation(),rot);

        //adding the position and rotation to the node
        irrball->setPosition(vector3df(trans.getOrigin().getX(),trans.getOrigin().getY(),trans.getOrigin().getZ()));
        irrball->setRotation(vector3df(rot.getX(),rot.getY(),rot.getZ()));
            //stepping the simulation
            dynamicsWorld->stepSimulation(1/60.f,10);

            std::cout << "sphere height: " << trans.getOrigin().getY() << std::endl;

            driver->beginScene(true, true, SColor(0,200,200,200));

            smgr->drawAll();
            guienv->drawAll();

            driver->endScene();
        }

        // Clean up behind ourselves like good little programmers
        dynamicsWorld->removeRigidBody(fallRigidBody);
    delete fallRigidBody->getMotionState();
    delete fallRigidBody;

    dynamicsWorld->removeRigidBody(groundRigidBody);
    delete groundRigidBody->getMotionState();
    delete groundRigidBody;


    delete fallShape;

    delete groundShape;


    delete dynamicsWorld;
    delete solver;
    delete collisionConfiguration;
    delete dispatcher;
    delete broadphase;

    device->drop();

    return 0;
}

Hint : the plane isn't really drawed...


If you have any suggestions for improvement let me know.
And i am also going to make a object oriented style example when i get the chance.

[edit]If you know how to do debug drawing with irrlicht and bullet send me an example or another example which uses it so i can take a look on how its done else i will have to do the bloody researches myself



I hope this helps someone. :)


New formated code in oop style format : Click here!
Last edited by Lil Margin on Sat May 22, 2010 5:42 pm, edited 1 time in total.
User avatar
Lil Margin
 
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Re: Simple ball falling down on plane using bullet

Postby randomMesh » Fri May 14, 2010 9:48 pm

Lil Margin wrote:If you know how to do debug drawing with irrlicht and bullet send me an example

Click
"In fact, nearly every sequence of punctuation is used for something in Perl. So, if you get writer’s block, just let the cat walk across the keyboard, and debug the result."

Katastrophe - A free, open source flocking boids simulation
User avatar
randomMesh
 
Posts: 1138
Joined: Fri Dec 29, 2006 12:04 am

Postby Lil Margin » Fri May 14, 2010 10:39 pm

Works like a charm on the ground, i don't see any debug lines on the ball/sphere tho but that may be cause i am not using a mesh, ill try loading a mesh with bullet and irrlicht to see how it goes.
User avatar
Lil Margin
 
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Postby randomMesh » Fri May 14, 2010 10:43 pm

Your sphere is too big. The default value for the radius is 5. Try 1., so it matches the size of the Bullet body.

Also, use MotionStates for the movement of the sphere
Code: Select all
#include <irrlicht.h>
#include <btBulletDynamicsCommon.h>

class MotionState : public btMotionState
{

public:

   MotionState(const btTransform& initalTransformation, irr::scene::ISceneNode* const node) :
      node(node), initalTransformation(initalTransformation)
   {

   }

   void getWorldTransform(btTransform& worldTrans) const
   {
      worldTrans = this->initalTransformation;
   }

   void setWorldTransform(const btTransform& worldTrans)
   {
      worldTrans.getOpenGLMatrix(matr.pointer());

      this->node->setRotation(matr.getRotationDegrees());
      this->node->setPosition(matr.getTranslation());
   }

private:

   irr::scene::ISceneNode* const node;

   irr::core::matrix4 matr;

   btTransform initalTransformation;
};

int main()
{
   irr::IrrlichtDevice* device = irr::createDevice();
   irr::video::IVideoDriver* driver = device->getVideoDriver();
   irr::scene::ISceneManager* smgr = device->getSceneManager();


   btDbvtBroadphase* broadphase = new btDbvtBroadphase;
   btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration;
   btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
   btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;

   btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
   dynamicsWorld->setGravity(btVector3(0, -9.80665, 0));



   irr::scene::ICameraSceneNode* camera = smgr->addCameraSceneNode();
   camera->setPosition(irr::core::vector3df(0.0f, 5.0f, -15.0f));




   btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0.0, 1.0, 0.0), 1.0);
   btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1),btVector3(0,-1,0)));

   btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0.0, 0.0, 0.0));
   btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);
   dynamicsWorld->addRigidBody(groundRigidBody);




   irr::scene::IMeshSceneNode* sphere = smgr->addSphereSceneNode(1.0f);
   sphere->setMaterialFlag(irr::video::EMF_LIGHTING, false);

   btCollisionShape* fallShape = new btSphereShape(1.0);
   MotionState* fallMotionState = new MotionState(btTransform(btQuaternion(0.0, 0.0, 0.0, 1.0), btVector3(0.0, 50.0, 0.0)), sphere);
   btScalar mass = 1.0;
   btVector3 inertia(0.0, 0.0, 0.0);
   fallShape->calculateLocalInertia(mass, inertia);

   btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass, fallMotionState, fallShape, inertia);
   btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
   dynamicsWorld->addRigidBody(fallRigidBody);




   irr::ITimer* const timer = device->getTimer();
   irr::u32 then = timer->getTime();

   while (device->run())
   {
      const irr::u32 now = timer->getTime();
      const btScalar frameDeltaTime = (btScalar)(now - then)*0.001; // Time in seconds
      then = now;

      dynamicsWorld->stepSimulation(frameDeltaTime, 10);

      driver->beginScene(true, true, irr::video::SColor(255, 133, 133, 133));
      smgr->drawAll();
      driver->endScene();
   }


   // Clean up behind ourselves like good little programmers
   dynamicsWorld->removeRigidBody(fallRigidBody);
   delete fallRigidBody->getMotionState();
   delete fallRigidBody;

   dynamicsWorld->removeRigidBody(groundRigidBody);
   delete groundRigidBody->getMotionState();
   delete groundRigidBody;

   delete fallShape;
   delete groundShape;

   delete dynamicsWorld;
   delete solver;
   delete dispatcher;
   delete collisionConfiguration;
   delete broadphase;

   device->drop();

   return 0;
}
"In fact, nearly every sequence of punctuation is used for something in Perl. So, if you get writer’s block, just let the cat walk across the keyboard, and debug the result."

Katastrophe - A free, open source flocking boids simulation
User avatar
randomMesh
 
Posts: 1138
Joined: Fri Dec 29, 2006 12:04 am

Postby Lil Margin » Fri May 14, 2010 11:00 pm

Thanks, did not know the radius of 5 is to big :lol:

Ill use your motion-state class in my next example.

Thanks for the help :)
User avatar
Lil Margin
 
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Postby Midnight » Tue May 18, 2010 8:42 pm

cool man, the world can use more code examples. I'll look at it more when I got the time.
User avatar
Midnight
 
Posts: 1767
Joined: Fri Jul 02, 2004 2:37 pm
Location: Wonderland

Postby Lil Margin » Sat May 22, 2010 5:44 pm

New oop format example : Click here!


Leave comments and or constructive criticism :)
User avatar
Lil Margin
 
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Postby jpenguin » Wed Mar 16, 2011 3:42 am

Sorry for resurrecting an old topic, but I get errs with bullet 2.77 I edited your oop format example to use mac-style headers/frameworks


Code: Select all
Build BallBullet of project BallBullet with configuration Release

Ld build/Release/BallBullet.app/Contents/MacOS/BallBullet normal i386
cd /Users/jpenguin/Irrlicht/BallBullet
setenv MACOSX_DEPLOYMENT_TARGET 10.6
/Developer/usr/bin/llvm-g++-4.2 -arch i386 -isysroot /Developer/SDKs/MacOSX10.6.sdk -L/Users/jpenguin/Irrlicht/BallBullet/build/Release -F/Users/jpenguin/Irrlicht/BallBullet/build/Release -filelist /Users/jpenguin/Irrlicht/BallBullet/build/BallBullet.build/Release/BallBullet.build/Objects-normal/i386/BallBullet.LinkFileList -mmacosx-version-min=10.6 -framework Foundation -framework AppKit -framework Irrlicht -framework BulletCollision -framework BulletDynamics -framework BulletSoftBody -framework BulletSoftBodySolvers_CPU -framework BulletSoftBodySolvers_OpenCL_Apple -framework BulletSoftBodySolvers_OpenCL_Mini -o /Users/jpenguin/Irrlicht/BallBullet/build/Release/BallBullet.app/Contents/MacOS/BallBullet

Undefined symbols:
  "btAlignedFreeInternal(void*)", referenced from:
      Ball::Ball(btDiscreteDynamicsWorld*, irr::scene::ISceneManager*, irr::video::IVideoDriver*, int, int, btVector3)in ball.o
      Ball::Ball(btDiscreteDynamicsWorld*, irr::scene::ISceneManager*, irr::video::IVideoDriver*, int, int, btVector3)in ball.o
      btAlignedObjectArray<btHashInt>::~btAlignedObjectArray()in ball.o
      btAlignedObjectArray<btTriangleInfo>::~btAlignedObjectArray()in ball.o
      btAlignedObjectArray<int>::~btAlignedObjectArray()in ball.o
      btAlignedObjectArray<btHashInt>::~btAlignedObjectArray()in Device.o
      btAlignedObjectArray<btTriangleInfo>::~btAlignedObjectArray()in Device.o
      btAlignedObjectArray<int>::~btAlignedObjectArray()in Device.o
      OBJPLANE::OBJPLANE(btDiscreteDynamicsWorld*)in ground.o
      btAlignedObjectArray<btHashInt>::~btAlignedObjectArray()in ground.o
      btAlignedObjectArray<btTriangleInfo>::~btAlignedObjectArray()in ground.o
      btAlignedObjectArray<int>::~btAlignedObjectArray()in ground.o
      btAlignedObjectArray<btHashInt>::~btAlignedObjectArray()in main-D484BC599686465F.o
      btAlignedObjectArray<btTriangleInfo>::~btAlignedObjectArray()in main-D484BC599686465F.o
      btAlignedObjectArray<int>::~btAlignedObjectArray()in main-D484BC599686465F.o
      btAlignedObjectArray<btHashInt>::~btAlignedObjectArray()in Motionstate.o
      btAlignedObjectArray<btTriangleInfo>::~btAlignedObjectArray()in Motionstate.o
      btAlignedObjectArray<int>::~btAlignedObjectArray()in Motionstate.o
  "btAlignedAllocInternal(unsigned long, int)", referenced from:
      Ball::Ball(btDiscreteDynamicsWorld*, irr::scene::ISceneManager*, irr::video::IVideoDriver*, int, int, btVector3)in ball.o
      Ball::Ball(btDiscreteDynamicsWorld*, irr::scene::ISceneManager*, irr::video::IVideoDriver*, int, int, btVector3)in ball.o
      OBJPLANE::OBJPLANE(btDiscreteDynamicsWorld*)in ground.o
ld: symbol(s) not found
collect2: ld returned 1 exit status


I did the Quake3map & HelloWorld examples, so I know Irrlicht works
jpenguin
 
Posts: 10
Joined: Mon Feb 16, 2009 7:48 pm

Postby Lil Margin » Wed Mar 16, 2011 1:49 pm

Thank you :)
User avatar
Lil Margin
 
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Nevermind

Postby jpenguin » Wed Mar 16, 2011 5:15 pm

Sorry about that. I got it, I just forgot to include LinearMath.framwork

xCode project folder
Single file xCode project
jpenguin
 
Posts: 10
Joined: Mon Feb 16, 2009 7:48 pm


Return to Code Snippets

Who is online

Users browsing this forum: No registered users and 1 guest