Spatial SDK 0.14.0: Can KINEMATIC → DYNAMIC leave physics bodies unable to sleep?
I am a solo developer building a game with Kotlin and Meta Spatial SDK 0.14.0 on Quest 3. I test with a production-signed, fully AOT-compiled release APK.
My game has an on-screen counter labelled “FPS”, but that counter actually measures gameplay update callbacks per second. It does not measure rendered frames. When it shows 36, that does not mean the headset is rendering at 36 FPS.
In an earlier recording, I measured the same time interval using two separate sources:
- Meta OVR Metrics: approximately 72 rendered frames per second.
- Perfetto, counting main gameplay update callbacks: approximately 37 updates per second.
Rendering continues at around 72 FPS, while gameplay updates happen roughly half as often and physical movement looks less smooth. I verified the update callback count in Perfetto, so the slowdown is not just an incorrect HUD reading.
I have observed update slowdowns in multiple levels. The simultaneous render/update readings above come from that earlier recording; my latest offline session recorded update rate but did not record render FPS.
While investigating CPU physics costs, I found a possible problem with returning bodies from KINEMATIC to DYNAMIC.
My game temporarily makes some physics bodies KINEMATIC, then returns them to DYNAMIC. I expect those bodies to move normally again and become eligible for sleeping once they settle. Sleeping should allow the physics engine to reduce unnecessary simulation work for resting bodies.
Inspection of the shipped arm64 libMetaSpatialSDKPhysics.so shows the following:
- The KINEMATIC path calls setActivationState(4). In Bullet, this is DISABLE_DEACTIVATION, which prevents the body from automatically sleeping.
- The path returning the body to DYNAMIC calls setActivationState(1) and activate(true).
- However, in this binary those calls do not clear an existing DISABLE_DEACTIVATION state.
- Consequently, this restoration path cannot remove the sleeping restriction assigned during KINEMATIC mode.
I could not find a supported public API in SDK 0.14.0 to read a body’s actual native sleeping state or reset this activation state. The sleeping-threshold and deactivation-time setters do not appear to remove that restriction either.
The native control flow has been inspected, but I have not directly read activation state from live bodies. I therefore cannot report how many bodies are affected or how much CPU time this adds. I am not claiming that this explains the entire gameplay slowdown. I have also not yet verified it in a separate minimal one-box example.
so:
- Should returning a body from KINEMATIC to DYNAMIC re-enable automatic sleeping?
- Is this a known issue in SDK 0.14.0, and is there a fixed version?
- Is there a supported workaround without recreating the rigidbody or changing its collider or physics settings?
- How can I inspect native activation state or active/sleeping body counts to verify the behavior?
I can provide the binary build ID, relevant native addresses, Perfetto recordings and the resolved SDK public API dump if needed.
