#1500: Clicks in crowds and alt-clicks pick what is under them without a GPU wait #1502

Open
TheSlowly wants to merge 3 commits from TheSlowly/Slipstream:held-click-pages into main
Collaborator

Fixes #1500.

  • A held click whose depth page is missing (its hold ran out, or a pick on the same press asked a different chain) answers that page now instead of hitting nothing. This was the alt-click focus failure in crowds.
  • Alt-click's long camera ray (~8 km with DisableCameraConstraints and a long draw distance) takes the held 1024 m answer for that stretch and asks now only when nothing is hit there. Before, every alt-click waited ~15-20 ms for the GPU.
  • RenderVKPickDebug logs each held click's page waits and every answer-now pick with the reason.

pick_hitch.py gains MISSING-PAGE and LONG-RAY guards (both failed on the old code); all 27 source checks pass.

Fixes #1500. - A held click whose depth page is missing (its hold ran out, or a pick on the same press asked a different chain) answers that page now instead of hitting nothing. This was the alt-click focus failure in crowds. - Alt-click's long camera ray (~8 km with DisableCameraConstraints and a long draw distance) takes the held 1024 m answer for that stretch and asks now only when nothing is hit there. Before, every alt-click waited ~15-20 ms for the GPU. - RenderVKPickDebug logs each held click's page waits and every answer-now pick with the reason. pick_hitch.py gains MISSING-PAGE and LONG-RAY guards (both failed on the old code); all 27 source checks pass.
In a crowd every click's world layer overflows (about 5,200 rigged wearer draws crossed every
ray in the user's region) and needs a depth-window page. A held click waits at most 8 frames
for each page; at ~25 fps the page often had not come, pageAnswer returned false, the walk
ended undecided without visiting any fragment, and the click hit nothing -- alt-click focus and
the camera did nothing, while hover at the same pixel found the object.

A page the hold did not bring in is now answered now (the behaviour before held clicks, only
for a click whose hold ran out), so the click costs one GPU wait instead of missing.

RenderVKPickDebug also logs each held click's steps: frames each waited, when fillRequest
asked for it, and why the newest answers meanwhile were not its own (none, voided, another
pixel's, not asked yet, older, stale, another page's), to find why pages come late.

Test-Plan:
    python3 scripts/check/run.py --only pick-hitch: pass (the new MISSING-PAGE guard failed
        on the old pageAnswer)
    clang-cl /Zs llcleancursorpick.cpp: clean
    In world, a crowded region: alt-click focus works every time; with RenderVKPickDebug on,
        "held click (...)" lines show each page's wait and the latency line counts missing
        pages answered now

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Held clicks still leave one to three picks per press that wait for the GPU (~15-25 ms each),
plain clicks as well as alt-clicks: a pick whose ray the held answer does not cover (alt-click's
camera pick is longer than the held 1024 m request with DisableCameraConstraints and a long
draw distance), and pages of such a pick, which are not among the held click's pages.

With RenderVKPickDebug on, every answer-now pick logs who asked (intersectAll /
intersectObject), its pixel and length, and why neither the held click's answer nor the newest
answer covered it (pixel, origin, HUD layer, length, direction, outside the click, expired);
a page answered now logs its window and length against the held answer's.

Test-Plan:
    python3 scripts/check/run.py --only pick-hitch: pass
    clang-cl /Zs llcleancursorpick.cpp: clean
    In world with RenderVKPickDebug on: plain clicks and alt-clicks each log their
        "pick answered now (...)" lines with a reason

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With DisableCameraConstraints and a long draw distance, alt-click's camera pick asks ~8 km
(LLPickInfo::getPickDepth), while the held click's answer and the per-frame request reach
1024 m: covers() rejected the longer ray, so every alt-click asked the GPU now, ~15-20 ms on
the main thread (the pick log showed one per alt-click and none for plain clicks).

A click ray longer than the held / newest answer's request now takes that answer for its
stretch: the walk is nearest first, so a hit there is the long ray's first hit too. Only when
nothing is hit on it is the whole ray answered now (the first hit can only lie beyond). Hover
and intersectObject keep the strict rule.

Test-Plan:
    python3 scripts/check/run.py --only pick-hitch: pass (the new LONG-RAY guard failed on
        the old covers / answerFor / intersectAll)
    python3 scripts/check/run.py --stage source: 27 checks pass
    clang-cl /Zs llcleancursorpick.cpp: clean
    In world with RenderVKPickDebug on: alt-clicks on nearby objects log no
        "pick answered now" line; an alt-click on open sky logs "nothing on the answer's
        1024 m of ... m: the whole ray answered now"

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u held-click-pages:TheSlowly-held-click-pages
git switch TheSlowly-held-click-pages
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sky_line/Slipstream!1502
No description provided.