Merge main again: readouts built once, said in the instrument's voice
Main moved while the previous merge was being verified. It brought the shared bodyReadouts builder — one source for a body's measured and derived rows, used by the detail page and the system view's new object card — plus the derived-value asterisk in the HUD readout panel. All of that data flow is kept. The templates it arrived in are restyled to this branch's idiom: the info panel and the object card share the same organism (header, full-bleed readout rows, provenance line, route rail), the object card's route rail sits at the bottom because there the route is the next step rather than the way back, and the derived asterisk and its footnote keep their meaning in sentence case. The card also needed the restyle to render at all — it arrived wearing hud-panel, a class the observatory system no longer defines. Verified: build clean, 527/527 unit, 6/6 e2e, design detector clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jxMkwA2rbicdGxHosecYi
This commit is contained in:
@@ -6,9 +6,6 @@ import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
||||
|
||||
import { DataLoaderService } from '../../core/data/data-loader.service';
|
||||
import { EngineService } from '../../core/engine/engine.service';
|
||||
import { appearanceForBody, appearanceForExoplanet } from '../../shared/astro/body-appearance';
|
||||
import { EARTH_RADIUS_KM } from '../../shared/astro/planet-appearance';
|
||||
import { luminositySolar } from '../../shared/astro/stellar';
|
||||
import { planetTexture } from '../../shared/rendering/procedural-planet-texture';
|
||||
import { applyMilkyWaySkybox, createGlowSprite } from '../../shared/rendering/skybox';
|
||||
import { atmosphereColorFor, bodyTexturePath, loadCachedTexture, MILKY_WAY_SKYBOX_PATH, SATURN_RING_TEXTURE_PATH } from '../../shared/rendering/texture-catalog';
|
||||
@@ -17,6 +14,7 @@ import { ExoplanetRecord } from '../../shared/models/exoplanet.model';
|
||||
import { StarRecord } from '../../shared/models/star.model';
|
||||
import { NavigationStore } from '../../shared/state/navigation.store';
|
||||
import { BodyDetailViewModel } from './body-detail.model';
|
||||
import { buildBodyViewModel } from './body-view-model';
|
||||
import { InfoPanelComponent } from './info-panel.component';
|
||||
|
||||
/** Gas giants read as smoother/less rocky than terrestrial bodies under the same lighting rig. */
|
||||
@@ -127,44 +125,18 @@ export class BodyDetailSceneComponent implements AfterViewInit, OnDestroy {
|
||||
return;
|
||||
}
|
||||
|
||||
const body = this.bodies.find((candidate) => candidate.id === id);
|
||||
const exoplanet = this.exoplanets.find((candidate) => candidate.id === id);
|
||||
|
||||
if (body) {
|
||||
const hostStar = this.stars.find((star) => star.id === body.systemStarId);
|
||||
this.viewModel.set({
|
||||
id: body.id,
|
||||
name: body.name,
|
||||
kind: body.kind,
|
||||
hostStarName: hostStar?.name ?? 'Unknown star',
|
||||
radiusKm: body.radiusKm,
|
||||
orbit: body.orbit,
|
||||
appearance: appearanceForBody(body, this.bodies, this.luminosityOf(hostStar)),
|
||||
hasPhotography: bodyTexturePath(body.id) !== undefined
|
||||
});
|
||||
this.navigationStore.selectStar(body.systemStarId);
|
||||
} else if (exoplanet) {
|
||||
const hostStar = this.stars.find((star) => star.id === exoplanet.hostStarId);
|
||||
this.viewModel.set({
|
||||
id: exoplanet.id,
|
||||
name: exoplanet.name,
|
||||
kind: 'exoplanet',
|
||||
hostStarName: exoplanet.hostStarName,
|
||||
radiusKm: exoplanet.radiusEarth ? exoplanet.radiusEarth * EARTH_RADIUS_KM : undefined,
|
||||
massEarth: exoplanet.massEarth,
|
||||
discoveryYear: exoplanet.discoveryYear,
|
||||
orbit: exoplanet.orbit,
|
||||
appearance: appearanceForExoplanet(exoplanet, this.luminosityOf(hostStar)),
|
||||
hasPhotography: bodyTexturePath(exoplanet.id) !== undefined
|
||||
});
|
||||
if (exoplanet.hostStarId !== null) {
|
||||
this.navigationStore.selectStar(exoplanet.hostStarId);
|
||||
}
|
||||
} else {
|
||||
// Shared with the system view's object card, so the same body cannot read differently there.
|
||||
const viewModel = buildBodyViewModel(id, { bodies: this.bodies, exoplanets: this.exoplanets, stars: this.stars });
|
||||
if (!viewModel) {
|
||||
this.viewModel.set(undefined);
|
||||
this.notFound.set(true);
|
||||
return;
|
||||
}
|
||||
this.viewModel.set(viewModel);
|
||||
|
||||
if (viewModel.hostStarId !== undefined) {
|
||||
this.navigationStore.selectStar(viewModel.hostStarId);
|
||||
}
|
||||
|
||||
this.notFound.set(false);
|
||||
this.navigationStore.selectBody(id);
|
||||
@@ -173,18 +145,6 @@ export class BodyDetailSceneComponent implements AfterViewInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The host star's luminosity in solar units, from its own catalogued magnitude and distance.
|
||||
* `null` for an exoplanet whose host never cross-referenced to the star catalogue, which
|
||||
* leaves its planets with no derived temperature rather than a guessed one.
|
||||
*/
|
||||
private luminosityOf(star: StarRecord | undefined): number | null {
|
||||
if (!star) {
|
||||
return null;
|
||||
}
|
||||
return luminositySolar({ magnitude: star.magnitude, distancePc: Math.hypot(star.x, star.y, star.z), spectralType: star.spectralType });
|
||||
}
|
||||
|
||||
private applyViewModelToScene(): void {
|
||||
const viewModel = this.viewModel();
|
||||
if (!viewModel || !this.planetMaterial) {
|
||||
|
||||
Reference in New Issue
Block a user