During the course of the game when a entity is killed I remove the rigid body when destroying the rest of the entity. This code works fine for regular shapes but crashes when trying to delete a compound shape. What is the proper way of deleting compound shapes?
void CEntity::DeleteBody()
{
if (GetBody() != NULL)
{
// still may be rendering the object so set the entity position to the current rigid
// body position before deleting the rigid body
D3DXMATRIX mat;
btTransform trans;
GetBody()->getMotionState()->getWorldTransform(trans);
mat = ConvertBulletTransform(&trans);
btCollisionObject *obj = static_cast<btCollisionObject *>(GetBody());
m_world->removeCollisionObject(obj);
m_world->removeRigidBody(GetBody());
delete GetBody()->getMotionState();
delete GetBody();
D3DXQuaternionRotationMatrix(&m_rotation, &mat);
SetBody(NULL);
SetPosition(D3DXVECTOR3(mat._41, mat._42, mat._43));
}
}
GetBody() returns the btRigidBody pointer. The crash is an access viloation when calling the removeCollisionObject() function.
But I was reading that compound shapes don't remove their own children. So is the following code is what is needed to make sure a compound cleans up after itself?
void CEntity::DeleteBody()
{
if (GetBody() != NULL)
{
// still may be rendering the object so set the entity position to the current rigid
// body position before deleting the rigid body
D3DXMATRIX mat;
btTransform trans;
GetBody()->getMotionState()->getWorldTransform(trans);
mat = ConvertBulletTransform(&trans);
btCollisionObject *obj = static_cast<btCollisionObject *>(GetBody());
btCollisionShape *shape = obj->getCollisionShape();
if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
{
btCompoundShape *compound = static_cast<btCompoundShape *>(shape);
for (int i=0; i<compound->getNumChildShapes(); ++i)
{
btCollisionShape *s = compound->getChildShape(i);
compound->removeChildShape(s);
}
}
m_world->removeCollisionObject(obj);
m_world->removeRigidBody(GetBody());
delete GetBody()->getMotionState();
delete GetBody();
D3DXQuaternionRotationMatrix(&m_rotation, &mat);
SetBody(NULL);
SetPosition(D3DXVECTOR3(mat._41, mat._42, mat._43));
}
}
It is better to store all collision shape in a separate array, including child shapes of compound shapes, and delete them separately. Use 'delete' and not 'removeChildShape'.
addRigidBody should be used with removeRigidBody, and addCollisionObject should be used with removeCollisionObject. Don't call them both for a single object.