Skip to content

test+docs(nav): characterise cursor-anchored LB pan (KD-38) + rotate sky-grab guard - #1881

Merged
kfarr merged 1 commit into
3DStreet:mainfrom
diarmidmackenzie:nav-pan-cursorlock-doc-and-rotate-test
Jul 24, 2026
Merged

test+docs(nav): characterise cursor-anchored LB pan (KD-38) + rotate sky-grab guard#1881
kfarr merged 1 commit into
3DStreet:mainfrom
diarmidmackenzie:nav-pan-cursorlock-doc-and-rotate-test

Conversation

@diarmidmackenzie

Copy link
Copy Markdown
Contributor

Follow-up to the recent navigation regression fixes (#1855 / #1859 / #1868). No runtime change — docs + one test only.

Why

Tracing #1867 (sky-grab pan lurch) back, the root is that LB pan is cursor-anchored: it grabs the world point under the cursor at mouse-down and keeps that point under the cursor for the whole drag (unlike legacy EditorControls, whose pan rate was cursor-independent). That model was carried over from the original controls but was never written down as a decision — so its consequences (rate scales with anchor depth; a sky grab needs a synthetic anchor on the cursor ray; a near-zero-distance anchor degenerates) only surfaced as the #1867 / TH-80 / TH-81 fixes. This PR states the model explicitly and closes a test-coverage gap on the rotate side.

Changes

  • docs/02-key-decisions.md — new KD-38. Characterises cursor-anchored LB pan and, crucially, the pan-vs-rotate asymmetry: on a source === 'fallback' (sky) grab, pan uses the fallback point (why it must lie on the cursor ray, regression: cannot pan up while looking out at the horizon and grabbing top half of screen #1867), while Shift+LB rotate branches on source and orbits the screen-centre ground pivot (_mapModePivot's fallbackCentre), ignoring the point. So the two gestures degenerate differently at the same cursor position — a degenerate-cursor change must be checked against both.
  • docs/04-glossary.md — a note on the LB "pan" terms flagging the cursor-anchored dependence, pointing to KD-38.
  • test/.../ExperimentalControls.rotation.test.js — a regression guard for the rotate side of the sky grab: Shift+LB over sky orbits fallbackCentre (y ≈ 0), never the cursor-ray fallback point (y > 1). The pan side is already covered by the ExperimentalControls.lbPan sky-grab tests (regression: cannot pan up while looking out at the horizon and grabbing top half of screen #1867); this guards the branch that keeps rotate immune to the same fault.

Testing

  • ExperimentalControls.rotation.test.js: 3/3 green (2 existing + the new guard).
  • Break-it check: forcing rotate to consume the fallback point makes the new test red (pivot.y 42.7 vs the < 0.5 assertion), confirming the guard bites.
  • No src changes, so lint is unaffected.

🤖 Generated with Claude Code

…y-grab asymmetry

LB pan is cursor-anchored (keeps the grabbed world point under the cursor),
so its rate scales with the anchor's depth and it needs a valid on-cursor-ray
anchor — the model behind the 3DStreet#1867 cursor-ray fallback, TH-80 zoom floor, and
TH-81 reach cap, but never stated in the docs. Add KD-38 characterising it
explicitly, plus the pan-vs-rotate degenerate-cursor asymmetry: on a sky grab
(source==='fallback') pan uses the fallback POINT while rotate branches on
source and orbits the screen-centre GROUND pivot, ignoring the point.

Add a rotation regression test: Shift+LB over sky orbits fallbackCentre
(y approximately 0), never the cursor-ray fallback point (y>1) — the rotate
side of the sky grab; the pan side is already covered in the lbPan suite.

- 02-key-decisions.md: KD-38
- 04-glossary.md: cursor-anchored-pan note pointing to KD-38
- ExperimentalControls.rotation.test.js: sky-grab asymmetry guard
@diarmidmackenzie
diarmidmackenzie requested a review from kfarr as a code owner July 23, 2026 14:20
@kfarr
kfarr merged commit 8112f2f into 3DStreet:main Jul 24, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants