Test that a photograph shows in its own colours once it reaches its body

Since 2d4b8a9 a photographed marker is built in its kind's flat colour (a planet's 0.55, 0.75, 1.0,
a moon's 0.75 grey, a dwarf planet's 0.8, 0.7, 0.55) and only showNextPhotograph sets it back to
white when the map goes on. The material multiplies its map by its colour, so without that one line
every photograph would be tinted: each planet's turned blue, Mars's red cut by 45 per cent. The
review's mutant that drops it passed all 835 tests; the photographs test only looked at the map.

The test now also reads each material's colour: the kind's colour before the image loads, and
0xffffff for both bodies once their maps are on. Controls, each failing that test only (1 failed,
836 passed): showNextPhotograph without the white reset; and the marker built white from the start.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-29 21:16:04 +02:00
co-authored by Claude Opus 5.5
parent 20c34f9662
commit 85cb66e63c
@@ -450,7 +450,7 @@ describe('rotation without IAU elements', () => {
}); });
describe('photographs', () => { describe('photographs', () => {
it('puts them on their bodies once loaded, one a frame, so the GPU is not handed every map at once', () => { it('puts them on their bodies once loaded, one a frame, so the GPU is not handed every map at once, and in their own colours', () => {
// Ids no other test here draws, since the loaded textures are shared through the cache. // Ids no other test here draws, since the loaded textures are shared through the cache.
const ids = ['ganymede', 'callisto']; const ids = ['ganymede', 'callisto'];
const records: BodyRecord[] = ids.map((id, index) => ({ const records: BodyRecord[] = ids.map((id, index) => ({
@@ -459,10 +459,14 @@ describe('photographs', () => {
rates: keplerRates(1 + index, GM_SUN_AU3_PER_DAY2) rates: keplerRates(1 + index, GM_SUN_AU3_PER_DAY2)
})); }));
const renderer = new SystemOrbitsRenderer(records, []); const renderer = new SystemOrbitsRenderer(records, []);
const maps = (): Array<THREE.Texture | null> => renderer.members.map((member) => ((member.marker as THREE.Mesh).material as THREE.MeshStandardMaterial).map); const materials = (): THREE.MeshStandardMaterial[] => renderer.members.map((member) => (member.marker as THREE.Mesh).material as THREE.MeshStandardMaterial);
const maps = (): Array<THREE.Texture | null> => materials().map((material) => material.map);
const colours = (): number[] => materials().map((material) => material.color.getHex());
renderer.update(DEFAULT_EPOCH_JD); renderer.update(DEFAULT_EPOCH_JD);
expect(maps()).toEqual([null, null]); // not loaded yet: jsdom never loads an image expect(maps()).toEqual([null, null]); // not loaded yet: jsdom never loads an image
// Until then each is its kind's flat colour, a planet's pale blue.
expect(colours()).toEqual([new THREE.Color(0.55, 0.75, 1).getHex(), new THREE.Color(0.55, 0.75, 1).getHex()]);
for (const id of ids) { for (const id of ids) {
loadCachedTexture(bodyTexturePath(id)!).image = { width: 2, height: 1 }; loadCachedTexture(bodyTexturePath(id)!).image = { width: 2, height: 1 };
@@ -471,6 +475,9 @@ describe('photographs', () => {
expect(maps().filter(Boolean)).toHaveLength(1); expect(maps().filter(Boolean)).toHaveLength(1);
renderer.update(DEFAULT_EPOCH_JD); renderer.update(DEFAULT_EPOCH_JD);
expect(maps()).toEqual(ids.map((id) => loadCachedTexture(bodyTexturePath(id)!))); expect(maps()).toEqual(ids.map((id) => loadCachedTexture(bodyTexturePath(id)!)));
// The material multiplies its map by its colour: left pale blue, every planet's photograph would
// be tinted, Mars's red cut by 45 per cent.
expect(colours()).toEqual([0xffffff, 0xffffff]);
renderer.dispose(); renderer.dispose();
}); });
}); });