perf(ui): F8-12 — pixel-space planet sizing + single-copy label/outline layers (#55)
* Planet size formula moves to pixel-space: `pointRadiusBasePx = 2 + 2 * cbrt(size / SIZE_NORMALIZER)`. The on-screen disc now reads ~4-7 px at the reference zoom regardless of how large the world rectangle is — the previous `world-units` formulation blew up on small maps and made Source-class planets swallow their neighbours. * Labels + outlines live in the origin copy only. The 9× replication across torus copies was the dominant cost on a 100+ planet map (Pixi.Text creation + Graphics rebuilds on every zoom step); the origin-copy layout is what the camera-wrap listener guarantees the user actually sees. * `setPlanetLabels` and `setPlanetOutlines` skip Pixi-object rebuilds when the input fingerprint is unchanged — toggle flips and selection changes now keep the existing Text / Graphics instances alive and only repaint the affected pieces. * `renderer.md` updated to the new contract. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+13
-9
@@ -73,14 +73,17 @@ and `displayPointRadiusWorld` (in `src/map/world.ts`) compute those
|
||||
world-space values; the hit-test reads the same helpers so the click
|
||||
zone always matches the visible footprint.
|
||||
|
||||
`style.pointRadiusWorld` is the alternative sizing rule for planet
|
||||
`style.pointRadiusBasePx` is the alternative sizing rule for planet
|
||||
discs with a known `size`: the renderer treats the base radius as
|
||||
world units and softens its growth with the camera scale through
|
||||
`PLANET_SIZE_ZOOM_ALPHA` (0.33). At `scale = scaleRef` (the
|
||||
"whole world fits the viewport" zoom) the visible radius equals the
|
||||
base radius; zooming in grows it sub-linearly so on-screen pixel
|
||||
size scales as `scale^α`. Setting both `pointRadiusWorld` and
|
||||
`pointRadiusPx` ignores the pixel-space field.
|
||||
on-screen pixels **at the reference scale** and grows its on-screen
|
||||
pixel size with the camera scale through `PLANET_SIZE_ZOOM_ALPHA`
|
||||
(0.33). At `scale = scaleRef` (the "whole world fits the viewport"
|
||||
zoom) the visible disc reads at `pointRadiusBasePx` screen pixels;
|
||||
zooming in grows it as `scale^α` instead of linearly. This keeps
|
||||
known-size planets sane on every world rectangle — a 4000×4000 map
|
||||
and a 100×100 map both default to the same on-screen size. Setting
|
||||
both `pointRadiusBasePx` and `pointRadiusPx` ignores the pixel-space
|
||||
field.
|
||||
|
||||
Default hit slop in screen pixels: point=8, circle=6, line=6.
|
||||
These are touch-ergonomic defaults; per-primitive `hitSlopPx > 0`
|
||||
@@ -168,8 +171,9 @@ Per-primitive distance:
|
||||
small ergonomic margin on top. `visibleRadiusWorld` comes from
|
||||
`displayPointRadiusWorld` (F8-12 / #28 + #31): pixel-space
|
||||
`pointRadiusPx / scale` for unidentified planets and most ship
|
||||
groups, softened-by-zoom `pointRadiusWorld * (scale / scaleRef)^(α-1)`
|
||||
for planets with a known `size`. `pointRadiusPx` defaults to
|
||||
groups, softened-by-zoom
|
||||
`pointRadiusBasePx * (scale / scaleRef)^α / scale` for planets
|
||||
with a known `size`. `pointRadiusPx` defaults to
|
||||
`DEFAULT_POINT_RADIUS_PX = 3` when neither field is set.
|
||||
- **Filled circle**: `distSq ≤ (radius + slopWorld)²` where
|
||||
`radius` is in world units. The circle counts as filled when
|
||||
|
||||
Reference in New Issue
Block a user