Basically what I want is to do the following. Setup an environment made from a mesh of triangles. In the environment there will be a stack of boxes. Another box will fall on the stack. When a box stops moving there will be a callback to some of my own code. If an object starts moving again, another callback will call some of my own code.
I have done the following
1) Created a btBvhTriangleMeshShape for the world.
2) Created a btRigidBody for each box.
My code is pretty much copy and paste work from the demos, but I have two basic questions
1) Why do my boxes continuously jitter about? Why do they not deactivate eventually?
2) How do I add the desired callbacks?
Thanks!
Here's what I currently have.
Code: Select all
//Load the world
Object *O = new Object("sponza.tri");
Objects.push_back(O);
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btVector3 worldAabbMin(O->tree->aabb.min.x -100, O->tree->aabb.min.y -100, O->tree->aabb.min.z -100);
btVector3 worldAabbMax(O->tree->aabb.max.x +100, O->tree->aabb.max.y +100, O->tree->aabb.max.z +100);
int maxProxies = 1024;
btAxisSweep3* overlappingPairCache = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies);
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,overlappingPairCache,solver,collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0, 0, -100));
/*
* Create a BVH Mesha object from discrete triangles (the main static geometry)
*/
int totalTriangles = Objects[0]->triangles.size();
int totalVerts = totalTriangles * 3;
btVector3 *m_vertices = new btVector3[totalVerts];
int *gIndices = new int[totalTriangles*3];
int vertStride = sizeof(btVector3);
int indexStride = 3*sizeof(int);
int index = 0;
for (tri_vec_it c_tri = Objects[0]->triangles.begin(); c_tri != Objects[0]->triangles.end(); c_tri++) {
for (int i = 0; i < 3; ++i) {
Tri& t = *c_tri;
Point& p = t[i];
m_vertices[index].setValue(p.x, p.y, p.z);
index++;
gIndices[index] = index;
}
}
btTriangleIndexVertexArray *m_indexVertexArrays = new btTriangleIndexVertexArray(
totalTriangles,
gIndices,
indexStride,
totalVerts,
(btScalar*) &m_vertices[0].x(),
vertStride);
bool useQuantizedAabbCompression = true;
btCollisionShape *groundShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression);
btAlignedObjectArray<btCollisionShape*> collisionShapes;
collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, 0, 0));
{
btScalar mass(0.);
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
//add the body to the dynamics world
dynamicsWorld->addRigidBody(body);
}
//Load another object
O = new Object("small_cube.tri");
//cube starts off suspended in the air above stack of boxes
O->offset.set(0.0, 0.0, 300);
Objects.push_back(O);
{
//create a dynamic rigidbody
btCollisionShape *colShape = new btBoxShape(btVector3( (O->tree->aabb.max.x - O->tree->aabb.min.x)/2.0f,
(O->tree->aabb.max.y - O->tree->aabb.min.y)/2.0f,
(O->tree->aabb.max.z - O->tree->aabb.min.z)/2.0f));
//btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1));
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(O->offset.x, O->offset.y, O->offset.z));
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
colShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, colShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
dynamicsWorld->addRigidBody(body);
}
//Sponza and Cube Loaded
//Now to instance cube a few times...
for (int x = 0; x < 5; ++x) {
for (int z = 0; z < 5; ++z) {
O = new Object();
O->tree = Objects[1]->tree;
O->offset.set(x * 10, 0.0, (z * 10) + 10);
Objects.push_back(O);
{
//create a dynamic rigidbody
btCollisionShape *colShape = new btBoxShape(btVector3( (O->tree->aabb.max.x - O->tree->aabb.min.x)/2.0f,
(O->tree->aabb.max.y - O->tree->aabb.min.y)/2.0f,
(O->tree->aabb.max.z - O->tree->aabb.min.z)/2.0f));
//btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1));
//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
collisionShapes.push_back(colShape);
/// Create Dynamic Objects
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(O->offset.x, O->offset.y, O->offset.z));
btScalar mass(1.f);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
colShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, colShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
dynamicsWorld->addRigidBody(body);
}
}
}