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.
Post Reply
Lil Margin
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Simple ball falling down on plane using bullet

Post by Lil Margin »

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.
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Re: Simple ball falling down on plane using bullet

Post by randomMesh »

Lil Margin wrote:If you know how to do debug drawing with irrlicht and bullet send me an example
Click
"Whoops..."
Lil Margin
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Post by Lil Margin »

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.
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Post by randomMesh »

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;
}
"Whoops..."
Lil Margin
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Post by Lil Margin »

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 :)
Midnight
Posts: 1772
Joined: Fri Jul 02, 2004 2:37 pm
Location: Wonderland

Post by Midnight »

cool man, the world can use more code examples. I'll look at it more when I got the time.
Lil Margin
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Post by Lil Margin »

New oop format example : Click here!


Leave comments and or constructive criticism :)
jpenguin
Posts: 10
Joined: Mon Feb 16, 2009 7:48 pm

Post by jpenguin »

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
Lil Margin
Posts: 212
Joined: Sun Jul 19, 2009 4:24 am
Location: Netherlands Antilles, Curacao

Post by Lil Margin »

Thank you :)
jpenguin
Posts: 10
Joined: Mon Feb 16, 2009 7:48 pm

Nevermind

Post by jpenguin »

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

xCode project folder
Single file xCode project
Post Reply