mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-18 14:32:43 +00:00
feat(highway_3d): cap the fret-wire flash at one outer pair
Fast passages overlap their decay tails: consecutive notes on nearby frets left three, four, five wires glowing at once — the picket fence the chord rule was written to avoid, arriving through time instead of through a shape. The apply pass now decays every wire's glow state as before, but flashes only the outermost pair of the lit span (or the single wire when only one is above threshold). Interior wires keep decaying invisibly — the base tier loop re-seeds their materials each frame — so the bracket tightens naturally as the outer tails expire, and a hit inside the current span widens nothing. Net effect: at most two wires are ever lit, and everything currently glowing reads as one bracket, exactly like a chord. Signed-off-by: topkoa <topkoa@gmail.com>
This commit is contained in:
+4
-2
@@ -49,8 +49,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
bracketing it light up. A fretted note lights the wire behind it and the wire it's
|
bracketing it light up. A fretted note lights the wire behind it and the wire it's
|
||||||
pressed against; a chord lights only the outermost wires of its shape; an open
|
pressed against; a chord lights only the outermost wires of its shape; an open
|
||||||
string lights the anchor lane's edge wires (its gem is drawn as a slab spanning the
|
string lights the anchor lane's edge wires (its gem is drawn as a slab spanning the
|
||||||
lane, so those are the wires it sits between). With no scorer attached, nothing
|
lane, so those are the wires it sits between). At most **two wires are ever lit at
|
||||||
changes.
|
once**: when overlapping decay tails (fast passages) would light a run of wires, the
|
||||||
|
flash collapses to the outermost pair of the lit span — one bracket, never a picket
|
||||||
|
fence. With no scorer attached, nothing changes.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- **`GET /api/song/{f}?stems=1`** (new, opt-in) — returns the pack's playable stem
|
- **`GET /api/song/{f}?stems=1`** (new, opt-in) — returns the pack's playable stem
|
||||||
|
|||||||
@@ -12680,10 +12680,28 @@
|
|||||||
? Math.exp(-_fwDt / FRET_WIRE_HIT_DECAY)
|
? Math.exp(-_fwDt / FRET_WIRE_HIT_DECAY)
|
||||||
: 0;
|
: 0;
|
||||||
_fwHitPrevTime = now;
|
_fwHitPrevTime = now;
|
||||||
|
// Decay EVERY wire's glow state, but flash only the OUTERMOST
|
||||||
|
// pair of lit wires. Fast passages overlap their decay tails, so
|
||||||
|
// without this a run of consecutive notes lights a picket fence
|
||||||
|
// of wires at once; collapsing to the outer pair keeps the whole
|
||||||
|
// lit span reading as ONE bracket — the same rule chords already
|
||||||
|
// follow, applied across everything currently glowing. Interior
|
||||||
|
// wires keep decaying invisibly (the base tier loop re-seeds
|
||||||
|
// their materials each frame), so the bracket tightens naturally
|
||||||
|
// as outer tails expire.
|
||||||
|
let _fwLo = -1, _fwHi = -1;
|
||||||
for (let _f = 0; _f <= NFRETS; _f++) {
|
for (let _f = 0; _f <= NFRETS; _f++) {
|
||||||
const _g = Math.max(_fwHitIn[_f], _fwHitGlow[_f] * _fwDecay);
|
const _g = Math.max(_fwHitIn[_f], _fwHitGlow[_f] * _fwDecay);
|
||||||
_fwHitGlow[_f] = _g;
|
_fwHitGlow[_f] = _g;
|
||||||
if (_g < 0.004) continue; // below perceptible — skip the lerps
|
if (_g < 0.004) continue; // below perceptible
|
||||||
|
if (_fwLo < 0) _fwLo = _f;
|
||||||
|
_fwHi = _f;
|
||||||
|
}
|
||||||
|
for (let _i = 0; _i < 2; _i++) {
|
||||||
|
const _f = _i === 0 ? _fwLo : _fwHi;
|
||||||
|
if (_f < 0) break; // nothing lit
|
||||||
|
if (_i === 1 && _f === _fwLo) break; // single wire lit
|
||||||
|
const _g = _fwHitGlow[_f];
|
||||||
const _m = fretWireMats[_f];
|
const _m = fretWireMats[_f];
|
||||||
if (!_m) continue;
|
if (!_m) continue;
|
||||||
_m.color.lerp(_fwHitColor, _g);
|
_m.color.lerp(_fwHitColor, _g);
|
||||||
|
|||||||
Reference in New Issue
Block a user