Repository navigation
visionOS: update spatial pinch input to the current revision of godotengine/godot#123732 - #4
Merged
Conversation
…engine#123732 Move the spatial event support from the original revision of godotengine#123732 by Olivier Pinon to its current revision (3d0e597). Upstream changes carried over: - Spatial events no longer register their own trackers. The system pinch drives the `left_hand` and `right_hand` controller trackers that accessories and hand gestures already use, through the new VisionOSSharedController owned by VisionOSXRInterface. While a spatial event is active it owns `trigger_click` and the `default` pose (corrected to the OpenXR hand interaction convention). - The selection ray is published once per pinch as the `default` pose of a new `/user/eyes_ext` tracker. - `left_hand` and `right_hand` are always registered. Adaptations for this fork: - Hand-gesture mirroring now writes to the shared controllers. While a spatial event is active, the optical pinch does not write `trigger_click` or the `default` pose. After the event ends, the optical `trigger_click` stays released until the optical pinch releases, so one pinch cannot click twice. Analog trigger, grip, and the aim, grip and palm poses still come from hand tracking. - Accessory updates skip a hand while a spatial event drives it. - The engine-thread dispatch of spatial events and the weak renderer capture are kept. - Null guards were added, `eyes_ray` is released with unref(), spatial-event state is reset on uninitialize, and events are ignored before the interface is initialized. - The shared trackers are created only after CompositorServices initialization succeeds. - visionos_reset_input_tracking takes the shared controllers. The arbitration helpers are header-only and covered by unit tests. Removed trackers: `visionos/left_hand_pinch`, `visionos/right_hand_pinch`, `visionos/left_hand_ray` and `visionos/right_hand_ray`.
Clancey
marked this pull request as ready for review
October 6, 2026 05:08
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What problem(s) does this PR solve?
3d0e597f890cf4785310f4e95e202c5fc05a451a.Additional information
Upstream design now carried
left_hand/right_handXRControllerTrackers throughVisionOSSharedController, whichVisionOSXRInterfaceowns. Accessories and hand gestures drive the same trackers. While a spatial event is active, it ownstrigger_clickand thedefaultpose. The pose is corrected to the OpenXR hand interaction convention.defaultpose of a new/user/eyes_exttracker.left_hand/right_handare now always registered.Conflicts and how existing fork behavior was preserved
fdd2c87 was applied after the gesture-derivation and scene-understanding commits, so the delta conflicts with fork code rather than the other way round. Resolution:
VisionOSHandTrackingno longer owns its ownleft_hand/right_handtrackers.publish_gestureswrites into the shared controllers instead. While a spatial event is active, the optical pinch does not writetrigger_clickor thedefaultpose. After the event ends, the opticaltrigger_clickstays released until the optical pinch itself releases, so one pinch cannot click twice. Analogtrigger,grip/grip_click, theaim/grip/palmposes and thevisionos_hand_trackingprofile still come from hand tracking. A hand with an accessory attached is still left to the accessory.VisionOSControllerTrackinguses the shared trackers. It skips a hand while a spatial event drives it. Haptics lookups are null-safe.[weak renderer]capture are kept.on_spatial_eventis ignored until the interface is initialized.visionos_reset_input_trackingnow resets the shared controllers. Its tests were updated.eyes_ray.unref()(upstream callsunreference()),Hand::controllerdefaults tonullptr, null guards, and spatial-event state is reset on uninitialize. The shared trackers are created only after CompositorServices initialization succeeds, so a failed initialize does not leave them registered.Downstream-visible changes
visionos/left_hand_pinch,visionos/right_hand_pinch,visionos/left_hand_ray,visionos/right_hand_ray.Ui/3d/xr_rig.gd(_spatial_pinch,_spatial_ray,_log_spatial_trackers) andtests/xr_rig_test.gdread these and must migrate before taking a release with this change. Otherwise gaze-and-pinch selection gets no ray.left_hand/right_handtrigger_click, plus thedefaultpose while pressed.defaultpose of/user/eyes_ext. It is a single tracker shared by both hands and is updated once at the start of each pinch.defaultpose ofleft_hand/right_handfollows the spatial-event hand pose instead of the optical aim pose. Useaimfor a stable optical aim.left_hand/right_handexist even when hand and controller tracking are both disabled. Their descriptions changed to "visionOS left/right controller and spatial event".VisionOSSharedController.VisionOSHandTracking::initializelost its accessory flag, andVisionOSHandTracking::uninitializewas removed.VisionOSControllerTracking::initializeandVisionOSSpatialEventTracking::initializetake the shared controllers.Validation
scons platform=visionos target=template_release arch=arm64 dev_mode=yes module_text_server_fb_enabled=yes tests=no debug_symbols=no: passedsimulator=yes: passedscons platform=macos target=editor arch=arm64 dev_mode=yes module_text_server_fb_enabled=yes tests=yes: passedgodot.macos.editor.arm64 --headless --test --test-case="*visionOS*": 56 test cases and 11390 assertions passed. This includes the new spatial-event arbitration test and the updated lost-head-tracking test.godot.macos.editor.arm64 --headless --test --test-case="*XR*,*[XR]*": passedxmllintonVisionOSXRInterface.xml: passedCoordination
clancey-qr-tracking-native-contractbranch changesvisionos_xr_interface.{h,mm}and scene understanding. It will likely need a rebase and conflict resolution against this change, mainly inVisionOSXRInterface::initialize/uninitialize.visionos-4.8republishes thevisionos-latestrelease that LogicLand CI consumes. Hold the merge until LogicLand has migrated off the removed tracker names.