mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-12 11:49:28 +00:00
fix(bend): GP8 short-bend curve loss + 2D curve timing + 3D bnv gating (#535)
Post-merge Codex review of the bend-curve PRs (#531/#532) surfaced edge cases: - GP8 (#531 P2): bnv timing used rn.sustain, which is zeroed for notes <= 0.2s, so short GP8 bends kept the scalar bn but lost bt/bnv. Use the beat duration `dur` (matching the GP5 path) so the curve survives. - 2D highway (#532 P2): bnvNormalizedPoints mapped x over the curve's own t-range [first,last] instead of the note span, so curves not starting at 0 / ending at sus were time-distorted. Now maps over [0, sus] (clamped), with a curve-span fallback when sus<=0 (existing no-sus callers unaffected). - 3D highway (#532 P3): the sustain ribbon + bend chevron were gated on bn>0, so a note carrying an authoritative bnv with bn==0 drew no ribbon/marker. Both now also fire on bnv presence; chevron steps derived from max(bn, bnv peak). Codex-reviewed: clean (no findings). +1 JS test (sus-relative mapping + fallback). JS 8/8, 250 core GP/song tests pass. NB: GP8's short-bend path still lacks a dedicated synthetic-GPIF fixture (same gap as the GP8 offset-prop-names P3) — _gpx_bend_shape units cover the function; the fix is the one-line caller change. Part of got-feedback/feedback#334. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
351b273ab5
commit
a858617d71
@@ -30,13 +30,26 @@ const bnvSampleAt = loadFn('plugins/highway_3d/screen.js', 'bnvSampleAt');
|
||||
|
||||
// ── bnvNormalizedPoints (2D) ─────────────────────────────────────────────────
|
||||
|
||||
test('bnvNormalizedPoints normalizes t to 0..1 across the span', () => {
|
||||
test('bnvNormalizedPoints normalizes t to 0..1 across the curve span (no sus)', () => {
|
||||
const pts = bnvNormalizedPoints([
|
||||
{ t: 0.5, v: 0 }, { t: 1.0, v: 2 }, { t: 1.5, v: 0 }]);
|
||||
assert.deepEqual(pts, [
|
||||
{ x: 0, v: 0 }, { x: 0.5, v: 2 }, { x: 1, v: 0 }]);
|
||||
});
|
||||
|
||||
test('bnvNormalizedPoints maps t over the note sus span when given', () => {
|
||||
// A bend that completes at t=0.4 of a 0.5s note draws to x=0.8, not x=1 —
|
||||
// i.e. it stops short of the glyph's right edge (correct timing shape).
|
||||
assert.deepEqual(
|
||||
bnvNormalizedPoints([{ t: 0, v: 0 }, { t: 0.25, v: 1 }, { t: 0.4, v: 0 }], 0.5),
|
||||
[{ x: 0, v: 0 }, { x: 0.5, v: 1 }, { x: 0.8, v: 0 }]);
|
||||
// Points beyond sus clamp to 1; sus<=0 falls back to curve-span mapping.
|
||||
assert.deepEqual(bnvNormalizedPoints([{ t: 0, v: 0 }, { t: 1, v: 2 }], 0.5),
|
||||
[{ x: 0, v: 0 }, { x: 1, v: 2 }]);
|
||||
assert.deepEqual(bnvNormalizedPoints([{ t: 0, v: 0 }, { t: 1, v: 2 }], 0),
|
||||
[{ x: 0, v: 0 }, { x: 1, v: 2 }]);
|
||||
});
|
||||
|
||||
test('bnvNormalizedPoints handles degenerate/empty input', () => {
|
||||
assert.deepEqual(bnvNormalizedPoints([]), []);
|
||||
assert.deepEqual(bnvNormalizedPoints(null), []);
|
||||
|
||||
Reference in New Issue
Block a user