Can I update btRigidBody without adding/removing it from world?

Post Reply
BruceBanjo
Posts: 3
Joined: Fri Jan 21, 2022 8:42 pm

Can I update btRigidBody without adding/removing it from world?

Post by BruceBanjo »

Hi,

Do I have to remove a btRigidBody from the btDiscreteDynamicsWorld and then re-add it for all changes?

For example, I think I read somewhere that it's OK to use btCompoundShape::updateChildTransform() without removing the body from the world when dealing with animated rigid bodies.

On the other hand, I read that for something as simple as changing the mass of the btRigidBody, it must be removed and re-added to the world.

So is there a general rule or documentation somewhere about what operations require the btRigidBody to be removed and re-added to the world?

For example, what if I do this to a shape that's being used by a rigid body in the world?

Code: Select all

shape->~btBoxShape();
new (shape) btBoxShape({ extents.x, extents.y, extents.z });
Thanks
BruceBanjo
Posts: 3
Joined: Fri Jan 21, 2022 8:42 pm

Re: Can I update btRigidBody without adding/removing it from world?

Post by BruceBanjo »

I found this very old post indicating a known issue:
https://code.google.com/archive/p/bullet/issues/325

Is there an update on this?

I've noticed btRigidBody has the variable m_updateRevision. If I call btRigidBody::setCollisionShape to force an increment, does that eliminate the need for adding/removing the rigidbody from the world, for all things including change of mass?
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Can I update btRigidBody without adding/removing it from world?

Post by drleviathan »

I read that for something as simple as changing the mass of the btRigidBody, it must be removed and re-added to the world.
Not true: you can dynamically change the mass of a RigidBody without re-adding it to the world. However, if the body is inactive --> you probably want to activate it just in case its changed mass would trigger the collapse of some stacked pile that was in equilibrium.

I know of a few reasons to "re-add an object to the world": (a) the bounding box of the object is changing and its proxy in the broadphase needs to be updated, (b) you're changing the collision group/mask (these fields live in the broadphase proxy, not the CollisionObject), and (c) you're changing the friction and need to rebuild any persistent contact points to pick up the new value.

In each of these cases you don't actually need to "re-add the object to the world", but you do need to update some data structures which are automatically updated when you do re-add it. Hence, the re-add trick is a short-cut of sorts: it is short to implement in code but is not necessarily shorter when it comes to CPU cycles.
BruceBanjo
Posts: 3
Joined: Fri Jan 21, 2022 8:42 pm

Re: Can I update btRigidBody without adding/removing it from world?

Post by BruceBanjo »

drleviathan wrote: Wed Mar 09, 2022 8:33 pm Not true: you can dynamically change the mass of a RigidBody without re-adding it to the world. However, if the body is inactive --> you probably want to activate it just in case its changed mass would trigger the collapse of some stacked pile that was in equilibrium.

I know of a few reasons to "re-add an object to the world": (a) the bounding box of the object is changing and its proxy in the broadphase needs to be updated, (b) you're changing the collision group/mask (these fields live in the broadphase proxy, not the CollisionObject), and (c) you're changing the friction and need to rebuild any persistent contact points to pick up the new value.

In each of these cases you don't actually need to "re-add the object to the world", but you do need to update some data structures which are automatically updated when you do re-add it. Hence, the re-add trick is a short-cut of sorts: it is short to implement in code but is not necessarily shorter when it comes to CPU cycles.
Ok thanks for the clarification.

I was assuming based on the following post (from 2010), where it seems to indirectly state that mass changes require remove/re-add, since inertia tensor must be set at same time as mass.

viewtopic.php?p=21396&hilit=updateChild ... ntent21396
For the inertia tensor, make sure to remove the object from the world before making the change, and re-insert it afterwards.
Maybe that information is obsolete?

Anyways, I'm not that worried about performance for now, I just need to ensure things work reliably, so I think I'll just remove/re-add. I don't have sufficient experience with Bullet to know how or when to do tasks (a), (b), and (c).

I'm a little worried that since remove/re-add will move by teleportation rather than by force/velocity, that I will get strange explosions/impulses when bodies are re-added in a way that causes overlap. I guess I'll just bank on this being an edge case that doesn't come up. :lol:

Thanks
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Can I update btRigidBody without adding/removing it from world?

Post by drleviathan »

For the inertia tensor, make sure to remove the object from the world before making the change, and re-insert it afterwards.
Yes, changing the mass would also change the inertia tensor. It turns out the only way to change the mass is to make a call that also takes the local inertia diagonal. Bullet assumes the local-frame interia tensor is diagonal --> it is the application's duty to diagonalize it.

Code: Select all

void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia)
Meanwhile, the world-frame inverse inertia tensor is what is used for the simulation calculations and it is always updated on the fly because it depends on the object's world transform:

Code: Select all

void btRigidBody::updateInertiaTensor()
{
   ·m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose();
}
Post Reply