HomePhorge
Easier Bullet physics

Although it hasn't been super obvious as to how they are used unless, perhaps, you're not familiar with the Bullet Physics Engine, but Echo has classes that allow you to use Bullet with SceneEntity objects.

Previously you had to build a dynamics world manually, which includes a lot of detail that you might not be interested in initially. Then you would construct your Bullet Bodies and Shapes and set up the link to a SceneEntity with a motion state. Here is an example:

//Create a dynamics world.
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btBroadphaseInterface* broadphase = new btSimpleBroadphase();
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
shared_ptr<btDiscreteDynamicsWorld> collisionWorld(new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration));
shared_ptr<BulletPhysicsWorld> world(new BulletPhysicsWorld(collisionWorld));
	
//Create a body with a sphere shape.
btRigidBody::btRigidBodyConstructionInfo constructInfo(1, 0, new btBoxShape(Convert(spinningCube->GetAxisAlignedBox(false).GetSize()*0.5f)));
shared_ptr<btRigidBody> bulletBody(new btRigidBody(constructInfo));
shared_ptr<BulletRigidBody> body(new BulletRigidBody(world,bulletBody));
body->SetPosition(Vector3(0,10,0));

//The visual for the cube
shared_ptr<SpinningCube> spinningCube(new SpinningCube());
spinningCube->GetMesh()->SetMaterial(GetMaterialManager()->GetResource("Echo"));
mScene.AddRenderable(spinningCube);

//Link the two with a motion state
shared_ptr<BulletDynamicMotionState> motionState(new BulletDynamicMotionState(*body,spinningCube));
motionState->Activate();
body->SetMotionState(motionState);	//Stop the motion state from being deleted.
world->AddBody(body);

//Create a floor for the shape above to fall onto.
btRigidBody::btRigidBodyConstructionInfo constructInfo2(0, 0, new btBoxShape(btVector3(10,10,10));
shared_ptr<btRigidBody> bulletBody2(new btRigidBody(constructInfo2));
shared_ptr<BulletRigidBody> body2(new BulletRigidBody(world,bulletBody2));
body2->SetPosition(Vector3(0,-15,0));
world->AddBody(body2);

The biggest problem with all of this is that you also need to manage the memory for all of the Bullet objects. But there is still a lot of work involved to get a relatively simple scene set up.

I've done a bit of work to the Bullet Physics support and have also created BulletFactory to make construction of the objects you need for physics easier. BulletFactory will grow as time goes on. So creating the same scene above using the new method:

// A factory will create a default world for us.
BulletFactory factory;
mScene.AddTask(factory.GetWorld());		//This stops the world from being destroyed after we're done with the factory.

shared_ptr<SpinningCube> spinningCube(new SpinningCube());
spinningCube->GetMesh()->SetMaterial(GetMaterialManager()->GetResource("Echo"));
mScene.AddRenderable(spinningCube);
		
//Create a box body for the entity, position it at y=10 and automatically add it to the world.
factory.CreateRigidBody(1,cube,factory.CreateBox(spinningCube->GetAxisAlignedBox(false).GetSize()*0.5f),true)->SetPosition(Vector3(0,10,0));

//Create a floor for the shape above to fall onto, position it at y=-15 and automatically add it to the world.
factory.CreateRigidBody(0,factory.CreateBox(Vector3(10,10,10)),true)->SetPosition(Vector3(0,-15,0));
AddCube(factory.GetWorld());

This takes care of object ownership for you and is clearly a lot simpler. You can still customise the body's parameters as you like by using the object returned by CreateRigidBody().

Written by 0xseantasker on Jun 27 2016, 11:47 AM.
User
Projects
None
Subscribers
None

Event Timeline