Summary
Allow a different interp (linear / cubic / step) to be specified per breakpoint macrozone, not just per loop block. Today only loop blocks carry an interp; standalone BP runs in a mixed envelope can only fall back to linear.
Current behaviour (envelopes-reference §2 + §5)
| Shape |
Interp |
Combinable with loops? |
[item, item, …] (mixed array) |
per loop block (item[3]) |
yes |
{type, points: [[t,v]…]} (typed) |
one global interp for ALL points |
no |
- Pure-BP envelope: one interp for the whole curve.
- Mixed envelope (BPs + loops): interp on each loop, but every standalone BP run is implicitly
linear.
- Two BP macrozones in the same envelope cannot have different interps.
Goal
Two BP macrozones in the same envelope should interpolate differently. Example: cubic fade-in → step ladder → linear tail, possibly with a loop block between them.
# illustrative
density_env:
- [0.0, 0]
- [0.2, 12] # group A — wants cubic
- [0.4, 8]
- [[[0,8],[50,18],[100,8]], 0.7, 4, 'linear', 'linear'] # loop
- [0.75, 6] # group B — wants step
- [0.9, 6]
- [1.0, 0]
Proposed data model — Option 2 (preferred)
Wrap a run of BPs in a compact group carrying its own interp, symmetric with loop blocks:
# [points, interp] — a "BP group" item
- [[[0.0, 0], [0.2, 12], [0.4, 8]], 'cubic']
- [[[0,8],[50,18],[100,8]], 0.7, 4, 'linear', 'linear'] # loop block, unchanged
- [[[0.75, 6], [0.9, 6], [1.0, 0]], 'step']
Tuple length discriminates BP group (2 elements: points + interp) from loop block (4–5 elements). Needs a new check in isCompactBlock / isBPGroup.
Alternative options considered
Option 1 — interp sentinel item
- {interp: cubic}
- [0.0, 0]
- [0.2, 12]
- {interp: step}
- [0.75, 6]
Backward compatible, but mixes dicts into the list array.
Option 3 — typed dict nested inside mixed array
- {type: cubic, points: [[0.0,0],[0.2,12]]}
- {type: step, points: [[0.75,6],[0.9,6]]}
Reuses existing shape but risks ambiguity at top level.
Compatibility & migration
- Existing
[item, item, …] envelopes: unchanged. Bare BPs keep linear.
- Existing
{type, points} envelopes: unchanged (pure-BP global-interp form still valid).
fmtEnvInline needs an emitter branch for the new BP-group form.
parseEnvLiteral needs a shape check / isBPGroup helper.
UI consequences (PGE-ui)
- Per-BP-macrozone
interp selector in the macro-zones bar (same control loop blocks already have).
- Drop the top-right global interp selector when the envelope contains more than one macrozone.
expandMixed must propagate per-zone interp so the curve renders with the right per-segment interpolation.
Acceptance criteria
Out of scope
- Per-segment interpolation inside a BP zone.
- Per-cycle interpolation inside a loop.
Summary
Allow a different
interp(linear/cubic/step) to be specified per breakpoint macrozone, not just per loop block. Today only loop blocks carry an interp; standalone BP runs in a mixed envelope can only fall back tolinear.Current behaviour (envelopes-reference §2 + §5)
[item, item, …](mixed array){type, points: [[t,v]…]}(typed)linear.Goal
Two BP macrozones in the same envelope should interpolate differently. Example:
cubicfade-in →stepladder →lineartail, possibly with a loop block between them.Proposed data model — Option 2 (preferred)
Wrap a run of BPs in a compact group carrying its own interp, symmetric with loop blocks:
Tuple length discriminates BP group (2 elements:
points+interp) from loop block (4–5 elements). Needs a new check inisCompactBlock/isBPGroup.Alternative options considered
Option 1 — interp sentinel item
Backward compatible, but mixes dicts into the list array.
Option 3 — typed dict nested inside mixed array
Reuses existing shape but risks ambiguity at top level.
Compatibility & migration
[item, item, …]envelopes: unchanged. Bare BPs keeplinear.{type, points}envelopes: unchanged (pure-BP global-interp form still valid).fmtEnvInlineneeds an emitter branch for the new BP-group form.parseEnvLiteralneeds a shape check /isBPGrouphelper.UI consequences (PGE-ui)
interpselector in the macro-zones bar (same control loop blocks already have).expandMixedmust propagate per-zone interp so the curve renders with the right per-segment interpolation.Acceptance criteria
interpselector and writes the new form.cubicBP groups use PCHIP (Fritsch–Carlson monotone) — same as editor preview.DISCONTINUITY_OFFSETrule.Out of scope