-
-
Notifications
You must be signed in to change notification settings - Fork 24.9k
Physics interpolation is broken on XR nodes and XRServer #103232
Description
Tested versions
- Reproducible in v4.4 (0e3dbba)
System information
Godot v4.4.rc.mono (0e3dbba) - Windows 11 (build 26100) - Multi-window, 1 monitor - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 4090 (NVIDIA; 32.0.15.7247) - AMD Ryzen 9 7950X3D 16-Core Processor (32 threads)
Issue description
Physics interpolation is broken in XR in general, causing the following issues:
XROrigin3DupdatesXRServer::world_originonly when the transform changes, which meansXRServer::world_originnever has the interpolated value for the transform on each render frame.XRServer::world_originis used to know where the camera is in the world and to render properly, if it isn't also interpolated then there's is a mismatch between the activeXROrigin3Dtransform and whatXRServerhas saved. This results in the following behavior:
current.mov
- All XR nodes that have a
XRPositionalTrackerwill update their position every time the"pose_changed"signal is triggered. This happens every timeXRServer::_processgets called because it asks the active XR interface to poll events and it happens every render frame. Tracked nodes being updated every frame make sense because if we instead poll events on each physics frame and interpolate them the motion sickness on something like the HMD would be unreal, and you don't want your hand trackers to lag behind your real hands. However, when interpolation is enabled the engine really doesn't want you to be updating your transforms on render frame and this causes the childs of those tracked nodes to jitter a bit.
Here is an example in the attached MRP, when the "hand" is interpolated, it follows the parent just fine but the childs aren't smooth at all (also spams in the console the warning that an interpolated transform was set outside physics process)
2025-02-24.18-04-54.mp4
Disabling interpolation in the hand results in really smooth child movement but then when it comes to following the parent everything falls apart:
2025-02-24.18-05-37.mp4
I created a WIP pull request (#103233) with a fix for the XRServer::world_origin interpolation where it works as expected:
fix.mov
However for the second issue I'm out of ideas about how to proceed. Disabling interpolation on the tracked node makes it jitter because it will now follow the non interpolated transform of the parent even if the parent is set as interpolated.
Steps to reproduce
Enable interpolation in a project and make XROrigin3D a child of any physics object
Minimal reproduction project (MRP)
It can be reproduced on the official openxr_character_centric_movement demo, modifying start_vr.gd to remove the line Engine.physics_ticks_per_second = current_refresh_rate so the physics FPS can be different than the target framerate
https://github.com/godotengine/godot-demo-projects/tree/master/xr/openxr_character_centric_movement
However here I include a modified version that just adds a moving platform where you can easily see the problem
Here is an MRP to test the tracker issue with a fake hand for anyone who wants to test without XR hardware:
Metadata
Metadata
Assignees
Type
Projects
Status