#1
Yes, I have seen happen this myself before. The reason is that Bullet in some cases is not able to update the internal bounding box correctly.
The link you gave advises that after adding/removing shapes the mass properties have to be updated. We do this already, from the very first moment on: BulletBodyNode.add/remove_node both call the virtual function “shape_changed”, which is implemented in BulletbodyNode.shape_changed:
void BulletRigidBodyNode::
shape_changed() {
set_mass(get_mass());
transform_changed();
}
void BulletRigidBodyNode::
set_mass(PN_stdfloat mass) {
btScalar bt_mass = mass;
btVector3 bt_inertia(0.0, 0.0, 0.0);
if (bt_mass > 0.0) {
_rigid->getCollisionShape()->calculateLocalInertia(bt_mass, bt_inertia);
}
_rigid->setMassProps(bt_mass, bt_inertia);
_rigid->updateInertiaTensor();
}
There is very little I can do here, beside what we already do.
Background information: native Bullet allows only one shape per body, and this shape can not have a local transform. If you want to have several shapes you have to add one btCompundShape, which in turn can have several child shape with local transforms.
for Panda3D I wanted to have a flat list of shapes (zero, one or more) where each shape can have a local transform. In order to emulate this I do quite a bit of logic in add/remove_shape methods:
- Zero child shapes means I have one native btEmptyShape assigned to the rigid body.
- One shape without local transform: the shape is added directly to the rigid body.
- One shape with local transform: the body has one compound shape, which holds one child shape.
- Two or more shapes: the body has one compund shape with several child shapes.
So we never have the situation that the native Bullet body has no shape at all assigned; even if the list of shapes in Python is empty we have a special btEmptyShape shape assigned.
#2 & #3
I agree that the names are not very, well, intuitive. However, there has been a reason for choosing exactly these names: we (mostly me) don’t understand exactly what data the native Bullet member exactly hold, so chhosing our own names is likely to produce problems. In such a situation I think it is best to stick as close as possible to the native Bullet names. This has the advantage that users can look at the original Bullet documentation (incl. forums etc.) and have a chance to transfer knowledge they gain from these source to Panda3D Bullet. Here is an example of how closely we follow the native names:
////////////////////////////////////////////////////////////////////
// Function: BulletManifoldPoint::get_index0
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
int BulletManifoldPoint::
get_index0() const {
return _pt.m_index0;
}
index0 is a member in C++ Bullet, but since the Panda3D Python wrappers can’t create Python members I have to expose it as a getter method.
Of course this approach has disadvantages too. For example if the Bullet C++ API changes a tiny bit we have to adjust the Python API here too, and run into problems with ABI compatibiliy… hence it is always best to use Bullet development snapshots when dealing with Bullet.
#4
No, would not make sense, because sweep and ghost test are “intersections” of volumes, and don’t have exactly defined hit points, unlike raycasts or contact tests.
Or more practically: since native Bullet makes no such information available we can’t expose it from C++ to Python.