btDiscreteDynamicsWorld keeps stale gravity on sleeping bodies after setGravity
Environment
- OS: Ubuntu 24.04.5 LTS, Linux 7.0.0-28-generic x86_64
- Compiler: GCC 11.5.0
- Python: 3.12.3
- Source:
bulletphysics/bullet3masterat63c4d67e337017f9d8b298c900e9aabdb69296e7 - PyBullet: built locally from that exact checkout
Description
btDiscreteDynamicsWorld::setGravity updates the world's gravity but copies it only to rigid bodies for which isActive() is true. A sleeping body therefore keeps its previous per-body gravity. If it is woken later, its next step uses that stale value.
Expected behavior: changing world gravity updates every registered non-static body that has not opted out with BT_DISABLE_WORLD_GRAVITY, regardless of its transient sleep state.
Actual behavior: with a 0.1 s step, changing z gravity from -10 to +20 gives an active body z velocity +2, while an otherwise identical sleeping-then-woken body gets -1.
The PyBullet guide describes setGravity as setting the default gravity force for all objects. btSimpleDynamicsWorld::setGravity also updates every body without an active-state gate.
Reproduction package:
sleeping-body-world-gravity-poc.zip
Steps to reproduce
- Build PyBullet from the commit above using
poc/README.md. - Run
python poc/reproducer.py active. - Run
python poc/reproducer.py sleeping.
Observed output is in poc/observed-output.txt.
Source: bulletphysics/bullet3