Fix what the review of this branch found, starting with the pick rule it only claimed
The off-screen rule for clicks was described in 3f0abf8 and in the pull request, but only its
comment was committed: pickAt still let the slop reach past the frame. The mutant that was said
to catch it matched nothing, and an unrelated flaky test failed instead. The frame test is now in
pickAt, before the slop, and its test fails without it (star at NDC 1.01, click at 0.995).
Venus, Uranus and Pluto turned forwards: Horizons states a retrograde spin twice, by a negative
rate and by an obliquity over 90 degrees, and both were applied. The period's sign is now used
only when no obliquity is known. Measured on the live markers, spin axis against orbit normal is
cos(obliquity) for each: Venus -0.999, Uranus -0.135, Pluto -0.494, Earth 0.917.
Moons listed as rates rather than "Synchronous" drifted about 5 degrees an orbit and Titan did not
turn: every moon is now locked at its Kepler period. Pluto's obliquity comes from IAU WGCCRE 2015,
Horizons gives none.
Also:
- the star's light is white at pi, not a warm 2.2 that left the photographs dim;
- procedural textures are 128x64, not 512x256 that froze the main thread ~60 ms a body;
- Io, Pluto, Titan and Deimos lose their "maps", which were disc photographs with black sky;
- an exoplanet with only a mass gets a radius from it (M^0.55, capped at Jupiter), not Earth's;
- the clock knows when it has left the present even once back at real time, so the date and
"Back to now" stay up.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,8 +30,9 @@ export interface BodyRecord {
|
||||
*/
|
||||
parentBodyId?: string;
|
||||
/**
|
||||
* How the body turns on its own axis: the sidereal rotation period in hours, negative where it
|
||||
* turns retrograde (Venus, Triton), and the tilt of that axis from its orbital plane.
|
||||
* How the body turns on its own axis: the sidereal rotation period in hours, negative where
|
||||
* Horizons gives a negative rate (Venus, Uranus), and the tilt of that axis from its orbital
|
||||
* plane — which past 90 degrees already says the turn is retrograde.
|
||||
*
|
||||
* Absent where Horizons publishes neither — the view then leaves the body still rather than
|
||||
* spinning it at an invented rate.
|
||||
|
||||
@@ -4,18 +4,21 @@ import * as THREE from 'three/webgpu';
|
||||
* Real NASA/ESA/USGS photography baked into `src/assets/textures/bodies/` at build time,
|
||||
* keyed by the same ids used in `bodies.json`.
|
||||
*
|
||||
* This map is the whole of what has actually been photographed. Everything else — every
|
||||
* exoplanet, since not one has ever been imaged, and the moons no probe returned a usable map
|
||||
* of — falls through to `procedural-planet-texture.ts`, which derives a surface from the body's
|
||||
* own measured size, mass, orbit and host star instead.
|
||||
* Only surface *maps* belong here: equirectangular images, twice as wide as tall, that wrap a
|
||||
* sphere. Everything else — every exoplanet, since not one has ever been imaged, and every moon
|
||||
* or dwarf planet with no such map in the repository — falls through to
|
||||
* `procedural-planet-texture.ts`, which derives a surface from the body's own measured size,
|
||||
* mass, orbit and host star instead.
|
||||
*
|
||||
* Provenance (all public domain NASA/JPL or CC BY 4.0 Solar System Scope, via Wikimedia
|
||||
* Commons — see each file's Commons page for the original credit line):
|
||||
* mercury/venus/earth/mars/saturn/uranus/neptune/moon/sun/saturn-ring/skybox — Solar System
|
||||
* Scope texture pack (CC BY 4.0); jupiter — Solar System Scope 8k pack (CC BY 4.0); pluto —
|
||||
* NASA/JHUAPL/SwRI New Horizons true-color mosaic; deimos — NASA/JPL/University of Arizona
|
||||
* MRO HiRISE; io — NASA/JPL Galileo highest-resolution true-color mosaic; titan — NASA/JPL
|
||||
* Cassini true-color view.
|
||||
* Io, Pluto, Titan and Deimos used to be listed with the square photographs of them in
|
||||
* `assets/textures/bodies/`: pictures of a lit disc against black sky, not maps. Wrapped round a
|
||||
* sphere they put black sky on a fifth to a third of the surface, in a band up to 57 degrees wide
|
||||
* across the equator that the spin then swept past the camera. They are left out until a real map
|
||||
* of each is added.
|
||||
*
|
||||
* Provenance (CC BY 4.0 Solar System Scope, via Wikimedia Commons — see each file's Commons page
|
||||
* for the original credit line): mercury/venus/earth/mars/saturn/uranus/neptune/moon/sun/
|
||||
* saturn-ring/skybox — Solar System Scope texture pack; jupiter — Solar System Scope 8k pack.
|
||||
*/
|
||||
const BODY_TEXTURE_PATHS: Record<string, string> = {
|
||||
mercury: 'assets/textures/bodies/mercury.jpg',
|
||||
@@ -26,11 +29,7 @@ const BODY_TEXTURE_PATHS: Record<string, string> = {
|
||||
saturn: 'assets/textures/bodies/saturn.jpg',
|
||||
uranus: 'assets/textures/bodies/uranus.jpg',
|
||||
neptune: 'assets/textures/bodies/neptune.jpg',
|
||||
pluto: 'assets/textures/bodies/pluto.jpg',
|
||||
moon: 'assets/textures/bodies/moon.jpg',
|
||||
deimos: 'assets/textures/bodies/deimos.jpg',
|
||||
io: 'assets/textures/bodies/io.jpg',
|
||||
titan: 'assets/textures/bodies/titan.jpg'
|
||||
moon: 'assets/textures/bodies/moon.jpg'
|
||||
};
|
||||
|
||||
/** The Sun isn't a `BodyRecord` (it's the system's star marker), so it's looked up separately. */
|
||||
|
||||
@@ -48,6 +48,18 @@ describe('TimeStore', () => {
|
||||
expect(time.julianDate() - afterTwoDays).toBeLessThan(1 / 24);
|
||||
});
|
||||
|
||||
it('knows the map is away from now even once it is back at real time', () => {
|
||||
expect(time.atNow()).toBe(true);
|
||||
time.setRate(2_629_800);
|
||||
vi.advanceTimersByTime(5000);
|
||||
time.setRate(1);
|
||||
|
||||
// Real time, months ahead: the rate says nothing about where the clock stands.
|
||||
expect(time.atNow()).toBe(false);
|
||||
time.reset();
|
||||
expect(time.atNow()).toBe(true);
|
||||
});
|
||||
|
||||
it('comes back to now, at real time', () => {
|
||||
time.setRate(2_629_800);
|
||||
vi.advanceTimersByTime(5000); // months away
|
||||
|
||||
@@ -38,6 +38,11 @@ const JULIAN_DATE_AT_EPOCH = 2440587.5;
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class TimeStore {
|
||||
readonly rate = signal<number>(TIME_RATES[0].secondsPerSecond);
|
||||
/**
|
||||
* Whether the map is drawn for the present. Not the same as a rate of one: after an excursion at
|
||||
* a month a second, real time carries on from months ahead, and the map is still away from now.
|
||||
*/
|
||||
readonly atNow = signal(true);
|
||||
|
||||
private anchorJd = dateToJulianDate();
|
||||
private anchorWallMs = Date.now();
|
||||
@@ -62,6 +67,9 @@ export class TimeStore {
|
||||
this.anchorJd = this.julianDate();
|
||||
this.anchorWallMs = Date.now();
|
||||
this.rate.set(secondsPerSecond);
|
||||
if (secondsPerSecond !== 1) {
|
||||
this.atNow.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
/** Back to now, at real time — the state the map opens in. */
|
||||
@@ -69,5 +77,6 @@ export class TimeStore {
|
||||
this.anchorJd = dateToJulianDate();
|
||||
this.anchorWallMs = Date.now();
|
||||
this.rate.set(TIME_RATES[0].secondsPerSecond);
|
||||
this.atNow.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user