Files
gods-eye-view/src/data/trafficPresetStyle.js
T
Said Turksever 39a60b4034 Remove the Snow visual preset
Snow is no longer offered anywhere a style can be chosen: the Visual
Presets tray, keyboard shortcut 7, the Cockpit vision carousel, and the
set_visual_style voice action. The shader and its labels go with it;
weather snowfall and the SNOW weather condition are unaffected.

Share links keep working. Snow's enum code (6) stays reserved, so a
compact or long-form link that names it opens on Normal and drops the
Snow shader parameters without reporting them as unknown. A Scene
Director shot saved with Snow plays on Normal too. Snow's frozen share
defaults matched Normal's apart from those parameters, so no other
setting in an old link changes meaning.

The legacy voice-schema pins restore Snow before hashing, so the
unchanged pins still prove nothing else moved; the complete Realtime
payload digest is re-derived.
2026-10-29 11:20:49 +00:00

151 lines
6.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file Preset-aware traffic dot styling — pure lookup tables mapping the
* active post-FX style (StyleManager preset name) + congestion bucket to a
* dot treatment the shaders cannot destroy.
*
* Why: traffic dots are in-scene PointPrimitives, so they pass THROUGH the
* post-FX shaders (unlike the detection/FIRMS canvases composited above
* them). NVG and FLIR reduce the scene to luminance (hue is discarded), and
* the shipped bucket palette's Rec.601 luma ordering is free 0.58 / slow
* 0.72 / jam 0.49 — under NVG a jam renders DIMMER than free flow. CRT
* keeps hue but its 5-px pixelation + dithering shred 4–6 px dots.
*
* Encoding per profile (owner verdict 2026-07-23 round 2: "just bright
* dots" — a luminance RAMP failed in the field because dim free-flow dots
* read as dark holes on NVG-bright roads; classification is the detection
* brackets' job via `trafficBucketTier`, presence is the dots' job):
* - `mono` (surveillance/NVG, thermal/FLIR, noir): every colored dot is a
* bright white core with a thin black halo (local contrast survives any
* luma mapping, including Ironbow where white stays the hottest end);
* jam keeps a size bump so queues read as fat beads.
* - `crt` (retro): saturated primaries that survive 10-level posterization
* plus an all-bucket size boost to out-shout the pixel grid.
* - `normal` (normal/anime/unknown): every lookup returns null/0 —
* the shipped palette and sizing apply untouched.
*
* Sim/uncovered dots (bucket null/'sim') are NEVER restyled under any
* style: the keyless simulation path stays byte-identical (qa-traffic
* gate v), and white is already luminance-legible everywhere.
*
* Cesium-free so the tables are unit-testable; traffic.js maps tuples to
* Cesium colors at spawn/restyle time (see `trafficFlowStyle.js` pattern).
*
* @module data/trafficPresetStyle
*/
/** @const {Object<string,'mono'|'crt'>} Style name → non-normal profile. */
const PROFILE_BY_STYLE = {
surveillance: 'mono', // NVG — P43 phosphor × luma
thermal: 'mono', // FLIR — grayscale/ironbow × luma
noir: 'mono', // full desaturation
retro: 'crt', // CRT — hue survives, small dots don't
};
/**
* Per-profile bucket treatments: rgba ([r,g,b] 0–255 + alpha 0–1) and the
* pixel-size delta added ON TOP of the shipped sizing (which already gives
* jam +1). Mono luma: jam 1.00 / slow 0.70 / free 0.36.
* @const {Object<string, Object<string, {rgba:number[], sizeDelta:number}>>}
*/
const DOT_STYLE = {
mono: {
jam: {
rgba: [255, 255, 255, 0.95],
sizeDelta: 3,
outline: { rgba: [0, 0, 0, 0.9], width: 2 },
},
slow: {
rgba: [255, 255, 255, 0.9],
sizeDelta: 1,
outline: { rgba: [0, 0, 0, 0.85], width: 1 },
},
free: {
rgba: [255, 255, 255, 0.85],
sizeDelta: 0,
outline: { rgba: [0, 0, 0, 0.8], width: 1 },
},
},
crt: {
jam: {
rgba: [255, 59, 48, 0.95],
sizeDelta: 3,
outline: { rgba: [0, 0, 0, 0.9], width: 2 },
},
slow: {
rgba: [255, 179, 0, 0.92],
sizeDelta: 2,
outline: { rgba: [0, 0, 0, 0.85], width: 1 },
},
free: { rgba: [0, 255, 102, 0.9], sizeDelta: 1, outline: null },
},
};
/**
* Classify a StyleManager preset name into a traffic styling profile.
* @param {string|null|undefined} styleName - Active style (e.g. 'surveillance').
* @returns {'normal'|'mono'|'crt'} Styling profile; unknown → 'normal'.
*/
export function trafficStyleProfile(styleName) {
return PROFILE_BY_STYLE[styleName] || 'normal';
}
/**
* Preset dot color for a congestion bucket, or null to keep the shipped
* FLOW_BUCKET_COLORS value. Null/'sim' buckets always return null.
* @param {string|null|undefined} styleName - Active style name.
* @param {'free'|'slow'|'jam'|'sim'|null|undefined} bucket - Flow bucket.
* @returns {number[]|null} [r,g,b,a] with rgb 0–255, alpha 0–1, or null.
*/
export function presetDotRgba(styleName, bucket) {
const entry = DOT_STYLE[trafficStyleProfile(styleName)]?.[bucket];
return entry ? entry.rgba : null;
}
/**
* Pixel-size delta a preset adds on top of the shipped dot sizing.
* @param {string|null|undefined} styleName - Active style name.
* @param {'free'|'slow'|'jam'|'sim'|null|undefined} bucket - Flow bucket.
* @returns {number} Pixels to add (0 under the normal profile / sim dots).
*/
export function presetSizeDelta(styleName, bucket) {
const entry = DOT_STYLE[trafficStyleProfile(styleName)]?.[bucket];
return entry ? entry.sizeDelta : 0;
}
/**
* Dark halo for a preset dot, or null for none. Why: NVG auto-gain pushes
* the whole scene near saturation, so a bright dot has almost no contrast
* against a bright road — a dark outline restores LOCAL contrast, which
* every luma-mapping shader preserves. Null under the normal profile and
* for sim dots (shipped dots never draw outlines).
* @param {string|null|undefined} styleName - Active style name.
* @param {'free'|'slow'|'jam'|'sim'|null|undefined} bucket - Flow bucket.
* @returns {{rgba:number[], width:number}|null} Outline spec or null.
*/
export function presetDotOutline(styleName, bucket) {
const entry = DOT_STYLE[trafficStyleProfile(styleName)]?.[bucket];
return entry?.outline || null;
}
/**
* Detection-overlay tier key for a traffic contact's flow bucket. The
* detection canvas composites ABOVE the post-FX chain, so tier colors are
* literal screen RGB in every preset — the brackets carry the congestion
* classification the in-scene dots can no longer encode under mono
* presets. Per-theme colors live in detection.js THEME_MAP `tiers`
* (veh_jam / veh_slow / veh_free / veh_nodata).
*
* Callers pass 'sim' for LIVE-mode roads TomTom has no data for; in
* keyless mode they must pass null so contacts keep the stock 'vehicle'
* tier — the keyless experience stays byte-identical.
*
* @param {'free'|'slow'|'jam'|'sim'|null|undefined} bucket - Flow bucket.
* @returns {string|null} Tier key, or null (no override → stock 'vehicle').
*/
export function trafficBucketTier(bucket) {
if (bucket === 'free' || bucket === 'slow' || bucket === 'jam')
return `veh_${bucket}`;
if (bucket === 'sim') return 'veh_nodata';
return null;
}