Γ-W1-T3: staged contour traces draw the curve their exponent defines

New pure curve_tessellate joins the overlay's node vertices through curveMap,
one sample per pixel column; the knot no longer floats off its own trace.
This commit is contained in:
2026-08-01 18:43:55 -04:00
parent ab3548dced
commit f39fb1b145
7 changed files with 507 additions and 9 deletions
+1
View File
@@ -91,6 +91,7 @@ if(WIN32 AND EXISTS "${VST3_SDK}/public.sdk/source/main/pluginfactory.cpp")
knob_deck deck_groups deck_values curve_popup spline_edit master_gain sample_usage
bake_hold
file_bytes curve_law stroke_aa
curve_tessellate
bake_plan bake_render bake_reset bake_wire wav_codec)
# SDK_INC gives the REAPER VST3 interfaces + API header for the bridge; WDL_INC gives
# LICE for the editor. The VST3 SDK headers arrive via vst3_sdk PUBLIC.
@@ -13,6 +13,7 @@
#include <vector>
#include "core/audio/peaks.h" // computeEnvelope (waveform binning)
#include "core/instrument/ui/curve_tessellate.h" // buildEnvelopeTrace (the staged trace)
#include "core/instrument/ui/spline_edit.h" // splineOverlayBox (the contour's mapping box)
#include "core/instrument/ui/waveform_view.h" // waveformSurface / laneEnvelope / frameToX
#include "shell/instrument/editor_internal.h" // kit adapters
@@ -212,17 +213,9 @@ void ReaSamplerEditor::paintEnvelopeOverlay(LICE_IBitmap* bmp, const OverlayArea
const StageEnvelope env = packEnvelope(overlayEnv_, params_.play, frames, startFrame);
const std::vector<EnvVertex> poly = buildEnvelopePolyline(env, waveArea, totalSeconds);
// Clip x to the wave rect. Knots are handles, not line vertices. Vertices stay INTEGER here
// — unlike the spline traces above — because they are the same positions the draggable
// handles are drawn at, and a sub-pixel trace would sit off its own handles.
const LICE_pixel line = toLice(roleColor(Role::OverlayTrace));
std::vector<ui::StrokePoint>& trace = scratchPoints();
trace.clear();
for (const EnvVertex& v : poly) {
if (v.knot) continue;
const int vx = (std::max)(area.x, (std::min)(area.right() - 1, v.x));
trace.push_back(ui::StrokePoint{static_cast<float>(vx), static_cast<float>(v.y)});
}
buildEnvelopeTrace(poly, env, area.x, area.right() - 1, trace);
// A degenerate envelope (every stage collapsed to zero span) can reduce this to ONE vertex.
// strokePolylineAA's round-cap zero-length case then draws a dot at it, marking the sole
// point rather than drawing nothing — kept deliberately as more legible than a blank trace.