Reputation: 4375
I can't seem to get a proper physics behavior with a basic bullet c++ simulation. I am trying to initialize btRigidBody from a mesh loaded from an STL file, for that I am using lib assimp.
When using a cube the physics behavior seems valid but not with a rectangular shape. What am I missing in the way I load the meshes into the physics?
void SimulationManager::addRigidBodyFromMesh (const BodyInfo& bodyInfo, const aiMesh* mesh) {
btTriangleMesh* trimesh = new btTriangleMesh();
for (int i=0;i<mesh->mNumFaces; ++i) {
const aiFace& face = mesh->mFaces[i];
aiVector3D v0 = mesh->mVertices[face.mIndices[0]];
aiVector3D v1 = mesh->mVertices[face.mIndices[1]];
aiVector3D v2 = mesh->mVertices[face.mIndices[2]];
trimesh->addTriangle(
btVector3(v0.x, v0.y, v0.z),
btVector3(v1.x, v1.y, v1.z),
btVector3(v2.x, v2.y, v2.z));
}
btCollisionShape* colShape = new btConvexTriangleMeshShape(trimesh);
//static, non-moving world environment geometry
//bool useQuantization = true;
//shape = new btBvhTriangleMeshShape(trimesh,useQuantization);
this->_collisionShapes.push_back(colShape);
btTransform transform;
transform.setIdentity();
btScalar mass(1.f);
btVector3 localInertia(0, 0, 0);
colShape->calculateLocalInertia(mass, localInertia);
transform.setOrigin(btVector3(bodyInfo.x, bodyInfo.y, bodyInfo.z));
btDefaultMotionState* motionState = new btDefaultMotionState(transform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, motionState, colShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setAngularVelocity(btVector3(bodyInfo.aX, bodyInfo.aY, bodyInfo.aZ));
this->_pDynamicsWorld->addRigidBody(body);
}
I then update the simulation and retrieve rigidbody transform as follow:
void SimulationManager::update(double dt, std::vector<BodyTransform>& transforms){
this->_pDynamicsWorld->stepSimulation(dt, 10);
for (int i = 0; i < this->_pDynamicsWorld->getNumCollisionObjects(); ++i) {
btCollisionObject* obj = this->_pDynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
float invMass = body->getInvMass();
if (invMass > 0) {
btTransform trans;
body->getMotionState()->getWorldTransform(trans);
BodyTransform bodyTransform;
bodyTransform.matrix = new btScalar[16];
trans.getOpenGLMatrix(bodyTransform.matrix);
transforms.push_back(bodyTransform);
}
}
};
And update the opengl meshes as follow:
std::vector<BodyTransform> transforms;
simulationManager.update(0.005, transforms);
for (std::vector<BodyTransform>::iterator it = transforms.begin() ; it != transforms.end(); ++it) {
glPushMatrix();
glMultMatrixf((GLfloat*)it->matrix);
drawModel(bar);
glPopMatrix();
delete [] it->matrix;
}
Here is how my simulation looks like with cubes:
But with rectangles, the meshes are initially laying on the floor and they stabilize vertically, quite strange:
I would be very grateful for any help on the topic. Thanks!
Upvotes: 0
Views: 382
Reputation: 4375
After struggling for a while I found out what was the problem, so I will answer my own question in case it can be useful to someone else: bullet expects the center of gravity of the mesh to be placed at its origin, if it's not the case you will get the strange behaviour that you cab see above.
Upvotes: 1