mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-10 18:59:56 +00:00
feat(highway_3d): colour theming — string presets + Background/Highway scene themes (#596)
* feat(highway_3d): add one-click string-color presets
Adds 12 named string-color presets (Warm→Cool, Vivid, Colorblind-friendly,
Neon, Accessible, Warm Ember, Tape Deck, CRT Green/Amber, Pitch Ramp, Sunrise)
selectable from the 3D Highway settings panel.
Extends the existing core HWC (highway-color) subsystem in static/app.js with
HWC_PRESETS + applyHighwayStringPreset(), exposed on the existing facade as
window.feedBack.highwayColors.{presets, applyPreset}. The plugin settings page
renders the preset buttons from that core list and refreshes the per-string
pickers on apply. Purely additive — stock behavior is unchanged.
Scope: core static/app.js (the shared HWC facade both highways consume) plus the
highway_3d plugin's settings.html / screen.js / CLAUDE.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Q9BpGYqUaga9ZJyS3dDPq
* fix(highway_3d): address review of colour-theming PR
- Rebuild assets/plugin.css so the new `flex-wrap` (preset row) and
`text-[10px]` (theme-dropdown helper) Tailwind classes are actually
compiled, and bump plugin.json 3.26.0 -> 3.27.0 so the <link>'s ?v=
cache-buster fetches the fresh CSS (per the plugin's build rule).
- Replace the mirror-at-every-read hwTheme migration with a one-time
backfill (persist hwTheme := bgTheme on first load, no emit). The two
scene-color axes are now genuinely independent: changing the Background
dropdown no longer silently retints the Highway surface/lane, and the
rendered highway can't disagree with the Highway dropdown value.
- Collapse the duplicated theme id-set in settings.html (two identical
<option> lists + VALID_BG_THEMES) into a single SCENE_THEMES source the
dropdowns and validator are generated from; sync points 4 -> 2.
- Update CLAUDE.md to document the backfill + reduced sync contract.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: byrongamatos <xasiklas@gmail.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
byrongamatos
parent
b70fde9b02
commit
97dae88860
@@ -1123,7 +1123,7 @@
|
||||
return _bgBandsCache;
|
||||
}
|
||||
|
||||
const BG_DEFAULTS = { style: 'particles', intensity: 0.5, reactive: true, palette: 'default', showFretOnNote: true, fretNumberGhostScope: 'chords', cameraSmoothing: 0.5, zoomSmoothing: 0.5, tiltSmoothing: 0.5, cameraLockLow: false, cameraLockZoom: 0.5, cameraMode: 'lookahead', nutHeadstockVisible: true, tuningLabelsVisible: true, nutColor: '#f5f3f0', headstockColor: '#d4b48a', textSize: 0.5, vibrancy: 0.85, glow: 0.25, customImageDataUrl: '', customImageName: '', customVideoName: '', chordDiagramVisible: true, chordDiagramSize: 0.5, chordDiagramPosition: 'tl', fretColumnMarkerCadence: 1, projectionVisible: true, inlayLabelsVisible: false, sectionLabelsOnHighway: false, sectionHudVisible: false, sectionHudPosition: 'tr', sectionHudSize: 0.5, toneHudVisible: false, toneHudPosition: 'tl', toneHudSize: 0.5, fpsVisible: false, fretDividersVisible: true, slideArrowApproachVisible: true, slideArrowNeckVisible: true, slideArrowChainPreviewVisible: true };
|
||||
const BG_DEFAULTS = { style: 'particles', intensity: 0.5, reactive: true, palette: 'default', bgTheme: 'default', hwTheme: 'default', showFretOnNote: true, fretNumberGhostScope: 'chords', cameraSmoothing: 0.5, zoomSmoothing: 0.5, tiltSmoothing: 0.5, cameraLockLow: false, cameraLockZoom: 0.5, cameraMode: 'lookahead', nutHeadstockVisible: true, tuningLabelsVisible: true, nutColor: '#f5f3f0', headstockColor: '#d4b48a', textSize: 0.5, vibrancy: 0.85, glow: 0.25, customImageDataUrl: '', customImageName: '', customVideoName: '', chordDiagramVisible: true, chordDiagramSize: 0.5, chordDiagramPosition: 'tl', fretColumnMarkerCadence: 1, projectionVisible: true, inlayLabelsVisible: false, sectionLabelsOnHighway: false, sectionHudVisible: false, sectionHudPosition: 'tr', sectionHudSize: 0.5, toneHudVisible: false, toneHudPosition: 'tl', toneHudSize: 0.5, fpsVisible: false, fretDividersVisible: true, slideArrowApproachVisible: true, slideArrowNeckVisible: true, slideArrowChainPreviewVisible: true };
|
||||
// User-selectable, persistable bg styles — must mirror settings.html's
|
||||
// VALID_STYLES. 'venue' is deliberately NOT here: it is an internal effective
|
||||
// style reached only via _venueSceneOverride (the viz-picker Venue flow), so
|
||||
@@ -1131,6 +1131,83 @@
|
||||
// mount outside that flow and settings.html (which can't represent 'venue')
|
||||
// would be unable to switch back. BG_STYLES still has a 'venue' renderer entry.
|
||||
const BG_STYLE_IDS = ['off', 'particles', 'silhouettes', 'lights', 'geometric', 'image', 'video'];
|
||||
// Scene color themes — TWO INDEPENDENT AXES sharing one palette family.
|
||||
// The combined `BG_THEMES` table below is the single source of truth; each
|
||||
// entry carries the colors for BOTH axes, but the two axes are selected and
|
||||
// applied SEPARATELY (two dropdowns, two settings keys):
|
||||
// • BACKGROUND axis (setting key `bgTheme`) owns:
|
||||
// clear — WebGL clear color (the empty background behind everything)
|
||||
// fog — distance fog tint (kept === clear so the horizon dissolves
|
||||
// cleanly instead of showing a seam)
|
||||
// • HIGHWAY axis (setting key `hwTheme`) owns:
|
||||
// board — the fretboard / highway-surface plane color
|
||||
// lane — the lit highway lane strip under the gems (optional)
|
||||
// laneDim — the lane's dimmer alternating row (optional)
|
||||
// Because both axes read from the SAME id-set (the keys of this table), ANY
|
||||
// background id can mix with ANY highway id (e.g. Deep Focus background +
|
||||
// Cathode Green highway); picking the SAME id in both gives the original
|
||||
// "matched" combined look. _bgBackgroundColors()/_bgHighwayColors() below
|
||||
// are the per-axis accessors; both fall back to 'default' for unknown ids.
|
||||
// 'default' reproduces the original look byte-for-byte on BOTH axes, so
|
||||
// existing users (and anyone who never touches either setting) see no
|
||||
// change. A migration in _bgLoadSettings() makes an existing single-`bgTheme`
|
||||
// pick drive BOTH axes until the user diverges them, so upgrades are
|
||||
// visually identical too. All themes keep the board very dark and the
|
||||
// background dark so the bright per-string note gems, lane, and labels
|
||||
// retain contrast. NOTE: settings.html mirrors these ids in its
|
||||
// VALID_BG_THEMES set (shared by both dropdowns) — keep them in sync.
|
||||
// Optional `lane` / `laneDim` fields retint the lit highway lane strip + its
|
||||
// dimmer alternating row. A theme that omits them falls back to the stock
|
||||
// blue lane (HWY_LANE_STRIPE_ODD_HEX / _EVEN_HEX); only 'default' relies on
|
||||
// that fallback (so its output stays byte-identical). Every other theme sets
|
||||
// its own lane so the Highway axis is visibly distinct entry-to-entry — the
|
||||
// near-black neutral boards alone aren't separable, so the lane carries it.
|
||||
// See _applyBgTheme().
|
||||
const BG_THEMES = {
|
||||
default: { clear: 0x101820, fog: 0x101820, board: 0x08080e },
|
||||
// Cool navy surface + a brighter pure-blue lane, so it reads distinct
|
||||
// from 'default' (neutral board + stock teal-blue lane) on the Highway axis.
|
||||
midnight: { clear: 0x0a0e1a, fog: 0x0a0e1a, board: 0x080d1c, lane: 0x244fae, laneDim: 0x122a5e },
|
||||
// Lighter NEUTRAL-grey surface + a steel-grey lane — the only mid-dark
|
||||
// neutral board, so the surface itself is visibly different from the
|
||||
// near-black neutrals around it (board kept dark enough for gem contrast).
|
||||
charcoal: { clear: 0x16181c, fog: 0x16181c, board: 0x141417, lane: 0x525a66, laneDim: 0x282d34 },
|
||||
deeppurple: { clear: 0x140a1e, fog: 0x140a1e, board: 0x0b0610, lane: 0x3a1f6e, laneDim: 0x1f1040 },
|
||||
forest: { clear: 0x0a1614, fog: 0x0a1614, board: 0x06100c, lane: 0x15602a, laneDim: 0x0a3318 },
|
||||
// Warm dark neutral (espresso/umber) — the first non-cool scene.
|
||||
warmslate: { clear: 0x1c130b, fog: 0x1c130b, board: 0x0e0805, lane: 0x5e3a12, laneDim: 0x341f0a },
|
||||
// Recessive near-black neutral (a hair above #000000, ~zero chroma) —
|
||||
// maximizes gem-vs-board contrast; a clean stage/stream look. Purest-dark
|
||||
// board + a clean steel-cyan lane (brighter/cooler than 'default's muted
|
||||
// teal-blue) so the Highway axis reads clearly distinct from default.
|
||||
deepfocus: { clear: 0x0c0c0d, fog: 0x0c0c0d, board: 0x060606, lane: 0x2f7fa0, laneDim: 0x163c4e },
|
||||
// Calm dark teal — blue-dominant so it reads distinct from the navy
|
||||
// 'midnight' and the green 'forest'.
|
||||
deepsea: { clear: 0x06222b, fog: 0x06222b, board: 0x03141a, lane: 0x0e5a63, laneDim: 0x063338 },
|
||||
// Retro CRT glow — a warm AMBER phosphor cast (the classic amber
|
||||
// terminal). Amber rather than green so a phosphor board can't crush
|
||||
// green/teal gems, and so it stays clearly distinct from 'forest' and
|
||||
// 'deepsea'. Board stays very dark / low-chroma to keep gems popping.
|
||||
cathode: { clear: 0x140b03, fog: 0x140b03, board: 0x0c0702, lane: 0x6e4a0e, laneDim: 0x3a2806 },
|
||||
// Retro CRT GREEN phosphor — leaned more saturated / cyan-green than
|
||||
// 'forest' so it reads as a terminal, not woodland (dRGB 35 vs forest,
|
||||
// 32 vs deepsea). Phosphor-green board + green lane. Verified to keep
|
||||
// green/teal gems legible (green-on-green floor CR ~2.2).
|
||||
cathodegreen: { clear: 0x07301a, fog: 0x07301a, board: 0x031a0c, lane: 0x0e6e2a, laneDim: 0x073a18 },
|
||||
// Warm hearth — the first warm-RED scene, pairs with the Ember/Sunrise
|
||||
// strings. Deep red, pushed away from the amber 'cathode'/'warmslate'
|
||||
// (dRGB ~26 from cathode). Ember-red lane.
|
||||
hearth: { clear: 0x280806, fog: 0x280806, board: 0x1a0606, lane: 0x7a2410, laneDim: 0x3f1409 },
|
||||
};
|
||||
const BG_THEME_IDS = Object.keys(BG_THEMES);
|
||||
// Shared lookup for the combined entry (both axes are keyed by the same id
|
||||
// set, so a single id list / coerce check validates either axis).
|
||||
function _bgThemeColors(id) { return BG_THEMES[id] || BG_THEMES.default; }
|
||||
// Per-axis accessors. Background reads clear/fog; highway reads
|
||||
// board/lane/laneDim. They alias the same table — splitting at read-time
|
||||
// keeps one source of truth while letting the two dropdowns pick freely.
|
||||
function _bgBackgroundColors(id) { return _bgThemeColors(id); }
|
||||
function _bgHighwayColors(id) { return _bgThemeColors(id); }
|
||||
const VENUE_SCENE_ASSET_BASE = '/static/assets/venue/themes/small-club/';
|
||||
const VENUE_BG_PLATE_PNG = 'bg-plate.png';
|
||||
const VENUE_BG_PLATE_WEBP = 'bg-plate.webp';
|
||||
@@ -1412,6 +1489,9 @@
|
||||
if (_BG_BOOL_KEYS.has(key)) return _bgCoerceBool(val, BG_DEFAULTS[key]);
|
||||
if (key === 'style') return BG_STYLE_IDS.includes(val) ? val : BG_DEFAULTS.style;
|
||||
if (key === 'palette') return (PALETTE_IDS.includes(val) || val === 'custom') ? val : BG_DEFAULTS.palette;
|
||||
if (key === 'bgTheme') return BG_THEME_IDS.includes(val) ? val : BG_DEFAULTS.bgTheme;
|
||||
// Highway axis shares the same id-set as the background axis.
|
||||
if (key === 'hwTheme') return BG_THEME_IDS.includes(val) ? val : BG_DEFAULTS.hwTheme;
|
||||
if (key === 'chordDiagramPosition')
|
||||
return CHORD_DIAG_POSITION_IDS.includes(val) ? val : BG_DEFAULTS.chordDiagramPosition;
|
||||
if (key === 'sectionHudPosition')
|
||||
@@ -1483,6 +1563,20 @@
|
||||
window.h3dBgSetIntensity = (v) => _bgWriteGlobal('intensity', v);
|
||||
window.h3dBgSetReactive = (v) => _bgWriteGlobal('reactive', !!v);
|
||||
window.h3dBgSetPalette = (v) => _bgWriteGlobal('palette', v);
|
||||
// BACKGROUND scene-color axis (clear + fog only). Validated against
|
||||
// BG_THEME_IDS in _bgCoerce; the listener re-applies clear/fog live and
|
||||
// independently of the highway axis.
|
||||
window.h3dBgSetBgTheme = (v) => {
|
||||
const s = String(v);
|
||||
_bgWriteGlobal('bgTheme', BG_THEME_IDS.includes(s) ? s : BG_DEFAULTS.bgTheme);
|
||||
};
|
||||
// HIGHWAY scene-color axis (board + lane + laneDim). Same id-set as the
|
||||
// background axis, so any highway can mix with any background. The listener
|
||||
// re-applies the board plane + lane live and independently.
|
||||
window.h3dBgSetHwTheme = (v) => {
|
||||
const s = String(v);
|
||||
_bgWriteGlobal('hwTheme', BG_THEME_IDS.includes(s) ? s : BG_DEFAULTS.hwTheme);
|
||||
};
|
||||
// Apply a user-defined per-string color set (core theming UI). `hexArray`
|
||||
// is up to 8 hex strings; invalid/missing entries fall back to the default
|
||||
// palette per index. Writes the colors, then flips the palette to 'custom'
|
||||
@@ -2738,6 +2832,13 @@
|
||||
let bgGroup = null, bgStage = null, bgState = null;
|
||||
let bgMountedStyleId = null;
|
||||
let bgStyleId = 'particles', bgIntensity = 0.5, bgReactive = true;
|
||||
// Active scene color theme (background + highway surface). Read in
|
||||
// _bgLoadSettings, applied by _applyBgTheme (clear + fog + board plane).
|
||||
let bgThemeId = 'default'; // BACKGROUND axis (clear + fog)
|
||||
let hwThemeId = 'default'; // HIGHWAY axis (board + lane + laneDim)
|
||||
// Board (fretboard/highway-surface) plane material — kept so the theme
|
||||
// can recolor it live without rebuilding the board. Set in buildBoard().
|
||||
let _boardPlaneMat = null;
|
||||
// Per-render opt-out for plugins borrowing the highway as a viz: when the
|
||||
// mount bundle sets bgReactive === false, suppress the audio-reactive
|
||||
// background for THIS instance only (no shared h3d_bg_* write). Captured
|
||||
@@ -6220,6 +6321,11 @@
|
||||
|
||||
_bgLoadSettings();
|
||||
buildBoard();
|
||||
// Apply the scene color theme now that settings + board exist. Sets
|
||||
// the clear color + fog tint (board plane was themed in buildBoard).
|
||||
// For the default theme this is identical to the hardcoded values
|
||||
// initScene seeded above, so nothing changes for existing users.
|
||||
_applyBgTheme();
|
||||
|
||||
// Background animations (#13). Read settings keyed by this
|
||||
// panel and mount the active style's meshes. Subscribe to
|
||||
@@ -6337,6 +6443,17 @@
|
||||
if (bgStyleId === 'lights') _bgRebuild();
|
||||
return;
|
||||
}
|
||||
if (changedKey === 'bgTheme' || changedKey === 'hwTheme') {
|
||||
// A scene-color axis changed (background = bgTheme:
|
||||
// clear+fog; highway = hwTheme: board plane + lane). Recolor
|
||||
// in place — no mesh rebuild needed (the board plane material
|
||||
// is mutated via _boardPlaneMat, the lane via mLaneOdd/Even).
|
||||
// _applyBgTheme reapplies both axes from their own keys, so
|
||||
// changing one dropdown retints only its half.
|
||||
_bgLoadSettings();
|
||||
_applyBgTheme();
|
||||
return;
|
||||
}
|
||||
if (changedKey === 'customImageDataUrl') {
|
||||
// Asset bytes changed. Rebuild only when the image
|
||||
// style is active — otherwise the new bytes will
|
||||
@@ -6543,6 +6660,25 @@
|
||||
_bgPaletteSig = newSig;
|
||||
_applyPaletteToMaterials();
|
||||
}
|
||||
bgThemeId = _bgReadSetting(panelKey, 'bgTheme');
|
||||
// Highway axis. ONE-TIME BACKWARD-COMPAT BACKFILL: the first time we
|
||||
// load with no stored hwTheme (pre-split installs, or anyone who only
|
||||
// ever touched the old single "Scene colors" control), seed hwTheme
|
||||
// FROM the background pick AND PERSIST it, so an existing 'cathode'
|
||||
// selection looks byte-identical right after the upgrade. Persisting
|
||||
// immediately (rather than re-inheriting on every read) is what keeps
|
||||
// the two axes truly INDEPENDENT thereafter: once hwTheme is stored,
|
||||
// changing the Background dropdown no longer drags the Highway
|
||||
// surface along, and the settings UI's Highway value can never
|
||||
// disagree with what's rendered. Written without _bgEmitChange so the
|
||||
// backfill can't re-enter the change listener.
|
||||
if (_bgHasStored(panelKey, 'hwTheme')) {
|
||||
hwThemeId = _bgReadSetting(panelKey, 'hwTheme');
|
||||
} else {
|
||||
hwThemeId = bgThemeId;
|
||||
_bgMemFallback.hwTheme = String(bgThemeId);
|
||||
try { localStorage.setItem('h3d_bg_hwTheme', String(bgThemeId)); } catch (_) { /* storage blocked — mem fallback still seeds the read */ }
|
||||
}
|
||||
showFretOnNote = _bgReadSetting(panelKey, 'showFretOnNote');
|
||||
fretNumberGhostScope = _bgReadSetting(panelKey, 'fretNumberGhostScope');
|
||||
cameraSmoothing = _bgReadSetting(panelKey, 'cameraSmoothing');
|
||||
@@ -6916,14 +7052,54 @@
|
||||
if (ren) ren.setClearColor(0x080c12);
|
||||
if (ambLight) ambLight.intensity = 0.68;
|
||||
} else {
|
||||
scene.fog.color.setHex(0x101820);
|
||||
// Restore the user's scene-color theme (clear + fog) rather than
|
||||
// the old hardcoded gray, so deactivating venue doesn't wipe a
|
||||
// chosen background theme. _applyBgTheme reads the current theme.
|
||||
scene.fog.near = FOG_START * 0.8;
|
||||
scene.fog.far = FOG_END * 1.2;
|
||||
if (ren) ren.setClearColor(0x101820);
|
||||
if (ambLight) ambLight.intensity = 0.85;
|
||||
_applyBgTheme();
|
||||
}
|
||||
}
|
||||
|
||||
// Apply BOTH scene-color axes, each from its own setting key:
|
||||
// • BACKGROUND (bgThemeId): the WebGL clear color + the distance-fog
|
||||
// tint. Skipped while the venue scene is active (venue owns those —
|
||||
// see _bgApplyVenueSceneFog).
|
||||
// • HIGHWAY (hwThemeId): the fretboard/highway-surface plane + the lit
|
||||
// highway lane strip (the bright quad under the gems) + its dimmer
|
||||
// alternating row. Always themed; venue doesn't touch them.
|
||||
// The two axes are independent, so picking a different id in each mixes
|
||||
// freely. Safe to call any time; called from initScene, buildBoard, and
|
||||
// the scene-theme listener (so a live switch of EITHER dropdown retints
|
||||
// only its half immediately).
|
||||
//
|
||||
// The lane fields are OPTIONAL on a highway theme: one that omits `lane`
|
||||
// / `laneDim` falls back to the stock lit/dim lane hexes, so every
|
||||
// existing/neutral highway theme stays byte-identical (default blue lane
|
||||
// unchanged). Only colored highway themes opt into a coordinated lane.
|
||||
function _applyBgTheme() {
|
||||
// --- Background axis: clear + fog ---
|
||||
const bg = _bgBackgroundColors(bgThemeId);
|
||||
if (!_venueSceneOverride) {
|
||||
if (scene && scene.fog) scene.fog.color.setHex(bg.fog);
|
||||
if (ren) ren.setClearColor(bg.clear);
|
||||
}
|
||||
// --- Highway axis: board plane + lane ---
|
||||
const hw = _bgHighwayColors(hwThemeId);
|
||||
if (_boardPlaneMat) _boardPlaneMat.color.setHex(hw.board);
|
||||
// Lit lane strip + its dimmer alternating row. Fall back to the
|
||||
// hardcoded stock lane colors when the highway theme omits them.
|
||||
const laneLit = (typeof hw.lane === 'number') ? hw.lane : HWY_LANE_STRIPE_ODD_HEX;
|
||||
const laneDim = (typeof hw.laneDim === 'number') ? hw.laneDim : HWY_LANE_STRIPE_EVEN_HEX;
|
||||
if (mLaneOdd) mLaneOdd.color.setHex(laneLit);
|
||||
if (mLaneEven) mLaneEven.color.setHex(laneDim);
|
||||
// Keep the (otherwise vestigial) lane target color in sync with the
|
||||
// lit lane so any future lane-blend consumer reads the themed value.
|
||||
if (_laneTargetColor) _laneTargetColor.setHex(laneLit);
|
||||
else _laneTargetColor = new T.Color(laneLit);
|
||||
}
|
||||
|
||||
/* ── Fretboard (static geometry) ────────────────────────────────── */
|
||||
function _h3dHexOrDefault(hexStr, defHex) {
|
||||
const d = defHex || BG_DEFAULTS.nutColor;
|
||||
@@ -6967,7 +7143,12 @@
|
||||
// spawn horizon (-AHEAD * TS), so the far edge aligns with AHEAD.
|
||||
const blAhead = TS * AHEAD;
|
||||
const pg = new T.PlaneGeometry(bw, blAhead);
|
||||
const pm = new T.MeshLambertMaterial({ color: 0x08080e, transparent: true, opacity: 0.6 });
|
||||
// Board (highway-surface) color comes from the active HIGHWAY scene
|
||||
// theme (default theme = the original 0x08080e). Kept on
|
||||
// _boardPlaneMat so _applyBgTheme can recolor it live without
|
||||
// rebuilding the board.
|
||||
const pm = new T.MeshLambertMaterial({ color: _bgHighwayColors(hwThemeId).board, transparent: true, opacity: 0.6 });
|
||||
_boardPlaneMat = pm;
|
||||
const p = new T.Mesh(pg, pm);
|
||||
p.rotation.x = -Math.PI / 2;
|
||||
p.position.set(board.center, S_BASE - NH / 2 - 2 * K, -blAhead / 2);
|
||||
@@ -13156,7 +13337,7 @@
|
||||
if (ren) { ren.dispose(); ren = null; }
|
||||
scene = cam = noteG = beatG = lblG = fretG = tuningLblG = null;
|
||||
ambLight = dirLight = null;
|
||||
mStr = []; mGlow = []; mSus = []; mStrHitOutline = []; mAccentOutline = []; mAccentCore = []; mAccentHaloNear = []; mAccentHaloMid = []; mAccentHaloFar = []; _accentShellsByString = []; mWhiteOutline = mSusOutline = null; mMissOutline = null; mHitSusOutline = null; stringLines = []; stringLineGlows = []; fretWireMats = []; fretTubeGeo?.dispose?.(); fretTubeGeo = null;
|
||||
mStr = []; mGlow = []; mSus = []; mStrHitOutline = []; mAccentOutline = []; mAccentCore = []; mAccentHaloNear = []; mAccentHaloMid = []; mAccentHaloFar = []; _accentShellsByString = []; mWhiteOutline = mSusOutline = null; mMissOutline = null; mHitSusOutline = null; stringLines = []; stringLineGlows = []; _boardPlaneMat = null; fretWireMats = []; fretTubeGeo?.dispose?.(); fretTubeGeo = null;
|
||||
for (const m of _inlayMats) m?.dispose?.(); _inlayMats = []; _inlayLabels = [];
|
||||
// mTapChevron: dispose explicitly — if no tap marker ever
|
||||
// spawned a pooled mesh, the scene.traverse() pass above never
|
||||
|
||||
Reference in New Issue
Block a user