mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-11 03:09:57 +00:00
- setPixelRatio at last: DPR (cap 2; 1.25 when >1 instance) x host adaptive bundle.renderScale — HiDPI displays were rendering at CSS resolution and upscaling (soft/aliased) - Bloom: port _bloomEnsure/_bloomDispose (UnrealBloomPass 0.65/0.5/0.82, MSAA HalfFloat target, ACES<->None switch); hit-line, flames and consume-glow benefit immediately; direct render is the degrade path - First settings panel: settings.html (graphics category) with a live Glow (bloom) toggle; FX scaffold (FX_DEFAULTS/readFxSettings/ window.keys3dSetFx, keys3d_bg_* keys, keys3d:settings event) - Combo/accuracy/best-streak DOM HUD (drum_highway_3d pattern), gated on a live MIDI session - tests/fx_settings.test.js (3 tests; vm harness) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
38 lines
3.9 KiB
Markdown
38 lines
3.9 KiB
Markdown
# Keys Highway 3D
|
||
|
||
RS+-style falling-note 3D piano highway for [Slopsmith](https://github.com/got-feedback/feedback), fed by the **Sloppak Notation Format** (sloppak-spec §5.3) — part of the piano/keys first-class epic (slopsmith#828, plugin workstream slopsmith#824).
|
||
|
||
- Consumes the `notation_info` / `notation_measures` highway-WS stream over a private per-instance socket and flattens measure → staff → voice → beat → note into `{midi, t, durSec, hand}` (durations derived from written `dur`/`dot`/`tu` at the running tempo; ties extend; overlap-clamped).
|
||
- 3D perspective highway to a vanishing point with a real white/black-key keyboard; per-key **pitch-class colours** (Synthesia convention — C red, D yellow, E blue, …) with hand (rh/lh) as a secondary brightness cue.
|
||
- Full RS+ visual treatment: key **letter glyphs** printed on the active-range key tops (cached CanvasTextures), **bevelled gem-style note blocks** (ExtrudeGeometry, geometry/material caches keyed by size and pitch-class×hand), **floating bar numbers** scrolling with the notes, **active-range lane dimming** so the playable span pops, and a **glowing pulsing hit-line** (layered additive gradient planes — no postprocessing).
|
||
- Performance discipline: no per-frame allocations or DOM queries in `draw()`. Chart-scoped resources — note geometries/materials, bar-number and glow textures — are cached and disposed on chart teardown; the key-letter glyph `CanvasTexture`s live in a shared module-level cache that survives teardown and is reused across instances.
|
||
- Auto-selected for arrangements with notation via `matchesArrangement(songInfo.has_notation)`; capability-native `visualization` provider declaration.
|
||
- **Web MIDI input scoring**: module-level MIDI singleton (one access per tab, focused-instance routing) with device auto-connect by saved id+name, loopback blocklist, channel filter, transpose and CC64 sustain (`keys3d_` localStorage prefix; `window.keysH3d*` settings API). Hit detection matches played MIDI against the flattened chart notes within ±0.10 s with per-note dedupe and a missed-note sweep (only while a device is connected — never retroactive across a mid-song connect).
|
||
- **Live hit feedback on the MIDI path** (not the chart): key depress (~4° back-edge pivot, ~120 ms spring; the key letter rides along), wrong-note red key flash, and a vertical flame flare on hits (pooled additive sprites, white-hot base fading into the pitch-class colour, ~400 ms).
|
||
- **End-of-run stats**: POSTs `/api/stats` `{filename, arrangement, score, accuracy}` exactly once per run with the same formula as the guitar notedetect path (`accuracy = hits / max(1, hits+misses)`, `score = round(hits·100·accuracy)`), then notifies the progression core when present.
|
||
- **Capability wiring** (all guarded for servers without the hosts): registers as a note-detection `midi` provider (`keys-midi`, `verify.target`), opens a per-song binding scoped to the chart's keys range, reports hit/miss observability events, and exposes Web MIDI inputs to the audio-input domain with pseudonymized labels (`midi-input-1`, …) via `source.enumerate/describe/open/close`.
|
||
- Headless test hook: `window.__keysHwTest = { injectNoteOn(midi, when), getScore() }`.
|
||
|
||
## Tests
|
||
|
||
```
|
||
node --test tests/*.test.js
|
||
```
|
||
|
||
## Ported helpers (keep in sync with highway_3d)
|
||
|
||
Visual-parity code copied from `plugins/highway_3d/screen.js` — same
|
||
function names, signatures, and constants on purpose, marked with
|
||
`PORTED FROM highway_3d` comments at each site. If the guitar highway
|
||
tunes one of these, mirror the change here (and in `drum_highway_3d`):
|
||
|
||
- `_bloomEnsure()` / `_bloomDispose()` — EffectComposer + UnrealBloomPass
|
||
(0.65/0.5/0.82) on a multisampled HalfFloat target, ACES↔None tone-
|
||
mapping switch in `draw()`; addons dynamic-imported from
|
||
`/static/vendor/three/addons/` (no CDN fallback — direct render is the
|
||
graceful degrade)
|
||
|
||
## License
|
||
|
||
AGPL-3.0.
|