I've read the manual, searched the forums (found this similar problem at: http://bulletphysics.org/Bullet/phpBB3/ ... php?t=5195), and tried debugging by checking the call stack, reading the values. I haven't figured it out, but perhaps the problem is easily visible to more experienced eyes. Here's the code:
Code: Select all
class Physics
{
private:
struct EntityShape
{
btConvexShape* childShape; //target shape
btConvex2dShape* shape; //containing shape for 2d physics
//ctor
EntityShape() : childShape(NULL), shape(NULL) {}
//dtor, deletes both containing shape and target shape
~EntityShape() {if(shape) delete shape; shape = NULL; if(childShape) delete childShape; childShape = NULL;}
//creates a 2d shape container from the passed in target shape
void create(btConvexShape* ChildShape)
{
childShape = ChildShape;
if(childShape == NULL)
return;
shape = new btConvex2dShape(childShape);
}
};
btBroadphaseInterface *m_broadphase; //first sweep
btDefaultCollisionConfiguration *m_config; //collision config
btCollisionDispatcher *m_dispatcher; //second sweep/dispatcher
btSequentialImpulseConstraintSolver *m_solver; //constraint solver
btDiscreteDynamicsWorld *m_world; //world
std::vector<EntityShape> m_templateShapes; //all the collision shapes, with the 2d containers
std::vector<btRigidBody*> m_bodies; //all the rigid bodies
public:
//ctor
Physics()
: m_broadphase(NULL), m_config(NULL), m_dispatcher(NULL), m_solver(NULL), m_world(NULL)
{
//make new broadphase interface
m_broadphase = new btDbvtBroadphase();
//collision config and dispatcher
m_config = new btDefaultCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher( m_config );
//2d solver setup
btVoronoiSimplexSolver *simplex = new btVoronoiSimplexSolver();
btMinkowskiPenetrationDepthSolver *pdSolver = new btMinkowskiPenetrationDepthSolver();
btConvex2dConvex2dAlgorithm::CreateFunc *convexAlgo2d = new btConvex2dConvex2dAlgorithm::CreateFunc(simplex, pdSolver);
m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,convexAlgo2d);
m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,convexAlgo2d);
m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,convexAlgo2d);
m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,new btBox2dBox2dCollisionAlgorithm::CreateFunc());
//physics solver
m_solver = new btSequentialImpulseConstraintSolver();
//world setup
m_world = new btDiscreteDynamicsWorld( m_dispatcher, m_broadphase, m_solver, m_config );
m_world->setGravity( btVector3(0.0f, -10.0f, 0.0f) );
}
//dtor
~Physics()
{
if( m_world != NULL )
delete m_world;
if( m_solver != NULL )
delete m_solver;
if( m_dispatcher != NULL )
delete m_dispatcher;
if( m_config != NULL )
delete m_config;
if( m_broadphase != NULL )
delete m_broadphase;
}
//creates the simulation
void createSimulation()
{
//local params
btConvexShape *shape = NULL;
btDefaultMotionState *motion = NULL;
btRigidBody::btRigidBodyConstructionInfo ci(0.0f, 0, 0);
btRigidBody *body = NULL;
//object 1
shape = new btBox2dShape( btVector3(20.0f, .5f, 0) );
m_templateShapes.resize( m_templateShapes.size() + 1 );
m_templateShapes.back().create( shape );
motion = new btDefaultMotionState( btTransform( btQuaternion(0,0,0,1) ) );
ci = btRigidBody::btRigidBodyConstructionInfo( 0.0f, motion, m_templateShapes.back().shape );
ci.m_restitution = 1.0f;
body = new btRigidBody(ci);
m_bodies.push_back( body );
m_world->addRigidBody( m_bodies.back() );
//object 2
shape = new btCylinderShapeZ( btVector3(1.0f, 1.0f, .05f) );
m_templateShapes.resize( m_templateShapes.size() + 1 );
m_templateShapes.back().create( shape );
motion = new btDefaultMotionState( btTransform( btQuaternion(0,0,0,1), btVector3(0, 50, 0) ) );
btVector3 fallInertia;
m_templateShapes.back().shape->calculateLocalInertia(1.0f, fallInertia);
ci = btRigidBody::btRigidBodyConstructionInfo( 1.0f, motion, m_templateShapes.back().shape, fallInertia );
ci.m_restitution = .5f;
body = new btRigidBody(ci);
m_bodies.push_back( body );
m_world->addRigidBody( m_bodies.back() );
}
//stops the simulation, deallocating shapes and objects
void destroySimulation()
{
if( m_world )
{
while(m_world->getCollisionObjectArray().size() > 0)
{
btCollisionObject* obj = m_world->getCollisionObjectArray().at( m_world->getCollisionObjectArray().size() - 1 );
btRigidBody* body = btRigidBody::upcast(obj);
if( body && body->getMotionState() )
delete body->getMotionState();
m_world->removeCollisionObject( obj );
if( obj )
{
delete obj;
}
}
}
m_bodies.clear();
m_templateShapes.clear();
}
//steps the simulation by dt
void stepSimulation(float dt)
{
m_world->stepSimulation(dt, 10);
}
//gets the world transform of the indexed rigid body
XMMATRIX getWorldTransform(UINT index)
{
XMMATRIX transform = XMMatrixIdentity();
if( index < m_bodies.size() )
{
btTransform& t = m_bodies[index]->getWorldTransform();
XMFLOAT4X4 data;
t.getOpenGLMatrix( (float*)&data );
//not transposing here since XMMATRIX are row-major, just as OpenGL matrices
transform = /*XMMatrixTranspose*/(XMLoadFloat4x4( &data ));
}
return transform;
}
};
The problem was resolved by the third post.