#4807·bullet3

btDiscreteDynamicsWorld keeps stale gravity on sleeping bodies after setGravity

Author: peachtree0222Created Sep 15, 2026Updated Sep 15, 2026

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/bullet3 master at 63c4d67e337017f9d8b298c900e9aabdb69296e7
  • 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.

Source: https://github.com/bulletphysics/bullet3/blob/63c4d67e337017f9d8b298c900e9aabdb69296e7/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp#L499-L510

Reproduction package:

sleeping-body-world-gravity-poc.zip

Steps to reproduce

  1. Build PyBullet from the commit above using poc/README.md.
  2. Run python poc/reproducer.py active.
  3. Run python poc/reproducer.py sleeping.

Observed output is in poc/observed-output.txt.