Clickable previews: exact app deep-links everywhere
Every rendered still links to the app frame that produced it (song + seed + frame + venue/viz pins + probe warm-up, new window), via shared src/ui/preview.js. Supporting work, each measured: app honors ?frame/?venueSel/?viz/?warm= with pre-build pins (Show.applyPins) and primes deep-link loads; shared pinViz/pinVenueShell paths for gallery, filmstrip and app; probes prime and carry their warm-up; bank probes analyse the bank PCM and file decode is fixed-rate with bit-exact WAV parsing so app and probes see identical samples; materials built mid-update compile synchronously (needsCompile). Round trip verified bit-identical gallery-versus-app.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
// Pin one viz as the subject of every section's stacks.
|
||||
//
|
||||
// The same override in two places: the venue gallery's viz picker and the
|
||||
// app's `?viz=`. One code path, so a gallery card and its app deep-link
|
||||
// render the same pixels — the venue ground (and overlays) stay untouched,
|
||||
// only the subject slot is re-cast. Seeds derive from (viz, section, look
|
||||
// seed), so the pin is stable across rebuilds and identical everywhere.
|
||||
|
||||
import { Rng, hashString } from '../engine/rng.js';
|
||||
import { sampleValues } from '../params/schema.js';
|
||||
import { subjectIndexOf } from './stack.js';
|
||||
import { scenes } from '../scenes/registry.js';
|
||||
|
||||
/**
|
||||
* @param {object} look LookSpec from generateLook (mutated in place)
|
||||
* @param {string} name scene name, e.g. 'Synthwave Corridor'
|
||||
* @returns {object} the pinned scene module
|
||||
*/
|
||||
export function pinViz(look, name) {
|
||||
const viz = scenes.find((s) => s.name === name);
|
||||
if (!viz) throw new Error(`unknown viz "${name}"`);
|
||||
const seedBase = look.seed >>> 0;
|
||||
const temper = look.personality && look.personality.temperament;
|
||||
for (const sec of look.sections) {
|
||||
const rng = new Rng(hashString(`${viz.name}:sec:${sec.index}:${seedBase}`));
|
||||
for (let v = 0; v < (sec.variants || []).length; v++) {
|
||||
const stack = sec.variants[v];
|
||||
if (!stack) continue;
|
||||
const at = subjectIndexOf(stack);
|
||||
const cur = stack[at];
|
||||
if (!cur) continue;
|
||||
stack[at] = {
|
||||
module: viz,
|
||||
params: sampleValues(viz, rng.fork(`variant:${v}`), sec.bias, temper),
|
||||
seed: rng.int(0, 0x7fffffff),
|
||||
// A model viz composites by alpha; a fragment viz needs the
|
||||
// key/screen path over the venue ground. Reuse the old blend
|
||||
// when it already fits, else fall back to the compositor-safe one.
|
||||
blend: viz.kind === 'model' ? 'normal'
|
||||
: (cur.blend === 'normal' ? 'lumakey' : cur.blend),
|
||||
opacity: cur.opacity ?? 1,
|
||||
blaze: cur.blaze ?? false,
|
||||
};
|
||||
}
|
||||
}
|
||||
return viz;
|
||||
}
|
||||
Reference in New Issue
Block a user