Skip to content

prep(engine): ground for the Sgr A* black-hole close-up (P1-P3) - #649

Merged
rulkens merged 8 commits into
mainfrom
prep-black-hole-ground
Sep 1, 2026
Merged

rulkens merged 8 commits into
mainfrom
prep-black-hole-ground

Conversation

@rulkens

@rulkens rulkens commented Sep 1, 2026 •

Copy link
Copy Markdown
Owner

Ground-preparation PR for the black-hole close-up feature — three refactors from the spec's Ground preparation section (docs/superpowers/specs/2026-09-01-render-black-hole-design.md, on #645), each its own commit, zero behaviour change for every existing scene:

  • P1 — slab candidacy from body data: visibleSlabBodies takes one bodies roster (predicate over SceneBody), admitting anchor bodies; BODY_SLAB_CAPACITY derives from the same set; both stale "DRAWS NOTHING" docblocks corrected; anchor orientation-identity pinned by test.
  • P2 — per-body camera-standoff floor: optional standoffRadii on body data; the orbit-controls lane carries ONE pivotFraming getter ({ radiusMpc, floorMpc }) with the floor computed at the source — clampDistance takes a precomputed floor, zoomedDistance keeps the raw radius for its taper, and the standoff concept lives only in body data + SelectionRow + one derivation line. Sgr A* floors at 2 r_s; every other body keeps the global 1.0000024. (Reworked from an earlier two-parallel-getter shape at user direction; behaviour-identical, equivalence independently re-derived in review.)
  • P3 — fixed-size render targets: RenderTargetSpec.fixedSizePx (canvas-independent, multi-layer) alongside the canvas-divisor scale; no production row uses it yet.

Each task implemented + reviewed via SDD (3 fix rounds total, all closed). Full suite 7853 green, typecheck clean on this branch after cherry-pick.

Feature PR (Phase B: probe, physics data, deflection LUT, sky capture, geodesic pass) follows after this merges.

🤖 Generated with Claude Code

rulkens and others added 5 commits September 1, 2026 11:47
visibleSlabBodies now takes a flat `bodies: readonly SceneBody[]` list
instead of hardcoding `{earth, planets}` and concatenating internally
— the caller assembles the candidate list, so an AnchorPointBody (Sgr
A*) can join the roster on the same frustum/pixel-cull terms as a
planet. BODY_SLAB_CAPACITY sums the same three sources. Zero behaviour
change for every existing scene: the anchor's culls reject it at any
sane viewing distance, and the new SCENE_ANCHOR_POINT_BODIES array
mirrors SCENE_PLANETS so a second anchor is a data append, not a
call-site edit.

Also corrects the stale "DRAWS NOTHING" docblock claim in
AnchorPointBody.d.ts and sgr-a-star.ts — a future anchor may draw a
far-field glint and lensing-band geodesic pass via dedicated
ContentLayer rows.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…yer targets

Adds the RenderTargetSpec.fixedSizePx field and the reconcile/allocate
branch that honours it, ahead of the sky-cubemap target row that needs
a fixed 2d-array texture regardless of canvas size (Phase B). No
production row sets it yet; createRenderTargets gains a test-only
extraRows injection seam so the branch is exercisable now.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review finding: the test file's module-header comment still described
the pre-change `[earth, ...planets]` signature after task 1's
`{ bodies }` param rename — mirrors the src file's already-correct
header at visibleSlabBodies.ts:11.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
clampDistance gains an optional standoffRadii third param (default
SURFACE_STANDOFF_RADII) so a focused body can override the Earth-tuned
global zoom floor. AnchorPointBody carries the override; SGR_A_STAR
sets it to 2.0 (Q10's descent floor).

Threaded through the zoom path that actually reaches clampDistance for
a focused body — zoomedDistance/zoomedPose, applyWheelZoom, and both
attachOrbitControls zoom sites (pinch, wheel-during-gesture) — via a
new pivotStandoffRadii(row) helper mirroring pivotRadiusMpc, read the
same way in wireInput.ts. Every other body (no override) falls through
to the existing default unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nRow

Every existing zoom-path test hand-builds a SelectionRow with
standoffRadii already set, so the 'standoffRadii' in body narrowing in
extractSelectionRow.ts had no coverage against the real SCENE_BODIES
seed — a typo'd property or a reversed condition would silently drop
Sgr A*'s Q10 floor with the suite green. Adds a test against the real
SGR_A_STAR seed plus an explicit undefined-field assertion for a body
with no override, so a reversed condition fails on either side.

Verified by temporarily reversing the condition: the new Sgr A* case
goes red (undefined vs 2), confirming it catches the regression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
skymap 4c5b05a Commit Preview URL

Branch Preview URL
Sep 01 2026, 11:14 AM

rulkens and others added 2 commits September 1, 2026 12:47
…Framing getter

Task 2 threaded the per-body camera-standoff floor as a second parallel
getter lane beside pivotRadiusMpc through the orbit-controls input stack
(OrbitControlsOptions -> orbitControls -> applyWheelZoom -> zoomedPose ->
zoomedDistance -> clampDistance). Reworks that into a single
`pivotFraming: () => PivotFraming` getter carrying { radiusMpc, floorMpc }
in one bundle, per the user's rejection of the two-lane shape.

floorMpc is precomputed at the lane source (pivotRadiusMpc.ts's new
pivotFraming(), built beside the untouched pivotRadiusMpc() scalar export
that runFrame.ts/frameContext.ts/logCameraState.ts still consume directly),
so clampDistance drops back to a plain two-arg (distance, floorMpc) clamp
with no pivot-radius/standoff-ratio knowledge of its own. zoomedDistance
keeps reading the bundle's raw radiusMpc for its altitude-taper anchor
(h = distance - radiusMpc) alongside the precomputed floor — the two fields
diverge on purpose, which is why they ride one bundle instead of collapsing
into a single number. Deletes pivotStandoffRadii.ts (merged into
pivotFraming); Sgr A*'s 2 r_s override stays covered by
pivotRadiusMpc.test.ts's pivotFraming describe block plus a wireInput.ts
wiring test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Task 2b review (fix round 1):
- SelectionRow.d.ts's standoffRadii comment still named the deleted
  pivotStandoffRadii helper; points at pivotFraming instead.
- pivotRadiusMpc.ts's module header ran 12 lines, over the ≤10 budget;
  trimmed both doc comments to their load-bearing why (outside-lane
  consumers, the null-radius floor equivalence) and dropped restated detail.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@rulkens
rulkens marked this pull request as ready for review September 1, 2026 10:48
Union of two independent orbit-controls refactors that diverged from the same
base: this branch's pivotRadiusMpc+standoffRadii -> single pivotFraming getter
(PivotFraming { radiusMpc, floorMpc }), and origin/main's #648 (P5 CameraPose
roll + P6 input recognizer/aggregator split, orbitControls -> pure gesture
recognizer, camera math moved to applyInputToCamera.ts/drainInput.ts).

orbitControls.ts, wireInput.ts, and their tests took #648's structure verbatim
(the pivot getter no longer belongs in OrbitControlsOptions once the recognizer
touches no camera state). zoomedPose.ts is a real union: kept this branch's
PivotFraming-typed zoomedDistance call and added #648's roll field. Two new
#648 files that git auto-merged without conflict (applyInputToCamera.ts,
drainInput.ts, both new so only one side had touched them) still called the
pre-merge scalar pivotRadiusMpc where the merged lane now expects PivotFraming
— repointed both, plus applyInputToCamera.test.ts's raw-number arguments, at
pivotFraming. No standoffRadii/pivotStandoffRadii reference or leftover
conflict marker remains anywhere in the tree.

tsc clean on both tsconfigs; npx vitest run: 1169 files / 7899 tests, all
passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@rulkens
rulkens merged commit 0b1787a into main Sep 1, 2026
@rulkens
rulkens deleted the prep-black-hole-ground branch September 1, 2026 11:13
rulkens added a commit that referenced this pull request Sep 1, 2026
…-render-black-hole

Lane files resolved by taking main's tree: main's squash of #649 already
contains the pivotFraming-x-#648 union, and this branch carried no src/tests
content beyond what #649 shipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant