Code: Select all
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <btBulletDynamicsCommon.h>
class PhysicsWorld {
public:
PhysicsWorld ()
{
col_conf = new btDefaultCollisionConfiguration();
col_disp = new btCollisionDispatcher(col_conf);
// first 2 params specify the world AABB
// last param is the max number of "proxies"
broadphase = new btAxisSweep3(btVector3(-1000,-1000,-1000),btVector3(1000,1000,1000),32766);
con_solver = new btSequentialImpulseConstraintSolver();
world = new btDiscreteDynamicsWorld(col_disp,broadphase,con_solver,col_conf);
world->setGravity(btVector3(0,0,-9.8));
}
virtual ~PhysicsWorld ()
{
for (int i=world->getNumCollisionObjects()-1 ; i>=0 ; --i) {
btCollisionObject* obj =
world->getCollisionObjectArray()[i];
btRigidBody* victim = btRigidBody::upcast(obj);
if (victim==NULL) continue;
deleteBody(victim);
}
delete world;
delete con_solver;
delete broadphase;
delete col_disp;
delete col_conf;
}
btRigidBody *createBody (btCollisionShape *shape, float mass, float ccd_motion_thresh, btMotionState* motion = NULL)
{
btVector3 local_inertia(0,0,0);
if (mass != 0)
shape->calculateLocalInertia(mass,local_inertia);
btRigidBody::btRigidBodyConstructionInfo cInfo(mass, motion, shape, local_inertia);
btRigidBody* body = new btRigidBody(cInfo);
world->addRigidBody(body);
// Only do CCD if motion in one timestep (1.f/60.f) exceeds this
body->setCcdSquareMotionThreshold(ccd_motion_thresh);
//Experimental: better estimation of CCD Time of Impact:
//body->setCcdSweptSphereRadius( 0.2*0.5 );
return body;
}
void deleteBody (btRigidBody *victim)
{
world->removeRigidBody(victim);
btMotionState* motion = victim->getMotionState();
delete motion;
delete victim;
}
btBoxShape *createBox (float lx, float ly, float lz)
{
btBoxShape *r = new btBoxShape (btVector3(lx,ly,lz));
r->setMargin(0.05);
return r;
}
btCylinderShape *createCylinder (float lx, float ly, float lz)
{
btCylinderShape *r = new btCylinderShape(btVector3(lx,ly,lz));
r->setMargin(0.05);
return r;
}
int pump (float seconds)
{
//during idle mode, just run 1 simulation step maximum
return world->stepSimulation(seconds,100000);
}
protected:
btDefaultCollisionConfiguration *col_conf;
btCollisionDispatcher *col_disp;
btBroadphaseInterface *broadphase;
btConstraintSolver *con_solver;
btDiscreteDynamicsWorld *world;
// add some objects
};
class MotionCallback : public btMotionState {
protected:
btVector3 initialPos;
int counter;
public:
MotionCallback (float x, float y, float z)
: initialPos(x,y,z), counter(0)
{ }
virtual void getWorldTransform (btTransform& into_here) const
{
into_here.setIdentity();
into_here.setOrigin(initialPos);
}
virtual void setWorldTransform (const btTransform& current_xform)
{
std::cout << counter++ << " " << current_xform.getOrigin().z() << std::endl;
}
};
int main (void)
{
PhysicsWorld *pw = new PhysicsWorld();
btCollisionShape *floor = pw->createBox(200,200,0.5);
btCollisionShape *cylinder = pw->createCylinder(0.5,0.5,0.5);
pw->createBody(floor, 0, 0.5, NULL);
pw->createBody(cylinder, 1, 0.5, new MotionCallback(0,0,10));
for (int i=0 ; i<2 ; ++i) {
pw->pump(1);
}
delete pw;
delete floor;
delete cylinder;
return EXIT_SUCCESS;
}
Two things, the "kink" at the 60th iteration, i.e. at the edge of calls to world->stepSimulation(...), is it supposed to be there? Can I get rid of it?
The slight penetration at the end of the fall, why does this happen? Can I get rid of it?
Thanks.