Draw the system at true scale, drop the halo, and refuse to enter what is off screen
Three changes to what the system view claims, all of them the same claim: that the sizes on screen mean something. **The halo is gone.** It was a sprite sized against the arrival frame — 1.12 AU for the Sun — so it stayed that wide as the camera closed in and ended up a flat gradient filling the screen, over the photograph it was meant to dress. It existed to keep the star visible at a framing that holds the whole system, which is now handled in pixels instead. **Bodies are drawn at their own radius.** The old marker size was exaggerated and scaled to the system span, and clamped: Jupiter and Ganymede both ran past the ceiling and were drawn at one radius, so every moon orbited inside its planet, and Phobos and Triton sat entirely within Mars and Neptune. True scale needs no rule against that — physics already puts a moon outside the planet it orbits. What it costs is visibility at the arrival framing, where every body is sub-pixel, so the scene floors each marker at 3 px on screen and holds a moon to half its planet's drawn size. Measured in the Sun's system: at arrival, planets 3 px and moons 1.5 px, against 3 px for everything before; at Jupiter, the planet 10.8 px at scale 1 with the Galilean moons on their orbits outside it. The Sun is drawn at its own radius too. Every other star keeps a size derived from its innermost orbit, because no stellar radius reaches the app — Gaia's `radius_gspphot` is the obvious next fetch. **A click cannot enter a system that is not on screen.** The picker tested depth but not the frame, and a star's hit area is its drawn size plus a slop, so a click in the last pixels of the view could fly into a system outside it, with nothing on screen to explain where it had gone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi
This commit is contained in:
@@ -18,6 +18,8 @@ export interface SystemMember {
|
||||
id: string;
|
||||
kind: SystemMemberKind;
|
||||
marker: THREE.Object3D;
|
||||
/** For a moon, the id of the body it orbits: what its drawn size is held against. */
|
||||
parentId?: string;
|
||||
}
|
||||
|
||||
const PLANET_COLOR = new THREE.Color(0.55, 0.75, 1.0);
|
||||
@@ -126,8 +128,8 @@ function buildOrbitLine(elements: OrbitalElements, kind: SystemMemberKind, frame
|
||||
* The texture is tiny (see `MARKER_TEXTURE_WIDTH`): a marker is a few pixels across, so what
|
||||
* survives is essentially its average colour, and generating it costs well under a millisecond.
|
||||
*/
|
||||
function buildMarker(kind: SystemMemberKind, radiusKm: number | undefined, systemSpanAu: number, appearance: PlanetAppearance | undefined): THREE.Mesh {
|
||||
const geometry = new THREE.SphereGeometry(bodyMarkerRadiusAu(radiusKm, systemSpanAu), 16, 12);
|
||||
function buildMarker(kind: SystemMemberKind, radiusKm: number | undefined, appearance: PlanetAppearance | undefined): THREE.Mesh {
|
||||
const geometry = new THREE.SphereGeometry(bodyMarkerRadiusAu(radiusKm), 16, 12);
|
||||
const material = appearance
|
||||
? new THREE.MeshBasicMaterial({ map: planetTexture(appearance, { width: MARKER_TEXTURE_WIDTH, height: MARKER_TEXTURE_HEIGHT }) })
|
||||
: new THREE.MeshBasicMaterial({ color: colorForKind(kind) });
|
||||
@@ -241,7 +243,7 @@ export class SystemOrbitsRenderer {
|
||||
continue; // orphaned moon reference; skip rather than crash.
|
||||
}
|
||||
const moon = this.addMoon(body.id, body.orbit, gmForParent(body.parentBodyId), body.radiusKm, parentTracked, ECLIPTIC_FRAME, appearanceForBody(body, bodies, hostLuminositySolar));
|
||||
members.push({ id: body.id, kind: 'moon', marker: moon.marker });
|
||||
members.push({ id: body.id, kind: 'moon', marker: moon.marker, parentId: parent.id });
|
||||
}
|
||||
|
||||
// Every exoplanet in a system shares the same line of sight, so the frame is built once.
|
||||
@@ -374,7 +376,7 @@ export class SystemOrbitsRenderer {
|
||||
appearance?: PlanetAppearance
|
||||
): TrackedTopLevelBody {
|
||||
const orbitLine = buildOrbitLine(elements, kind, frame);
|
||||
const marker = buildMarker(kind, radiusKm, this.maxTopLevelSemiMajorAxisAu, appearance);
|
||||
const marker = buildMarker(kind, radiusKm, appearance);
|
||||
this.object.add(orbitLine, marker);
|
||||
this.trackDisposable(orbitLine.geometry, orbitLine.material as THREE.Material);
|
||||
this.trackDisposable(marker.geometry, marker.material as THREE.Material);
|
||||
@@ -395,7 +397,9 @@ export class SystemOrbitsRenderer {
|
||||
): TrackedMoon {
|
||||
const pivot = new THREE.Group();
|
||||
const orbitLine = buildOrbitLine(elements, 'moon', frame);
|
||||
const marker = buildMarker('moon', radiusKm, this.maxTopLevelSemiMajorAxisAu, appearance);
|
||||
// A moon's own orbit is the thing it must not swallow: drawn at the system's exaggeration it
|
||||
// is the same size as its planet, and every moon here orbits inside one.
|
||||
const marker = buildMarker('moon', radiusKm, appearance);
|
||||
pivot.add(orbitLine, marker);
|
||||
this.object.add(pivot);
|
||||
this.trackDisposable(orbitLine.geometry, orbitLine.material as THREE.Material);
|
||||
|
||||
Reference in New Issue
Block a user